aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-05-30 15:11:26 -0400
committerH. Peter Anvin <hpa@zytor.com>2012-05-30 15:11:32 -0400
commitbbd771474ec44b516107685d77e1c80bbe09f141 (patch)
tree0cb15781539a68f27b4ea6c89f827282630cbce6 /arch
parent403e1c5b7495d7b80fae9fc4d0a7a6f5abdc3307 (diff)
parent319b6ffc6df892e4ccffff823cc5521a4a5d2dca (diff)
Merge branch 'x86/trampoline' into x86/urgent
x86/trampoline contains an urgent commit which is necessarily on a newer baseline. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig3
-rw-r--r--arch/alpha/include/asm/kvm_para.h1
-rw-r--r--arch/arm/Kconfig16
-rw-r--r--arch/arm/Kconfig.debug37
-rw-r--r--arch/arm/Makefile8
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts48
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi60
-rw-r--r--arch/arm/boot/dts/imx23-evk.dts43
-rw-r--r--arch/arm/boot/dts/imx23.dtsi295
-rw-r--r--arch/arm/boot/dts/imx27-phytec-phycore.dts8
-rw-r--r--arch/arm/boot/dts/imx27.dtsi14
-rw-r--r--arch/arm/boot/dts/imx28-evk.dts114
-rw-r--r--arch/arm/boot/dts/imx28.dtsi497
-rw-r--r--arch/arm/boot/dts/imx51-babbage.dts40
-rw-r--r--arch/arm/boot/dts/imx51.dtsi41
-rw-r--r--arch/arm/boot/dts/imx53-ard.dts6
-rw-r--r--arch/arm/boot/dts/imx53-evk.dts8
-rw-r--r--arch/arm/boot/dts/imx53-qsb.dts121
-rw-r--r--arch/arm/boot/dts/imx53-smd.dts16
-rw-r--r--arch/arm/boot/dts/imx53.dtsi45
-rw-r--r--arch/arm/boot/dts/imx6q-arm2.dts15
-rw-r--r--arch/arm/boot/dts/imx6q-sabrelite.dts50
-rw-r--r--arch/arm/boot/dts/imx6q-sabresd.dts53
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi171
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts2
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts4
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts6
-rw-r--r--arch/arm/boot/dts/spear1310-evb.dts292
-rw-r--r--arch/arm/boot/dts/spear1310.dtsi184
-rw-r--r--arch/arm/boot/dts/spear1340-evb.dts308
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi56
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi262
-rw-r--r--arch/arm/boot/dts/spear300-evb.dts25
-rw-r--r--arch/arm/boot/dts/spear310-evb.dts20
-rw-r--r--arch/arm/boot/dts/spear320-evb.dts25
-rw-r--r--arch/arm/boot/dts/spear3xx.dtsi6
-rw-r--r--arch/arm/boot/dts/spear600-evb.dts29
-rw-r--r--arch/arm/boot/dts/spear600.dtsi6
-rw-r--r--arch/arm/boot/dts/tegra-cardhu.dts110
-rw-r--r--arch/arm/boot/dts/tegra-harmony.dts118
-rw-r--r--arch/arm/boot/dts/tegra-paz00.dts128
-rw-r--r--arch/arm/boot/dts/tegra-seaboard.dts213
-rw-r--r--arch/arm/boot/dts/tegra-trimslice.dts99
-rw-r--r--arch/arm/boot/dts/tegra-ventana.dts96
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi275
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi305
-rw-r--r--arch/arm/common/dmabounce.c84
-rw-r--r--arch/arm/configs/imx_v4_v5_defconfig3
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig8
-rw-r--r--arch/arm/configs/mxs_defconfig1
-rw-r--r--arch/arm/configs/prima2_defconfig69
-rw-r--r--arch/arm/configs/spear13xx_defconfig95
-rw-r--r--arch/arm/configs/spear3xx_defconfig4
-rw-r--r--arch/arm/configs/spear6xx_defconfig5
-rw-r--r--arch/arm/configs/tegra_defconfig11
-rw-r--r--arch/arm/include/asm/device.h4
-rw-r--r--arch/arm/include/asm/dma-contiguous.h15
-rw-r--r--arch/arm/include/asm/dma-iommu.h34
-rw-r--r--arch/arm/include/asm/dma-mapping.h407
-rw-r--r--arch/arm/include/asm/hardware/pl080.h2
-rw-r--r--arch/arm/include/asm/io.h24
-rw-r--r--arch/arm/include/asm/kvm_para.h1
-rw-r--r--arch/arm/include/asm/mach/arch.h1
-rw-r--r--arch/arm/include/asm/mach/map.h1
-rw-r--r--arch/arm/include/asm/thread_info.h8
-rw-r--r--arch/arm/kernel/entry-common.S8
-rw-r--r--arch/arm/kernel/ptrace.c3
-rw-r--r--arch/arm/kernel/setup.c17
-rw-r--r--arch/arm/kernel/signal.c85
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/kernel/traps.c2
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c1
-rw-r--r--arch/arm/mach-at91/include/mach/at_hdmac.h26
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c1
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c1
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c2
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c1
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c1
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c1
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c1
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c1
-rw-r--r--arch/arm/mach-davinci/clock.c3
-rw-r--r--arch/arm/mach-davinci/common.c7
-rw-r--r--arch/arm/mach-davinci/cpufreq.c3
-rw-r--r--arch/arm/mach-davinci/dma.c69
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h19
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S58
-rw-r--r--arch/arm/mach-davinci/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h10
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h30
-rw-r--r--arch/arm/mach-davinci/pm.c3
-rw-r--r--arch/arm/mach-dove/common.c39
-rw-r--r--arch/arm/mach-dove/dove-db-setup.c1
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c1
-rw-r--r--arch/arm/mach-ep93xx/core.c7
-rw-r--r--arch/arm/mach-ep93xx/crunch.c4
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c8
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c1
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h7
-rw-r--r--arch/arm/mach-ep93xx/micro9.c4
-rw-r--r--arch/arm/mach-ep93xx/simone.c1
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c1
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c1
-rw-r--r--arch/arm/mach-ep93xx/vision_ep9307.c1
-rw-r--r--arch/arm/mach-exynos/Kconfig24
-rw-r--r--arch/arm/mach-exynos/Makefile7
-rw-r--r--arch/arm/mach-exynos/Makefile.boot3
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c79
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.h2
-rw-r--r--arch/arm/mach-exynos/clock-exynos4210.c11
-rw-r--r--arch/arm/mach-exynos/clock-exynos4212.c38
-rw-r--r--arch/arm/mach-exynos/clock-exynos5.c141
-rw-r--r--arch/arm/mach-exynos/common.c187
-rw-r--r--arch/arm/mach-exynos/common.h7
-rw-r--r--arch/arm/mach-exynos/dev-drm.c29
-rw-r--r--arch/arm/mach-exynos/dev-sysmmu.c457
-rw-r--r--arch/arm/mach-exynos/dma.c141
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h65
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h45
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-clock.h7
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu.h10
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-sysmmu.h28
-rw-r--r--arch/arm/mach-exynos/include/mach/spi-clocks.h2
-rw-r--r--arch/arm/mach-exynos/include/mach/sysmmu.h88
-rw-r--r--arch/arm/mach-exynos/mach-armlex4210.c2
-rw-r--r--arch/arm/mach-exynos/mach-exynos4-dt.c1
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c5
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c1
-rw-r--r--arch/arm/mach-exynos/mach-origen.c1
-rw-r--r--arch/arm/mach-exynos/mach-smdk4x12.c1
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c2
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c1
-rw-r--r--arch/arm/mach-exynos/mct.c17
-rw-r--r--arch/arm/mach-exynos/pm.c4
-rw-r--r--arch/arm/mach-exynos/pm_domains.c3
-rw-r--r--arch/arm/mach-exynos/pmu.c24
-rw-r--r--arch/arm/mach-imx/Kconfig8
-rw-r--r--arch/arm/mach-imx/Makefile19
-rw-r--r--arch/arm/mach-imx/Makefile.boot3
-rw-r--r--arch/arm/mach-imx/clk-busy.c189
-rw-r--r--arch/arm/mach-imx/clk-gate2.c118
-rw-r--r--arch/arm/mach-imx/clk-imx1.c115
-rw-r--r--arch/arm/mach-imx/clk-imx21.c186
-rw-r--r--arch/arm/mach-imx/clk-imx25.c248
-rw-r--r--arch/arm/mach-imx/clk-imx27.c290
-rw-r--r--arch/arm/mach-imx/clk-imx31.c182
-rw-r--r--arch/arm/mach-imx/clk-imx35.c278
-rw-r--r--arch/arm/mach-imx/clk-imx51-imx53.c506
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c444
-rw-r--r--arch/arm/mach-imx/clk-pfd.c147
-rw-r--r--arch/arm/mach-imx/clk-pllv1.c66
-rw-r--r--arch/arm/mach-imx/clk-pllv2.c249
-rw-r--r--arch/arm/mach-imx/clk-pllv3.c419
-rw-r--r--arch/arm/mach-imx/clk.h83
-rw-r--r--arch/arm/mach-imx/clock-imx1.c636
-rw-r--r--arch/arm/mach-imx/clock-imx21.c1239
-rw-r--r--arch/arm/mach-imx/clock-imx25.c346
-rw-r--r--arch/arm/mach-imx/clock-imx27.c785
-rw-r--r--arch/arm/mach-imx/clock-imx31.c630
-rw-r--r--arch/arm/mach-imx/clock-imx35.c536
-rw-r--r--arch/arm/mach-imx/clock-imx6q.c2111
-rw-r--r--arch/arm/mach-imx/clock-mx51-mx53.c1675
-rw-r--r--arch/arm/mach-imx/cpu-imx5.c6
-rw-r--r--arch/arm/mach-imx/crmregs-imx3.h79
-rw-r--r--arch/arm/mach-imx/imx51-dt.c1
-rw-r--r--arch/arm/mach-imx/imx53-dt.c19
-rw-r--r--arch/arm/mach-imx/lluart.c6
-rw-r--r--arch/arm/mach-imx/mach-cpuimx51sd.c1
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c55
-rw-r--r--arch/arm/mach-imx/mach-mx51_3ds.c1
-rw-r--r--arch/arm/mach-imx/mach-mx51_babbage.c7
-rw-r--r--arch/arm/mach-imx/mach-mx51_efikamx.c42
-rw-r--r--arch/arm/mach-imx/mach-mx51_efikasb.c28
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c6
-rw-r--r--arch/arm/mach-imx/mach-pcm037_eet.c5
-rw-r--r--arch/arm/mach-imx/mm-imx3.c6
-rw-r--r--arch/arm/mach-imx/mm-imx5.c6
-rw-r--r--arch/arm/mach-imx/pcm037.h6
-rw-r--r--arch/arm/mach-imx/pm-imx3.c4
-rw-r--r--arch/arm/mach-kirkwood/board-dreamplug.c1
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c3
-rw-r--r--arch/arm/mach-kirkwood/common.c286
-rw-r--r--arch/arm/mach-kirkwood/common.h1
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h16
-rw-r--r--arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c1
-rw-r--r--arch/arm/mach-kirkwood/pcie.c25
-rw-r--r--arch/arm/mach-kirkwood/rd88f6192-nas-setup.c1
-rw-r--r--arch/arm/mach-kirkwood/t5325-setup.c1
-rw-r--r--arch/arm/mach-kirkwood/tsx1x-common.c1
-rw-r--r--arch/arm/mach-msm/board-halibut.c6
-rw-r--r--arch/arm/mach-msm/board-mahimahi.c6
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c9
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c8
-rw-r--r--arch/arm/mach-msm/board-msm8960.c7
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c10
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c7
-rw-r--r--arch/arm/mach-msm/board-sapphire.c6
-rw-r--r--arch/arm/mach-msm/board-trout.c6
-rw-r--r--arch/arm/mach-msm/include/mach/board.h6
-rw-r--r--arch/arm/mach-msm/smd_debug.c3
-rw-r--r--arch/arm/mach-mv78xx0/common.c45
-rw-r--r--arch/arm/mach-mxs/Kconfig10
-rw-r--r--arch/arm/mach-mxs/Makefile6
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c536
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c803
-rw-r--r--arch/arm/mach-mxs/clock.c211
-rw-r--r--arch/arm/mach-mxs/devices/Kconfig1
-rw-r--r--arch/arm/mach-mxs/devices/platform-dma.c21
-rw-r--r--arch/arm/mach-mxs/devices/platform-gpio-mxs.c24
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c21
-rw-r--r--arch/arm/mach-mxs/include/mach/clock.h62
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h11
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h3
-rw-r--r--arch/arm/mach-mxs/include/mach/mmc.h18
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c2
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c121
-rw-r--r--arch/arm/mach-mxs/mm.c16
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx23.h331
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx28.h486
-rw-r--r--arch/arm/mach-mxs/system.c16
-rw-r--r--arch/arm/mach-mxs/timer.c11
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c8
-rw-r--r--arch/arm/mach-omap1/board-fsample.c1
-rw-r--r--arch/arm/mach-omap1/board-generic.c1
-rw-r--r--arch/arm/mach-omap1/board-h2.c1
-rw-r--r--arch/arm/mach-omap1/board-h3.c1
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c1
-rw-r--r--arch/arm/mach-omap1/board-innovator.c1
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c1
-rw-r--r--arch/arm/mach-omap1/board-osk.c1
-rw-r--r--arch/arm/mach-omap1/board-palmte.c1
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c1
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c1
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c1
-rw-r--r--arch/arm/mach-omap1/board-sx1.c1
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c1
-rw-r--r--arch/arm/mach-omap1/common.h19
-rw-r--r--arch/arm/mach-omap1/devices.c121
-rw-r--r--arch/arm/mach-omap1/io.c5
-rw-r--r--arch/arm/mach-omap1/serial.c3
-rw-r--r--arch/arm/mach-omap1/time.c16
-rw-r--r--arch/arm/mach-omap1/timer32k.c28
-rw-r--r--arch/arm/mach-omap2/Kconfig8
-rw-r--r--arch/arm/mach-omap2/Makefile167
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c1
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c1
-rw-r--r--arch/arm/mach-omap2/board-apollon.c1
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c1
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c1
-rw-r--r--arch/arm/mach-omap2/board-generic.c1
-rw-r--r--arch/arm/mach-omap2/board-h4.c1
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c2
-rw-r--r--arch/arm/mach-omap2/board-ldp.c1
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c3
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c2
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c1
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c1
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/board-rm680.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51.c1
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c2
-rw-r--r--arch/arm/mach-omap2/board-zoom.c2
-rw-r--r--arch/arm/mach-omap2/common.h51
-rw-r--r--arch/arm/mach-omap2/devices.c19
-rw-r--r--arch/arm/mach-omap2/dma.c11
-rw-r--r--arch/arm/mach-omap2/dsp.c27
-rw-r--r--arch/arm/mach-omap2/gpmc.c30
-rw-r--r--arch/arm/mach-omap2/hsmmc.c8
-rw-r--r--arch/arm/mach-omap2/id.c7
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-wakeupgen.h8
-rw-r--r--arch/arm/mach-omap2/io.c101
-rw-r--r--arch/arm/mach-omap2/iomap.h28
-rw-r--r--arch/arm/mach-omap2/irq.c2
-rw-r--r--arch/arm/mach-omap2/mux.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/pm.c3
-rw-r--r--arch/arm/mach-omap2/pm24xx.c17
-rw-r--r--arch/arm/mach-omap2/pm34xx.c7
-rw-r--r--arch/arm/mach-omap2/pm44xx.c6
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/timer.c118
-rw-r--r--arch/arm/mach-omap2/usb-musb.c2
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c2
-rw-r--r--arch/arm/mach-orion5x/common.c27
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c1
-rw-r--r--arch/arm/mach-pnx4008/core.c12
-rw-r--r--arch/arm/mach-pnx4008/pm.c4
-rw-r--r--arch/arm/mach-prima2/common.h6
-rw-r--r--arch/arm/mach-prima2/pm.c3
-rw-r--r--arch/arm/mach-prima2/prima2.c6
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig5
-rw-r--r--arch/arm/mach-s3c24xx/Makefile7
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2416.c1
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2443.c6
-rw-r--r--arch/arm/mach-s3c24xx/common-s3c2443.c15
-rw-r--r--arch/arm/mach-s3c24xx/common.c (renamed from arch/arm/plat-s3c24xx/cpu.c)69
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2443.c16
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/dma.h4
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/map.h5
-rw-r--r--arch/arm/mach-s3c24xx/irq-pm.c (renamed from arch/arm/plat-s3c24xx/irq-pm.c)0
-rw-r--r--arch/arm/mach-s3c24xx/pm.c (renamed from arch/arm/plat-s3c24xx/pm.c)0
-rw-r--r--arch/arm/mach-s3c24xx/setup-spi.c39
-rw-r--r--arch/arm/mach-s3c24xx/sleep.S (renamed from arch/arm/plat-s3c24xx/sleep.S)0
-rw-r--r--arch/arm/mach-s3c64xx/common.c5
-rw-r--r--arch/arm/mach-s3c64xx/common.h7
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c1
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c1
-rw-r--r--arch/arm/mach-s3c64xx/pm.c3
-rw-r--r--arch/arm/mach-sa1100/assabet.c1
-rw-r--r--arch/arm/mach-sa1100/badge4.c1
-rw-r--r--arch/arm/mach-sa1100/cerf.c1
-rw-r--r--arch/arm/mach-sa1100/collie.c1
-rw-r--r--arch/arm/mach-sa1100/generic.c4
-rw-r--r--arch/arm/mach-sa1100/generic.h7
-rw-r--r--arch/arm/mach-sa1100/h3100.c1
-rw-r--r--arch/arm/mach-sa1100/h3600.c1
-rw-r--r--arch/arm/mach-sa1100/hackkit.c1
-rw-r--r--arch/arm/mach-sa1100/jornada720.c1
-rw-r--r--arch/arm/mach-sa1100/lart.c1
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c1
-rw-r--r--arch/arm/mach-sa1100/neponset.c1
-rw-r--r--arch/arm/mach-sa1100/pleb.c1
-rw-r--r--arch/arm/mach-sa1100/pm.c4
-rw-r--r--arch/arm/mach-sa1100/shannon.c1
-rw-r--r--arch/arm/mach-sa1100/simpad.c1
-rw-r--r--arch/arm/mach-shmobile/Makefile2
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c1
-rw-r--r--arch/arm/mach-shmobile/board-bonito.c1
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c1
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c1
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c1
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c1
-rw-r--r--arch/arm/mach-shmobile/common.c24
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c3
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h14
-rw-r--r--arch/arm/mach-shmobile/suspend.c3
-rw-r--r--arch/arm/mach-spear13xx/Kconfig20
-rw-r--r--arch/arm/mach-spear13xx/Makefile10
-rw-r--r--arch/arm/mach-spear13xx/Makefile.boot6
-rw-r--r--arch/arm/mach-spear13xx/headsmp.S47
-rw-r--r--arch/arm/mach-spear13xx/hotplug.c119
-rw-r--r--arch/arm/mach-spear13xx/include/mach/debug-macro.S14
-rw-r--r--arch/arm/mach-spear13xx/include/mach/dma.h128
-rw-r--r--arch/arm/mach-spear13xx/include/mach/generic.h49
-rw-r--r--arch/arm/mach-spear13xx/include/mach/gpio.h19
-rw-r--r--arch/arm/mach-spear13xx/include/mach/hardware.h1
-rw-r--r--arch/arm/mach-spear13xx/include/mach/irqs.h20
-rw-r--r--arch/arm/mach-spear13xx/include/mach/spear.h62
-rw-r--r--arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h0
-rw-r--r--arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h0
-rw-r--r--arch/arm/mach-spear13xx/include/mach/timex.h19
-rw-r--r--arch/arm/mach-spear13xx/include/mach/uncompress.h19
-rw-r--r--arch/arm/mach-spear13xx/platsmp.c127
-rw-r--r--arch/arm/mach-spear13xx/spear1310.c88
-rw-r--r--arch/arm/mach-spear13xx/spear1340.c192
-rw-r--r--arch/arm/mach-spear13xx/spear13xx.c197
-rw-r--r--arch/arm/mach-spear3xx/Makefile2
-rw-r--r--arch/arm/mach-spear3xx/clock.c892
-rw-r--r--arch/arm/mach-spear3xx/include/mach/generic.h21
-rw-r--r--arch/arm/mach-spear3xx/include/mach/irqs.h1
-rw-r--r--arch/arm/mach-spear3xx/include/mach/misc_regs.h2
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear.h14
-rw-r--r--arch/arm/mach-spear3xx/spear300.c1
-rw-r--r--arch/arm/mach-spear3xx/spear310.c1
-rw-r--r--arch/arm/mach-spear3xx/spear320.c12
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c4
-rw-r--r--arch/arm/mach-spear6xx/Makefile2
-rw-r--r--arch/arm/mach-spear6xx/clock.c789
-rw-r--r--arch/arm/mach-spear6xx/include/mach/generic.h2
-rw-r--r--arch/arm/mach-spear6xx/include/mach/irqs.h3
-rw-r--r--arch/arm/mach-spear6xx/include/mach/misc_regs.h2
-rw-r--r--arch/arm/mach-spear6xx/include/mach/spear.h1
-rw-r--r--arch/arm/mach-spear6xx/spear6xx.c7
-rw-r--r--arch/arm/mach-tegra/Kconfig37
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c1
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c11
-rw-r--r--arch/arm/mach-tegra/board-harmony.c1
-rw-r--r--arch/arm/mach-tegra/board-paz00.c4
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c3
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c3
-rw-r--r--arch/arm/mach-tegra/board.h14
-rw-r--r--arch/arm/mach-tegra/clock.c3
-rw-r--r--arch/arm/mach-tegra/common.c28
-rw-r--r--arch/arm/mach-tegra/devices.c5
-rw-r--r--arch/arm/mach-tegra/devices.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra-ahb.h19
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h176
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h4
-rw-r--r--arch/arm/mach-tegra/powergate.c4
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c4
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks.c9
-rw-r--r--arch/arm/mach-tegra/usb_phy.c15
-rw-r--r--arch/arm/mach-ux500/board-mop500.c6
-rw-r--r--arch/arm/mach-ux500/clock.c6
-rw-r--r--arch/arm/mach-ux500/clock.h12
-rw-r--r--arch/arm/mach-ux500/cpu.c6
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h1
-rw-r--r--arch/arm/mm/dma-mapping.c1348
-rw-r--r--arch/arm/mm/init.c23
-rw-r--r--arch/arm/mm/mm.h3
-rw-r--r--arch/arm/mm/mmu.c31
-rw-r--r--arch/arm/mm/vmregion.h2
-rw-r--r--arch/arm/plat-mxc/clock.c11
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx6q.h2
-rw-r--r--arch/arm/plat-mxc/time.c14
-rw-r--r--arch/arm/plat-omap/counter_32k.c93
-rw-r--r--arch/arm/plat-omap/devices.c122
-rw-r--r--arch/arm/plat-omap/dma.c4
-rw-r--r--arch/arm/plat-omap/dmtimer.c2
-rw-r--r--arch/arm/plat-omap/include/plat/common.h2
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h8
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h5
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h1
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h9
-rw-r--r--arch/arm/plat-orion/common.c104
-rw-r--r--arch/arm/plat-orion/include/plat/common.h34
-rw-r--r--arch/arm/plat-orion/include/plat/orion_wdt.h18
-rw-r--r--arch/arm/plat-orion/pcie.c4
-rw-r--r--arch/arm/plat-pxa/include/plat/pxa27x_keypad.h4
-rw-r--r--arch/arm/plat-s3c24xx/Makefile6
-rw-r--r--arch/arm/plat-s3c24xx/clock.c59
-rw-r--r--arch/arm/plat-s3c24xx/dev-uart.c100
-rw-r--r--arch/arm/plat-s5p/Kconfig140
-rw-r--r--arch/arm/plat-s5p/Makefile28
-rw-r--r--arch/arm/plat-s5p/sysmmu.c313
-rw-r--r--arch/arm/plat-samsung/Kconfig142
-rw-r--r--arch/arm/plat-samsung/Makefile13
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p-clock.h4
-rw-r--r--arch/arm/plat-samsung/include/plat/sysmmu.h95
-rw-r--r--arch/arm/plat-samsung/s5p-clock.c (renamed from arch/arm/plat-s5p/clock.c)33
-rw-r--r--arch/arm/plat-samsung/s5p-dev-mfc.c (renamed from arch/arm/plat-s5p/dev-mfc.c)4
-rw-r--r--arch/arm/plat-samsung/s5p-dev-uart.c (renamed from arch/arm/plat-s5p/dev-uart.c)78
-rw-r--r--arch/arm/plat-samsung/s5p-irq-eint.c (renamed from arch/arm/plat-s5p/irq-eint.c)3
-rw-r--r--arch/arm/plat-samsung/s5p-irq-gpioint.c (renamed from arch/arm/plat-s5p/irq-gpioint.c)3
-rw-r--r--arch/arm/plat-samsung/s5p-irq-pm.c (renamed from arch/arm/plat-s5p/irq-pm.c)3
-rw-r--r--arch/arm/plat-samsung/s5p-irq.c (renamed from arch/arm/plat-s5p/irq.c)3
-rw-r--r--arch/arm/plat-samsung/s5p-pm.c (renamed from arch/arm/plat-s5p/pm.c)3
-rw-r--r--arch/arm/plat-samsung/s5p-sleep.S (renamed from arch/arm/plat-s5p/sleep.S)3
-rw-r--r--arch/arm/plat-samsung/s5p-time.c (renamed from arch/arm/plat-s5p/s5p-time.c)3
-rw-r--r--arch/arm/plat-samsung/setup-mipiphy.c (renamed from arch/arm/plat-s5p/setup-mipiphy.c)0
-rw-r--r--arch/arm/plat-spear/Kconfig12
-rw-r--r--arch/arm/plat-spear/Makefile5
-rw-r--r--arch/arm/plat-spear/clock.c1005
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h249
-rw-r--r--arch/arm/plat-spear/restart.c5
-rw-r--r--arch/arm/plat-spear/time.c39
-rw-r--r--arch/avr32/include/asm/kvm_para.h1
-rw-r--r--arch/blackfin/include/asm/kvm_para.h1
-rw-r--r--arch/c6x/include/asm/kvm_para.h1
-rw-r--r--arch/cris/Kconfig1
-rw-r--r--arch/cris/arch-v10/drivers/ds1302.c515
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c380
-rw-r--r--arch/cris/arch-v10/kernel/fasttimer.c2
-rw-r--r--arch/cris/arch-v10/kernel/kgdb.c2
-rw-r--r--arch/cris/arch-v10/kernel/time.c9
-rw-r--r--arch/cris/arch-v10/lib/Makefile3
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c6
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c2
-rw-r--r--arch/cris/arch-v32/kernel/time.c7
-rw-r--r--arch/cris/include/arch-v32/arch/cache.h2
-rw-r--r--arch/cris/include/asm/Kbuild1
-rw-r--r--arch/cris/include/asm/posix_types.h2
-rw-r--r--arch/cris/include/asm/rtc.h107
-rw-r--r--arch/cris/kernel/time.c76
-rw-r--r--arch/cris/kernel/vmlinux.lds.S1
-rw-r--r--arch/cris/mm/fault.c31
-rw-r--r--arch/frv/include/asm/kvm_para.h1
-rw-r--r--arch/h8300/include/asm/kvm_para.h1
-rw-r--r--arch/hexagon/include/asm/kvm_para.h1
-rw-r--r--arch/ia64/include/asm/kvm_host.h3
-rw-r--r--arch/ia64/include/asm/kvm_para.h5
-rw-r--r--arch/ia64/kvm/kvm-ia64.c30
-rw-r--r--arch/m68k/include/asm/kvm_para.h1
-rw-r--r--arch/microblaze/Kconfig2
-rw-r--r--arch/microblaze/include/asm/kvm_para.h1
-rw-r--r--arch/microblaze/kernel/entry.S7
-rw-r--r--arch/microblaze/kernel/mcount.S2
-rw-r--r--arch/microblaze/kernel/process.c6
-rw-r--r--arch/microblaze/mm/fault.c33
-rw-r--r--arch/mips/Kconfig15
-rw-r--r--arch/mips/Makefile4
-rw-r--r--arch/mips/alchemy/devboards/db1200.c1
-rw-r--r--arch/mips/ath79/Kconfig25
-rw-r--r--arch/mips/ath79/Makefile2
-rw-r--r--arch/mips/ath79/clock.c81
-rw-r--r--arch/mips/ath79/common.c9
-rw-r--r--arch/mips/ath79/dev-common.c3
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.c4
-rw-r--r--arch/mips/ath79/dev-leds-gpio.c4
-rw-r--r--arch/mips/ath79/dev-wmac.c30
-rw-r--r--arch/mips/ath79/early_printk.c3
-rw-r--r--arch/mips/ath79/gpio.c47
-rw-r--r--arch/mips/ath79/irq.c147
-rw-r--r--arch/mips/ath79/mach-db120.c134
-rw-r--r--arch/mips/ath79/mach-pb44.c2
-rw-r--r--arch/mips/ath79/mach-ubnt-xm.c43
-rw-r--r--arch/mips/ath79/machtypes.h1
-rw-r--r--arch/mips/ath79/pci.c130
-rw-r--r--arch/mips/ath79/pci.h34
-rw-r--r--arch/mips/ath79/setup.c45
-rw-r--r--arch/mips/bcm63xx/boards/Makefile2
-rw-r--r--arch/mips/cavium-octeon/setup.c1
-rw-r--r--arch/mips/cavium-octeon/smp.c6
-rw-r--r--arch/mips/fw/arc/Makefile2
-rw-r--r--arch/mips/include/asm/clkdev.h25
-rw-r--r--arch/mips/include/asm/kvm_para.h1
-rw-r--r--arch/mips/include/asm/mach-ath79/ar71xx_regs.h91
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h23
-rw-r--r--arch/mips/include/asm/mach-ath79/irq.h10
-rw-r--r--arch/mips/include/asm/mach-ath79/pci-ath724x.h21
-rw-r--r--arch/mips/include/asm/mach-ath79/pci.h28
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h1
-rw-r--r--arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h23
-rw-r--r--arch/mips/include/asm/mach-lantiq/falcon/irq.h18
-rw-r--r--arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h67
-rw-r--r--arch/mips/include/asm/mach-lantiq/gpio.h16
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq.h34
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq_platform.h33
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h44
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h136
-rw-r--r--arch/mips/include/asm/mips-boards/generic.h4
-rw-r--r--arch/mips/include/asm/module.h1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcieep-defs.h1365
-rw-r--r--arch/mips/include/asm/pci.h6
-rw-r--r--arch/mips/include/asm/prom.h26
-rw-r--r--arch/mips/include/asm/setup.h3
-rw-r--r--arch/mips/include/asm/sparsemem.h6
-rw-r--r--arch/mips/include/asm/termios.h2
-rw-r--r--arch/mips/include/asm/traps.h1
-rw-r--r--arch/mips/include/asm/uasm.h2
-rw-r--r--arch/mips/jz4740/Makefile2
-rw-r--r--arch/mips/kernel/cpu-probe.c54
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c3
-rw-r--r--arch/mips/kernel/proc.c26
-rw-r--r--arch/mips/kernel/prom.c13
-rw-r--r--arch/mips/kernel/setup.c2
-rw-r--r--arch/mips/kernel/smp.c2
-rw-r--r--arch/mips/kernel/traps.c17
-rw-r--r--arch/mips/lantiq/Kconfig16
-rw-r--r--arch/mips/lantiq/Makefile5
-rw-r--r--arch/mips/lantiq/Platform1
-rw-r--r--arch/mips/lantiq/clk.c146
-rw-r--r--arch/mips/lantiq/clk.h68
-rw-r--r--arch/mips/lantiq/devices.c120
-rw-r--r--arch/mips/lantiq/devices.h23
-rw-r--r--arch/mips/lantiq/dts/Makefile4
-rw-r--r--arch/mips/lantiq/dts/danube.dtsi105
-rw-r--r--arch/mips/lantiq/dts/easy50712.dts113
-rw-r--r--arch/mips/lantiq/early_printk.c17
-rw-r--r--arch/mips/lantiq/falcon/Makefile1
-rw-r--r--arch/mips/lantiq/falcon/prom.c87
-rw-r--r--arch/mips/lantiq/falcon/reset.c90
-rw-r--r--arch/mips/lantiq/falcon/sysctrl.c260
-rw-r--r--arch/mips/lantiq/irq.c255
-rw-r--r--arch/mips/lantiq/machtypes.h20
-rw-r--r--arch/mips/lantiq/prom.c74
-rw-r--r--arch/mips/lantiq/prom.h8
-rw-r--r--arch/mips/lantiq/setup.c66
-rw-r--r--arch/mips/lantiq/xway/Kconfig23
-rw-r--r--arch/mips/lantiq/xway/Makefile8
-rw-r--r--arch/mips/lantiq/xway/clk-ase.c48
-rw-r--r--arch/mips/lantiq/xway/clk-xway.c223
-rw-r--r--arch/mips/lantiq/xway/clk.c151
-rw-r--r--arch/mips/lantiq/xway/devices.c119
-rw-r--r--arch/mips/lantiq/xway/devices.h20
-rw-r--r--arch/mips/lantiq/xway/dma.c61
-rw-r--r--arch/mips/lantiq/xway/ebu.c52
-rw-r--r--arch/mips/lantiq/xway/gpio.c12
-rw-r--r--arch/mips/lantiq/xway/gpio_ebu.c126
-rw-r--r--arch/mips/lantiq/xway/gpio_stp.c157
-rw-r--r--arch/mips/lantiq/xway/mach-easy50601.c57
-rw-r--r--arch/mips/lantiq/xway/mach-easy50712.c74
-rw-r--r--arch/mips/lantiq/xway/pmu.c69
-rw-r--r--arch/mips/lantiq/xway/prom-ase.c39
-rw-r--r--arch/mips/lantiq/xway/prom-xway.c54
-rw-r--r--arch/mips/lantiq/xway/prom.c115
-rw-r--r--arch/mips/lantiq/xway/reset.c77
-rw-r--r--arch/mips/lantiq/xway/setup-ase.c19
-rw-r--r--arch/mips/lantiq/xway/setup-xway.c20
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c371
-rw-r--r--arch/mips/mm/c-octeon.c14
-rw-r--r--arch/mips/mm/c-r4k.c14
-rw-r--r--arch/mips/oprofile/Makefile2
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c12
-rw-r--r--arch/mips/pci/Makefile6
-rw-r--r--arch/mips/pci/fixup-lantiq.c40
-rw-r--r--arch/mips/pci/ops-loongson2.c1
-rw-r--r--arch/mips/pci/pci-ar71xx.c375
-rw-r--r--arch/mips/pci/pci-ar724x.c292
-rw-r--r--arch/mips/pci/pci-ath724x.c174
-rw-r--r--arch/mips/pci/pci-lantiq.c219
-rw-r--r--arch/mips/pci/pci.c55
-rw-r--r--arch/mips/pmc-sierra/yosemite/Makefile2
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c1
-rw-r--r--arch/mips/powertv/Makefile2
-rw-r--r--arch/mips/powertv/asic/Makefile2
-rw-r--r--arch/mips/powertv/pci/Makefile2
-rw-r--r--arch/mips/rb532/devices.c1
-rw-r--r--arch/mips/sni/setup.c1
-rw-r--r--arch/mn10300/include/asm/kvm_para.h1
-rw-r--r--arch/openrisc/Kconfig2
-rw-r--r--arch/openrisc/include/asm/Kbuild1
-rw-r--r--arch/openrisc/include/asm/kvm_para.h1
-rw-r--r--arch/openrisc/include/asm/uaccess.h40
-rw-r--r--arch/openrisc/lib/string.S99
-rw-r--r--arch/parisc/include/asm/kvm_para.h1
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/boot/dts/mpc8569mds.dts1
-rw-r--r--arch/powerpc/include/asm/cputable.h23
-rw-r--r--arch/powerpc/include/asm/dbell.h3
-rw-r--r--arch/powerpc/include/asm/hvcall.h10
-rw-r--r--arch/powerpc/include/asm/hw_irq.h1
-rw-r--r--arch/powerpc/include/asm/kvm.h1
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h18
-rw-r--r--arch/powerpc/include/asm/kvm_book3s.h3
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h8
-rw-r--r--arch/powerpc/include/asm/kvm_booke.h3
-rw-r--r--arch/powerpc/include/asm/kvm_booke_hv_asm.h49
-rw-r--r--arch/powerpc/include/asm/kvm_e500.h96
-rw-r--r--arch/powerpc/include/asm/kvm_host.h60
-rw-r--r--arch/powerpc/include/asm/kvm_para.h5
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h20
-rw-r--r--arch/powerpc/include/asm/mmu-book3e.h6
-rw-r--r--arch/powerpc/include/asm/processor.h3
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/include/asm/reg_booke.h34
-rw-r--r--arch/powerpc/include/asm/switch_to.h1
-rw-r--r--arch/powerpc/include/asm/time.h1
-rw-r--r--arch/powerpc/include/asm/uaccess.h41
-rw-r--r--arch/powerpc/include/asm/word-at-a-time.h41
-rw-r--r--arch/powerpc/kernel/asm-offsets.c19
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S1
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S12
-rw-r--r--arch/powerpc/kernel/head_44x.S23
-rw-r--r--arch/powerpc/kernel/head_booke.h69
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S98
-rw-r--r--arch/powerpc/kernel/idle_power7.S7
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c6
-rw-r--r--arch/powerpc/kernel/time.c3
-rw-r--r--arch/powerpc/kvm/44x.c12
-rw-r--r--arch/powerpc/kvm/44x_emulate.c51
-rw-r--r--arch/powerpc/kvm/Kconfig28
-rw-r--r--arch/powerpc/kvm/Makefile17
-rw-r--r--arch/powerpc/kvm/book3s.c7
-rw-r--r--arch/powerpc/kvm/book3s_64_mmu_hv.c31
-rw-r--r--arch/powerpc/kvm/book3s_64_slb.S2
-rw-r--r--arch/powerpc/kvm/book3s_64_vio.c150
-rw-r--r--arch/powerpc/kvm/book3s_64_vio_hv.c3
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c106
-rw-r--r--arch/powerpc/kvm/book3s_hv.c467
-rw-r--r--arch/powerpc/kvm/book3s_hv_interrupts.S9
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S185
-rw-r--r--arch/powerpc/kvm/book3s_pr.c59
-rw-r--r--arch/powerpc/kvm/book3s_pr_papr.c101
-rw-r--r--arch/powerpc/kvm/book3s_segment.S13
-rw-r--r--arch/powerpc/kvm/booke.c471
-rw-r--r--arch/powerpc/kvm/booke.h62
-rw-r--r--arch/powerpc/kvm/booke_emulate.c118
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S8
-rw-r--r--arch/powerpc/kvm/bookehv_interrupts.S597
-rw-r--r--arch/powerpc/kvm/e500.c372
-rw-r--r--arch/powerpc/kvm/e500.h306
-rw-r--r--arch/powerpc/kvm/e500_emulate.c210
-rw-r--r--arch/powerpc/kvm/e500_tlb.c666
-rw-r--r--arch/powerpc/kvm/e500_tlb.h174
-rw-r--r--arch/powerpc/kvm/e500mc.c342
-rw-r--r--arch/powerpc/kvm/emulate.c197
-rw-r--r--arch/powerpc/kvm/powerpc.c94
-rw-r--r--arch/powerpc/kvm/timing.h6
-rw-r--r--arch/powerpc/lib/string.S45
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c2
-rw-r--r--arch/s390/hypfs/inode.c2
-rw-r--r--arch/s390/include/asm/kvm.h5
-rw-r--r--arch/s390/include/asm/kvm_host.h1
-rw-r--r--arch/s390/include/asm/kvm_para.h5
-rw-r--r--arch/s390/include/asm/sclp.h1
-rw-r--r--arch/s390/kvm/diag.c29
-rw-r--r--arch/s390/kvm/intercept.c1
-rw-r--r--arch/s390/kvm/kvm-s390.c87
-rw-r--r--arch/s390/kvm/kvm-s390.h1
-rw-r--r--arch/s390/kvm/priv.c31
-rw-r--r--arch/score/include/asm/kvm_para.h1
-rw-r--r--arch/sh/include/asm/kvm_para.h1
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/Kbuild1
-rw-r--r--arch/sparc/include/asm/kvm_para.h1
-rw-r--r--arch/sparc/include/asm/uaccess_32.h22
-rw-r--r--arch/sparc/include/asm/uaccess_64.h8
-rw-r--r--arch/sparc/lib/Makefile1
-rw-r--r--arch/sparc/lib/ksyms.c2
-rw-r--r--arch/sparc/lib/strlen_user_32.S109
-rw-r--r--arch/sparc/lib/strlen_user_64.S97
-rw-r--r--arch/tile/Kconfig43
-rw-r--r--arch/tile/Makefile7
-rw-r--r--arch/tile/include/arch/spr_def_32.h56
-rw-r--r--arch/tile/include/arch/spr_def_64.h43
-rw-r--r--arch/tile/include/asm/Kbuild2
-rw-r--r--arch/tile/include/asm/atomic_32.h10
-rw-r--r--arch/tile/include/asm/bitops.h12
-rw-r--r--arch/tile/include/asm/byteorder.h20
-rw-r--r--arch/tile/include/asm/cachectl.h42
-rw-r--r--arch/tile/include/asm/compat.h3
-rw-r--r--arch/tile/include/asm/elf.h5
-rw-r--r--arch/tile/include/asm/futex.h143
-rw-r--r--arch/tile/include/asm/hardwall.h18
-rw-r--r--arch/tile/include/asm/hugetlb.h21
-rw-r--r--arch/tile/include/asm/irqflags.h34
-rw-r--r--arch/tile/include/asm/kexec.h12
-rw-r--r--arch/tile/include/asm/kvm_para.h1
-rw-r--r--arch/tile/include/asm/mmu.h2
-rw-r--r--arch/tile/include/asm/mmu_context.h8
-rw-r--r--arch/tile/include/asm/module.h40
-rw-r--r--arch/tile/include/asm/page.h18
-rw-r--r--arch/tile/include/asm/pgalloc.h92
-rw-r--r--arch/tile/include/asm/pgtable.h111
-rw-r--r--arch/tile/include/asm/pgtable_32.h40
-rw-r--r--arch/tile/include/asm/pgtable_64.h57
-rw-r--r--arch/tile/include/asm/processor.h17
-rw-r--r--arch/tile/include/asm/setup.h10
-rw-r--r--arch/tile/include/asm/syscalls.h3
-rw-r--r--arch/tile/include/asm/tlbflush.h17
-rw-r--r--arch/tile/include/asm/uaccess.h222
-rw-r--r--arch/tile/include/asm/unistd.h4
-rw-r--r--arch/tile/include/hv/drv_xgbe_intf.h2
-rw-r--r--arch/tile/include/hv/hypervisor.h325
-rw-r--r--arch/tile/kernel/Makefile3
-rw-r--r--arch/tile/kernel/entry.S3
-rw-r--r--arch/tile/kernel/hardwall.c754
-rw-r--r--arch/tile/kernel/head_32.S8
-rw-r--r--arch/tile/kernel/head_64.S22
-rw-r--r--arch/tile/kernel/hvglue.lds3
-rw-r--r--arch/tile/kernel/intvec_64.S80
-rw-r--r--arch/tile/kernel/machine_kexec.c42
-rw-r--r--arch/tile/kernel/module.c12
-rw-r--r--arch/tile/kernel/proc.c1
-rw-r--r--arch/tile/kernel/process.c16
-rw-r--r--arch/tile/kernel/relocate_kernel_32.S (renamed from arch/tile/kernel/relocate_kernel.S)0
-rw-r--r--arch/tile/kernel/relocate_kernel_64.S260
-rw-r--r--arch/tile/kernel/setup.c169
-rw-r--r--arch/tile/kernel/single_step.c16
-rw-r--r--arch/tile/kernel/smp.c2
-rw-r--r--arch/tile/kernel/sys.c10
-rw-r--r--arch/tile/kernel/sysfs.c8
-rw-r--r--arch/tile/kernel/tlb.c11
-rw-r--r--arch/tile/kernel/traps.c30
-rw-r--r--arch/tile/lib/atomic_32.c47
-rw-r--r--arch/tile/lib/exports.c8
-rw-r--r--arch/tile/lib/memchr_64.c8
-rw-r--r--arch/tile/lib/memcpy_64.c23
-rw-r--r--arch/tile/lib/memcpy_tile64.c8
-rw-r--r--arch/tile/lib/strchr_64.c15
-rw-r--r--arch/tile/lib/string-endian.h33
-rw-r--r--arch/tile/lib/strlen_64.c11
-rw-r--r--arch/tile/lib/usercopy_32.S76
-rw-r--r--arch/tile/lib/usercopy_64.S49
-rw-r--r--arch/tile/mm/fault.c34
-rw-r--r--arch/tile/mm/homecache.c1
-rw-r--r--arch/tile/mm/hugetlbpage.c285
-rw-r--r--arch/tile/mm/init.c19
-rw-r--r--arch/tile/mm/migrate.h6
-rw-r--r--arch/tile/mm/migrate_32.S36
-rw-r--r--arch/tile/mm/migrate_64.S34
-rw-r--r--arch/tile/mm/pgtable.c40
-rw-r--r--arch/um/Makefile11
-rw-r--r--arch/um/include/asm/kvm_para.h1
-rw-r--r--arch/unicore32/include/asm/kvm_para.h1
-rw-r--r--arch/x86/Kbuild2
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/x86/include/asm/acpi.h9
-rw-r--r--arch/x86/include/asm/dma-contiguous.h13
-rw-r--r--arch/x86/include/asm/dma-mapping.h5
-rw-r--r--arch/x86/include/asm/kvm_emulate.h4
-rw-r--r--arch/x86/include/asm/kvm_host.h13
-rw-r--r--arch/x86/include/asm/kvm_para.h24
-rw-r--r--arch/x86/include/asm/pgtable-3level.h50
-rw-r--r--arch/x86/include/asm/processor.h7
-rw-r--r--arch/x86/include/asm/pvclock-abi.h1
-rw-r--r--arch/x86/include/asm/realmode.h62
-rw-r--r--arch/x86/include/asm/sta2x11.h12
-rw-r--r--arch/x86/include/asm/trampoline.h39
-rw-r--r--arch/x86/include/asm/uaccess.h4
-rw-r--r--arch/x86/include/asm/uaccess_32.h17
-rw-r--r--arch/x86/include/asm/uaccess_64.h3
-rw-r--r--arch/x86/include/asm/word-at-a-time.h32
-rw-r--r--arch/x86/include/asm/xen/events.h1
-rw-r--r--arch/x86/include/asm/xen/page.h1
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/acpi/Makefile9
-rw-r--r--arch/x86/kernel/acpi/realmode/.gitignore3
-rw-r--r--arch/x86/kernel/acpi/realmode/Makefile59
-rw-r--r--arch/x86/kernel/acpi/realmode/bioscall.S1
-rw-r--r--arch/x86/kernel/acpi/realmode/copy.S1
-rw-r--r--arch/x86/kernel/acpi/realmode/regs.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-bios.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-mode.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-vesa.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/video-vga.c1
-rw-r--r--arch/x86/kernel/acpi/realmode/wakeup.lds.S62
-rw-r--r--arch/x86/kernel/acpi/sleep.c33
-rw-r--r--arch/x86/kernel/acpi/sleep.h2
-rw-r--r--arch/x86/kernel/acpi/wakeup_rm.S12
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-apei.c3
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c26
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c24
-rw-r--r--arch/x86/kernel/e820.c53
-rw-r--r--arch/x86/kernel/head32.c1
-rw-r--r--arch/x86/kernel/head64.c1
-rw-r--r--arch/x86/kernel/head_32.S5
-rw-r--r--arch/x86/kernel/head_64.S4
-rw-r--r--arch/x86/kernel/kvmclock.c20
-rw-r--r--arch/x86/kernel/mpparse.c11
-rw-r--r--arch/x86/kernel/pci-dma.c18
-rw-r--r--arch/x86/kernel/pci-nommu.c8
-rw-r--r--arch/x86/kernel/reboot.c25
-rw-r--r--arch/x86/kernel/setup.c24
-rw-r--r--arch/x86/kernel/smpboot.c18
-rw-r--r--arch/x86/kernel/tboot.c7
-rw-r--r--arch/x86/kernel/trampoline.c42
-rw-r--r--arch/x86/kernel/trampoline_32.S83
-rw-r--r--arch/x86/kernel/vmlinux.lds.S12
-rw-r--r--arch/x86/kvm/Kconfig1
-rw-r--r--arch/x86/kvm/cpuid.c5
-rw-r--r--arch/x86/kvm/emulate.c293
-rw-r--r--arch/x86/kvm/i8254.c31
-rw-r--r--arch/x86/kvm/i8254.h7
-rw-r--r--arch/x86/kvm/lapic.c31
-rw-r--r--arch/x86/kvm/mmu.c345
-rw-r--r--arch/x86/kvm/mmu_audit.c10
-rw-r--r--arch/x86/kvm/paging_tmpl.h2
-rw-r--r--arch/x86/kvm/svm.c9
-rw-r--r--arch/x86/kvm/vmx.c41
-rw-r--r--arch/x86/kvm/x86.c280
-rw-r--r--arch/x86/kvm/x86.h2
-rw-r--r--arch/x86/lib/usercopy.c97
-rw-r--r--arch/x86/lib/usercopy_32.c41
-rw-r--r--arch/x86/lib/usercopy_64.c48
-rw-r--r--arch/x86/mm/init.c16
-rw-r--r--arch/x86/mm/numa.c32
-rw-r--r--arch/x86/mm/numa_emulation.c4
-rw-r--r--arch/x86/mm/pat.c42
-rw-r--r--arch/x86/mm/srat.c5
-rw-r--r--arch/x86/pci/xen.c4
-rw-r--r--arch/x86/realmode/Makefile18
-rw-r--r--arch/x86/realmode/init.c115
-rw-r--r--arch/x86/realmode/rm/.gitignore3
-rw-r--r--arch/x86/realmode/rm/Makefile82
-rw-r--r--arch/x86/realmode/rm/bioscall.S1
-rw-r--r--arch/x86/realmode/rm/copy.S1
-rw-r--r--arch/x86/realmode/rm/header.S41
-rw-r--r--arch/x86/realmode/rm/realmode.h21
-rw-r--r--arch/x86/realmode/rm/realmode.lds.S76
-rw-r--r--arch/x86/realmode/rm/reboot_32.S (renamed from arch/x86/kernel/reboot_32.S)89
-rw-r--r--arch/x86/realmode/rm/regs.c1
-rw-r--r--arch/x86/realmode/rm/stack.S19
-rw-r--r--arch/x86/realmode/rm/trampoline_32.S74
-rw-r--r--arch/x86/realmode/rm/trampoline_64.S (renamed from arch/x86/kernel/trampoline_64.S)148
-rw-r--r--arch/x86/realmode/rm/trampoline_common.S7
-rw-r--r--arch/x86/realmode/rm/video-bios.c1
-rw-r--r--arch/x86/realmode/rm/video-mode.c1
-rw-r--r--arch/x86/realmode/rm/video-vesa.c1
-rw-r--r--arch/x86/realmode/rm/video-vga.c1
-rw-r--r--arch/x86/realmode/rm/wakemain.c (renamed from arch/x86/kernel/acpi/realmode/wakemain.c)3
-rw-r--r--arch/x86/realmode/rm/wakeup.h (renamed from arch/x86/kernel/acpi/realmode/wakeup.h)10
-rw-r--r--arch/x86/realmode/rm/wakeup_asm.S (renamed from arch/x86/kernel/acpi/realmode/wakeup.S)131
-rw-r--r--arch/x86/realmode/rmpiggy.S20
-rw-r--r--arch/x86/tools/relocs.c7
-rw-r--r--arch/x86/xen/debugfs.c104
-rw-r--r--arch/x86/xen/debugfs.h4
-rw-r--r--arch/x86/xen/enlighten.c13
-rw-r--r--arch/x86/xen/mmu.c23
-rw-r--r--arch/x86/xen/p2m.c104
-rw-r--r--arch/x86/xen/setup.c171
-rw-r--r--arch/x86/xen/smp.c112
-rw-r--r--arch/x86/xen/smp.h12
-rw-r--r--arch/x86/xen/spinlock.c12
-rw-r--r--arch/x86/xen/xen-ops.h1
-rw-r--r--arch/xtensa/include/asm/kvm_para.h1
907 files changed, 26163 insertions, 26550 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index e9a910876cd..8c3d957fa8e 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -159,6 +159,9 @@ config HAVE_ARCH_TRACEHOOK
159config HAVE_DMA_ATTRS 159config HAVE_DMA_ATTRS
160 bool 160 bool
161 161
162config HAVE_DMA_CONTIGUOUS
163 bool
164
162config USE_GENERIC_SMP_HELPERS 165config USE_GENERIC_SMP_HELPERS
163 bool 166 bool
164 167
diff --git a/arch/alpha/include/asm/kvm_para.h b/arch/alpha/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/alpha/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5458aa9db06..5e7601301b4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,9 @@ config ARM
5 select HAVE_AOUT 5 select HAVE_AOUT
6 select HAVE_DMA_API_DEBUG 6 select HAVE_DMA_API_DEBUG
7 select HAVE_IDE if PCI || ISA || PCMCIA 7 select HAVE_IDE if PCI || ISA || PCMCIA
8 select HAVE_DMA_ATTRS
9 select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
10 select CMA if (CPU_V6 || CPU_V6K || CPU_V7)
8 select HAVE_MEMBLOCK 11 select HAVE_MEMBLOCK
9 select RTC_LIB 12 select RTC_LIB
10 select SYS_SUPPORTS_APM_EMULATION 13 select SYS_SUPPORTS_APM_EMULATION
@@ -54,6 +57,14 @@ config ARM
54config ARM_HAS_SG_CHAIN 57config ARM_HAS_SG_CHAIN
55 bool 58 bool
56 59
60config NEED_SG_DMA_LENGTH
61 bool
62
63config ARM_DMA_USE_IOMMU
64 select NEED_SG_DMA_LENGTH
65 select ARM_HAS_SG_CHAIN
66 bool
67
57config HAVE_PWM 68config HAVE_PWM
58 bool 69 bool
59 70
@@ -445,8 +456,10 @@ config ARCH_MXS
445 select ARCH_REQUIRE_GPIOLIB 456 select ARCH_REQUIRE_GPIOLIB
446 select CLKDEV_LOOKUP 457 select CLKDEV_LOOKUP
447 select CLKSRC_MMIO 458 select CLKSRC_MMIO
459 select COMMON_CLK
448 select HAVE_CLK_PREPARE 460 select HAVE_CLK_PREPARE
449 select PINCTRL 461 select PINCTRL
462 select USE_OF
450 help 463 help
451 Support for Freescale MXS-based family of processors 464 Support for Freescale MXS-based family of processors
452 465
@@ -936,6 +949,7 @@ config PLAT_SPEAR
936 select ARM_AMBA 949 select ARM_AMBA
937 select ARCH_REQUIRE_GPIOLIB 950 select ARCH_REQUIRE_GPIOLIB
938 select CLKDEV_LOOKUP 951 select CLKDEV_LOOKUP
952 select COMMON_CLK
939 select CLKSRC_MMIO 953 select CLKSRC_MMIO
940 select GENERIC_CLOCKEVENTS 954 select GENERIC_CLOCKEVENTS
941 select HAVE_CLK 955 select HAVE_CLK
@@ -1040,7 +1054,6 @@ source "arch/arm/mach-sa1100/Kconfig"
1040 1054
1041source "arch/arm/plat-samsung/Kconfig" 1055source "arch/arm/plat-samsung/Kconfig"
1042source "arch/arm/plat-s3c24xx/Kconfig" 1056source "arch/arm/plat-s3c24xx/Kconfig"
1043source "arch/arm/plat-s5p/Kconfig"
1044 1057
1045source "arch/arm/plat-spear/Kconfig" 1058source "arch/arm/plat-spear/Kconfig"
1046 1059
@@ -1091,6 +1104,7 @@ config PLAT_ORION
1091 bool 1104 bool
1092 select CLKSRC_MMIO 1105 select CLKSRC_MMIO
1093 select GENERIC_IRQ_CHIP 1106 select GENERIC_IRQ_CHIP
1107 select COMMON_CLK
1094 1108
1095config PLAT_PXA 1109config PLAT_PXA
1096 bool 1110 bool
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 85348a09d65..01a13414121 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -103,6 +103,35 @@ choice
103 Say Y here if you want the debug print routines to direct 103 Say Y here if you want the debug print routines to direct
104 their output to the second serial port on these devices. 104 their output to the second serial port on these devices.
105 105
106 config DEBUG_DAVINCI_DA8XX_UART1
107 bool "Kernel low-level debugging on DaVinci DA8XX using UART1"
108 depends on ARCH_DAVINCI_DA8XX
109 help
110 Say Y here if you want the debug print routines to direct
111 their output to UART1 serial port on DaVinci DA8XX devices.
112
113 config DEBUG_DAVINCI_DA8XX_UART2
114 bool "Kernel low-level debugging on DaVinci DA8XX using UART2"
115 depends on ARCH_DAVINCI_DA8XX
116 help
117 Say Y here if you want the debug print routines to direct
118 their output to UART2 serial port on DaVinci DA8XX devices.
119
120 config DEBUG_DAVINCI_DMx_UART0
121 bool "Kernel low-level debugging on DaVinci DMx using UART0"
122 depends on ARCH_DAVINCI_DMx
123 help
124 Say Y here if you want the debug print routines to direct
125 their output to UART0 serial port on DaVinci DMx devices.
126
127 config DEBUG_DAVINCI_TNETV107X_UART1
128 bool "Kernel low-level debugging on DaVinci TNETV107x using UART1"
129 depends on ARCH_DAVINCI_TNETV107X
130 help
131 Say Y here if you want the debug print routines to direct
132 their output to UART1 serial port on DaVinci TNETV107X
133 devices.
134
106 config DEBUG_DC21285_PORT 135 config DEBUG_DC21285_PORT
107 bool "Kernel low-level debugging messages via footbridge serial port" 136 bool "Kernel low-level debugging messages via footbridge serial port"
108 depends on FOOTBRIDGE 137 depends on FOOTBRIDGE
@@ -180,6 +209,14 @@ choice
180 Say Y here if you want kernel low-level debugging support 209 Say Y here if you want kernel low-level debugging support
181 on i.MX50 or i.MX53. 210 on i.MX50 or i.MX53.
182 211
212 config DEBUG_IMX6Q_UART2
213 bool "i.MX6Q Debug UART2"
214 depends on SOC_IMX6Q
215 help
216 Say Y here if you want kernel low-level debugging support
217 on i.MX6Q UART2. This is correct for e.g. the SabreLite
218 board.
219
183 config DEBUG_IMX6Q_UART4 220 config DEBUG_IMX6Q_UART4
184 bool "i.MX6Q Debug UART4" 221 bool "i.MX6Q Debug UART4"
185 depends on SOC_IMX6Q 222 depends on SOC_IMX6Q
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 157900da878..0298b00fe24 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -160,9 +160,7 @@ machine-$(CONFIG_ARCH_MXS) := mxs
160machine-$(CONFIG_ARCH_NETX) := netx 160machine-$(CONFIG_ARCH_NETX) := netx
161machine-$(CONFIG_ARCH_NOMADIK) := nomadik 161machine-$(CONFIG_ARCH_NOMADIK) := nomadik
162machine-$(CONFIG_ARCH_OMAP1) := omap1 162machine-$(CONFIG_ARCH_OMAP1) := omap1
163machine-$(CONFIG_ARCH_OMAP2) := omap2 163machine-$(CONFIG_ARCH_OMAP2PLUS) := omap2
164machine-$(CONFIG_ARCH_OMAP3) := omap2
165machine-$(CONFIG_ARCH_OMAP4) := omap2
166machine-$(CONFIG_ARCH_ORION5X) := orion5x 164machine-$(CONFIG_ARCH_ORION5X) := orion5x
167machine-$(CONFIG_ARCH_PICOXCELL) := picoxcell 165machine-$(CONFIG_ARCH_PICOXCELL) := picoxcell
168machine-$(CONFIG_ARCH_PNX4008) := pnx4008 166machine-$(CONFIG_ARCH_PNX4008) := pnx4008
@@ -188,6 +186,8 @@ machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
188machine-$(CONFIG_ARCH_VT8500) := vt8500 186machine-$(CONFIG_ARCH_VT8500) := vt8500
189machine-$(CONFIG_ARCH_W90X900) := w90x900 187machine-$(CONFIG_ARCH_W90X900) := w90x900
190machine-$(CONFIG_FOOTBRIDGE) := footbridge 188machine-$(CONFIG_FOOTBRIDGE) := footbridge
189machine-$(CONFIG_MACH_SPEAR1310) := spear13xx
190machine-$(CONFIG_MACH_SPEAR1340) := spear13xx
191machine-$(CONFIG_MACH_SPEAR300) := spear3xx 191machine-$(CONFIG_MACH_SPEAR300) := spear3xx
192machine-$(CONFIG_MACH_SPEAR310) := spear3xx 192machine-$(CONFIG_MACH_SPEAR310) := spear3xx
193machine-$(CONFIG_MACH_SPEAR320) := spear3xx 193machine-$(CONFIG_MACH_SPEAR320) := spear3xx
@@ -205,7 +205,7 @@ plat-$(CONFIG_PLAT_NOMADIK) := nomadik
205plat-$(CONFIG_PLAT_ORION) := orion 205plat-$(CONFIG_PLAT_ORION) := orion
206plat-$(CONFIG_PLAT_PXA) := pxa 206plat-$(CONFIG_PLAT_PXA) := pxa
207plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung 207plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung
208plat-$(CONFIG_PLAT_S5P) := s5p samsung 208plat-$(CONFIG_PLAT_S5P) := samsung
209plat-$(CONFIG_PLAT_SPEAR) := spear 209plat-$(CONFIG_PLAT_SPEAR) := spear
210plat-$(CONFIG_PLAT_VERSATILE) := versatile 210plat-$(CONFIG_PLAT_VERSATILE) := versatile
211 211
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 399d17b231d..49945cc1bc7 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -23,4 +23,52 @@
23 chosen { 23 chosen {
24 bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200"; 24 bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200";
25 }; 25 };
26
27 i2c@12C60000 {
28 samsung,i2c-sda-delay = <100>;
29 samsung,i2c-max-bus-freq = <20000>;
30 gpios = <&gpb3 0 2 3 0>,
31 <&gpb3 1 2 3 0>;
32
33 eeprom@50 {
34 compatible = "samsung,s524ad0xd1";
35 reg = <0x50>;
36 };
37 };
38
39 i2c@12C70000 {
40 samsung,i2c-sda-delay = <100>;
41 samsung,i2c-max-bus-freq = <20000>;
42 gpios = <&gpb3 2 2 3 0>,
43 <&gpb3 3 2 3 0>;
44
45 eeprom@51 {
46 compatible = "samsung,s524ad0xd1";
47 reg = <0x51>;
48 };
49 };
50
51 i2c@12C80000 {
52 status = "disabled";
53 };
54
55 i2c@12C90000 {
56 status = "disabled";
57 };
58
59 i2c@12CA0000 {
60 status = "disabled";
61 };
62
63 i2c@12CB0000 {
64 status = "disabled";
65 };
66
67 i2c@12CC0000 {
68 status = "disabled";
69 };
70
71 i2c@12CD0000 {
72 status = "disabled";
73 };
26}; 74};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index dfc43359943..5ca0cdb7641 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -23,11 +23,11 @@
23 compatible = "samsung,exynos5250"; 23 compatible = "samsung,exynos5250";
24 interrupt-parent = <&gic>; 24 interrupt-parent = <&gic>;
25 25
26 gic:interrupt-controller@10490000 { 26 gic:interrupt-controller@10481000 {
27 compatible = "arm,cortex-a9-gic"; 27 compatible = "arm,cortex-a9-gic";
28 #interrupt-cells = <3>; 28 #interrupt-cells = <3>;
29 interrupt-controller; 29 interrupt-controller;
30 reg = <0x10490000 0x1000>, <0x10480000 0x100>; 30 reg = <0x10481000 0x1000>, <0x10482000 0x2000>;
31 }; 31 };
32 32
33 watchdog { 33 watchdog {
@@ -42,30 +42,6 @@
42 interrupts = <0 43 0>, <0 44 0>; 42 interrupts = <0 43 0>, <0 44 0>;
43 }; 43 };
44 44
45 sdhci@12200000 {
46 compatible = "samsung,exynos4210-sdhci";
47 reg = <0x12200000 0x100>;
48 interrupts = <0 75 0>;
49 };
50
51 sdhci@12210000 {
52 compatible = "samsung,exynos4210-sdhci";
53 reg = <0x12210000 0x100>;
54 interrupts = <0 76 0>;
55 };
56
57 sdhci@12220000 {
58 compatible = "samsung,exynos4210-sdhci";
59 reg = <0x12220000 0x100>;
60 interrupts = <0 77 0>;
61 };
62
63 sdhci@12230000 {
64 compatible = "samsung,exynos4210-sdhci";
65 reg = <0x12230000 0x100>;
66 interrupts = <0 78 0>;
67 };
68
69 serial@12C00000 { 45 serial@12C00000 {
70 compatible = "samsung,exynos4210-uart"; 46 compatible = "samsung,exynos4210-uart";
71 reg = <0x12C00000 0x100>; 47 reg = <0x12C00000 0x100>;
@@ -94,48 +70,64 @@
94 compatible = "samsung,s3c2440-i2c"; 70 compatible = "samsung,s3c2440-i2c";
95 reg = <0x12C60000 0x100>; 71 reg = <0x12C60000 0x100>;
96 interrupts = <0 56 0>; 72 interrupts = <0 56 0>;
73 #address-cells = <1>;
74 #size-cells = <0>;
97 }; 75 };
98 76
99 i2c@12C70000 { 77 i2c@12C70000 {
100 compatible = "samsung,s3c2440-i2c"; 78 compatible = "samsung,s3c2440-i2c";
101 reg = <0x12C70000 0x100>; 79 reg = <0x12C70000 0x100>;
102 interrupts = <0 57 0>; 80 interrupts = <0 57 0>;
81 #address-cells = <1>;
82 #size-cells = <0>;
103 }; 83 };
104 84
105 i2c@12C80000 { 85 i2c@12C80000 {
106 compatible = "samsung,s3c2440-i2c"; 86 compatible = "samsung,s3c2440-i2c";
107 reg = <0x12C80000 0x100>; 87 reg = <0x12C80000 0x100>;
108 interrupts = <0 58 0>; 88 interrupts = <0 58 0>;
89 #address-cells = <1>;
90 #size-cells = <0>;
109 }; 91 };
110 92
111 i2c@12C90000 { 93 i2c@12C90000 {
112 compatible = "samsung,s3c2440-i2c"; 94 compatible = "samsung,s3c2440-i2c";
113 reg = <0x12C90000 0x100>; 95 reg = <0x12C90000 0x100>;
114 interrupts = <0 59 0>; 96 interrupts = <0 59 0>;
97 #address-cells = <1>;
98 #size-cells = <0>;
115 }; 99 };
116 100
117 i2c@12CA0000 { 101 i2c@12CA0000 {
118 compatible = "samsung,s3c2440-i2c"; 102 compatible = "samsung,s3c2440-i2c";
119 reg = <0x12CA0000 0x100>; 103 reg = <0x12CA0000 0x100>;
120 interrupts = <0 60 0>; 104 interrupts = <0 60 0>;
105 #address-cells = <1>;
106 #size-cells = <0>;
121 }; 107 };
122 108
123 i2c@12CB0000 { 109 i2c@12CB0000 {
124 compatible = "samsung,s3c2440-i2c"; 110 compatible = "samsung,s3c2440-i2c";
125 reg = <0x12CB0000 0x100>; 111 reg = <0x12CB0000 0x100>;
126 interrupts = <0 61 0>; 112 interrupts = <0 61 0>;
113 #address-cells = <1>;
114 #size-cells = <0>;
127 }; 115 };
128 116
129 i2c@12CC0000 { 117 i2c@12CC0000 {
130 compatible = "samsung,s3c2440-i2c"; 118 compatible = "samsung,s3c2440-i2c";
131 reg = <0x12CC0000 0x100>; 119 reg = <0x12CC0000 0x100>;
132 interrupts = <0 62 0>; 120 interrupts = <0 62 0>;
121 #address-cells = <1>;
122 #size-cells = <0>;
133 }; 123 };
134 124
135 i2c@12CD0000 { 125 i2c@12CD0000 {
136 compatible = "samsung,s3c2440-i2c"; 126 compatible = "samsung,s3c2440-i2c";
137 reg = <0x12CD0000 0x100>; 127 reg = <0x12CD0000 0x100>;
138 interrupts = <0 63 0>; 128 interrupts = <0 63 0>;
129 #address-cells = <1>;
130 #size-cells = <0>;
139 }; 131 };
140 132
141 amba { 133 amba {
@@ -157,13 +149,13 @@
157 interrupts = <0 35 0>; 149 interrupts = <0 35 0>;
158 }; 150 };
159 151
160 mdma0: pdma@10800000 { 152 mdma0: mdma@10800000 {
161 compatible = "arm,pl330", "arm,primecell"; 153 compatible = "arm,pl330", "arm,primecell";
162 reg = <0x10800000 0x1000>; 154 reg = <0x10800000 0x1000>;
163 interrupts = <0 33 0>; 155 interrupts = <0 33 0>;
164 }; 156 };
165 157
166 mdma1: pdma@11C10000 { 158 mdma1: mdma@11C10000 {
167 compatible = "arm,pl330", "arm,primecell"; 159 compatible = "arm,pl330", "arm,primecell";
168 reg = <0x11C10000 0x1000>; 160 reg = <0x11C10000 0x1000>;
169 interrupts = <0 124 0>; 161 interrupts = <0 124 0>;
@@ -242,6 +234,12 @@
242 #gpio-cells = <4>; 234 #gpio-cells = <4>;
243 }; 235 };
244 236
237 gpc4: gpio-controller@114002E0 {
238 compatible = "samsung,exynos4-gpio";
239 reg = <0x114002E0 0x20>;
240 #gpio-cells = <4>;
241 };
242
245 gpd0: gpio-controller@11400160 { 243 gpd0: gpio-controller@11400160 {
246 compatible = "samsung,exynos4-gpio"; 244 compatible = "samsung,exynos4-gpio";
247 reg = <0x11400160 0x20>; 245 reg = <0x11400160 0x20>;
@@ -388,19 +386,19 @@
388 386
389 gpv2: gpio-controller@10D10040 { 387 gpv2: gpio-controller@10D10040 {
390 compatible = "samsung,exynos4-gpio"; 388 compatible = "samsung,exynos4-gpio";
391 reg = <0x10D10040 0x20>; 389 reg = <0x10D10060 0x20>;
392 #gpio-cells = <4>; 390 #gpio-cells = <4>;
393 }; 391 };
394 392
395 gpv3: gpio-controller@10D10060 { 393 gpv3: gpio-controller@10D10060 {
396 compatible = "samsung,exynos4-gpio"; 394 compatible = "samsung,exynos4-gpio";
397 reg = <0x10D10060 0x20>; 395 reg = <0x10D10080 0x20>;
398 #gpio-cells = <4>; 396 #gpio-cells = <4>;
399 }; 397 };
400 398
401 gpv4: gpio-controller@10D10080 { 399 gpv4: gpio-controller@10D10080 {
402 compatible = "samsung,exynos4-gpio"; 400 compatible = "samsung,exynos4-gpio";
403 reg = <0x10D10080 0x20>; 401 reg = <0x10D100C0 0x20>;
404 #gpio-cells = <4>; 402 #gpio-cells = <4>;
405 }; 403 };
406 404
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
new file mode 100644
index 00000000000..70bffa929b6
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/dts-v1/;
13/include/ "imx23.dtsi"
14
15/ {
16 model = "Freescale i.MX23 Evaluation Kit";
17 compatible = "fsl,imx23-evk", "fsl,imx23";
18
19 memory {
20 reg = <0x40000000 0x08000000>;
21 };
22
23 apb@80000000 {
24 apbh@80000000 {
25 ssp0: ssp@80010000 {
26 compatible = "fsl,imx23-mmc";
27 pinctrl-names = "default";
28 pinctrl-0 = <&mmc0_8bit_pins_a &mmc0_pins_fixup>;
29 bus-width = <8>;
30 wp-gpios = <&gpio1 30 0>;
31 status = "okay";
32 };
33 };
34
35 apbx@80040000 {
36 duart: serial@80070000 {
37 pinctrl-names = "default";
38 pinctrl-0 = <&duart_pins_a>;
39 status = "okay";
40 };
41 };
42 };
43};
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
new file mode 100644
index 00000000000..8c5f9994f3f
--- /dev/null
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -0,0 +1,295 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/include/ "skeleton.dtsi"
13
14/ {
15 interrupt-parent = <&icoll>;
16
17 aliases {
18 gpio0 = &gpio0;
19 gpio1 = &gpio1;
20 gpio2 = &gpio2;
21 };
22
23 cpus {
24 cpu@0 {
25 compatible = "arm,arm926ejs";
26 };
27 };
28
29 apb@80000000 {
30 compatible = "simple-bus";
31 #address-cells = <1>;
32 #size-cells = <1>;
33 reg = <0x80000000 0x80000>;
34 ranges;
35
36 apbh@80000000 {
37 compatible = "simple-bus";
38 #address-cells = <1>;
39 #size-cells = <1>;
40 reg = <0x80000000 0x40000>;
41 ranges;
42
43 icoll: interrupt-controller@80000000 {
44 compatible = "fsl,imx23-icoll", "fsl,mxs-icoll";
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 reg = <0x80000000 0x2000>;
48 };
49
50 dma-apbh@80004000 {
51 compatible = "fsl,imx23-dma-apbh";
52 reg = <0x80004000 2000>;
53 };
54
55 ecc@80008000 {
56 reg = <0x80008000 2000>;
57 status = "disabled";
58 };
59
60 bch@8000a000 {
61 reg = <0x8000a000 2000>;
62 status = "disabled";
63 };
64
65 gpmi@8000c000 {
66 reg = <0x8000c000 2000>;
67 status = "disabled";
68 };
69
70 ssp0: ssp@80010000 {
71 reg = <0x80010000 2000>;
72 interrupts = <15 14>;
73 fsl,ssp-dma-channel = <1>;
74 status = "disabled";
75 };
76
77 etm@80014000 {
78 reg = <0x80014000 2000>;
79 status = "disabled";
80 };
81
82 pinctrl@80018000 {
83 #address-cells = <1>;
84 #size-cells = <0>;
85 compatible = "fsl,imx23-pinctrl", "simple-bus";
86 reg = <0x80018000 2000>;
87
88 gpio0: gpio@0 {
89 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
90 interrupts = <16>;
91 gpio-controller;
92 #gpio-cells = <2>;
93 interrupt-controller;
94 #interrupt-cells = <2>;
95 };
96
97 gpio1: gpio@1 {
98 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
99 interrupts = <17>;
100 gpio-controller;
101 #gpio-cells = <2>;
102 interrupt-controller;
103 #interrupt-cells = <2>;
104 };
105
106 gpio2: gpio@2 {
107 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
108 interrupts = <18>;
109 gpio-controller;
110 #gpio-cells = <2>;
111 interrupt-controller;
112 #interrupt-cells = <2>;
113 };
114
115 duart_pins_a: duart@0 {
116 reg = <0>;
117 fsl,pinmux-ids = <0x11a2 0x11b2>;
118 fsl,drive-strength = <0>;
119 fsl,voltage = <1>;
120 fsl,pull-up = <0>;
121 };
122
123 mmc0_8bit_pins_a: mmc0-8bit@0 {
124 reg = <0>;
125 fsl,pinmux-ids = <0x2020 0x2030 0x2040
126 0x2050 0x0082 0x0092 0x00a2
127 0x00b2 0x2000 0x2010 0x2060>;
128 fsl,drive-strength = <1>;
129 fsl,voltage = <1>;
130 fsl,pull-up = <1>;
131 };
132
133 mmc0_pins_fixup: mmc0-pins-fixup {
134 fsl,pinmux-ids = <0x2010 0x2060>;
135 fsl,pull-up = <0>;
136 };
137 };
138
139 digctl@8001c000 {
140 reg = <0x8001c000 2000>;
141 status = "disabled";
142 };
143
144 emi@80020000 {
145 reg = <0x80020000 2000>;
146 status = "disabled";
147 };
148
149 dma-apbx@80024000 {
150 compatible = "fsl,imx23-dma-apbx";
151 reg = <0x80024000 2000>;
152 };
153
154 dcp@80028000 {
155 reg = <0x80028000 2000>;
156 status = "disabled";
157 };
158
159 pxp@8002a000 {
160 reg = <0x8002a000 2000>;
161 status = "disabled";
162 };
163
164 ocotp@8002c000 {
165 reg = <0x8002c000 2000>;
166 status = "disabled";
167 };
168
169 axi-ahb@8002e000 {
170 reg = <0x8002e000 2000>;
171 status = "disabled";
172 };
173
174 lcdif@80030000 {
175 reg = <0x80030000 2000>;
176 status = "disabled";
177 };
178
179 ssp1: ssp@80034000 {
180 reg = <0x80034000 2000>;
181 interrupts = <2 20>;
182 fsl,ssp-dma-channel = <2>;
183 status = "disabled";
184 };
185
186 tvenc@80038000 {
187 reg = <0x80038000 2000>;
188 status = "disabled";
189 };
190 };
191
192 apbx@80040000 {
193 compatible = "simple-bus";
194 #address-cells = <1>;
195 #size-cells = <1>;
196 reg = <0x80040000 0x40000>;
197 ranges;
198
199 clkctl@80040000 {
200 reg = <0x80040000 2000>;
201 status = "disabled";
202 };
203
204 saif0: saif@80042000 {
205 reg = <0x80042000 2000>;
206 status = "disabled";
207 };
208
209 power@80044000 {
210 reg = <0x80044000 2000>;
211 status = "disabled";
212 };
213
214 saif1: saif@80046000 {
215 reg = <0x80046000 2000>;
216 status = "disabled";
217 };
218
219 audio-out@80048000 {
220 reg = <0x80048000 2000>;
221 status = "disabled";
222 };
223
224 audio-in@8004c000 {
225 reg = <0x8004c000 2000>;
226 status = "disabled";
227 };
228
229 lradc@80050000 {
230 reg = <0x80050000 2000>;
231 status = "disabled";
232 };
233
234 spdif@80054000 {
235 reg = <0x80054000 2000>;
236 status = "disabled";
237 };
238
239 i2c@80058000 {
240 reg = <0x80058000 2000>;
241 status = "disabled";
242 };
243
244 rtc@8005c000 {
245 reg = <0x8005c000 2000>;
246 status = "disabled";
247 };
248
249 pwm@80064000 {
250 reg = <0x80064000 2000>;
251 status = "disabled";
252 };
253
254 timrot@80068000 {
255 reg = <0x80068000 2000>;
256 status = "disabled";
257 };
258
259 auart0: serial@8006c000 {
260 reg = <0x8006c000 0x2000>;
261 status = "disabled";
262 };
263
264 auart1: serial@8006e000 {
265 reg = <0x8006e000 0x2000>;
266 status = "disabled";
267 };
268
269 duart: serial@80070000 {
270 compatible = "arm,pl011", "arm,primecell";
271 reg = <0x80070000 0x2000>;
272 interrupts = <0>;
273 status = "disabled";
274 };
275
276 usbphy@8007c000 {
277 reg = <0x8007c000 0x2000>;
278 status = "disabled";
279 };
280 };
281 };
282
283 ahb@80080000 {
284 compatible = "simple-bus";
285 #address-cells = <1>;
286 #size-cells = <1>;
287 reg = <0x80080000 0x80000>;
288 ranges;
289
290 usbctrl@80080000 {
291 reg = <0x80080000 0x10000>;
292 status = "disabled";
293 };
294 };
295};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore.dts b/arch/arm/boot/dts/imx27-phytec-phycore.dts
index a51a08fc2af..2b0ff60247a 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycore.dts
+++ b/arch/arm/boot/dts/imx27-phytec-phycore.dts
@@ -27,22 +27,22 @@
27 status = "okay"; 27 status = "okay";
28 }; 28 };
29 29
30 uart@1000a000 { 30 serial@1000a000 {
31 fsl,uart-has-rtscts; 31 fsl,uart-has-rtscts;
32 status = "okay"; 32 status = "okay";
33 }; 33 };
34 34
35 uart@1000b000 { 35 serial@1000b000 {
36 fsl,uart-has-rtscts; 36 fsl,uart-has-rtscts;
37 status = "okay"; 37 status = "okay";
38 }; 38 };
39 39
40 uart@1000c000 { 40 serial@1000c000 {
41 fsl,uart-has-rtscts; 41 fsl,uart-has-rtscts;
42 status = "okay"; 42 status = "okay";
43 }; 43 };
44 44
45 fec@1002b000 { 45 ethernet@1002b000 {
46 status = "okay"; 46 status = "okay";
47 }; 47 };
48 48
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index bc5e7d5ddd5..2b1a166d41f 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -59,28 +59,28 @@
59 status = "disabled"; 59 status = "disabled";
60 }; 60 };
61 61
62 uart1: uart@1000a000 { 62 uart1: serial@1000a000 {
63 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 63 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
64 reg = <0x1000a000 0x1000>; 64 reg = <0x1000a000 0x1000>;
65 interrupts = <20>; 65 interrupts = <20>;
66 status = "disabled"; 66 status = "disabled";
67 }; 67 };
68 68
69 uart2: uart@1000b000 { 69 uart2: serial@1000b000 {
70 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 70 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
71 reg = <0x1000b000 0x1000>; 71 reg = <0x1000b000 0x1000>;
72 interrupts = <19>; 72 interrupts = <19>;
73 status = "disabled"; 73 status = "disabled";
74 }; 74 };
75 75
76 uart3: uart@1000c000 { 76 uart3: serial@1000c000 {
77 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 77 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
78 reg = <0x1000c000 0x1000>; 78 reg = <0x1000c000 0x1000>;
79 interrupts = <18>; 79 interrupts = <18>;
80 status = "disabled"; 80 status = "disabled";
81 }; 81 };
82 82
83 uart4: uart@1000d000 { 83 uart4: serial@1000d000 {
84 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 84 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
85 reg = <0x1000d000 0x1000>; 85 reg = <0x1000d000 0x1000>;
86 interrupts = <17>; 86 interrupts = <17>;
@@ -183,14 +183,14 @@
183 status = "disabled"; 183 status = "disabled";
184 }; 184 };
185 185
186 uart5: uart@1001b000 { 186 uart5: serial@1001b000 {
187 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 187 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
188 reg = <0x1001b000 0x1000>; 188 reg = <0x1001b000 0x1000>;
189 interrupts = <49>; 189 interrupts = <49>;
190 status = "disabled"; 190 status = "disabled";
191 }; 191 };
192 192
193 uart6: uart@1001c000 { 193 uart6: serial@1001c000 {
194 compatible = "fsl,imx27-uart", "fsl,imx21-uart"; 194 compatible = "fsl,imx27-uart", "fsl,imx21-uart";
195 reg = <0x1001c000 0x1000>; 195 reg = <0x1001c000 0x1000>;
196 interrupts = <48>; 196 interrupts = <48>;
@@ -206,7 +206,7 @@
206 status = "disabled"; 206 status = "disabled";
207 }; 207 };
208 208
209 fec: fec@1002b000 { 209 fec: ethernet@1002b000 {
210 compatible = "fsl,imx27-fec"; 210 compatible = "fsl,imx27-fec";
211 reg = <0x1002b000 0x4000>; 211 reg = <0x1002b000 0x4000>;
212 interrupts = <50>; 212 interrupts = <50>;
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
new file mode 100644
index 00000000000..ee520a529cb
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/dts-v1/;
13/include/ "imx28.dtsi"
14
15/ {
16 model = "Freescale i.MX28 Evaluation Kit";
17 compatible = "fsl,imx28-evk", "fsl,imx28";
18
19 memory {
20 reg = <0x40000000 0x08000000>;
21 };
22
23 apb@80000000 {
24 apbh@80000000 {
25 ssp0: ssp@80010000 {
26 compatible = "fsl,imx28-mmc";
27 pinctrl-names = "default";
28 pinctrl-0 = <&mmc0_8bit_pins_a
29 &mmc0_cd_cfg &mmc0_sck_cfg>;
30 bus-width = <8>;
31 wp-gpios = <&gpio2 12 0>;
32 status = "okay";
33 };
34
35 ssp1: ssp@80012000 {
36 compatible = "fsl,imx28-mmc";
37 bus-width = <8>;
38 wp-gpios = <&gpio0 28 0>;
39 status = "okay";
40 };
41 };
42
43 apbx@80040000 {
44 saif0: saif@80042000 {
45 pinctrl-names = "default";
46 pinctrl-0 = <&saif0_pins_a>;
47 status = "okay";
48 };
49
50 saif1: saif@80046000 {
51 pinctrl-names = "default";
52 pinctrl-0 = <&saif1_pins_a>;
53 fsl,saif-master = <&saif0>;
54 status = "okay";
55 };
56
57 i2c0: i2c@80058000 {
58 pinctrl-names = "default";
59 pinctrl-0 = <&i2c0_pins_a>;
60 status = "okay";
61
62 sgtl5000: codec@0a {
63 compatible = "fsl,sgtl5000";
64 reg = <0x0a>;
65 VDDA-supply = <&reg_3p3v>;
66 VDDIO-supply = <&reg_3p3v>;
67
68 };
69 };
70
71 duart: serial@80074000 {
72 pinctrl-names = "default";
73 pinctrl-0 = <&duart_pins_a>;
74 status = "okay";
75 };
76 };
77 };
78
79 ahb@80080000 {
80 mac0: ethernet@800f0000 {
81 phy-mode = "rmii";
82 pinctrl-names = "default";
83 pinctrl-0 = <&mac0_pins_a>;
84 status = "okay";
85 };
86
87 mac1: ethernet@800f4000 {
88 phy-mode = "rmii";
89 pinctrl-names = "default";
90 pinctrl-0 = <&mac1_pins_a>;
91 status = "okay";
92 };
93 };
94
95 regulators {
96 compatible = "simple-bus";
97
98 reg_3p3v: 3p3v {
99 compatible = "regulator-fixed";
100 regulator-name = "3P3V";
101 regulator-min-microvolt = <3300000>;
102 regulator-max-microvolt = <3300000>;
103 regulator-always-on;
104 };
105 };
106
107 sound {
108 compatible = "fsl,imx28-evk-sgtl5000",
109 "fsl,mxs-audio-sgtl5000";
110 model = "imx28-evk-sgtl5000";
111 saif-controllers = <&saif0 &saif1>;
112 audio-codec = <&sgtl5000>;
113 };
114};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
new file mode 100644
index 00000000000..4634cb861a5
--- /dev/null
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -0,0 +1,497 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/include/ "skeleton.dtsi"
13
14/ {
15 interrupt-parent = <&icoll>;
16
17 aliases {
18 gpio0 = &gpio0;
19 gpio1 = &gpio1;
20 gpio2 = &gpio2;
21 gpio3 = &gpio3;
22 gpio4 = &gpio4;
23 saif0 = &saif0;
24 saif1 = &saif1;
25 };
26
27 cpus {
28 cpu@0 {
29 compatible = "arm,arm926ejs";
30 };
31 };
32
33 apb@80000000 {
34 compatible = "simple-bus";
35 #address-cells = <1>;
36 #size-cells = <1>;
37 reg = <0x80000000 0x80000>;
38 ranges;
39
40 apbh@80000000 {
41 compatible = "simple-bus";
42 #address-cells = <1>;
43 #size-cells = <1>;
44 reg = <0x80000000 0x3c900>;
45 ranges;
46
47 icoll: interrupt-controller@80000000 {
48 compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
49 interrupt-controller;
50 #interrupt-cells = <1>;
51 reg = <0x80000000 0x2000>;
52 };
53
54 hsadc@80002000 {
55 reg = <0x80002000 2000>;
56 interrupts = <13 87>;
57 status = "disabled";
58 };
59
60 dma-apbh@80004000 {
61 compatible = "fsl,imx28-dma-apbh";
62 reg = <0x80004000 2000>;
63 };
64
65 perfmon@80006000 {
66 reg = <0x80006000 800>;
67 interrupts = <27>;
68 status = "disabled";
69 };
70
71 bch@8000a000 {
72 reg = <0x8000a000 2000>;
73 interrupts = <41>;
74 status = "disabled";
75 };
76
77 gpmi@8000c000 {
78 reg = <0x8000c000 2000>;
79 interrupts = <42 88>;
80 status = "disabled";
81 };
82
83 ssp0: ssp@80010000 {
84 reg = <0x80010000 2000>;
85 interrupts = <96 82>;
86 fsl,ssp-dma-channel = <0>;
87 status = "disabled";
88 };
89
90 ssp1: ssp@80012000 {
91 reg = <0x80012000 2000>;
92 interrupts = <97 83>;
93 fsl,ssp-dma-channel = <1>;
94 status = "disabled";
95 };
96
97 ssp2: ssp@80014000 {
98 reg = <0x80014000 2000>;
99 interrupts = <98 84>;
100 fsl,ssp-dma-channel = <2>;
101 status = "disabled";
102 };
103
104 ssp3: ssp@80016000 {
105 reg = <0x80016000 2000>;
106 interrupts = <99 85>;
107 fsl,ssp-dma-channel = <3>;
108 status = "disabled";
109 };
110
111 pinctrl@80018000 {
112 #address-cells = <1>;
113 #size-cells = <0>;
114 compatible = "fsl,imx28-pinctrl", "simple-bus";
115 reg = <0x80018000 2000>;
116
117 gpio0: gpio@0 {
118 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
119 interrupts = <127>;
120 gpio-controller;
121 #gpio-cells = <2>;
122 interrupt-controller;
123 #interrupt-cells = <2>;
124 };
125
126 gpio1: gpio@1 {
127 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
128 interrupts = <126>;
129 gpio-controller;
130 #gpio-cells = <2>;
131 interrupt-controller;
132 #interrupt-cells = <2>;
133 };
134
135 gpio2: gpio@2 {
136 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
137 interrupts = <125>;
138 gpio-controller;
139 #gpio-cells = <2>;
140 interrupt-controller;
141 #interrupt-cells = <2>;
142 };
143
144 gpio3: gpio@3 {
145 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
146 interrupts = <124>;
147 gpio-controller;
148 #gpio-cells = <2>;
149 interrupt-controller;
150 #interrupt-cells = <2>;
151 };
152
153 gpio4: gpio@4 {
154 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
155 interrupts = <123>;
156 gpio-controller;
157 #gpio-cells = <2>;
158 interrupt-controller;
159 #interrupt-cells = <2>;
160 };
161
162 duart_pins_a: duart@0 {
163 reg = <0>;
164 fsl,pinmux-ids = <0x3102 0x3112>;
165 fsl,drive-strength = <0>;
166 fsl,voltage = <1>;
167 fsl,pull-up = <0>;
168 };
169
170 mac0_pins_a: mac0@0 {
171 reg = <0>;
172 fsl,pinmux-ids = <0x4000 0x4010 0x4020
173 0x4030 0x4040 0x4060 0x4070
174 0x4080 0x4100>;
175 fsl,drive-strength = <1>;
176 fsl,voltage = <1>;
177 fsl,pull-up = <1>;
178 };
179
180 mac1_pins_a: mac1@0 {
181 reg = <0>;
182 fsl,pinmux-ids = <0x40f1 0x4091 0x40a1
183 0x40e1 0x40b1 0x40c1>;
184 fsl,drive-strength = <1>;
185 fsl,voltage = <1>;
186 fsl,pull-up = <1>;
187 };
188
189 mmc0_8bit_pins_a: mmc0-8bit@0 {
190 reg = <0>;
191 fsl,pinmux-ids = <0x2000 0x2010 0x2020
192 0x2030 0x2040 0x2050 0x2060
193 0x2070 0x2080 0x2090 0x20a0>;
194 fsl,drive-strength = <1>;
195 fsl,voltage = <1>;
196 fsl,pull-up = <1>;
197 };
198
199 mmc0_cd_cfg: mmc0-cd-cfg {
200 fsl,pinmux-ids = <0x2090>;
201 fsl,pull-up = <0>;
202 };
203
204 mmc0_sck_cfg: mmc0-sck-cfg {
205 fsl,pinmux-ids = <0x20a0>;
206 fsl,drive-strength = <2>;
207 fsl,pull-up = <0>;
208 };
209
210 i2c0_pins_a: i2c0@0 {
211 reg = <0>;
212 fsl,pinmux-ids = <0x3180 0x3190>;
213 fsl,drive-strength = <1>;
214 fsl,voltage = <1>;
215 fsl,pull-up = <1>;
216 };
217
218 saif0_pins_a: saif0@0 {
219 reg = <0>;
220 fsl,pinmux-ids =
221 <0x3140 0x3150 0x3160 0x3170>;
222 fsl,drive-strength = <2>;
223 fsl,voltage = <1>;
224 fsl,pull-up = <1>;
225 };
226
227 saif1_pins_a: saif1@0 {
228 reg = <0>;
229 fsl,pinmux-ids = <0x31a0>;
230 fsl,drive-strength = <2>;
231 fsl,voltage = <1>;
232 fsl,pull-up = <1>;
233 };
234 };
235
236 digctl@8001c000 {
237 reg = <0x8001c000 2000>;
238 interrupts = <89>;
239 status = "disabled";
240 };
241
242 etm@80022000 {
243 reg = <0x80022000 2000>;
244 status = "disabled";
245 };
246
247 dma-apbx@80024000 {
248 compatible = "fsl,imx28-dma-apbx";
249 reg = <0x80024000 2000>;
250 };
251
252 dcp@80028000 {
253 reg = <0x80028000 2000>;
254 interrupts = <52 53 54>;
255 status = "disabled";
256 };
257
258 pxp@8002a000 {
259 reg = <0x8002a000 2000>;
260 interrupts = <39>;
261 status = "disabled";
262 };
263
264 ocotp@8002c000 {
265 reg = <0x8002c000 2000>;
266 status = "disabled";
267 };
268
269 axi-ahb@8002e000 {
270 reg = <0x8002e000 2000>;
271 status = "disabled";
272 };
273
274 lcdif@80030000 {
275 reg = <0x80030000 2000>;
276 interrupts = <38 86>;
277 status = "disabled";
278 };
279
280 can0: can@80032000 {
281 reg = <0x80032000 2000>;
282 interrupts = <8>;
283 status = "disabled";
284 };
285
286 can1: can@80034000 {
287 reg = <0x80034000 2000>;
288 interrupts = <9>;
289 status = "disabled";
290 };
291
292 simdbg@8003c000 {
293 reg = <0x8003c000 200>;
294 status = "disabled";
295 };
296
297 simgpmisel@8003c200 {
298 reg = <0x8003c200 100>;
299 status = "disabled";
300 };
301
302 simsspsel@8003c300 {
303 reg = <0x8003c300 100>;
304 status = "disabled";
305 };
306
307 simmemsel@8003c400 {
308 reg = <0x8003c400 100>;
309 status = "disabled";
310 };
311
312 gpiomon@8003c500 {
313 reg = <0x8003c500 100>;
314 status = "disabled";
315 };
316
317 simenet@8003c700 {
318 reg = <0x8003c700 100>;
319 status = "disabled";
320 };
321
322 armjtag@8003c800 {
323 reg = <0x8003c800 100>;
324 status = "disabled";
325 };
326 };
327
328 apbx@80040000 {
329 compatible = "simple-bus";
330 #address-cells = <1>;
331 #size-cells = <1>;
332 reg = <0x80040000 0x40000>;
333 ranges;
334
335 clkctl@80040000 {
336 reg = <0x80040000 2000>;
337 status = "disabled";
338 };
339
340 saif0: saif@80042000 {
341 compatible = "fsl,imx28-saif";
342 reg = <0x80042000 2000>;
343 interrupts = <59 80>;
344 fsl,saif-dma-channel = <4>;
345 status = "disabled";
346 };
347
348 power@80044000 {
349 reg = <0x80044000 2000>;
350 status = "disabled";
351 };
352
353 saif1: saif@80046000 {
354 compatible = "fsl,imx28-saif";
355 reg = <0x80046000 2000>;
356 interrupts = <58 81>;
357 fsl,saif-dma-channel = <5>;
358 status = "disabled";
359 };
360
361 lradc@80050000 {
362 reg = <0x80050000 2000>;
363 status = "disabled";
364 };
365
366 spdif@80054000 {
367 reg = <0x80054000 2000>;
368 interrupts = <45 66>;
369 status = "disabled";
370 };
371
372 rtc@80056000 {
373 reg = <0x80056000 2000>;
374 interrupts = <28 29>;
375 status = "disabled";
376 };
377
378 i2c0: i2c@80058000 {
379 #address-cells = <1>;
380 #size-cells = <0>;
381 compatible = "fsl,imx28-i2c";
382 reg = <0x80058000 2000>;
383 interrupts = <111 68>;
384 status = "disabled";
385 };
386
387 i2c1: i2c@8005a000 {
388 #address-cells = <1>;
389 #size-cells = <0>;
390 compatible = "fsl,imx28-i2c";
391 reg = <0x8005a000 2000>;
392 interrupts = <110 69>;
393 status = "disabled";
394 };
395
396 pwm@80064000 {
397 reg = <0x80064000 2000>;
398 status = "disabled";
399 };
400
401 timrot@80068000 {
402 reg = <0x80068000 2000>;
403 status = "disabled";
404 };
405
406 auart0: serial@8006a000 {
407 reg = <0x8006a000 0x2000>;
408 interrupts = <112 70 71>;
409 status = "disabled";
410 };
411
412 auart1: serial@8006c000 {
413 reg = <0x8006c000 0x2000>;
414 interrupts = <113 72 73>;
415 status = "disabled";
416 };
417
418 auart2: serial@8006e000 {
419 reg = <0x8006e000 0x2000>;
420 interrupts = <114 74 75>;
421 status = "disabled";
422 };
423
424 auart3: serial@80070000 {
425 reg = <0x80070000 0x2000>;
426 interrupts = <115 76 77>;
427 status = "disabled";
428 };
429
430 auart4: serial@80072000 {
431 reg = <0x80072000 0x2000>;
432 interrupts = <116 78 79>;
433 status = "disabled";
434 };
435
436 duart: serial@80074000 {
437 compatible = "arm,pl011", "arm,primecell";
438 reg = <0x80074000 0x1000>;
439 interrupts = <47>;
440 status = "disabled";
441 };
442
443 usbphy0: usbphy@8007c000 {
444 reg = <0x8007c000 0x2000>;
445 status = "disabled";
446 };
447
448 usbphy1: usbphy@8007e000 {
449 reg = <0x8007e000 0x2000>;
450 status = "disabled";
451 };
452 };
453 };
454
455 ahb@80080000 {
456 compatible = "simple-bus";
457 #address-cells = <1>;
458 #size-cells = <1>;
459 reg = <0x80080000 0x80000>;
460 ranges;
461
462 usbctrl0: usbctrl@80080000 {
463 reg = <0x80080000 0x10000>;
464 status = "disabled";
465 };
466
467 usbctrl1: usbctrl@80090000 {
468 reg = <0x80090000 0x10000>;
469 status = "disabled";
470 };
471
472 dflpt@800c0000 {
473 reg = <0x800c0000 0x10000>;
474 status = "disabled";
475 };
476
477 mac0: ethernet@800f0000 {
478 compatible = "fsl,imx28-fec";
479 reg = <0x800f0000 0x4000>;
480 interrupts = <101>;
481 status = "disabled";
482 };
483
484 mac1: ethernet@800f4000 {
485 compatible = "fsl,imx28-fec";
486 reg = <0x800f4000 0x4000>;
487 interrupts = <102>;
488 status = "disabled";
489 };
490
491 switch@800f8000 {
492 reg = <0x800f8000 0x8000>;
493 status = "disabled";
494 };
495
496 };
497};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index 9949e6060de..de065b5976e 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -17,10 +17,6 @@
17 model = "Freescale i.MX51 Babbage Board"; 17 model = "Freescale i.MX51 Babbage Board";
18 compatible = "fsl,imx51-babbage", "fsl,imx51"; 18 compatible = "fsl,imx51-babbage", "fsl,imx51";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x90000000 0x20000000>; 21 reg = <0x90000000 0x20000000>;
26 }; 22 };
@@ -40,7 +36,7 @@
40 status = "okay"; 36 status = "okay";
41 }; 37 };
42 38
43 uart3: uart@7000c000 { 39 uart3: serial@7000c000 {
44 fsl,uart-has-rtscts; 40 fsl,uart-has-rtscts;
45 status = "okay"; 41 status = "okay";
46 }; 42 };
@@ -166,6 +162,11 @@
166 }; 162 };
167 }; 163 };
168 }; 164 };
165
166 ssi2: ssi@70014000 {
167 fsl,mode = "i2s-slave";
168 status = "okay";
169 };
169 }; 170 };
170 171
171 wdog@73f98000 { /* WDOG1 */ 172 wdog@73f98000 { /* WDOG1 */
@@ -177,12 +178,12 @@
177 reg = <0x73fa8000 0x4000>; 178 reg = <0x73fa8000 0x4000>;
178 }; 179 };
179 180
180 uart1: uart@73fbc000 { 181 uart1: serial@73fbc000 {
181 fsl,uart-has-rtscts; 182 fsl,uart-has-rtscts;
182 status = "okay"; 183 status = "okay";
183 }; 184 };
184 185
185 uart2: uart@73fc0000 { 186 uart2: serial@73fc0000 {
186 status = "okay"; 187 status = "okay";
187 }; 188 };
188 }; 189 };
@@ -195,13 +196,20 @@
195 i2c@83fc4000 { /* I2C2 */ 196 i2c@83fc4000 { /* I2C2 */
196 status = "okay"; 197 status = "okay";
197 198
198 codec: sgtl5000@0a { 199 sgtl5000: codec@0a {
199 compatible = "fsl,sgtl5000"; 200 compatible = "fsl,sgtl5000";
200 reg = <0x0a>; 201 reg = <0x0a>;
202 clock-frequency = <26000000>;
203 VDDA-supply = <&vdig_reg>;
204 VDDIO-supply = <&vvideo_reg>;
201 }; 205 };
202 }; 206 };
203 207
204 fec@83fec000 { 208 audmux@83fd0000 {
209 status = "okay";
210 };
211
212 ethernet@83fec000 {
205 phy-mode = "mii"; 213 phy-mode = "mii";
206 status = "okay"; 214 status = "okay";
207 }; 215 };
@@ -218,4 +226,18 @@
218 gpio-key,wakeup; 226 gpio-key,wakeup;
219 }; 227 };
220 }; 228 };
229
230 sound {
231 compatible = "fsl,imx51-babbage-sgtl5000",
232 "fsl,imx-audio-sgtl5000";
233 model = "imx51-babbage-sgtl5000";
234 ssi-controller = <&ssi2>;
235 audio-codec = <&sgtl5000>;
236 audio-routing =
237 "MIC_IN", "Mic Jack",
238 "Mic Jack", "Mic Bias",
239 "Headphone Jack", "HP_OUT";
240 mux-int-port = <2>;
241 mux-ext-port = <3>;
242 };
221}; 243};
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 6663986fe1c..bfa65abe8ef 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -86,7 +86,7 @@
86 status = "disabled"; 86 status = "disabled";
87 }; 87 };
88 88
89 uart3: uart@7000c000 { 89 uart3: serial@7000c000 {
90 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 90 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
91 reg = <0x7000c000 0x4000>; 91 reg = <0x7000c000 0x4000>;
92 interrupts = <33>; 92 interrupts = <33>;
@@ -102,6 +102,15 @@
102 status = "disabled"; 102 status = "disabled";
103 }; 103 };
104 104
105 ssi2: ssi@70014000 {
106 compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
107 reg = <0x70014000 0x4000>;
108 interrupts = <30>;
109 fsl,fifo-depth = <15>;
110 fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
111 status = "disabled";
112 };
113
105 esdhc@70020000 { /* ESDHC3 */ 114 esdhc@70020000 { /* ESDHC3 */
106 compatible = "fsl,imx51-esdhc"; 115 compatible = "fsl,imx51-esdhc";
107 reg = <0x70020000 0x4000>; 116 reg = <0x70020000 0x4000>;
@@ -171,14 +180,14 @@
171 status = "disabled"; 180 status = "disabled";
172 }; 181 };
173 182
174 uart1: uart@73fbc000 { 183 uart1: serial@73fbc000 {
175 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 184 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
176 reg = <0x73fbc000 0x4000>; 185 reg = <0x73fbc000 0x4000>;
177 interrupts = <31>; 186 interrupts = <31>;
178 status = "disabled"; 187 status = "disabled";
179 }; 188 };
180 189
181 uart2: uart@73fc0000 { 190 uart2: serial@73fc0000 {
182 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 191 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
183 reg = <0x73fc0000 0x4000>; 192 reg = <0x73fc0000 0x4000>;
184 interrupts = <32>; 193 interrupts = <32>;
@@ -235,7 +244,31 @@
235 status = "disabled"; 244 status = "disabled";
236 }; 245 };
237 246
238 fec@83fec000 { 247 ssi1: ssi@83fcc000 {
248 compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
249 reg = <0x83fcc000 0x4000>;
250 interrupts = <29>;
251 fsl,fifo-depth = <15>;
252 fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
253 status = "disabled";
254 };
255
256 audmux@83fd0000 {
257 compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
258 reg = <0x83fd0000 0x4000>;
259 status = "disabled";
260 };
261
262 ssi3: ssi@83fe8000 {
263 compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
264 reg = <0x83fe8000 0x4000>;
265 interrupts = <96>;
266 fsl,fifo-depth = <15>;
267 fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
268 status = "disabled";
269 };
270
271 ethernet@83fec000 {
239 compatible = "fsl,imx51-fec", "fsl,imx27-fec"; 272 compatible = "fsl,imx51-fec", "fsl,imx27-fec";
240 reg = <0x83fec000 0x4000>; 273 reg = <0x83fec000 0x4000>;
241 interrupts = <87>; 274 interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
index 2dccce46ed8..5b8eafcdbee 100644
--- a/arch/arm/boot/dts/imx53-ard.dts
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -17,10 +17,6 @@
17 model = "Freescale i.MX53 Automotive Reference Design Board"; 17 model = "Freescale i.MX53 Automotive Reference Design Board";
18 compatible = "fsl,imx53-ard", "fsl,imx53"; 18 compatible = "fsl,imx53-ard", "fsl,imx53";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x70000000 0x40000000>; 21 reg = <0x70000000 0x40000000>;
26 }; 22 };
@@ -44,7 +40,7 @@
44 reg = <0x53fa8000 0x4000>; 40 reg = <0x53fa8000 0x4000>;
45 }; 41 };
46 42
47 uart1: uart@53fbc000 { 43 uart1: serial@53fbc000 {
48 status = "okay"; 44 status = "okay";
49 }; 45 };
50 }; 46 };
diff --git a/arch/arm/boot/dts/imx53-evk.dts b/arch/arm/boot/dts/imx53-evk.dts
index 5bac4aa4800..9c798034675 100644
--- a/arch/arm/boot/dts/imx53-evk.dts
+++ b/arch/arm/boot/dts/imx53-evk.dts
@@ -17,10 +17,6 @@
17 model = "Freescale i.MX53 Evaluation Kit"; 17 model = "Freescale i.MX53 Evaluation Kit";
18 compatible = "fsl,imx53-evk", "fsl,imx53"; 18 compatible = "fsl,imx53-evk", "fsl,imx53";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x70000000 0x80000000>; 21 reg = <0x70000000 0x80000000>;
26 }; 22 };
@@ -75,7 +71,7 @@
75 reg = <0x53fa8000 0x4000>; 71 reg = <0x53fa8000 0x4000>;
76 }; 72 };
77 73
78 uart1: uart@53fbc000 { 74 uart1: serial@53fbc000 {
79 status = "okay"; 75 status = "okay";
80 }; 76 };
81 }; 77 };
@@ -99,7 +95,7 @@
99 }; 95 };
100 }; 96 };
101 97
102 fec@63fec000 { 98 ethernet@63fec000 {
103 phy-mode = "rmii"; 99 phy-mode = "rmii";
104 phy-reset-gpios = <&gpio7 6 0>; 100 phy-reset-gpios = <&gpio7 6 0>;
105 status = "okay"; 101 status = "okay";
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
index 5c57c8672c3..2d803a9a694 100644
--- a/arch/arm/boot/dts/imx53-qsb.dts
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -17,10 +17,6 @@
17 model = "Freescale i.MX53 Quick Start Board"; 17 model = "Freescale i.MX53 Quick Start Board";
18 compatible = "fsl,imx53-qsb", "fsl,imx53"; 18 compatible = "fsl,imx53-qsb", "fsl,imx53";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x70000000 0x40000000>; 21 reg = <0x70000000 0x40000000>;
26 }; 22 };
@@ -33,6 +29,11 @@
33 status = "okay"; 29 status = "okay";
34 }; 30 };
35 31
32 ssi2: ssi@50014000 {
33 fsl,mode = "i2s-slave";
34 status = "okay";
35 };
36
36 esdhc@50020000 { /* ESDHC3 */ 37 esdhc@50020000 { /* ESDHC3 */
37 cd-gpios = <&gpio3 11 0>; 38 cd-gpios = <&gpio3 11 0>;
38 wp-gpios = <&gpio3 12 0>; 39 wp-gpios = <&gpio3 12 0>;
@@ -49,7 +50,7 @@
49 reg = <0x53fa8000 0x4000>; 50 reg = <0x53fa8000 0x4000>;
50 }; 51 };
51 52
52 uart1: uart@53fbc000 { 53 uart1: serial@53fbc000 {
53 status = "okay"; 54 status = "okay";
54 }; 55 };
55 }; 56 };
@@ -62,9 +63,11 @@
62 i2c@63fc4000 { /* I2C2 */ 63 i2c@63fc4000 { /* I2C2 */
63 status = "okay"; 64 status = "okay";
64 65
65 codec: sgtl5000@0a { 66 sgtl5000: codec@0a {
66 compatible = "fsl,sgtl5000"; 67 compatible = "fsl,sgtl5000";
67 reg = <0x0a>; 68 reg = <0x0a>;
69 VDDA-supply = <&reg_3p2v>;
70 VDDIO-supply = <&reg_3p2v>;
68 }; 71 };
69 }; 72 };
70 73
@@ -77,12 +80,88 @@
77 }; 80 };
78 81
79 pmic: dialog@48 { 82 pmic: dialog@48 {
80 compatible = "dialog,da9053", "dialog,da9052"; 83 compatible = "dlg,da9053-aa", "dlg,da9052";
81 reg = <0x48>; 84 reg = <0x48>;
85
86 regulators {
87 buck0 {
88 regulator-min-microvolt = <500000>;
89 regulator-max-microvolt = <2075000>;
90 };
91
92 buck1 {
93 regulator-min-microvolt = <500000>;
94 regulator-max-microvolt = <2075000>;
95 };
96
97 buck2 {
98 regulator-min-microvolt = <925000>;
99 regulator-max-microvolt = <2500000>;
100 };
101
102 buck3 {
103 regulator-min-microvolt = <925000>;
104 regulator-max-microvolt = <2500000>;
105 };
106
107 ldo4 {
108 regulator-min-microvolt = <600000>;
109 regulator-max-microvolt = <1800000>;
110 };
111
112 ldo5 {
113 regulator-min-microvolt = <600000>;
114 regulator-max-microvolt = <1800000>;
115 };
116
117 ldo6 {
118 regulator-min-microvolt = <1725000>;
119 regulator-max-microvolt = <3300000>;
120 };
121
122 ldo7 {
123 regulator-min-microvolt = <1725000>;
124 regulator-max-microvolt = <3300000>;
125 };
126
127 ldo8 {
128 regulator-min-microvolt = <1200000>;
129 regulator-max-microvolt = <3600000>;
130 };
131
132 ldo9 {
133 regulator-min-microvolt = <1200000>;
134 regulator-max-microvolt = <3600000>;
135 };
136
137 ldo10 {
138 regulator-min-microvolt = <1200000>;
139 regulator-max-microvolt = <3600000>;
140 };
141
142 ldo11 {
143 regulator-min-microvolt = <1200000>;
144 regulator-max-microvolt = <3600000>;
145 };
146
147 ldo12 {
148 regulator-min-microvolt = <1250000>;
149 regulator-max-microvolt = <3650000>;
150 };
151
152 ldo13 {
153 regulator-min-microvolt = <1200000>;
154 regulator-max-microvolt = <3600000>;
155 };
156 };
82 }; 157 };
83 }; 158 };
84 159
85 fec@63fec000 { 160 audmux@63fd0000 {
161 status = "okay";
162 };
163
164 ethernet@63fec000 {
86 phy-mode = "rmii"; 165 phy-mode = "rmii";
87 phy-reset-gpios = <&gpio7 6 0>; 166 phy-reset-gpios = <&gpio7 6 0>;
88 status = "okay"; 167 status = "okay";
@@ -122,4 +201,30 @@
122 linux,default-trigger = "heartbeat"; 201 linux,default-trigger = "heartbeat";
123 }; 202 };
124 }; 203 };
204
205 regulators {
206 compatible = "simple-bus";
207
208 reg_3p2v: 3p2v {
209 compatible = "regulator-fixed";
210 regulator-name = "3P2V";
211 regulator-min-microvolt = <3200000>;
212 regulator-max-microvolt = <3200000>;
213 regulator-always-on;
214 };
215 };
216
217 sound {
218 compatible = "fsl,imx53-qsb-sgtl5000",
219 "fsl,imx-audio-sgtl5000";
220 model = "imx53-qsb-sgtl5000";
221 ssi-controller = <&ssi2>;
222 audio-codec = <&sgtl5000>;
223 audio-routing =
224 "MIC_IN", "Mic Jack",
225 "Mic Jack", "Mic Bias",
226 "Headphone Jack", "HP_OUT";
227 mux-int-port = <2>;
228 mux-ext-port = <5>;
229 };
125}; 230};
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index c7ee86c2dfb..08091029168 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -17,10 +17,6 @@
17 model = "Freescale i.MX53 Smart Mobile Reference Design Board"; 17 model = "Freescale i.MX53 Smart Mobile Reference Design Board";
18 compatible = "fsl,imx53-smd", "fsl,imx53"; 18 compatible = "fsl,imx53-smd", "fsl,imx53";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x70000000 0x40000000>; 21 reg = <0x70000000 0x40000000>;
26 }; 22 };
@@ -35,11 +31,11 @@
35 }; 31 };
36 32
37 esdhc@50008000 { /* ESDHC2 */ 33 esdhc@50008000 { /* ESDHC2 */
38 fsl,card-wired; 34 non-removable;
39 status = "okay"; 35 status = "okay";
40 }; 36 };
41 37
42 uart3: uart@5000c000 { 38 uart3: serial@5000c000 {
43 fsl,uart-has-rtscts; 39 fsl,uart-has-rtscts;
44 status = "okay"; 40 status = "okay";
45 }; 41 };
@@ -76,7 +72,7 @@
76 }; 72 };
77 73
78 esdhc@50020000 { /* ESDHC3 */ 74 esdhc@50020000 { /* ESDHC3 */
79 fsl,card-wired; 75 non-removable;
80 status = "okay"; 76 status = "okay";
81 }; 77 };
82 }; 78 };
@@ -90,11 +86,11 @@
90 reg = <0x53fa8000 0x4000>; 86 reg = <0x53fa8000 0x4000>;
91 }; 87 };
92 88
93 uart1: uart@53fbc000 { 89 uart1: serial@53fbc000 {
94 status = "okay"; 90 status = "okay";
95 }; 91 };
96 92
97 uart2: uart@53fc0000 { 93 uart2: serial@53fc0000 {
98 status = "okay"; 94 status = "okay";
99 }; 95 };
100 }; 96 };
@@ -142,7 +138,7 @@
142 }; 138 };
143 }; 139 };
144 140
145 fec@63fec000 { 141 ethernet@63fec000 {
146 phy-mode = "rmii"; 142 phy-mode = "rmii";
147 phy-reset-gpios = <&gpio7 6 0>; 143 phy-reset-gpios = <&gpio7 6 0>;
148 status = "okay"; 144 status = "okay";
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 5dd91b942c9..e3e869470cd 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -88,7 +88,7 @@
88 status = "disabled"; 88 status = "disabled";
89 }; 89 };
90 90
91 uart3: uart@5000c000 { 91 uart3: serial@5000c000 {
92 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 92 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
93 reg = <0x5000c000 0x4000>; 93 reg = <0x5000c000 0x4000>;
94 interrupts = <33>; 94 interrupts = <33>;
@@ -104,6 +104,15 @@
104 status = "disabled"; 104 status = "disabled";
105 }; 105 };
106 106
107 ssi2: ssi@50014000 {
108 compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
109 reg = <0x50014000 0x4000>;
110 interrupts = <30>;
111 fsl,fifo-depth = <15>;
112 fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
113 status = "disabled";
114 };
115
107 esdhc@50020000 { /* ESDHC3 */ 116 esdhc@50020000 { /* ESDHC3 */
108 compatible = "fsl,imx53-esdhc"; 117 compatible = "fsl,imx53-esdhc";
109 reg = <0x50020000 0x4000>; 118 reg = <0x50020000 0x4000>;
@@ -173,14 +182,14 @@
173 status = "disabled"; 182 status = "disabled";
174 }; 183 };
175 184
176 uart1: uart@53fbc000 { 185 uart1: serial@53fbc000 {
177 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 186 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
178 reg = <0x53fbc000 0x4000>; 187 reg = <0x53fbc000 0x4000>;
179 interrupts = <31>; 188 interrupts = <31>;
180 status = "disabled"; 189 status = "disabled";
181 }; 190 };
182 191
183 uart2: uart@53fc0000 { 192 uart2: serial@53fc0000 {
184 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 193 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
185 reg = <0x53fc0000 0x4000>; 194 reg = <0x53fc0000 0x4000>;
186 interrupts = <32>; 195 interrupts = <32>;
@@ -226,7 +235,7 @@
226 status = "disabled"; 235 status = "disabled";
227 }; 236 };
228 237
229 uart4: uart@53ff0000 { 238 uart4: serial@53ff0000 {
230 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 239 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
231 reg = <0x53ff0000 0x4000>; 240 reg = <0x53ff0000 0x4000>;
232 interrupts = <13>; 241 interrupts = <13>;
@@ -241,7 +250,7 @@
241 reg = <0x60000000 0x10000000>; 250 reg = <0x60000000 0x10000000>;
242 ranges; 251 ranges;
243 252
244 uart5: uart@63f90000 { 253 uart5: serial@63f90000 {
245 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 254 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
246 reg = <0x63f90000 0x4000>; 255 reg = <0x63f90000 0x4000>;
247 interrupts = <86>; 256 interrupts = <86>;
@@ -290,7 +299,31 @@
290 status = "disabled"; 299 status = "disabled";
291 }; 300 };
292 301
293 fec@63fec000 { 302 ssi1: ssi@63fcc000 {
303 compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
304 reg = <0x63fcc000 0x4000>;
305 interrupts = <29>;
306 fsl,fifo-depth = <15>;
307 fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
308 status = "disabled";
309 };
310
311 audmux@63fd0000 {
312 compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
313 reg = <0x63fd0000 0x4000>;
314 status = "disabled";
315 };
316
317 ssi3: ssi@63fe8000 {
318 compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
319 reg = <0x63fe8000 0x4000>;
320 interrupts = <96>;
321 fsl,fifo-depth = <15>;
322 fsl,ssi-dma-events = <47 46 45 44>; /* TX0 RX0 TX1 RX1 */
323 status = "disabled";
324 };
325
326 ethernet@63fec000 {
294 compatible = "fsl,imx53-fec", "fsl,imx25-fec"; 327 compatible = "fsl,imx53-fec", "fsl,imx25-fec";
295 reg = <0x63fec000 0x4000>; 328 reg = <0x63fec000 0x4000>;
296 interrupts = <87>; 329 interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
index ce1c8238c89..db4c6096c56 100644
--- a/arch/arm/boot/dts/imx6q-arm2.dts
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -17,19 +17,14 @@
17 model = "Freescale i.MX6 Quad Armadillo2 Board"; 17 model = "Freescale i.MX6 Quad Armadillo2 Board";
18 compatible = "fsl,imx6q-arm2", "fsl,imx6q"; 18 compatible = "fsl,imx6q-arm2", "fsl,imx6q";
19 19
20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
22 };
23
24 memory { 20 memory {
25 reg = <0x10000000 0x80000000>; 21 reg = <0x10000000 0x80000000>;
26 }; 22 };
27 23
28 soc { 24 soc {
29 aips-bus@02100000 { /* AIPS2 */ 25 aips-bus@02100000 { /* AIPS2 */
30 enet@02188000 { 26 ethernet@02188000 {
31 phy-mode = "rgmii"; 27 phy-mode = "rgmii";
32 local-mac-address = [00 04 9F 01 1B 61];
33 status = "okay"; 28 status = "okay";
34 }; 29 };
35 30
@@ -37,16 +32,20 @@
37 cd-gpios = <&gpio6 11 0>; 32 cd-gpios = <&gpio6 11 0>;
38 wp-gpios = <&gpio6 14 0>; 33 wp-gpios = <&gpio6 14 0>;
39 vmmc-supply = <&reg_3p3v>; 34 vmmc-supply = <&reg_3p3v>;
35 pinctrl-names = "default";
36 pinctrl-0 = <&pinctrl_usdhc3_1>;
40 status = "okay"; 37 status = "okay";
41 }; 38 };
42 39
43 usdhc@0219c000 { /* uSDHC4 */ 40 usdhc@0219c000 { /* uSDHC4 */
44 fsl,card-wired; 41 non-removable;
45 vmmc-supply = <&reg_3p3v>; 42 vmmc-supply = <&reg_3p3v>;
43 pinctrl-names = "default";
44 pinctrl-0 = <&pinctrl_usdhc4_1>;
46 status = "okay"; 45 status = "okay";
47 }; 46 };
48 47
49 uart4: uart@021f0000 { 48 uart4: serial@021f0000 {
50 status = "okay"; 49 status = "okay";
51 }; 50 };
52 }; 51 };
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 4663a4e5a28..e0ec92973e7 100644
--- a/arch/arm/boot/dts/imx6q-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -22,8 +22,30 @@
22 }; 22 };
23 23
24 soc { 24 soc {
25 aips-bus@02000000 { /* AIPS1 */
26 spba-bus@02000000 {
27 ecspi@02008000 { /* eCSPI1 */
28 fsl,spi-num-chipselects = <1>;
29 cs-gpios = <&gpio3 19 0>;
30 status = "okay";
31
32 flash: m25p80@0 {
33 compatible = "sst,sst25vf016b";
34 spi-max-frequency = <20000000>;
35 reg = <0>;
36 };
37 };
38
39 ssi1: ssi@02028000 {
40 fsl,mode = "i2s-slave";
41 status = "okay";
42 };
43 };
44
45 };
46
25 aips-bus@02100000 { /* AIPS2 */ 47 aips-bus@02100000 { /* AIPS2 */
26 enet@02188000 { 48 ethernet@02188000 {
27 phy-mode = "rgmii"; 49 phy-mode = "rgmii";
28 phy-reset-gpios = <&gpio3 23 0>; 50 phy-reset-gpios = <&gpio3 23 0>;
29 status = "okay"; 51 status = "okay";
@@ -43,13 +65,23 @@
43 status = "okay"; 65 status = "okay";
44 }; 66 };
45 67
46 uart2: uart@021e8000 { 68 audmux@021d8000 {
69 status = "okay";
70 pinctrl-names = "default";
71 pinctrl-0 = <&pinctrl_audmux_1>;
72 };
73
74 uart2: serial@021e8000 {
47 status = "okay"; 75 status = "okay";
76 pinctrl-names = "default";
77 pinctrl-0 = <&pinctrl_serial2_1>;
48 }; 78 };
49 79
50 i2c@021a0000 { /* I2C1 */ 80 i2c@021a0000 { /* I2C1 */
51 status = "okay"; 81 status = "okay";
52 clock-frequency = <100000>; 82 clock-frequency = <100000>;
83 pinctrl-names = "default";
84 pinctrl-0 = <&pinctrl_i2c1_1>;
53 85
54 codec: sgtl5000@0a { 86 codec: sgtl5000@0a {
55 compatible = "fsl,sgtl5000"; 87 compatible = "fsl,sgtl5000";
@@ -80,4 +112,18 @@
80 regulator-always-on; 112 regulator-always-on;
81 }; 113 };
82 }; 114 };
115
116 sound {
117 compatible = "fsl,imx6q-sabrelite-sgtl5000",
118 "fsl,imx-audio-sgtl5000";
119 model = "imx6q-sabrelite-sgtl5000";
120 ssi-controller = <&ssi1>;
121 audio-codec = <&codec>;
122 audio-routing =
123 "MIC_IN", "Mic Jack",
124 "Mic Jack", "Mic Bias",
125 "Headphone Jack", "HP_OUT";
126 mux-int-port = <1>;
127 mux-ext-port = <4>;
128 };
83}; 129};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
new file mode 100644
index 00000000000..07509a18117
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13/dts-v1/;
14/include/ "imx6q.dtsi"
15
16/ {
17 model = "Freescale i.MX6Q SABRE Smart Device Board";
18 compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
19
20 memory {
21 reg = <0x10000000 0x40000000>;
22 };
23
24 soc {
25
26 aips-bus@02000000 { /* AIPS1 */
27 spba-bus@02000000 {
28 uart1: serial@02020000 {
29 status = "okay";
30 };
31 };
32 };
33
34 aips-bus@02100000 { /* AIPS2 */
35 ethernet@02188000 {
36 phy-mode = "rgmii";
37 status = "okay";
38 };
39
40 usdhc@02194000 { /* uSDHC2 */
41 cd-gpios = <&gpio2 2 0>;
42 wp-gpios = <&gpio2 3 0>;
43 status = "okay";
44 };
45
46 usdhc@02198000 { /* uSDHC3 */
47 cd-gpios = <&gpio2 0 0>;
48 wp-gpios = <&gpio2 1 0>;
49 status = "okay";
50 };
51 };
52 };
53};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 4905f51a106..8c90cbac945 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -165,7 +165,7 @@
165 status = "disabled"; 165 status = "disabled";
166 }; 166 };
167 167
168 uart1: uart@02020000 { 168 uart1: serial@02020000 {
169 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 169 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
170 reg = <0x02020000 0x4000>; 170 reg = <0x02020000 0x4000>;
171 interrupts = <0 26 0x04>; 171 interrupts = <0 26 0x04>;
@@ -177,19 +177,31 @@
177 interrupts = <0 51 0x04>; 177 interrupts = <0 51 0x04>;
178 }; 178 };
179 179
180 ssi@02028000 { /* SSI1 */ 180 ssi1: ssi@02028000 {
181 compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
181 reg = <0x02028000 0x4000>; 182 reg = <0x02028000 0x4000>;
182 interrupts = <0 46 0x04>; 183 interrupts = <0 46 0x04>;
184 fsl,fifo-depth = <15>;
185 fsl,ssi-dma-events = <38 37>;
186 status = "disabled";
183 }; 187 };
184 188
185 ssi@0202c000 { /* SSI2 */ 189 ssi2: ssi@0202c000 {
190 compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
186 reg = <0x0202c000 0x4000>; 191 reg = <0x0202c000 0x4000>;
187 interrupts = <0 47 0x04>; 192 interrupts = <0 47 0x04>;
193 fsl,fifo-depth = <15>;
194 fsl,ssi-dma-events = <42 41>;
195 status = "disabled";
188 }; 196 };
189 197
190 ssi@02030000 { /* SSI3 */ 198 ssi3: ssi@02030000 {
199 compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
191 reg = <0x02030000 0x4000>; 200 reg = <0x02030000 0x4000>;
192 interrupts = <0 48 0x04>; 201 interrupts = <0 48 0x04>;
202 fsl,fifo-depth = <15>;
203 fsl,ssi-dma-events = <46 45>;
204 status = "disabled";
193 }; 205 };
194 206
195 asrc@02034000 { 207 asrc@02034000 {
@@ -346,6 +358,90 @@
346 compatible = "fsl,imx6q-anatop"; 358 compatible = "fsl,imx6q-anatop";
347 reg = <0x020c8000 0x1000>; 359 reg = <0x020c8000 0x1000>;
348 interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; 360 interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
361
362 regulator-1p1@110 {
363 compatible = "fsl,anatop-regulator";
364 regulator-name = "vdd1p1";
365 regulator-min-microvolt = <800000>;
366 regulator-max-microvolt = <1375000>;
367 regulator-always-on;
368 anatop-reg-offset = <0x110>;
369 anatop-vol-bit-shift = <8>;
370 anatop-vol-bit-width = <5>;
371 anatop-min-bit-val = <4>;
372 anatop-min-voltage = <800000>;
373 anatop-max-voltage = <1375000>;
374 };
375
376 regulator-3p0@120 {
377 compatible = "fsl,anatop-regulator";
378 regulator-name = "vdd3p0";
379 regulator-min-microvolt = <2800000>;
380 regulator-max-microvolt = <3150000>;
381 regulator-always-on;
382 anatop-reg-offset = <0x120>;
383 anatop-vol-bit-shift = <8>;
384 anatop-vol-bit-width = <5>;
385 anatop-min-bit-val = <0>;
386 anatop-min-voltage = <2625000>;
387 anatop-max-voltage = <3400000>;
388 };
389
390 regulator-2p5@130 {
391 compatible = "fsl,anatop-regulator";
392 regulator-name = "vdd2p5";
393 regulator-min-microvolt = <2000000>;
394 regulator-max-microvolt = <2750000>;
395 regulator-always-on;
396 anatop-reg-offset = <0x130>;
397 anatop-vol-bit-shift = <8>;
398 anatop-vol-bit-width = <5>;
399 anatop-min-bit-val = <0>;
400 anatop-min-voltage = <2000000>;
401 anatop-max-voltage = <2750000>;
402 };
403
404 regulator-vddcore@140 {
405 compatible = "fsl,anatop-regulator";
406 regulator-name = "cpu";
407 regulator-min-microvolt = <725000>;
408 regulator-max-microvolt = <1450000>;
409 regulator-always-on;
410 anatop-reg-offset = <0x140>;
411 anatop-vol-bit-shift = <0>;
412 anatop-vol-bit-width = <5>;
413 anatop-min-bit-val = <1>;
414 anatop-min-voltage = <725000>;
415 anatop-max-voltage = <1450000>;
416 };
417
418 regulator-vddpu@140 {
419 compatible = "fsl,anatop-regulator";
420 regulator-name = "vddpu";
421 regulator-min-microvolt = <725000>;
422 regulator-max-microvolt = <1450000>;
423 regulator-always-on;
424 anatop-reg-offset = <0x140>;
425 anatop-vol-bit-shift = <9>;
426 anatop-vol-bit-width = <5>;
427 anatop-min-bit-val = <1>;
428 anatop-min-voltage = <725000>;
429 anatop-max-voltage = <1450000>;
430 };
431
432 regulator-vddsoc@140 {
433 compatible = "fsl,anatop-regulator";
434 regulator-name = "vddsoc";
435 regulator-min-microvolt = <725000>;
436 regulator-max-microvolt = <1450000>;
437 regulator-always-on;
438 anatop-reg-offset = <0x140>;
439 anatop-vol-bit-shift = <18>;
440 anatop-vol-bit-width = <5>;
441 anatop-min-bit-val = <1>;
442 anatop-min-voltage = <725000>;
443 anatop-max-voltage = <1450000>;
444 };
349 }; 445 };
350 446
351 usbphy@020c9000 { /* USBPHY1 */ 447 usbphy@020c9000 { /* USBPHY1 */
@@ -386,7 +482,62 @@
386 }; 482 };
387 483
388 iomuxc@020e0000 { 484 iomuxc@020e0000 {
485 compatible = "fsl,imx6q-iomuxc";
389 reg = <0x020e0000 0x4000>; 486 reg = <0x020e0000 0x4000>;
487
488 /* shared pinctrl settings */
489 audmux {
490 pinctrl_audmux_1: audmux-1 {
491 fsl,pins = <18 0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
492 1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
493 11 0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
494 3 0x80000000>; /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
495 };
496 };
497
498 i2c1 {
499 pinctrl_i2c1_1: i2c1grp-1 {
500 fsl,pins = <137 0x4001b8b1 /* MX6Q_PAD_EIM_D21__I2C1_SCL */
501 196 0x4001b8b1>; /* MX6Q_PAD_EIM_D28__I2C1_SDA */
502 };
503 };
504
505 serial2 {
506 pinctrl_serial2_1: serial2grp-1 {
507 fsl,pins = <183 0x1b0b1 /* MX6Q_PAD_EIM_D26__UART2_TXD */
508 191 0x1b0b1>; /* MX6Q_PAD_EIM_D27__UART2_RXD */
509 };
510 };
511
512 usdhc3 {
513 pinctrl_usdhc3_1: usdhc3grp-1 {
514 fsl,pins = <1273 0x17059 /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
515 1281 0x10059 /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
516 1289 0x17059 /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
517 1297 0x17059 /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
518 1305 0x17059 /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
519 1312 0x17059 /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
520 1265 0x17059 /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */
521 1257 0x17059 /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */
522 1249 0x17059 /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */
523 1241 0x17059>; /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */
524 };
525 };
526
527 usdhc4 {
528 pinctrl_usdhc4_1: usdhc4grp-1 {
529 fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
530 1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
531 1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
532 1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
533 1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
534 1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
535 1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
536 1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
537 1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
538 1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
539 };
540 };
390 }; 541 };
391 542
392 dcic@020e4000 { /* DCIC1 */ 543 dcic@020e4000 { /* DCIC1 */
@@ -422,7 +573,7 @@
422 reg = <0x0217c000 0x4000>; 573 reg = <0x0217c000 0x4000>;
423 }; 574 };
424 575
425 enet@02188000 { 576 ethernet@02188000 {
426 compatible = "fsl,imx6q-fec"; 577 compatible = "fsl,imx6q-fec";
427 reg = <0x02188000 0x4000>; 578 reg = <0x02188000 0x4000>;
428 interrupts = <0 118 0x04 0 119 0x04>; 579 interrupts = <0 118 0x04 0 119 0x04>;
@@ -527,7 +678,9 @@
527 }; 678 };
528 679
529 audmux@021d8000 { 680 audmux@021d8000 {
681 compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
530 reg = <0x021d8000 0x4000>; 682 reg = <0x021d8000 0x4000>;
683 status = "disabled";
531 }; 684 };
532 685
533 mipi@021dc000 { /* MIPI-CSI */ 686 mipi@021dc000 { /* MIPI-CSI */
@@ -543,28 +696,28 @@
543 interrupts = <0 18 0x04>; 696 interrupts = <0 18 0x04>;
544 }; 697 };
545 698
546 uart2: uart@021e8000 { 699 uart2: serial@021e8000 {
547 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 700 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
548 reg = <0x021e8000 0x4000>; 701 reg = <0x021e8000 0x4000>;
549 interrupts = <0 27 0x04>; 702 interrupts = <0 27 0x04>;
550 status = "disabled"; 703 status = "disabled";
551 }; 704 };
552 705
553 uart3: uart@021ec000 { 706 uart3: serial@021ec000 {
554 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 707 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
555 reg = <0x021ec000 0x4000>; 708 reg = <0x021ec000 0x4000>;
556 interrupts = <0 28 0x04>; 709 interrupts = <0 28 0x04>;
557 status = "disabled"; 710 status = "disabled";
558 }; 711 };
559 712
560 uart4: uart@021f0000 { 713 uart4: serial@021f0000 {
561 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 714 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
562 reg = <0x021f0000 0x4000>; 715 reg = <0x021f0000 0x4000>;
563 interrupts = <0 29 0x04>; 716 interrupts = <0 29 0x04>;
564 status = "disabled"; 717 status = "disabled";
565 }; 718 };
566 719
567 uart5: uart@021f4000 { 720 uart5: serial@021f4000 {
568 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 721 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
569 reg = <0x021f4000 0x4000>; 722 reg = <0x021f4000 0x4000>;
570 interrupts = <0 30 0x04>; 723 interrupts = <0 30 0x04>;
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 8c756be4d7a..5b4506c0a8c 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -57,7 +57,7 @@
57&mmc1 { 57&mmc1 {
58 vmmc-supply = <&vmmc1>; 58 vmmc-supply = <&vmmc1>;
59 vmmc_aux-supply = <&vsim>; 59 vmmc_aux-supply = <&vsim>;
60 ti,bus-width = <8>; 60 bus-width = <8>;
61}; 61};
62 62
63&mmc2 { 63&mmc2 {
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index e671361bc79..1efe0c58798 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -70,7 +70,7 @@
70 70
71&mmc1 { 71&mmc1 {
72 vmmc-supply = <&vmmc>; 72 vmmc-supply = <&vmmc>;
73 ti,bus-width = <8>; 73 bus-width = <8>;
74}; 74};
75 75
76&mmc2 { 76&mmc2 {
@@ -87,5 +87,5 @@
87 87
88&mmc5 { 88&mmc5 {
89 ti,non-removable; 89 ti,non-removable;
90 ti,bus-width = <4>; 90 bus-width = <4>;
91}; 91};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index e5eeb6f9c6e..d08c4d13728 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -137,12 +137,12 @@
137 137
138&mmc1 { 138&mmc1 {
139 vmmc-supply = <&vmmc>; 139 vmmc-supply = <&vmmc>;
140 ti,bus-width = <8>; 140 bus-width = <8>;
141}; 141};
142 142
143&mmc2 { 143&mmc2 {
144 vmmc-supply = <&vaux1>; 144 vmmc-supply = <&vaux1>;
145 ti,bus-width = <8>; 145 bus-width = <8>;
146 ti,non-removable; 146 ti,non-removable;
147}; 147};
148 148
@@ -155,6 +155,6 @@
155}; 155};
156 156
157&mmc5 { 157&mmc5 {
158 ti,bus-width = <4>; 158 bus-width = <4>;
159 ti,non-removable; 159 ti,non-removable;
160}; 160};
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
new file mode 100644
index 00000000000..8314e417188
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -0,0 +1,292 @@
1/*
2 * DTS file for SPEAr1310 Evaluation Baord
3 *
4 * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/dts-v1/;
15/include/ "spear1310.dtsi"
16
17/ {
18 model = "ST SPEAr1310 Evaluation Board";
19 compatible = "st,spear1310-evb", "st,spear1310";
20 #address-cells = <1>;
21 #size-cells = <1>;
22
23 memory {
24 reg = <0 0x40000000>;
25 };
26
27 ahb {
28 pinmux@e0700000 {
29 pinctrl-names = "default";
30 pinctrl-0 = <&state_default>;
31
32 state_default: pinmux {
33 i2c0-pmx {
34 st,pins = "i2c0_grp";
35 st,function = "i2c0";
36 };
37 i2s1 {
38 st,pins = "i2s1_grp";
39 st,function = "i2s1";
40 };
41 gpio {
42 st,pins = "arm_gpio_grp";
43 st,function = "arm_gpio";
44 };
45 eth {
46 st,pins = "gmii_grp";
47 st,function = "gmii";
48 };
49 ssp0 {
50 st,pins = "ssp0_grp";
51 st,function = "ssp0";
52 };
53 kbd {
54 st,pins = "keyboard_6x6_grp";
55 st,function = "keyboard";
56 };
57 sdhci {
58 st,pins = "sdhci_grp";
59 st,function = "sdhci";
60 };
61 smi-pmx {
62 st,pins = "smi_2_chips_grp";
63 st,function = "smi";
64 };
65 uart0 {
66 st,pins = "uart0_grp";
67 st,function = "uart0";
68 };
69 rs485 {
70 st,pins = "rs485_0_1_tdm_0_1_grp";
71 st,function = "rs485_0_1_tdm_0_1";
72 };
73 i2c1_2 {
74 st,pins = "i2c_1_2_grp";
75 st,function = "i2c_1_2";
76 };
77 pci {
78 st,pins = "pcie0_grp","pcie1_grp",
79 "pcie2_grp";
80 st,function = "pci";
81 };
82 smii {
83 st,pins = "smii_0_1_2_grp";
84 st,function = "smii_0_1_2";
85 };
86 nand {
87 st,pins = "nand_8bit_grp",
88 "nand_16bit_grp";
89 st,function = "nand";
90 };
91 };
92 };
93
94 ahci@b1000000 {
95 status = "okay";
96 };
97
98 cf@b2800000 {
99 status = "okay";
100 };
101
102 dma@ea800000 {
103 status = "okay";
104 };
105
106 dma@eb000000 {
107 status = "okay";
108 };
109
110 fsmc: flash@b0000000 {
111 status = "okay";
112 };
113
114 gmac0: eth@e2000000 {
115 status = "okay";
116 };
117
118 sdhci@b3000000 {
119 status = "okay";
120 };
121
122 smi: flash@ea000000 {
123 status = "okay";
124 clock-rate=<50000000>;
125
126 flash@e6000000 {
127 #address-cells = <1>;
128 #size-cells = <1>;
129 reg = <0xe6000000 0x800000>;
130 st,smi-fast-mode;
131
132 partition@0 {
133 label = "xloader";
134 reg = <0x0 0x10000>;
135 };
136 partition@10000 {
137 label = "u-boot";
138 reg = <0x10000 0x40000>;
139 };
140 partition@50000 {
141 label = "linux";
142 reg = <0x50000 0x2c0000>;
143 };
144 partition@310000 {
145 label = "rootfs";
146 reg = <0x310000 0x4f0000>;
147 };
148 };
149 };
150
151 spi0: spi@e0100000 {
152 status = "okay";
153 };
154
155 ehci@e4800000 {
156 status = "okay";
157 };
158
159 ehci@e5800000 {
160 status = "okay";
161 };
162
163 ohci@e4000000 {
164 status = "okay";
165 };
166
167 ohci@e5000000 {
168 status = "okay";
169 };
170
171 apb {
172 adc@e0080000 {
173 status = "okay";
174 };
175
176 gpio0: gpio@e0600000 {
177 status = "okay";
178 };
179
180 gpio1: gpio@e0680000 {
181 status = "okay";
182 };
183
184 i2c0: i2c@e0280000 {
185 status = "okay";
186 };
187
188 i2c1: i2c@5cd00000 {
189 status = "okay";
190 };
191
192 kbd@e0300000 {
193 linux,keymap = < 0x00000001
194 0x00010002
195 0x00020003
196 0x00030004
197 0x00040005
198 0x00050006
199 0x00060007
200 0x00070008
201 0x00080009
202 0x0100000a
203 0x0101000c
204 0x0102000d
205 0x0103000e
206 0x0104000f
207 0x01050010
208 0x01060011
209 0x01070012
210 0x01080013
211 0x02000014
212 0x02010015
213 0x02020016
214 0x02030017
215 0x02040018
216 0x02050019
217 0x0206001a
218 0x0207001b
219 0x0208001c
220 0x0300001d
221 0x0301001e
222 0x0302001f
223 0x03030020
224 0x03040021
225 0x03050022
226 0x03060023
227 0x03070024
228 0x03080025
229 0x04000026
230 0x04010027
231 0x04020028
232 0x04030029
233 0x0404002a
234 0x0405002b
235 0x0406002c
236 0x0407002d
237 0x0408002e
238 0x0500002f
239 0x05010030
240 0x05020031
241 0x05030032
242 0x05040033
243 0x05050034
244 0x05060035
245 0x05070036
246 0x05080037
247 0x06000038
248 0x06010039
249 0x0602003a
250 0x0603003b
251 0x0604003c
252 0x0605003d
253 0x0606003e
254 0x0607003f
255 0x06080040
256 0x07000041
257 0x07010042
258 0x07020043
259 0x07030044
260 0x07040045
261 0x07050046
262 0x07060047
263 0x07070048
264 0x07080049
265 0x0800004a
266 0x0801004b
267 0x0802004c
268 0x0803004d
269 0x0804004e
270 0x0805004f
271 0x08060050
272 0x08070051
273 0x08080052 >;
274 autorepeat;
275 st,mode = <0>;
276 status = "okay";
277 };
278
279 rtc@e0580000 {
280 status = "okay";
281 };
282
283 serial@e0000000 {
284 status = "okay";
285 };
286
287 wdt@ec800620 {
288 status = "okay";
289 };
290 };
291 };
292};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
new file mode 100644
index 00000000000..9e61da404d5
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -0,0 +1,184 @@
1/*
2 * DTS file for all SPEAr1310 SoCs
3 *
4 * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/include/ "spear13xx.dtsi"
15
16/ {
17 compatible = "st,spear1310";
18
19 ahb {
20 ahci@b1000000 {
21 compatible = "snps,spear-ahci";
22 reg = <0xb1000000 0x10000>;
23 interrupts = <0 68 0x4>;
24 status = "disabled";
25 };
26
27 ahci@b1800000 {
28 compatible = "snps,spear-ahci";
29 reg = <0xb1800000 0x10000>;
30 interrupts = <0 69 0x4>;
31 status = "disabled";
32 };
33
34 ahci@b4000000 {
35 compatible = "snps,spear-ahci";
36 reg = <0xb4000000 0x10000>;
37 interrupts = <0 70 0x4>;
38 status = "disabled";
39 };
40
41 gmac1: eth@5c400000 {
42 compatible = "st,spear600-gmac";
43 reg = <0x5c400000 0x8000>;
44 interrupts = <0 95 0x4>;
45 interrupt-names = "macirq";
46 status = "disabled";
47 };
48
49 gmac2: eth@5c500000 {
50 compatible = "st,spear600-gmac";
51 reg = <0x5c500000 0x8000>;
52 interrupts = <0 96 0x4>;
53 interrupt-names = "macirq";
54 status = "disabled";
55 };
56
57 gmac3: eth@5c600000 {
58 compatible = "st,spear600-gmac";
59 reg = <0x5c600000 0x8000>;
60 interrupts = <0 97 0x4>;
61 interrupt-names = "macirq";
62 status = "disabled";
63 };
64
65 gmac4: eth@5c700000 {
66 compatible = "st,spear600-gmac";
67 reg = <0x5c700000 0x8000>;
68 interrupts = <0 98 0x4>;
69 interrupt-names = "macirq";
70 status = "disabled";
71 };
72
73 spi1: spi@5d400000 {
74 compatible = "arm,pl022", "arm,primecell";
75 reg = <0x5d400000 0x1000>;
76 interrupts = <0 99 0x4>;
77 status = "disabled";
78 };
79
80 apb {
81 i2c1: i2c@5cd00000 {
82 #address-cells = <1>;
83 #size-cells = <0>;
84 compatible = "snps,designware-i2c";
85 reg = <0x5cd00000 0x1000>;
86 interrupts = <0 87 0x4>;
87 status = "disabled";
88 };
89
90 i2c2: i2c@5ce00000 {
91 #address-cells = <1>;
92 #size-cells = <0>;
93 compatible = "snps,designware-i2c";
94 reg = <0x5ce00000 0x1000>;
95 interrupts = <0 88 0x4>;
96 status = "disabled";
97 };
98
99 i2c3: i2c@5cf00000 {
100 #address-cells = <1>;
101 #size-cells = <0>;
102 compatible = "snps,designware-i2c";
103 reg = <0x5cf00000 0x1000>;
104 interrupts = <0 89 0x4>;
105 status = "disabled";
106 };
107
108 i2c4: i2c@5d000000 {
109 #address-cells = <1>;
110 #size-cells = <0>;
111 compatible = "snps,designware-i2c";
112 reg = <0x5d000000 0x1000>;
113 interrupts = <0 90 0x4>;
114 status = "disabled";
115 };
116
117 i2c5: i2c@5d100000 {
118 #address-cells = <1>;
119 #size-cells = <0>;
120 compatible = "snps,designware-i2c";
121 reg = <0x5d100000 0x1000>;
122 interrupts = <0 91 0x4>;
123 status = "disabled";
124 };
125
126 i2c6: i2c@5d200000 {
127 #address-cells = <1>;
128 #size-cells = <0>;
129 compatible = "snps,designware-i2c";
130 reg = <0x5d200000 0x1000>;
131 interrupts = <0 92 0x4>;
132 status = "disabled";
133 };
134
135 i2c7: i2c@5d300000 {
136 #address-cells = <1>;
137 #size-cells = <0>;
138 compatible = "snps,designware-i2c";
139 reg = <0x5d300000 0x1000>;
140 interrupts = <0 93 0x4>;
141 status = "disabled";
142 };
143
144 serial@5c800000 {
145 compatible = "arm,pl011", "arm,primecell";
146 reg = <0x5c800000 0x1000>;
147 interrupts = <0 82 0x4>;
148 status = "disabled";
149 };
150
151 serial@5c900000 {
152 compatible = "arm,pl011", "arm,primecell";
153 reg = <0x5c900000 0x1000>;
154 interrupts = <0 83 0x4>;
155 status = "disabled";
156 };
157
158 serial@5ca00000 {
159 compatible = "arm,pl011", "arm,primecell";
160 reg = <0x5ca00000 0x1000>;
161 interrupts = <0 84 0x4>;
162 status = "disabled";
163 };
164
165 serial@5cb00000 {
166 compatible = "arm,pl011", "arm,primecell";
167 reg = <0x5cb00000 0x1000>;
168 interrupts = <0 85 0x4>;
169 status = "disabled";
170 };
171
172 serial@5cc00000 {
173 compatible = "arm,pl011", "arm,primecell";
174 reg = <0x5cc00000 0x1000>;
175 interrupts = <0 86 0x4>;
176 status = "disabled";
177 };
178
179 thermal@e07008c4 {
180 st,thermal-flags = <0x7000>;
181 };
182 };
183 };
184};
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
new file mode 100644
index 00000000000..0d8472e5ab9
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -0,0 +1,308 @@
1/*
2 * DTS file for SPEAr1340 Evaluation Baord
3 *
4 * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/dts-v1/;
15/include/ "spear1340.dtsi"
16
17/ {
18 model = "ST SPEAr1340 Evaluation Board";
19 compatible = "st,spear1340-evb", "st,spear1340";
20 #address-cells = <1>;
21 #size-cells = <1>;
22
23 memory {
24 reg = <0 0x40000000>;
25 };
26
27 ahb {
28 pinmux@e0700000 {
29 pinctrl-names = "default";
30 pinctrl-0 = <&state_default>;
31
32 state_default: pinmux {
33 pads_as_gpio {
34 st,pins = "pads_as_gpio_grp";
35 st,function = "pads_as_gpio";
36 };
37 fsmc {
38 st,pins = "fsmc_8bit_grp";
39 st,function = "fsmc";
40 };
41 kbd {
42 st,pins = "keyboard_row_col_grp",
43 "keyboard_col5_grp";
44 st,function = "keyboard";
45 };
46 uart0 {
47 st,pins = "uart0_grp", "uart0_enh_grp";
48 st,function = "uart0";
49 };
50 i2c0-pmx {
51 st,pins = "i2c0_grp";
52 st,function = "i2c0";
53 };
54 i2c1-pmx {
55 st,pins = "i2c1_grp";
56 st,function = "i2c1";
57 };
58 spdif-in {
59 st,pins = "spdif_in_grp";
60 st,function = "spdif_in";
61 };
62 spdif-out {
63 st,pins = "spdif_out_grp";
64 st,function = "spdif_out";
65 };
66 ssp0 {
67 st,pins = "ssp0_grp", "ssp0_cs1_grp",
68 "ssp0_cs3_grp";
69 st,function = "ssp0";
70 };
71 pwm {
72 st,pins = "pwm2_grp", "pwm3_grp";
73 st,function = "pwm";
74 };
75 smi-pmx {
76 st,pins = "smi_grp";
77 st,function = "smi";
78 };
79 i2s {
80 st,pins = "i2s_in_grp", "i2s_out_grp";
81 st,function = "i2s";
82 };
83 gmac {
84 st,pins = "gmii_grp", "rgmii_grp";
85 st,function = "gmac";
86 };
87 cam3 {
88 st,pins = "cam3_grp";
89 st,function = "cam3";
90 };
91 cec0 {
92 st,pins = "cec0_grp";
93 st,function = "cec0";
94 };
95 cec1 {
96 st,pins = "cec1_grp";
97 st,function = "cec1";
98 };
99 sdhci {
100 st,pins = "sdhci_grp";
101 st,function = "sdhci";
102 };
103 clcd {
104 st,pins = "clcd_grp";
105 st,function = "clcd";
106 };
107 sata {
108 st,pins = "sata_grp";
109 st,function = "sata";
110 };
111 };
112 };
113
114 dma@ea800000 {
115 status = "okay";
116 };
117
118 dma@eb000000 {
119 status = "okay";
120 };
121
122 fsmc: flash@b0000000 {
123 status = "okay";
124 };
125
126 gmac0: eth@e2000000 {
127 status = "okay";
128 };
129
130 sdhci@b3000000 {
131 status = "okay";
132 };
133
134 smi: flash@ea000000 {
135 status = "okay";
136 clock-rate=<50000000>;
137
138 flash@e6000000 {
139 #address-cells = <1>;
140 #size-cells = <1>;
141 reg = <0xe6000000 0x800000>;
142 st,smi-fast-mode;
143
144 partition@0 {
145 label = "xloader";
146 reg = <0x0 0x10000>;
147 };
148 partition@10000 {
149 label = "u-boot";
150 reg = <0x10000 0x40000>;
151 };
152 partition@50000 {
153 label = "linux";
154 reg = <0x50000 0x2c0000>;
155 };
156 partition@310000 {
157 label = "rootfs";
158 reg = <0x310000 0x4f0000>;
159 };
160 };
161 };
162
163 spi0: spi@e0100000 {
164 status = "okay";
165 };
166
167 ehci@e4800000 {
168 status = "okay";
169 };
170
171 ehci@e5800000 {
172 status = "okay";
173 };
174
175 ohci@e4000000 {
176 status = "okay";
177 };
178
179 ohci@e5000000 {
180 status = "okay";
181 };
182
183 apb {
184 adc@e0080000 {
185 status = "okay";
186 };
187
188 gpio0: gpio@e0600000 {
189 status = "okay";
190 };
191
192 gpio1: gpio@e0680000 {
193 status = "okay";
194 };
195
196 i2c0: i2c@e0280000 {
197 status = "okay";
198 };
199
200 i2c1: i2c@b4000000 {
201 status = "okay";
202 };
203
204 kbd@e0300000 {
205 linux,keymap = < 0x00000001
206 0x00010002
207 0x00020003
208 0x00030004
209 0x00040005
210 0x00050006
211 0x00060007
212 0x00070008
213 0x00080009
214 0x0100000a
215 0x0101000c
216 0x0102000d
217 0x0103000e
218 0x0104000f
219 0x01050010
220 0x01060011
221 0x01070012
222 0x01080013
223 0x02000014
224 0x02010015
225 0x02020016
226 0x02030017
227 0x02040018
228 0x02050019
229 0x0206001a
230 0x0207001b
231 0x0208001c
232 0x0300001d
233 0x0301001e
234 0x0302001f
235 0x03030020
236 0x03040021
237 0x03050022
238 0x03060023
239 0x03070024
240 0x03080025
241 0x04000026
242 0x04010027
243 0x04020028
244 0x04030029
245 0x0404002a
246 0x0405002b
247 0x0406002c
248 0x0407002d
249 0x0408002e
250 0x0500002f
251 0x05010030
252 0x05020031
253 0x05030032
254 0x05040033
255 0x05050034
256 0x05060035
257 0x05070036
258 0x05080037
259 0x06000038
260 0x06010039
261 0x0602003a
262 0x0603003b
263 0x0604003c
264 0x0605003d
265 0x0606003e
266 0x0607003f
267 0x06080040
268 0x07000041
269 0x07010042
270 0x07020043
271 0x07030044
272 0x07040045
273 0x07050046
274 0x07060047
275 0x07070048
276 0x07080049
277 0x0800004a
278 0x0801004b
279 0x0802004c
280 0x0803004d
281 0x0804004e
282 0x0805004f
283 0x08060050
284 0x08070051
285 0x08080052 >;
286 autorepeat;
287 st,mode = <0>;
288 status = "okay";
289 };
290
291 rtc@e0580000 {
292 status = "okay";
293 };
294
295 serial@e0000000 {
296 status = "okay";
297 };
298
299 serial@b4100000 {
300 status = "okay";
301 };
302
303 wdt@ec800620 {
304 status = "okay";
305 };
306 };
307 };
308};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
new file mode 100644
index 00000000000..a26fc47a55e
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -0,0 +1,56 @@
1/*
2 * DTS file for all SPEAr1340 SoCs
3 *
4 * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/include/ "spear13xx.dtsi"
15
16/ {
17 compatible = "st,spear1340";
18
19 ahb {
20 ahci@b1000000 {
21 compatible = "snps,spear-ahci";
22 reg = <0xb1000000 0x10000>;
23 interrupts = <0 72 0x4>;
24 status = "disabled";
25 };
26
27 spi1: spi@5d400000 {
28 compatible = "arm,pl022", "arm,primecell";
29 reg = <0x5d400000 0x1000>;
30 interrupts = <0 99 0x4>;
31 status = "disabled";
32 };
33
34 apb {
35 i2c1: i2c@b4000000 {
36 #address-cells = <1>;
37 #size-cells = <0>;
38 compatible = "snps,designware-i2c";
39 reg = <0xb4000000 0x1000>;
40 interrupts = <0 104 0x4>;
41 status = "disabled";
42 };
43
44 serial@b4100000 {
45 compatible = "arm,pl011", "arm,primecell";
46 reg = <0xb4100000 0x1000>;
47 interrupts = <0 105 0x4>;
48 status = "disabled";
49 };
50
51 thermal@e07008c4 {
52 st,thermal-flags = <0x2a00>;
53 };
54 };
55 };
56};
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
new file mode 100644
index 00000000000..1f8e1e1481d
--- /dev/null
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -0,0 +1,262 @@
1/*
2 * DTS file for all SPEAr13xx SoCs
3 *
4 * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
5 *
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/include/ "skeleton.dtsi"
15
16/ {
17 interrupt-parent = <&gic>;
18
19 cpus {
20 #address-cells = <1>;
21 #size-cells = <0>;
22
23 cpu@0 {
24 compatible = "arm,cortex-a9";
25 reg = <0>;
26 next-level-cache = <&L2>;
27 };
28
29 cpu@1 {
30 compatible = "arm,cortex-a9";
31 reg = <1>;
32 next-level-cache = <&L2>;
33 };
34 };
35
36 gic: interrupt-controller@ec801000 {
37 compatible = "arm,cortex-a9-gic";
38 interrupt-controller;
39 #interrupt-cells = <3>;
40 reg = < 0xec801000 0x1000 >,
41 < 0xec800100 0x0100 >;
42 };
43
44 pmu {
45 compatible = "arm,cortex-a9-pmu";
46 interrupts = <0 8 0x04
47 0 9 0x04>;
48 };
49
50 L2: l2-cache {
51 compatible = "arm,pl310-cache";
52 reg = <0xed000000 0x1000>;
53 cache-unified;
54 cache-level = <2>;
55 };
56
57 memory {
58 name = "memory";
59 device_type = "memory";
60 reg = <0 0x40000000>;
61 };
62
63 chosen {
64 bootargs = "console=ttyAMA0,115200";
65 };
66
67 ahb {
68 #address-cells = <1>;
69 #size-cells = <1>;
70 compatible = "simple-bus";
71 ranges = <0x50000000 0x50000000 0x10000000
72 0xb0000000 0xb0000000 0x10000000
73 0xe0000000 0xe0000000 0x10000000>;
74
75 sdhci@b3000000 {
76 compatible = "st,sdhci-spear";
77 reg = <0xb3000000 0x100>;
78 interrupts = <0 28 0x4>;
79 status = "disabled";
80 };
81
82 cf@b2800000 {
83 compatible = "arasan,cf-spear1340";
84 reg = <0xb2800000 0x100>;
85 interrupts = <0 29 0x4>;
86 status = "disabled";
87 };
88
89 dma@ea800000 {
90 compatible = "snps,dma-spear1340";
91 reg = <0xea800000 0x1000>;
92 interrupts = <0 19 0x4>;
93 status = "disabled";
94 };
95
96 dma@eb000000 {
97 compatible = "snps,dma-spear1340";
98 reg = <0xeb000000 0x1000>;
99 interrupts = <0 59 0x4>;
100 status = "disabled";
101 };
102
103 fsmc: flash@b0000000 {
104 compatible = "st,spear600-fsmc-nand";
105 #address-cells = <1>;
106 #size-cells = <1>;
107 reg = <0xb0000000 0x1000 /* FSMC Register */
108 0xb0800000 0x0010>; /* NAND Base */
109 reg-names = "fsmc_regs", "nand_data";
110 interrupts = <0 20 0x4
111 0 21 0x4
112 0 22 0x4
113 0 23 0x4>;
114 st,ale-off = <0x20000>;
115 st,cle-off = <0x10000>;
116 status = "disabled";
117 };
118
119 gmac0: eth@e2000000 {
120 compatible = "st,spear600-gmac";
121 reg = <0xe2000000 0x8000>;
122 interrupts = <0 23 0x4
123 0 24 0x4>;
124 interrupt-names = "macirq", "eth_wake_irq";
125 status = "disabled";
126 };
127
128 smi: flash@ea000000 {
129 compatible = "st,spear600-smi";
130 #address-cells = <1>;
131 #size-cells = <1>;
132 reg = <0xea000000 0x1000>;
133 interrupts = <0 30 0x4>;
134 status = "disabled";
135 };
136
137 spi0: spi@e0100000 {
138 compatible = "arm,pl022", "arm,primecell";
139 reg = <0xe0100000 0x1000>;
140 interrupts = <0 31 0x4>;
141 status = "disabled";
142 };
143
144 ehci@e4800000 {
145 compatible = "st,spear600-ehci", "usb-ehci";
146 reg = <0xe4800000 0x1000>;
147 interrupts = <0 64 0x4>;
148 status = "disabled";
149 };
150
151 ehci@e5800000 {
152 compatible = "st,spear600-ehci", "usb-ehci";
153 reg = <0xe5800000 0x1000>;
154 interrupts = <0 66 0x4>;
155 status = "disabled";
156 };
157
158 ohci@e4000000 {
159 compatible = "st,spear600-ohci", "usb-ohci";
160 reg = <0xe4000000 0x1000>;
161 interrupts = <0 65 0x4>;
162 status = "disabled";
163 };
164
165 ohci@e5000000 {
166 compatible = "st,spear600-ohci", "usb-ohci";
167 reg = <0xe5000000 0x1000>;
168 interrupts = <0 67 0x4>;
169 status = "disabled";
170 };
171
172 apb {
173 #address-cells = <1>;
174 #size-cells = <1>;
175 compatible = "simple-bus";
176 ranges = <0x50000000 0x50000000 0x10000000
177 0xb0000000 0xb0000000 0x10000000
178 0xe0000000 0xe0000000 0x10000000>;
179
180 gpio0: gpio@e0600000 {
181 compatible = "arm,pl061", "arm,primecell";
182 reg = <0xe0600000 0x1000>;
183 interrupts = <0 24 0x4>;
184 gpio-controller;
185 #gpio-cells = <2>;
186 interrupt-controller;
187 #interrupt-cells = <2>;
188 status = "disabled";
189 };
190
191 gpio1: gpio@e0680000 {
192 compatible = "arm,pl061", "arm,primecell";
193 reg = <0xe0680000 0x1000>;
194 interrupts = <0 25 0x4>;
195 gpio-controller;
196 #gpio-cells = <2>;
197 interrupt-controller;
198 #interrupt-cells = <2>;
199 status = "disabled";
200 };
201
202 kbd@e0300000 {
203 compatible = "st,spear300-kbd";
204 reg = <0xe0300000 0x1000>;
205 status = "disabled";
206 };
207
208 i2c0: i2c@e0280000 {
209 #address-cells = <1>;
210 #size-cells = <0>;
211 compatible = "snps,designware-i2c";
212 reg = <0xe0280000 0x1000>;
213 interrupts = <0 41 0x4>;
214 status = "disabled";
215 };
216
217 rtc@e0580000 {
218 compatible = "st,spear-rtc";
219 reg = <0xe0580000 0x1000>;
220 interrupts = <0 36 0x4>;
221 status = "disabled";
222 };
223
224 serial@e0000000 {
225 compatible = "arm,pl011", "arm,primecell";
226 reg = <0xe0000000 0x1000>;
227 interrupts = <0 36 0x4>;
228 status = "disabled";
229 };
230
231 adc@e0080000 {
232 compatible = "st,spear600-adc";
233 reg = <0xe0080000 0x1000>;
234 interrupts = <0 44 0x4>;
235 status = "disabled";
236 };
237
238 timer@e0380000 {
239 compatible = "st,spear-timer";
240 reg = <0xe0380000 0x400>;
241 interrupts = <0 37 0x4>;
242 };
243
244 timer@ec800600 {
245 compatible = "arm,cortex-a9-twd-timer";
246 reg = <0xec800600 0x20>;
247 interrupts = <1 13 0x301>;
248 };
249
250 wdt@ec800620 {
251 compatible = "arm,cortex-a9-twd-wdt";
252 reg = <0xec800620 0x20>;
253 status = "disabled";
254 };
255
256 thermal@e07008c4 {
257 compatible = "st,thermal-spear1340";
258 reg = <0xe07008c4 0x4>;
259 };
260 };
261 };
262};
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
index 910e264b87c..fc82b1a2645 100644
--- a/arch/arm/boot/dts/spear300-evb.dts
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -87,6 +87,31 @@
87 87
88 smi: flash@fc000000 { 88 smi: flash@fc000000 {
89 status = "okay"; 89 status = "okay";
90 clock-rate=<50000000>;
91
92 flash@f8000000 {
93 #address-cells = <1>;
94 #size-cells = <1>;
95 reg = <0xf8000000 0x800000>;
96 st,smi-fast-mode;
97
98 partition@0 {
99 label = "xloader";
100 reg = <0x0 0x10000>;
101 };
102 partition@10000 {
103 label = "u-boot";
104 reg = <0x10000 0x40000>;
105 };
106 partition@50000 {
107 label = "linux";
108 reg = <0x50000 0x2c0000>;
109 };
110 partition@310000 {
111 label = "rootfs";
112 reg = <0x310000 0x4f0000>;
113 };
114 };
90 }; 115 };
91 116
92 spi0: spi@d0100000 { 117 spi0: spi@d0100000 {
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
index 6d95317100a..dc5e2d445a9 100644
--- a/arch/arm/boot/dts/spear310-evb.dts
+++ b/arch/arm/boot/dts/spear310-evb.dts
@@ -103,11 +103,27 @@
103 clock-rate=<50000000>; 103 clock-rate=<50000000>;
104 104
105 flash@f8000000 { 105 flash@f8000000 {
106 label = "m25p64";
107 reg = <0xf8000000 0x800000>;
108 #address-cells = <1>; 106 #address-cells = <1>;
109 #size-cells = <1>; 107 #size-cells = <1>;
108 reg = <0xf8000000 0x800000>;
110 st,smi-fast-mode; 109 st,smi-fast-mode;
110
111 partition@0 {
112 label = "xloader";
113 reg = <0x0 0x10000>;
114 };
115 partition@10000 {
116 label = "u-boot";
117 reg = <0x10000 0x40000>;
118 };
119 partition@50000 {
120 label = "linux";
121 reg = <0x50000 0x2c0000>;
122 };
123 partition@310000 {
124 label = "rootfs";
125 reg = <0x310000 0x4f0000>;
126 };
111 }; 127 };
112 }; 128 };
113 129
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index 0c6463b71a3..6308fa3bec1 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -110,6 +110,31 @@
110 110
111 smi: flash@fc000000 { 111 smi: flash@fc000000 {
112 status = "okay"; 112 status = "okay";
113 clock-rate=<50000000>;
114
115 flash@f8000000 {
116 #address-cells = <1>;
117 #size-cells = <1>;
118 reg = <0xf8000000 0x800000>;
119 st,smi-fast-mode;
120
121 partition@0 {
122 label = "xloader";
123 reg = <0x0 0x10000>;
124 };
125 partition@10000 {
126 label = "u-boot";
127 reg = <0x10000 0x40000>;
128 };
129 partition@50000 {
130 label = "linux";
131 reg = <0x50000 0x2c0000>;
132 };
133 partition@310000 {
134 label = "rootfs";
135 reg = <0x310000 0x4f0000>;
136 };
137 };
113 }; 138 };
114 139
115 spi0: spi@d0100000 { 140 spi0: spi@d0100000 {
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi
index 0ae7c8e8631..91072553963 100644
--- a/arch/arm/boot/dts/spear3xx.dtsi
+++ b/arch/arm/boot/dts/spear3xx.dtsi
@@ -139,6 +139,12 @@
139 interrupts = <12>; 139 interrupts = <12>;
140 status = "disabled"; 140 status = "disabled";
141 }; 141 };
142
143 timer@f0000000 {
144 compatible = "st,spear-timer";
145 reg = <0xf0000000 0x400>;
146 interrupts = <2>;
147 };
142 }; 148 };
143 }; 149 };
144}; 150};
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts
index 790a7a8a5cc..1119c22c9a8 100644
--- a/arch/arm/boot/dts/spear600-evb.dts
+++ b/arch/arm/boot/dts/spear600-evb.dts
@@ -33,6 +33,35 @@
33 status = "okay"; 33 status = "okay";
34 }; 34 };
35 35
36 smi: flash@fc000000 {
37 status = "okay";
38 clock-rate=<50000000>;
39
40 flash@f8000000 {
41 #address-cells = <1>;
42 #size-cells = <1>;
43 reg = <0xf8000000 0x800000>;
44 st,smi-fast-mode;
45
46 partition@0 {
47 label = "xloader";
48 reg = <0x0 0x10000>;
49 };
50 partition@10000 {
51 label = "u-boot";
52 reg = <0x10000 0x40000>;
53 };
54 partition@50000 {
55 label = "linux";
56 reg = <0x50000 0x2c0000>;
57 };
58 partition@310000 {
59 label = "rootfs";
60 reg = <0x310000 0x4f0000>;
61 };
62 };
63 };
64
36 apb { 65 apb {
37 serial@d0000000 { 66 serial@d0000000 {
38 status = "okay"; 67 status = "okay";
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
index d777e3a6f17..089f0a42c50 100644
--- a/arch/arm/boot/dts/spear600.dtsi
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -177,6 +177,12 @@
177 interrupts = <28>; 177 interrupts = <28>;
178 status = "disabled"; 178 status = "disabled";
179 }; 179 };
180
181 timer@f0000000 {
182 compatible = "st,spear-timer";
183 reg = <0xf0000000 0x400>;
184 interrupts = <16>;
185 };
180 }; 186 };
181 }; 187 };
182}; 188};
diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts
index 0a9f34a2c3a..36321bceec4 100644
--- a/arch/arm/boot/dts/tegra-cardhu.dts
+++ b/arch/arm/boot/dts/tegra-cardhu.dts
@@ -7,10 +7,10 @@
7 compatible = "nvidia,cardhu", "nvidia,tegra30"; 7 compatible = "nvidia,cardhu", "nvidia,tegra30";
8 8
9 memory { 9 memory {
10 reg = < 0x80000000 0x40000000 >; 10 reg = <0x80000000 0x40000000>;
11 }; 11 };
12 12
13 pinmux@70000000 { 13 pinmux {
14 pinctrl-names = "default"; 14 pinctrl-names = "default";
15 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
16 16
@@ -51,64 +51,122 @@
51 nvidia,pull = <2>; 51 nvidia,pull = <2>;
52 nvidia,tristate = <0>; 52 nvidia,tristate = <0>;
53 }; 53 };
54 dap2_fs_pa2 {
55 nvidia,pins = "dap2_fs_pa2",
56 "dap2_sclk_pa3",
57 "dap2_din_pa4",
58 "dap2_dout_pa5";
59 nvidia,function = "i2s1";
60 nvidia,pull = <0>;
61 nvidia,tristate = <0>;
62 };
54 }; 63 };
55 }; 64 };
56 65
57 serial@70006000 { 66 serial@70006000 {
58 clock-frequency = < 408000000 >; 67 status = "okay";
59 }; 68 clock-frequency = <408000000>;
60
61 serial@70006040 {
62 status = "disable";
63 };
64
65 serial@70006200 {
66 status = "disable";
67 };
68
69 serial@70006300 {
70 status = "disable";
71 };
72
73 serial@70006400 {
74 status = "disable";
75 }; 69 };
76 70
77 i2c@7000c000 { 71 i2c@7000c000 {
72 status = "okay";
78 clock-frequency = <100000>; 73 clock-frequency = <100000>;
79 }; 74 };
80 75
81 i2c@7000c400 { 76 i2c@7000c400 {
77 status = "okay";
82 clock-frequency = <100000>; 78 clock-frequency = <100000>;
83 }; 79 };
84 80
85 i2c@7000c500 { 81 i2c@7000c500 {
82 status = "okay";
86 clock-frequency = <100000>; 83 clock-frequency = <100000>;
84
85 /* ALS and Proximity sensor */
86 isl29028@44 {
87 compatible = "isil,isl29028";
88 reg = <0x44>;
89 interrupt-parent = <&gpio>;
90 interrupts = <88 0x04>; /*gpio PL0 */
91 };
87 }; 92 };
88 93
89 i2c@7000c700 { 94 i2c@7000c700 {
95 status = "okay";
90 clock-frequency = <100000>; 96 clock-frequency = <100000>;
91 }; 97 };
92 98
93 i2c@7000d000 { 99 i2c@7000d000 {
100 status = "okay";
94 clock-frequency = <100000>; 101 clock-frequency = <100000>;
102
103 wm8903: wm8903@1a {
104 compatible = "wlf,wm8903";
105 reg = <0x1a>;
106 interrupt-parent = <&gpio>;
107 interrupts = <179 0x04>; /* gpio PW3 */
108
109 gpio-controller;
110 #gpio-cells = <2>;
111
112 micdet-cfg = <0>;
113 micdet-delay = <100>;
114 gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
115 };
116
117 tps62361 {
118 compatible = "ti,tps62361";
119 reg = <0x60>;
120
121 regulator-name = "tps62361-vout";
122 regulator-min-microvolt = <500000>;
123 regulator-max-microvolt = <1500000>;
124 regulator-boot-on;
125 regulator-always-on;
126 ti,vsel0-state-high;
127 ti,vsel1-state-high;
128 };
129 };
130
131 ahub {
132 i2s@70080400 {
133 status = "okay";
134 };
95 }; 135 };
96 136
97 sdhci@78000000 { 137 sdhci@78000000 {
138 status = "okay";
98 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 139 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
99 wp-gpios = <&gpio 155 0>; /* gpio PT3 */ 140 wp-gpios = <&gpio 155 0>; /* gpio PT3 */
100 power-gpios = <&gpio 31 0>; /* gpio PD7 */ 141 power-gpios = <&gpio 31 0>; /* gpio PD7 */
142 bus-width = <4>;
101 }; 143 };
102 144
103 sdhci@78000200 { 145 sdhci@78000600 {
104 status = "disable"; 146 status = "okay";
147 support-8bit;
148 bus-width = <8>;
105 }; 149 };
106 150
107 sdhci@78000400 { 151 sound {
108 status = "disable"; 152 compatible = "nvidia,tegra-audio-wm8903-cardhu",
109 }; 153 "nvidia,tegra-audio-wm8903";
154 nvidia,model = "NVIDIA Tegra Cardhu";
110 155
111 sdhci@78000400 { 156 nvidia,audio-routing =
112 support-8bit; 157 "Headphone Jack", "HPOUTR",
158 "Headphone Jack", "HPOUTL",
159 "Int Spk", "ROP",
160 "Int Spk", "RON",
161 "Int Spk", "LOP",
162 "Int Spk", "LON",
163 "Mic Jack", "MICBIAS",
164 "IN1L", "Mic Jack";
165
166 nvidia,i2s-controller = <&tegra_i2s1>;
167 nvidia,audio-codec = <&wm8903>;
168
169 nvidia,spkr-en-gpios = <&wm8903 2 0>;
170 nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
113 }; 171 };
114}; 172};
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index 1a0b1f18294..7de701365fc 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -6,11 +6,11 @@
6 model = "NVIDIA Tegra2 Harmony evaluation board"; 6 model = "NVIDIA Tegra2 Harmony evaluation board";
7 compatible = "nvidia,harmony", "nvidia,tegra20"; 7 compatible = "nvidia,harmony", "nvidia,tegra20";
8 8
9 memory@0 { 9 memory {
10 reg = < 0x00000000 0x40000000 >; 10 reg = <0x00000000 0x40000000>;
11 }; 11 };
12 12
13 pinmux@70000000 { 13 pinmux {
14 pinctrl-names = "default"; 14 pinctrl-names = "default";
15 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
16 16
@@ -167,28 +167,28 @@
167 }; 167 };
168 conf_ata { 168 conf_ata {
169 nvidia,pins = "ata", "atb", "atc", "atd", "ate", 169 nvidia,pins = "ata", "atb", "atc", "atd", "ate",
170 "cdev1", "dap1", "dtb", "gma", "gmb", 170 "cdev1", "cdev2", "dap1", "dtb", "gma",
171 "gmc", "gmd", "gme", "gpu7", "gpv", 171 "gmb", "gmc", "gmd", "gme", "gpu7",
172 "i2cp", "pta", "rm", "slxa", "slxk", 172 "gpv", "i2cp", "pta", "rm", "slxa",
173 "spia", "spib"; 173 "slxk", "spia", "spib", "uac";
174 nvidia,pull = <0>; 174 nvidia,pull = <0>;
175 nvidia,tristate = <0>; 175 nvidia,tristate = <0>;
176 }; 176 };
177 conf_cdev2 {
178 nvidia,pins = "cdev2", "csus", "spid", "spif";
179 nvidia,pull = <1>;
180 nvidia,tristate = <1>;
181 };
182 conf_ck32 { 177 conf_ck32 {
183 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", 178 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
184 "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; 179 "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
185 nvidia,pull = <0>; 180 nvidia,pull = <0>;
186 }; 181 };
182 conf_csus {
183 nvidia,pins = "csus", "spid", "spif";
184 nvidia,pull = <1>;
185 nvidia,tristate = <1>;
186 };
187 conf_crtp { 187 conf_crtp {
188 nvidia,pins = "crtp", "dap2", "dap3", "dap4", 188 nvidia,pins = "crtp", "dap2", "dap3", "dap4",
189 "dtc", "dte", "dtf", "gpu", "sdio1", 189 "dtc", "dte", "dtf", "gpu", "sdio1",
190 "slxc", "slxd", "spdi", "spdo", "spig", 190 "slxc", "slxd", "spdi", "spdo", "spig",
191 "uac", "uda"; 191 "uda";
192 nvidia,pull = <0>; 192 nvidia,pull = <0>;
193 nvidia,tristate = <1>; 193 nvidia,tristate = <1>;
194 }; 194 };
@@ -234,42 +234,81 @@
234 }; 234 };
235 }; 235 };
236 236
237 pmc@7000f400 { 237 i2s@70002800 {
238 nvidia,invert-interrupt; 238 status = "okay";
239 };
240
241 serial@70006300 {
242 status = "okay";
243 clock-frequency = <216000000>;
239 }; 244 };
240 245
241 i2c@7000c000 { 246 i2c@7000c000 {
247 status = "okay";
242 clock-frequency = <400000>; 248 clock-frequency = <400000>;
243 249
244 wm8903: wm8903@1a { 250 wm8903: wm8903@1a {
245 compatible = "wlf,wm8903"; 251 compatible = "wlf,wm8903";
246 reg = <0x1a>; 252 reg = <0x1a>;
247 interrupt-parent = <&gpio>; 253 interrupt-parent = <&gpio>;
248 interrupts = < 187 0x04 >; 254 interrupts = <187 0x04>;
249 255
250 gpio-controller; 256 gpio-controller;
251 #gpio-cells = <2>; 257 #gpio-cells = <2>;
252 258
253 micdet-cfg = <0>; 259 micdet-cfg = <0>;
254 micdet-delay = <100>; 260 micdet-delay = <100>;
255 gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; 261 gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
256 }; 262 };
257 }; 263 };
258 264
259 i2c@7000c400 { 265 i2c@7000c400 {
266 status = "okay";
260 clock-frequency = <400000>; 267 clock-frequency = <400000>;
261 }; 268 };
262 269
263 i2c@7000c500 { 270 i2c@7000c500 {
271 status = "okay";
264 clock-frequency = <400000>; 272 clock-frequency = <400000>;
265 }; 273 };
266 274
267 i2c@7000d000 { 275 i2c@7000d000 {
276 status = "okay";
268 clock-frequency = <400000>; 277 clock-frequency = <400000>;
269 }; 278 };
270 279
271 i2s@70002a00 { 280 pmc {
272 status = "disable"; 281 nvidia,invert-interrupt;
282 };
283
284 usb@c5000000 {
285 status = "okay";
286 };
287
288 usb@c5004000 {
289 status = "okay";
290 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
291 };
292
293 usb@c5008000 {
294 status = "okay";
295 };
296
297 sdhci@c8000200 {
298 status = "okay";
299 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
300 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
301 power-gpios = <&gpio 155 0>; /* gpio PT3 */
302 bus-width = <4>;
303 };
304
305 sdhci@c8000600 {
306 status = "okay";
307 cd-gpios = <&gpio 58 0>; /* gpio PH2 */
308 wp-gpios = <&gpio 59 0>; /* gpio PH3 */
309 power-gpios = <&gpio 70 0>; /* gpio PI6 */
310 support-8bit;
311 bus-width = <8>;
273 }; 312 };
274 313
275 sound { 314 sound {
@@ -295,45 +334,4 @@
295 nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ 334 nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
296 nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ 335 nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
297 }; 336 };
298
299 serial@70006000 {
300 status = "disable";
301 };
302
303 serial@70006040 {
304 status = "disable";
305 };
306
307 serial@70006200 {
308 status = "disable";
309 };
310
311 serial@70006300 {
312 clock-frequency = < 216000000 >;
313 };
314
315 serial@70006400 {
316 status = "disable";
317 };
318
319 sdhci@c8000000 {
320 status = "disable";
321 };
322
323 sdhci@c8000200 {
324 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
325 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
326 power-gpios = <&gpio 155 0>; /* gpio PT3 */
327 };
328
329 sdhci@c8000400 {
330 status = "disable";
331 };
332
333 sdhci@c8000600 {
334 cd-gpios = <&gpio 58 0>; /* gpio PH2 */
335 wp-gpios = <&gpio 59 0>; /* gpio PH3 */
336 power-gpios = <&gpio 70 0>; /* gpio PI6 */
337 support-8bit;
338 };
339}; 337};
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
index 10943fb2561..bfeb117d5ae 100644
--- a/arch/arm/boot/dts/tegra-paz00.dts
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -6,11 +6,11 @@
6 model = "Toshiba AC100 / Dynabook AZ"; 6 model = "Toshiba AC100 / Dynabook AZ";
7 compatible = "compal,paz00", "nvidia,tegra20"; 7 compatible = "compal,paz00", "nvidia,tegra20";
8 8
9 memory@0 { 9 memory {
10 reg = <0x00000000 0x20000000>; 10 reg = <0x00000000 0x20000000>;
11 }; 11 };
12 12
13 pinmux@70000000 { 13 pinmux {
14 pinctrl-names = "default"; 14 pinctrl-names = "default";
15 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
16 16
@@ -159,18 +159,14 @@
159 }; 159 };
160 conf_ata { 160 conf_ata {
161 nvidia,pins = "ata", "atb", "atc", "atd", "ate", 161 nvidia,pins = "ata", "atb", "atc", "atd", "ate",
162 "cdev1", "dap1", "dap2", "dtf", "gma", 162 "cdev1", "cdev2", "dap1", "dap2", "dtf",
163 "gmb", "gmc", "gmd", "gme", "gpu", 163 "gma", "gmb", "gmc", "gmd", "gme",
164 "gpu7", "gpv", "i2cp", "pta", "rm", 164 "gpu", "gpu7", "gpv", "i2cp", "pta",
165 "sdio1", "slxk", "spdo", "uac", "uda"; 165 "rm", "sdio1", "slxk", "spdo", "uac",
166 "uda";
166 nvidia,pull = <0>; 167 nvidia,pull = <0>;
167 nvidia,tristate = <0>; 168 nvidia,tristate = <0>;
168 }; 169 };
169 conf_cdev2 {
170 nvidia,pins = "cdev2";
171 nvidia,pull = <1>;
172 nvidia,tristate = <0>;
173 };
174 conf_ck32 { 170 conf_ck32 {
175 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", 171 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
176 "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; 172 "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
@@ -230,7 +226,22 @@
230 }; 226 };
231 }; 227 };
232 228
229 i2s@70002800 {
230 status = "okay";
231 };
232
233 serial@70006000 {
234 status = "okay";
235 clock-frequency = <216000000>;
236 };
237
238 serial@70006200 {
239 status = "okay";
240 clock-frequency = <216000000>;
241 };
242
233 i2c@7000c000 { 243 i2c@7000c000 {
244 status = "okay";
234 clock-frequency = <400000>; 245 clock-frequency = <400000>;
235 246
236 alc5632: alc5632@1e { 247 alc5632: alc5632@1e {
@@ -242,25 +253,23 @@
242 }; 253 };
243 254
244 i2c@7000c400 { 255 i2c@7000c400 {
256 status = "okay";
245 clock-frequency = <400000>; 257 clock-frequency = <400000>;
246 }; 258 };
247 259
248 i2c@7000c500 { 260 nvec {
249 status = "disable";
250 };
251
252 nvec@7000c500 {
253 #address-cells = <1>;
254 #size-cells = <0>;
255 compatible = "nvidia,nvec"; 261 compatible = "nvidia,nvec";
256 reg = <0x7000C500 0x100>; 262 reg = <0x7000c500 0x100>;
257 interrupts = <0 92 0x04>; 263 interrupts = <0 92 0x04>;
264 #address-cells = <1>;
265 #size-cells = <0>;
258 clock-frequency = <80000>; 266 clock-frequency = <80000>;
259 request-gpios = <&gpio 170 0>; 267 request-gpios = <&gpio 170 0>; /* gpio PV2 */
260 slave-addr = <138>; 268 slave-addr = <138>;
261 }; 269 };
262 270
263 i2c@7000d000 { 271 i2c@7000d000 {
272 status = "okay";
264 clock-frequency = <400000>; 273 clock-frequency = <400000>;
265 274
266 adt7461@4c { 275 adt7461@4c {
@@ -269,66 +278,31 @@
269 }; 278 };
270 }; 279 };
271 280
272 i2s@70002a00 { 281 usb@c5000000 {
273 status = "disable"; 282 status = "okay";
274 };
275
276 sound {
277 compatible = "nvidia,tegra-audio-alc5632-paz00",
278 "nvidia,tegra-audio-alc5632";
279
280 nvidia,model = "Compal PAZ00";
281
282 nvidia,audio-routing =
283 "Int Spk", "SPKOUT",
284 "Int Spk", "SPKOUTN",
285 "Headset Mic", "MICBIAS1",
286 "MIC1", "Headset Mic",
287 "Headset Stereophone", "HPR",
288 "Headset Stereophone", "HPL",
289 "DMICDAT", "Digital Mic";
290
291 nvidia,audio-codec = <&alc5632>;
292 nvidia,i2s-controller = <&tegra_i2s1>;
293 nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
294 };
295
296 serial@70006000 {
297 clock-frequency = <216000000>;
298 }; 283 };
299 284
300 serial@70006040 { 285 usb@c5004000 {
301 status = "disable"; 286 status = "okay";
287 nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
302 }; 288 };
303 289
304 serial@70006200 { 290 usb@c5008000 {
305 clock-frequency = <216000000>; 291 status = "okay";
306 };
307
308 serial@70006300 {
309 status = "disable";
310 };
311
312 serial@70006400 {
313 status = "disable";
314 }; 292 };
315 293
316 sdhci@c8000000 { 294 sdhci@c8000000 {
295 status = "okay";
317 cd-gpios = <&gpio 173 0>; /* gpio PV5 */ 296 cd-gpios = <&gpio 173 0>; /* gpio PV5 */
318 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 297 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
319 power-gpios = <&gpio 169 0>; /* gpio PV1 */ 298 power-gpios = <&gpio 169 0>; /* gpio PV1 */
320 }; 299 bus-width = <4>;
321
322 sdhci@c8000200 {
323 status = "disable";
324 };
325
326 sdhci@c8000400 {
327 status = "disable";
328 }; 300 };
329 301
330 sdhci@c8000600 { 302 sdhci@c8000600 {
303 status = "okay";
331 support-8bit; 304 support-8bit;
305 bus-width = <8>;
332 }; 306 };
333 307
334 gpio-keys { 308 gpio-keys {
@@ -347,8 +321,28 @@
347 321
348 wifi { 322 wifi {
349 label = "wifi-led"; 323 label = "wifi-led";
350 gpios = <&gpio 24 0>; 324 gpios = <&gpio 24 0>; /* gpio PD0 */
351 linux,default-trigger = "rfkill0"; 325 linux,default-trigger = "rfkill0";
352 }; 326 };
353 }; 327 };
328
329 sound {
330 compatible = "nvidia,tegra-audio-alc5632-paz00",
331 "nvidia,tegra-audio-alc5632";
332
333 nvidia,model = "Compal PAZ00";
334
335 nvidia,audio-routing =
336 "Int Spk", "SPKOUT",
337 "Int Spk", "SPKOUTN",
338 "Headset Mic", "MICBIAS1",
339 "MIC1", "Headset Mic",
340 "Headset Stereophone", "HPR",
341 "Headset Stereophone", "HPL",
342 "DMICDAT", "Digital Mic";
343
344 nvidia,audio-codec = <&alc5632>;
345 nvidia,i2s-controller = <&tegra_i2s1>;
346 nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
347 };
354}; 348};
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index ec33116f5df..89cb7f2acd9 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -7,11 +7,10 @@
7 compatible = "nvidia,seaboard", "nvidia,tegra20"; 7 compatible = "nvidia,seaboard", "nvidia,tegra20";
8 8
9 memory { 9 memory {
10 device_type = "memory"; 10 reg = <0x00000000 0x40000000>;
11 reg = < 0x00000000 0x40000000 >;
12 }; 11 };
13 12
14 pinmux@70000000 { 13 pinmux {
15 pinctrl-names = "default"; 14 pinctrl-names = "default";
16 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
17 16
@@ -100,7 +99,7 @@
100 }; 99 };
101 hdint { 100 hdint {
102 nvidia,pins = "hdint", "lpw0", "lpw2", "lsc1", 101 nvidia,pins = "hdint", "lpw0", "lpw2", "lsc1",
103 "lsck", "lsda", "pta"; 102 "lsck", "lsda";
104 nvidia,function = "hdmi"; 103 nvidia,function = "hdmi";
105 }; 104 };
106 i2cp { 105 i2cp {
@@ -134,6 +133,10 @@
134 nvidia,pins = "pmc"; 133 nvidia,pins = "pmc";
135 nvidia,function = "pwr_on"; 134 nvidia,function = "pwr_on";
136 }; 135 };
136 pta {
137 nvidia,pins = "pta";
138 nvidia,function = "i2c2";
139 };
137 rm { 140 rm {
138 nvidia,pins = "rm"; 141 nvidia,pins = "rm";
139 nvidia,function = "i2c1"; 142 nvidia,function = "i2c1";
@@ -254,108 +257,148 @@
254 }; 257 };
255 }; 258 };
256 259
260 i2s@70002800 {
261 status = "okay";
262 };
263
264 serial@70006300 {
265 status = "okay";
266 clock-frequency = <216000000>;
267 };
268
257 i2c@7000c000 { 269 i2c@7000c000 {
270 status = "okay";
258 clock-frequency = <400000>; 271 clock-frequency = <400000>;
259 272
260 wm8903: wm8903@1a { 273 wm8903: wm8903@1a {
261 compatible = "wlf,wm8903"; 274 compatible = "wlf,wm8903";
262 reg = <0x1a>; 275 reg = <0x1a>;
263 interrupt-parent = <&gpio>; 276 interrupt-parent = <&gpio>;
264 interrupts = < 187 0x04 >; 277 interrupts = <187 0x04>;
265 278
266 gpio-controller; 279 gpio-controller;
267 #gpio-cells = <2>; 280 #gpio-cells = <2>;
268 281
269 micdet-cfg = <0>; 282 micdet-cfg = <0>;
270 micdet-delay = <100>; 283 micdet-delay = <100>;
271 gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; 284 gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
285 };
286
287 /* ALS and proximity sensor */
288 isl29018@44 {
289 compatible = "isil,isl29018";
290 reg = <0x44>;
291 interrupt-parent = <&gpio>;
292 interrupts = <202 0x04>; /* GPIO PZ2 */
293 };
294
295 gyrometer@68 {
296 compatible = "invn,mpu3050";
297 reg = <0x68>;
298 interrupt-parent = <&gpio>;
299 interrupts = <204 0x04>; /* gpio PZ4 */
272 }; 300 };
273 }; 301 };
274 302
275 i2c@7000c400 { 303 i2c@7000c400 {
276 clock-frequency = <400000>; 304 status = "okay";
305 clock-frequency = <100000>;
306
307 smart-battery@b {
308 compatible = "ti,bq20z75", "smart-battery-1.1";
309 reg = <0xb>;
310 ti,i2c-retry-count = <2>;
311 ti,poll-retry-count = <10>;
312 };
277 }; 313 };
278 314
279 i2c@7000c500 { 315 i2c@7000c500 {
316 status = "okay";
280 clock-frequency = <400000>; 317 clock-frequency = <400000>;
281 }; 318 };
282 319
283 i2c@7000d000 { 320 i2c@7000d000 {
321 status = "okay";
284 clock-frequency = <400000>; 322 clock-frequency = <400000>;
285 323
286 adt7461@4c { 324 temperature-sensor@4c {
287 compatible = "adt7461"; 325 compatible = "nct1008";
288 reg = <0x4c>; 326 reg = <0x4c>;
289 }; 327 };
290 };
291
292 i2s@70002a00 {
293 status = "disable";
294 };
295
296 sound {
297 compatible = "nvidia,tegra-audio-wm8903-seaboard",
298 "nvidia,tegra-audio-wm8903";
299 nvidia,model = "NVIDIA Tegra Seaboard";
300
301 nvidia,audio-routing =
302 "Headphone Jack", "HPOUTR",
303 "Headphone Jack", "HPOUTL",
304 "Int Spk", "ROP",
305 "Int Spk", "RON",
306 "Int Spk", "LOP",
307 "Int Spk", "LON",
308 "Mic Jack", "MICBIAS",
309 "IN1R", "Mic Jack";
310
311 nvidia,i2s-controller = <&tegra_i2s1>;
312 nvidia,audio-codec = <&wm8903>;
313
314 nvidia,spkr-en-gpios = <&wm8903 2 0>;
315 nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
316 };
317 328
318 serial@70006000 { 329 magnetometer@c {
319 status = "disable"; 330 compatible = "ak8975";
320 }; 331 reg = <0xc>;
321 332 interrupt-parent = <&gpio>;
322 serial@70006040 { 333 interrupts = <109 0x04>; /* gpio PN5 */
323 status = "disable"; 334 };
324 }; 335 };
325 336
326 serial@70006200 { 337 emc {
327 status = "disable"; 338 emc-table@190000 {
328 }; 339 reg = <190000>;
340 compatible = "nvidia,tegra20-emc-table";
341 clock-frequency = <190000>;
342 nvidia,emc-registers = <0x0000000c 0x00000026
343 0x00000009 0x00000003 0x00000004 0x00000004
344 0x00000002 0x0000000c 0x00000003 0x00000003
345 0x00000002 0x00000001 0x00000004 0x00000005
346 0x00000004 0x00000009 0x0000000d 0x0000059f
347 0x00000000 0x00000003 0x00000003 0x00000003
348 0x00000003 0x00000001 0x0000000b 0x000000c8
349 0x00000003 0x00000007 0x00000004 0x0000000f
350 0x00000002 0x00000000 0x00000000 0x00000002
351 0x00000000 0x00000000 0x00000083 0xa06204ae
352 0x007dc010 0x00000000 0x00000000 0x00000000
353 0x00000000 0x00000000 0x00000000 0x00000000>;
354 };
329 355
330 serial@70006300 { 356 emc-table@380000 {
331 clock-frequency = < 216000000 >; 357 reg = <380000>;
358 compatible = "nvidia,tegra20-emc-table";
359 clock-frequency = <380000>;
360 nvidia,emc-registers = <0x00000017 0x0000004b
361 0x00000012 0x00000006 0x00000004 0x00000005
362 0x00000003 0x0000000c 0x00000006 0x00000006
363 0x00000003 0x00000001 0x00000004 0x00000005
364 0x00000004 0x00000009 0x0000000d 0x00000b5f
365 0x00000000 0x00000003 0x00000003 0x00000006
366 0x00000006 0x00000001 0x00000011 0x000000c8
367 0x00000003 0x0000000e 0x00000007 0x0000000f
368 0x00000002 0x00000000 0x00000000 0x00000002
369 0x00000000 0x00000000 0x00000083 0xe044048b
370 0x007d8010 0x00000000 0x00000000 0x00000000
371 0x00000000 0x00000000 0x00000000 0x00000000>;
372 };
332 }; 373 };
333 374
334 serial@70006400 { 375 usb@c5000000 {
335 status = "disable"; 376 status = "okay";
377 nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
378 dr_mode = "otg";
336 }; 379 };
337 380
338 sdhci@c8000000 { 381 usb@c5004000 {
339 status = "disable"; 382 status = "okay";
383 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
340 }; 384 };
341 385
342 sdhci@c8000200 { 386 usb@c5008000 {
343 status = "disable"; 387 status = "okay";
344 }; 388 };
345 389
346 sdhci@c8000400 { 390 sdhci@c8000400 {
391 status = "okay";
347 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 392 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
348 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 393 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
349 power-gpios = <&gpio 70 0>; /* gpio PI6 */ 394 power-gpios = <&gpio 70 0>; /* gpio PI6 */
395 bus-width = <4>;
350 }; 396 };
351 397
352 sdhci@c8000600 { 398 sdhci@c8000600 {
399 status = "okay";
353 support-8bit; 400 support-8bit;
354 }; 401 bus-width = <8>;
355
356 usb@c5000000 {
357 nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
358 dr_mode = "otg";
359 }; 402 };
360 403
361 gpio-keys { 404 gpio-keys {
@@ -378,41 +421,25 @@
378 }; 421 };
379 }; 422 };
380 423
381 emc@7000f400 { 424 sound {
382 emc-table@190000 { 425 compatible = "nvidia,tegra-audio-wm8903-seaboard",
383 reg = < 190000 >; 426 "nvidia,tegra-audio-wm8903";
384 compatible = "nvidia,tegra20-emc-table"; 427 nvidia,model = "NVIDIA Tegra Seaboard";
385 clock-frequency = < 190000 >;
386 nvidia,emc-registers = < 0x0000000c 0x00000026
387 0x00000009 0x00000003 0x00000004 0x00000004
388 0x00000002 0x0000000c 0x00000003 0x00000003
389 0x00000002 0x00000001 0x00000004 0x00000005
390 0x00000004 0x00000009 0x0000000d 0x0000059f
391 0x00000000 0x00000003 0x00000003 0x00000003
392 0x00000003 0x00000001 0x0000000b 0x000000c8
393 0x00000003 0x00000007 0x00000004 0x0000000f
394 0x00000002 0x00000000 0x00000000 0x00000002
395 0x00000000 0x00000000 0x00000083 0xa06204ae
396 0x007dc010 0x00000000 0x00000000 0x00000000
397 0x00000000 0x00000000 0x00000000 0x00000000 >;
398 };
399 428
400 emc-table@380000 { 429 nvidia,audio-routing =
401 reg = < 380000 >; 430 "Headphone Jack", "HPOUTR",
402 compatible = "nvidia,tegra20-emc-table"; 431 "Headphone Jack", "HPOUTL",
403 clock-frequency = < 380000 >; 432 "Int Spk", "ROP",
404 nvidia,emc-registers = < 0x00000017 0x0000004b 433 "Int Spk", "RON",
405 0x00000012 0x00000006 0x00000004 0x00000005 434 "Int Spk", "LOP",
406 0x00000003 0x0000000c 0x00000006 0x00000006 435 "Int Spk", "LON",
407 0x00000003 0x00000001 0x00000004 0x00000005 436 "Mic Jack", "MICBIAS",
408 0x00000004 0x00000009 0x0000000d 0x00000b5f 437 "IN1R", "Mic Jack";
409 0x00000000 0x00000003 0x00000003 0x00000006 438
410 0x00000006 0x00000001 0x00000011 0x000000c8 439 nvidia,i2s-controller = <&tegra_i2s1>;
411 0x00000003 0x0000000e 0x00000007 0x0000000f 440 nvidia,audio-codec = <&wm8903>;
412 0x00000002 0x00000000 0x00000000 0x00000002 441
413 0x00000000 0x00000000 0x00000083 0xe044048b 442 nvidia,spkr-en-gpios = <&wm8903 2 0>;
414 0x007d8010 0x00000000 0x00000000 0x00000000 443 nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
415 0x00000000 0x00000000 0x00000000 0x00000000 >;
416 };
417 }; 444 };
418}; 445};
diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 98efd5b0d7f..9de5636023f 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -6,11 +6,11 @@
6 model = "Compulab TrimSlice board"; 6 model = "Compulab TrimSlice board";
7 compatible = "compulab,trimslice", "nvidia,tegra20"; 7 compatible = "compulab,trimslice", "nvidia,tegra20";
8 8
9 memory@0 { 9 memory {
10 reg = < 0x00000000 0x40000000 >; 10 reg = <0x00000000 0x40000000>;
11 }; 11 };
12 12
13 pinmux@70000000 { 13 pinmux {
14 pinctrl-names = "default"; 14 pinctrl-names = "default";
15 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
16 16
@@ -182,23 +182,23 @@
182 nvidia,tristate = <1>; 182 nvidia,tristate = <1>;
183 }; 183 };
184 conf_atb { 184 conf_atb {
185 nvidia,pins = "atb", "cdev1", "dap1", "gma", 185 nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
186 "gmc", "gmd", "gpu", "gpu7", "gpv", 186 "gma", "gmc", "gmd", "gpu", "gpu7",
187 "sdio1", "slxa", "slxk", "uac"; 187 "gpv", "sdio1", "slxa", "slxk", "uac";
188 nvidia,pull = <0>; 188 nvidia,pull = <0>;
189 nvidia,tristate = <0>; 189 nvidia,tristate = <0>;
190 }; 190 };
191 conf_cdev2 {
192 nvidia,pins = "cdev2", "csus", "spia", "spib",
193 "spid", "spif";
194 nvidia,pull = <1>;
195 nvidia,tristate = <1>;
196 };
197 conf_ck32 { 191 conf_ck32 {
198 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", 192 nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
199 "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; 193 "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
200 nvidia,pull = <0>; 194 nvidia,pull = <0>;
201 }; 195 };
196 conf_csus {
197 nvidia,pins = "csus", "spia", "spib",
198 "spid", "spif";
199 nvidia,pull = <1>;
200 nvidia,tristate = <1>;
201 };
202 conf_ddc { 202 conf_ddc {
203 nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd"; 203 nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd";
204 nvidia,pull = <2>; 204 nvidia,pull = <2>;
@@ -240,68 +240,67 @@
240 }; 240 };
241 }; 241 };
242 242
243 i2s@70002800 {
244 status = "okay";
245 };
246
247 serial@70006000 {
248 status = "okay";
249 clock-frequency = <216000000>;
250 };
251
243 i2c@7000c000 { 252 i2c@7000c000 {
253 status = "okay";
244 clock-frequency = <400000>; 254 clock-frequency = <400000>;
245 }; 255 };
246 256
247 i2c@7000c400 { 257 i2c@7000c400 {
258 status = "okay";
248 clock-frequency = <400000>; 259 clock-frequency = <400000>;
249 }; 260 };
250 261
251 i2c@7000c500 { 262 i2c@7000c500 {
263 status = "okay";
252 clock-frequency = <400000>; 264 clock-frequency = <400000>;
253 };
254
255 i2c@7000d000 {
256 status = "disable";
257 };
258
259 i2s@70002800 {
260 status = "disable";
261 };
262
263 i2s@70002a00 {
264 status = "disable";
265 };
266
267 das@70000c00 {
268 status = "disable";
269 };
270 265
271 serial@70006000 { 266 codec: codec@1a {
272 clock-frequency = < 216000000 >; 267 compatible = "ti,tlv320aic23";
273 }; 268 reg = <0x1a>;
269 };
274 270
275 serial@70006040 { 271 rtc@56 {
276 status = "disable"; 272 compatible = "emmicro,em3027";
273 reg = <0x56>;
274 };
277 }; 275 };
278 276
279 serial@70006200 { 277 usb@c5000000 {
280 status = "disable"; 278 status = "okay";
281 }; 279 };
282 280
283 serial@70006300 { 281 usb@c5004000 {
284 status = "disable"; 282 nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
285 }; 283 };
286 284
287 serial@70006400 { 285 usb@c5008000 {
288 status = "disable"; 286 status = "okay";
289 }; 287 };
290 288
291 sdhci@c8000000 { 289 sdhci@c8000000 {
292 status = "disable"; 290 status = "okay";
291 bus-width = <4>;
293 }; 292 };
294 293
295 sdhci@c8000200 { 294 sdhci@c8000600 {
296 status = "disable"; 295 status = "okay";
297 }; 296 cd-gpios = <&gpio 121 0>; /* gpio PP1 */
298 297 wp-gpios = <&gpio 122 0>; /* gpio PP2 */
299 sdhci@c8000400 { 298 bus-width = <4>;
300 status = "disable";
301 }; 299 };
302 300
303 sdhci@c8000600 { 301 sound {
304 cd-gpios = <&gpio 121 0>; 302 compatible = "nvidia,tegra-audio-trimslice";
305 wp-gpios = <&gpio 122 0>; 303 nvidia,i2s-controller = <&tegra_i2s1>;
304 nvidia,audio-codec = <&codec>;
306 }; 305 };
307}; 306};
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
index 71eb2e50a66..445343b0fbd 100644
--- a/arch/arm/boot/dts/tegra-ventana.dts
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -7,10 +7,10 @@
7 compatible = "nvidia,ventana", "nvidia,tegra20"; 7 compatible = "nvidia,ventana", "nvidia,tegra20";
8 8
9 memory { 9 memory {
10 reg = < 0x00000000 0x40000000 >; 10 reg = <0x00000000 0x40000000>;
11 }; 11 };
12 12
13 pinmux@70000000 { 13 pinmux {
14 pinctrl-names = "default"; 14 pinctrl-names = "default";
15 pinctrl-0 = <&state_default>; 15 pinctrl-0 = <&state_default>;
16 16
@@ -240,38 +240,82 @@
240 }; 240 };
241 }; 241 };
242 242
243 i2s@70002800 {
244 status = "okay";
245 };
246
247 serial@70006300 {
248 status = "okay";
249 clock-frequency = <216000000>;
250 };
251
243 i2c@7000c000 { 252 i2c@7000c000 {
253 status = "okay";
244 clock-frequency = <400000>; 254 clock-frequency = <400000>;
245 255
246 wm8903: wm8903@1a { 256 wm8903: wm8903@1a {
247 compatible = "wlf,wm8903"; 257 compatible = "wlf,wm8903";
248 reg = <0x1a>; 258 reg = <0x1a>;
249 interrupt-parent = <&gpio>; 259 interrupt-parent = <&gpio>;
250 interrupts = < 187 0x04 >; 260 interrupts = <187 0x04>;
251 261
252 gpio-controller; 262 gpio-controller;
253 #gpio-cells = <2>; 263 #gpio-cells = <2>;
254 264
255 micdet-cfg = <0>; 265 micdet-cfg = <0>;
256 micdet-delay = <100>; 266 micdet-delay = <100>;
257 gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >; 267 gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
268 };
269
270 /* ALS and proximity sensor */
271 isl29018@44 {
272 compatible = "isil,isl29018";
273 reg = <0x44>;
274 interrupt-parent = <&gpio>;
275 interrupts = <202 0x04>; /*gpio PZ2 */
258 }; 276 };
259 }; 277 };
260 278
261 i2c@7000c400 { 279 i2c@7000c400 {
280 status = "okay";
262 clock-frequency = <400000>; 281 clock-frequency = <400000>;
263 }; 282 };
264 283
265 i2c@7000c500 { 284 i2c@7000c500 {
285 status = "okay";
266 clock-frequency = <400000>; 286 clock-frequency = <400000>;
267 }; 287 };
268 288
269 i2c@7000d000 { 289 i2c@7000d000 {
290 status = "okay";
270 clock-frequency = <400000>; 291 clock-frequency = <400000>;
271 }; 292 };
272 293
273 i2s@70002a00 { 294 usb@c5000000 {
274 status = "disable"; 295 status = "okay";
296 };
297
298 usb@c5004000 {
299 status = "okay";
300 nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
301 };
302
303 usb@c5008000 {
304 status = "okay";
305 };
306
307 sdhci@c8000400 {
308 status = "okay";
309 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
310 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
311 power-gpios = <&gpio 70 0>; /* gpio PI6 */
312 bus-width = <4>;
313 };
314
315 sdhci@c8000600 {
316 status = "okay";
317 support-8bit;
318 bus-width = <8>;
275 }; 319 };
276 320
277 sound { 321 sound {
@@ -294,45 +338,7 @@
294 338
295 nvidia,spkr-en-gpios = <&wm8903 2 0>; 339 nvidia,spkr-en-gpios = <&wm8903 2 0>;
296 nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */ 340 nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
297 nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */ 341 nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */
298 nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */ 342 nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
299 }; 343 };
300
301 serial@70006000 {
302 status = "disable";
303 };
304
305 serial@70006040 {
306 status = "disable";
307 };
308
309 serial@70006200 {
310 status = "disable";
311 };
312
313 serial@70006300 {
314 clock-frequency = < 216000000 >;
315 };
316
317 serial@70006400 {
318 status = "disable";
319 };
320
321 sdhci@c8000000 {
322 status = "disable";
323 };
324
325 sdhci@c8000200 {
326 status = "disable";
327 };
328
329 sdhci@c8000400 {
330 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
331 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
332 power-gpios = <&gpio 70 0>; /* gpio PI6 */
333 };
334
335 sdhci@c8000600 {
336 support-8bit;
337 };
338}; 344};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 108e894a892..c417d67e902 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,207 +4,242 @@
4 compatible = "nvidia,tegra20"; 4 compatible = "nvidia,tegra20";
5 interrupt-parent = <&intc>; 5 interrupt-parent = <&intc>;
6 6
7 pmc@7000f400 { 7 intc: interrupt-controller {
8 compatible = "nvidia,tegra20-pmc";
9 reg = <0x7000e400 0x400>;
10 };
11
12 intc: interrupt-controller@50041000 {
13 compatible = "arm,cortex-a9-gic"; 8 compatible = "arm,cortex-a9-gic";
9 reg = <0x50041000 0x1000
10 0x50040100 0x0100>;
14 interrupt-controller; 11 interrupt-controller;
15 #interrupt-cells = <3>; 12 #interrupt-cells = <3>;
16 reg = < 0x50041000 0x1000 >,
17 < 0x50040100 0x0100 >;
18 }; 13 };
19 14
20 pmu { 15 apbdma: dma {
21 compatible = "arm,cortex-a9-pmu";
22 interrupts = <0 56 0x04
23 0 57 0x04>;
24 };
25
26 apbdma: dma@6000a000 {
27 compatible = "nvidia,tegra20-apbdma"; 16 compatible = "nvidia,tegra20-apbdma";
28 reg = <0x6000a000 0x1200>; 17 reg = <0x6000a000 0x1200>;
29 interrupts = < 0 104 0x04 18 interrupts = <0 104 0x04
30 0 105 0x04 19 0 105 0x04
31 0 106 0x04 20 0 106 0x04
32 0 107 0x04 21 0 107 0x04
33 0 108 0x04 22 0 108 0x04
34 0 109 0x04 23 0 109 0x04
35 0 110 0x04 24 0 110 0x04
36 0 111 0x04 25 0 111 0x04
37 0 112 0x04 26 0 112 0x04
38 0 113 0x04 27 0 113 0x04
39 0 114 0x04 28 0 114 0x04
40 0 115 0x04 29 0 115 0x04
41 0 116 0x04 30 0 116 0x04
42 0 117 0x04 31 0 117 0x04
43 0 118 0x04 32 0 118 0x04
44 0 119 0x04 >; 33 0 119 0x04>;
45 }; 34 };
46 35
47 i2c@7000c000 { 36 ahb {
48 #address-cells = <1>; 37 compatible = "nvidia,tegra20-ahb";
49 #size-cells = <0>; 38 reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
50 compatible = "nvidia,tegra20-i2c"; 39 };
51 reg = <0x7000C000 0x100>; 40
52 interrupts = < 0 38 0x04 >; 41 gpio: gpio {
53 }; 42 compatible = "nvidia,tegra20-gpio";
54 43 reg = <0x6000d000 0x1000>;
55 i2c@7000c400 { 44 interrupts = <0 32 0x04
56 #address-cells = <1>; 45 0 33 0x04
57 #size-cells = <0>; 46 0 34 0x04
58 compatible = "nvidia,tegra20-i2c"; 47 0 35 0x04
59 reg = <0x7000C400 0x100>; 48 0 55 0x04
60 interrupts = < 0 84 0x04 >; 49 0 87 0x04
50 0 89 0x04>;
51 #gpio-cells = <2>;
52 gpio-controller;
53 #interrupt-cells = <2>;
54 interrupt-controller;
61 }; 55 };
62 56
63 i2c@7000c500 { 57 pinmux: pinmux {
64 #address-cells = <1>; 58 compatible = "nvidia,tegra20-pinmux";
65 #size-cells = <0>; 59 reg = <0x70000014 0x10 /* Tri-state registers */
66 compatible = "nvidia,tegra20-i2c"; 60 0x70000080 0x20 /* Mux registers */
67 reg = <0x7000C500 0x100>; 61 0x700000a0 0x14 /* Pull-up/down registers */
68 interrupts = < 0 92 0x04 >; 62 0x70000868 0xa8>; /* Pad control registers */
69 }; 63 };
70 64
71 i2c@7000d000 { 65 das {
72 #address-cells = <1>; 66 compatible = "nvidia,tegra20-das";
73 #size-cells = <0>; 67 reg = <0x70000c00 0x80>;
74 compatible = "nvidia,tegra20-i2c-dvc";
75 reg = <0x7000D000 0x200>;
76 interrupts = < 0 53 0x04 >;
77 }; 68 };
78 69
79 tegra_i2s1: i2s@70002800 { 70 tegra_i2s1: i2s@70002800 {
80 compatible = "nvidia,tegra20-i2s"; 71 compatible = "nvidia,tegra20-i2s";
81 reg = <0x70002800 0x200>; 72 reg = <0x70002800 0x200>;
82 interrupts = < 0 13 0x04 >; 73 interrupts = <0 13 0x04>;
83 nvidia,dma-request-selector = < &apbdma 2 >; 74 nvidia,dma-request-selector = <&apbdma 2>;
75 status = "disable";
84 }; 76 };
85 77
86 tegra_i2s2: i2s@70002a00 { 78 tegra_i2s2: i2s@70002a00 {
87 compatible = "nvidia,tegra20-i2s"; 79 compatible = "nvidia,tegra20-i2s";
88 reg = <0x70002a00 0x200>; 80 reg = <0x70002a00 0x200>;
89 interrupts = < 0 3 0x04 >; 81 interrupts = <0 3 0x04>;
90 nvidia,dma-request-selector = < &apbdma 1 >; 82 nvidia,dma-request-selector = <&apbdma 1>;
91 }; 83 status = "disable";
92
93 das@70000c00 {
94 compatible = "nvidia,tegra20-das";
95 reg = <0x70000c00 0x80>;
96 };
97
98 gpio: gpio@6000d000 {
99 compatible = "nvidia,tegra20-gpio";
100 reg = < 0x6000d000 0x1000 >;
101 interrupts = < 0 32 0x04
102 0 33 0x04
103 0 34 0x04
104 0 35 0x04
105 0 55 0x04
106 0 87 0x04
107 0 89 0x04 >;
108 #gpio-cells = <2>;
109 gpio-controller;
110 #interrupt-cells = <2>;
111 interrupt-controller;
112 };
113
114 pinmux: pinmux@70000000 {
115 compatible = "nvidia,tegra20-pinmux";
116 reg = < 0x70000014 0x10 /* Tri-state registers */
117 0x70000080 0x20 /* Mux registers */
118 0x700000a0 0x14 /* Pull-up/down registers */
119 0x70000868 0xa8 >; /* Pad control registers */
120 }; 84 };
121 85
122 serial@70006000 { 86 serial@70006000 {
123 compatible = "nvidia,tegra20-uart"; 87 compatible = "nvidia,tegra20-uart";
124 reg = <0x70006000 0x40>; 88 reg = <0x70006000 0x40>;
125 reg-shift = <2>; 89 reg-shift = <2>;
126 interrupts = < 0 36 0x04 >; 90 interrupts = <0 36 0x04>;
91 status = "disable";
127 }; 92 };
128 93
129 serial@70006040 { 94 serial@70006040 {
130 compatible = "nvidia,tegra20-uart"; 95 compatible = "nvidia,tegra20-uart";
131 reg = <0x70006040 0x40>; 96 reg = <0x70006040 0x40>;
132 reg-shift = <2>; 97 reg-shift = <2>;
133 interrupts = < 0 37 0x04 >; 98 interrupts = <0 37 0x04>;
99 status = "disable";
134 }; 100 };
135 101
136 serial@70006200 { 102 serial@70006200 {
137 compatible = "nvidia,tegra20-uart"; 103 compatible = "nvidia,tegra20-uart";
138 reg = <0x70006200 0x100>; 104 reg = <0x70006200 0x100>;
139 reg-shift = <2>; 105 reg-shift = <2>;
140 interrupts = < 0 46 0x04 >; 106 interrupts = <0 46 0x04>;
107 status = "disable";
141 }; 108 };
142 109
143 serial@70006300 { 110 serial@70006300 {
144 compatible = "nvidia,tegra20-uart"; 111 compatible = "nvidia,tegra20-uart";
145 reg = <0x70006300 0x100>; 112 reg = <0x70006300 0x100>;
146 reg-shift = <2>; 113 reg-shift = <2>;
147 interrupts = < 0 90 0x04 >; 114 interrupts = <0 90 0x04>;
115 status = "disable";
148 }; 116 };
149 117
150 serial@70006400 { 118 serial@70006400 {
151 compatible = "nvidia,tegra20-uart"; 119 compatible = "nvidia,tegra20-uart";
152 reg = <0x70006400 0x100>; 120 reg = <0x70006400 0x100>;
153 reg-shift = <2>; 121 reg-shift = <2>;
154 interrupts = < 0 91 0x04 >; 122 interrupts = <0 91 0x04>;
123 status = "disable";
155 }; 124 };
156 125
157 emc@7000f400 { 126 i2c@7000c000 {
127 compatible = "nvidia,tegra20-i2c";
128 reg = <0x7000c000 0x100>;
129 interrupts = <0 38 0x04>;
158 #address-cells = <1>; 130 #address-cells = <1>;
159 #size-cells = <0>; 131 #size-cells = <0>;
160 compatible = "nvidia,tegra20-emc"; 132 status = "disable";
161 reg = <0x7000f400 0x200>;
162 }; 133 };
163 134
164 sdhci@c8000000 { 135 i2c@7000c400 {
165 compatible = "nvidia,tegra20-sdhci"; 136 compatible = "nvidia,tegra20-i2c";
166 reg = <0xc8000000 0x200>; 137 reg = <0x7000c400 0x100>;
167 interrupts = < 0 14 0x04 >; 138 interrupts = <0 84 0x04>;
139 #address-cells = <1>;
140 #size-cells = <0>;
141 status = "disable";
168 }; 142 };
169 143
170 sdhci@c8000200 { 144 i2c@7000c500 {
171 compatible = "nvidia,tegra20-sdhci"; 145 compatible = "nvidia,tegra20-i2c";
172 reg = <0xc8000200 0x200>; 146 reg = <0x7000c500 0x100>;
173 interrupts = < 0 15 0x04 >; 147 interrupts = <0 92 0x04>;
148 #address-cells = <1>;
149 #size-cells = <0>;
150 status = "disable";
174 }; 151 };
175 152
176 sdhci@c8000400 { 153 i2c@7000d000 {
177 compatible = "nvidia,tegra20-sdhci"; 154 compatible = "nvidia,tegra20-i2c-dvc";
178 reg = <0xc8000400 0x200>; 155 reg = <0x7000d000 0x200>;
179 interrupts = < 0 19 0x04 >; 156 interrupts = <0 53 0x04>;
157 #address-cells = <1>;
158 #size-cells = <0>;
159 status = "disable";
180 }; 160 };
181 161
182 sdhci@c8000600 { 162 pmc {
183 compatible = "nvidia,tegra20-sdhci"; 163 compatible = "nvidia,tegra20-pmc";
184 reg = <0xc8000600 0x200>; 164 reg = <0x7000e400 0x400>;
185 interrupts = < 0 31 0x04 >; 165 };
166
167 mc {
168 compatible = "nvidia,tegra20-mc";
169 reg = <0x7000f000 0x024
170 0x7000f03c 0x3c4>;
171 interrupts = <0 77 0x04>;
172 };
173
174 gart {
175 compatible = "nvidia,tegra20-gart";
176 reg = <0x7000f024 0x00000018 /* controller registers */
177 0x58000000 0x02000000>; /* GART aperture */
178 };
179
180 emc {
181 compatible = "nvidia,tegra20-emc";
182 reg = <0x7000f400 0x200>;
183 #address-cells = <1>;
184 #size-cells = <0>;
186 }; 185 };
187 186
188 usb@c5000000 { 187 usb@c5000000 {
189 compatible = "nvidia,tegra20-ehci", "usb-ehci"; 188 compatible = "nvidia,tegra20-ehci", "usb-ehci";
190 reg = <0xc5000000 0x4000>; 189 reg = <0xc5000000 0x4000>;
191 interrupts = < 0 20 0x04 >; 190 interrupts = <0 20 0x04>;
192 phy_type = "utmi"; 191 phy_type = "utmi";
193 nvidia,has-legacy-mode; 192 nvidia,has-legacy-mode;
193 status = "disable";
194 }; 194 };
195 195
196 usb@c5004000 { 196 usb@c5004000 {
197 compatible = "nvidia,tegra20-ehci", "usb-ehci"; 197 compatible = "nvidia,tegra20-ehci", "usb-ehci";
198 reg = <0xc5004000 0x4000>; 198 reg = <0xc5004000 0x4000>;
199 interrupts = < 0 21 0x04 >; 199 interrupts = <0 21 0x04>;
200 phy_type = "ulpi"; 200 phy_type = "ulpi";
201 status = "disable";
201 }; 202 };
202 203
203 usb@c5008000 { 204 usb@c5008000 {
204 compatible = "nvidia,tegra20-ehci", "usb-ehci"; 205 compatible = "nvidia,tegra20-ehci", "usb-ehci";
205 reg = <0xc5008000 0x4000>; 206 reg = <0xc5008000 0x4000>;
206 interrupts = < 0 97 0x04 >; 207 interrupts = <0 97 0x04>;
207 phy_type = "utmi"; 208 phy_type = "utmi";
209 status = "disable";
210 };
211
212 sdhci@c8000000 {
213 compatible = "nvidia,tegra20-sdhci";
214 reg = <0xc8000000 0x200>;
215 interrupts = <0 14 0x04>;
216 status = "disable";
208 }; 217 };
209};
210 218
219 sdhci@c8000200 {
220 compatible = "nvidia,tegra20-sdhci";
221 reg = <0xc8000200 0x200>;
222 interrupts = <0 15 0x04>;
223 status = "disable";
224 };
225
226 sdhci@c8000400 {
227 compatible = "nvidia,tegra20-sdhci";
228 reg = <0xc8000400 0x200>;
229 interrupts = <0 19 0x04>;
230 status = "disable";
231 };
232
233 sdhci@c8000600 {
234 compatible = "nvidia,tegra20-sdhci";
235 reg = <0xc8000600 0x200>;
236 interrupts = <0 31 0x04>;
237 status = "disable";
238 };
239
240 pmu {
241 compatible = "arm,cortex-a9-pmu";
242 interrupts = <0 56 0x04
243 0 57 0x04>;
244 };
245};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 62a7b39f1c9..2dcc09e784b 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,183 +4,268 @@
4 compatible = "nvidia,tegra30"; 4 compatible = "nvidia,tegra30";
5 interrupt-parent = <&intc>; 5 interrupt-parent = <&intc>;
6 6
7 pmc@7000f400 { 7 intc: interrupt-controller {
8 compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
9 reg = <0x7000e400 0x400>;
10 };
11
12 intc: interrupt-controller@50041000 {
13 compatible = "arm,cortex-a9-gic"; 8 compatible = "arm,cortex-a9-gic";
9 reg = <0x50041000 0x1000
10 0x50040100 0x0100>;
14 interrupt-controller; 11 interrupt-controller;
15 #interrupt-cells = <3>; 12 #interrupt-cells = <3>;
16 reg = < 0x50041000 0x1000 >,
17 < 0x50040100 0x0100 >;
18 }; 13 };
19 14
20 pmu { 15 apbdma: dma {
21 compatible = "arm,cortex-a9-pmu";
22 interrupts = <0 144 0x04
23 0 145 0x04
24 0 146 0x04
25 0 147 0x04>;
26 };
27
28 apbdma: dma@6000a000 {
29 compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma"; 16 compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
30 reg = <0x6000a000 0x1400>; 17 reg = <0x6000a000 0x1400>;
31 interrupts = < 0 104 0x04 18 interrupts = <0 104 0x04
32 0 105 0x04 19 0 105 0x04
33 0 106 0x04 20 0 106 0x04
34 0 107 0x04 21 0 107 0x04
35 0 108 0x04 22 0 108 0x04
36 0 109 0x04 23 0 109 0x04
37 0 110 0x04 24 0 110 0x04
38 0 111 0x04 25 0 111 0x04
39 0 112 0x04 26 0 112 0x04
40 0 113 0x04 27 0 113 0x04
41 0 114 0x04 28 0 114 0x04
42 0 115 0x04 29 0 115 0x04
43 0 116 0x04 30 0 116 0x04
44 0 117 0x04 31 0 117 0x04
45 0 118 0x04 32 0 118 0x04
46 0 119 0x04 33 0 119 0x04
47 0 128 0x04 34 0 128 0x04
48 0 129 0x04 35 0 129 0x04
49 0 130 0x04 36 0 130 0x04
50 0 131 0x04 37 0 131 0x04
51 0 132 0x04 38 0 132 0x04
52 0 133 0x04 39 0 133 0x04
53 0 134 0x04 40 0 134 0x04
54 0 135 0x04 41 0 135 0x04
55 0 136 0x04 42 0 136 0x04
56 0 137 0x04 43 0 137 0x04
57 0 138 0x04 44 0 138 0x04
58 0 139 0x04 45 0 139 0x04
59 0 140 0x04 46 0 140 0x04
60 0 141 0x04 47 0 141 0x04
61 0 142 0x04 48 0 142 0x04
62 0 143 0x04 >; 49 0 143 0x04>;
63 };
64
65 i2c@7000c000 {
66 #address-cells = <1>;
67 #size-cells = <0>;
68 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
69 reg = <0x7000C000 0x100>;
70 interrupts = < 0 38 0x04 >;
71 };
72
73 i2c@7000c400 {
74 #address-cells = <1>;
75 #size-cells = <0>;
76 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
77 reg = <0x7000C400 0x100>;
78 interrupts = < 0 84 0x04 >;
79 };
80
81 i2c@7000c500 {
82 #address-cells = <1>;
83 #size-cells = <0>;
84 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
85 reg = <0x7000C500 0x100>;
86 interrupts = < 0 92 0x04 >;
87 }; 50 };
88 51
89 i2c@7000c700 { 52 ahb: ahb {
90 #address-cells = <1>; 53 compatible = "nvidia,tegra30-ahb";
91 #size-cells = <0>; 54 reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
92 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
93 reg = <0x7000c700 0x100>;
94 interrupts = < 0 120 0x04 >;
95 }; 55 };
96 56
97 i2c@7000d000 { 57 gpio: gpio {
98 #address-cells = <1>;
99 #size-cells = <0>;
100 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
101 reg = <0x7000D000 0x100>;
102 interrupts = < 0 53 0x04 >;
103 };
104
105 gpio: gpio@6000d000 {
106 compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio"; 58 compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
107 reg = < 0x6000d000 0x1000 >; 59 reg = <0x6000d000 0x1000>;
108 interrupts = < 0 32 0x04 60 interrupts = <0 32 0x04
109 0 33 0x04 61 0 33 0x04
110 0 34 0x04 62 0 34 0x04
111 0 35 0x04 63 0 35 0x04
112 0 55 0x04 64 0 55 0x04
113 0 87 0x04 65 0 87 0x04
114 0 89 0x04 66 0 89 0x04
115 0 125 0x04 >; 67 0 125 0x04>;
116 #gpio-cells = <2>; 68 #gpio-cells = <2>;
117 gpio-controller; 69 gpio-controller;
118 #interrupt-cells = <2>; 70 #interrupt-cells = <2>;
119 interrupt-controller; 71 interrupt-controller;
120 }; 72 };
121 73
74 pinmux: pinmux {
75 compatible = "nvidia,tegra30-pinmux";
76 reg = <0x70000868 0xd0 /* Pad control registers */
77 0x70003000 0x3e0>; /* Mux registers */
78 };
79
122 serial@70006000 { 80 serial@70006000 {
123 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; 81 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
124 reg = <0x70006000 0x40>; 82 reg = <0x70006000 0x40>;
125 reg-shift = <2>; 83 reg-shift = <2>;
126 interrupts = < 0 36 0x04 >; 84 interrupts = <0 36 0x04>;
85 status = "disable";
127 }; 86 };
128 87
129 serial@70006040 { 88 serial@70006040 {
130 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; 89 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
131 reg = <0x70006040 0x40>; 90 reg = <0x70006040 0x40>;
132 reg-shift = <2>; 91 reg-shift = <2>;
133 interrupts = < 0 37 0x04 >; 92 interrupts = <0 37 0x04>;
93 status = "disable";
134 }; 94 };
135 95
136 serial@70006200 { 96 serial@70006200 {
137 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; 97 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
138 reg = <0x70006200 0x100>; 98 reg = <0x70006200 0x100>;
139 reg-shift = <2>; 99 reg-shift = <2>;
140 interrupts = < 0 46 0x04 >; 100 interrupts = <0 46 0x04>;
101 status = "disable";
141 }; 102 };
142 103
143 serial@70006300 { 104 serial@70006300 {
144 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; 105 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
145 reg = <0x70006300 0x100>; 106 reg = <0x70006300 0x100>;
146 reg-shift = <2>; 107 reg-shift = <2>;
147 interrupts = < 0 90 0x04 >; 108 interrupts = <0 90 0x04>;
109 status = "disable";
148 }; 110 };
149 111
150 serial@70006400 { 112 serial@70006400 {
151 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart"; 113 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
152 reg = <0x70006400 0x100>; 114 reg = <0x70006400 0x100>;
153 reg-shift = <2>; 115 reg-shift = <2>;
154 interrupts = < 0 91 0x04 >; 116 interrupts = <0 91 0x04>;
117 status = "disable";
118 };
119
120 i2c@7000c000 {
121 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
122 reg = <0x7000c000 0x100>;
123 interrupts = <0 38 0x04>;
124 #address-cells = <1>;
125 #size-cells = <0>;
126 status = "disable";
127 };
128
129 i2c@7000c400 {
130 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
131 reg = <0x7000c400 0x100>;
132 interrupts = <0 84 0x04>;
133 #address-cells = <1>;
134 #size-cells = <0>;
135 status = "disable";
136 };
137
138 i2c@7000c500 {
139 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
140 reg = <0x7000c500 0x100>;
141 interrupts = <0 92 0x04>;
142 #address-cells = <1>;
143 #size-cells = <0>;
144 status = "disable";
145 };
146
147 i2c@7000c700 {
148 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
149 reg = <0x7000c700 0x100>;
150 interrupts = <0 120 0x04>;
151 #address-cells = <1>;
152 #size-cells = <0>;
153 status = "disable";
154 };
155
156 i2c@7000d000 {
157 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
158 reg = <0x7000d000 0x100>;
159 interrupts = <0 53 0x04>;
160 #address-cells = <1>;
161 #size-cells = <0>;
162 status = "disable";
163 };
164
165 pmc {
166 compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
167 reg = <0x7000e400 0x400>;
168 };
169
170 mc {
171 compatible = "nvidia,tegra30-mc";
172 reg = <0x7000f000 0x010
173 0x7000f03c 0x1b4
174 0x7000f200 0x028
175 0x7000f284 0x17c>;
176 interrupts = <0 77 0x04>;
177 };
178
179 smmu {
180 compatible = "nvidia,tegra30-smmu";
181 reg = <0x7000f010 0x02c
182 0x7000f1f0 0x010
183 0x7000f228 0x05c>;
184 nvidia,#asids = <4>; /* # of ASIDs */
185 dma-window = <0 0x40000000>; /* IOVA start & length */
186 nvidia,ahb = <&ahb>;
187 };
188
189 ahub {
190 compatible = "nvidia,tegra30-ahub";
191 reg = <0x70080000 0x200
192 0x70080200 0x100>;
193 interrupts = <0 103 0x04>;
194 nvidia,dma-request-selector = <&apbdma 1>;
195
196 ranges;
197 #address-cells = <1>;
198 #size-cells = <1>;
199
200 tegra_i2s0: i2s@70080300 {
201 compatible = "nvidia,tegra30-i2s";
202 reg = <0x70080300 0x100>;
203 nvidia,ahub-cif-ids = <4 4>;
204 status = "disable";
205 };
206
207 tegra_i2s1: i2s@70080400 {
208 compatible = "nvidia,tegra30-i2s";
209 reg = <0x70080400 0x100>;
210 nvidia,ahub-cif-ids = <5 5>;
211 status = "disable";
212 };
213
214 tegra_i2s2: i2s@70080500 {
215 compatible = "nvidia,tegra30-i2s";
216 reg = <0x70080500 0x100>;
217 nvidia,ahub-cif-ids = <6 6>;
218 status = "disable";
219 };
220
221 tegra_i2s3: i2s@70080600 {
222 compatible = "nvidia,tegra30-i2s";
223 reg = <0x70080600 0x100>;
224 nvidia,ahub-cif-ids = <7 7>;
225 status = "disable";
226 };
227
228 tegra_i2s4: i2s@70080700 {
229 compatible = "nvidia,tegra30-i2s";
230 reg = <0x70080700 0x100>;
231 nvidia,ahub-cif-ids = <8 8>;
232 status = "disable";
233 };
155 }; 234 };
156 235
157 sdhci@78000000 { 236 sdhci@78000000 {
158 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 237 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
159 reg = <0x78000000 0x200>; 238 reg = <0x78000000 0x200>;
160 interrupts = < 0 14 0x04 >; 239 interrupts = <0 14 0x04>;
240 status = "disable";
161 }; 241 };
162 242
163 sdhci@78000200 { 243 sdhci@78000200 {
164 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 244 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
165 reg = <0x78000200 0x200>; 245 reg = <0x78000200 0x200>;
166 interrupts = < 0 15 0x04 >; 246 interrupts = <0 15 0x04>;
247 status = "disable";
167 }; 248 };
168 249
169 sdhci@78000400 { 250 sdhci@78000400 {
170 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 251 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
171 reg = <0x78000400 0x200>; 252 reg = <0x78000400 0x200>;
172 interrupts = < 0 19 0x04 >; 253 interrupts = <0 19 0x04>;
254 status = "disable";
173 }; 255 };
174 256
175 sdhci@78000600 { 257 sdhci@78000600 {
176 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci"; 258 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
177 reg = <0x78000600 0x200>; 259 reg = <0x78000600 0x200>;
178 interrupts = < 0 31 0x04 >; 260 interrupts = <0 31 0x04>;
261 status = "disable";
179 }; 262 };
180 263
181 pinmux: pinmux@70000000 { 264 pmu {
182 compatible = "nvidia,tegra30-pinmux"; 265 compatible = "arm,cortex-a9-pmu";
183 reg = < 0x70000868 0xd0 /* Pad control registers */ 266 interrupts = <0 144 0x04
184 0x70003000 0x3e0 >; /* Mux registers */ 267 0 145 0x04
268 0 146 0x04
269 0 147 0x04>;
185 }; 270 };
186}; 271};
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 595ecd290eb..9d7eb530f95 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -173,7 +173,8 @@ find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_
173 read_lock_irqsave(&device_info->lock, flags); 173 read_lock_irqsave(&device_info->lock, flags);
174 174
175 list_for_each_entry(b, &device_info->safe_buffers, node) 175 list_for_each_entry(b, &device_info->safe_buffers, node)
176 if (b->safe_dma_addr == safe_dma_addr) { 176 if (b->safe_dma_addr <= safe_dma_addr &&
177 b->safe_dma_addr + b->size > safe_dma_addr) {
177 rb = b; 178 rb = b;
178 break; 179 break;
179 } 180 }
@@ -254,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
254 if (buf == NULL) { 255 if (buf == NULL) {
255 dev_err(dev, "%s: unable to map unsafe buffer %p!\n", 256 dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
256 __func__, ptr); 257 __func__, ptr);
257 return ~0; 258 return DMA_ERROR_CODE;
258 } 259 }
259 260
260 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", 261 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
@@ -307,8 +308,9 @@ static inline void unmap_single(struct device *dev, struct safe_buffer *buf,
307 * substitute the safe buffer for the unsafe one. 308 * substitute the safe buffer for the unsafe one.
308 * (basically move the buffer from an unsafe area to a safe one) 309 * (basically move the buffer from an unsafe area to a safe one)
309 */ 310 */
310dma_addr_t __dma_map_page(struct device *dev, struct page *page, 311static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page,
311 unsigned long offset, size_t size, enum dma_data_direction dir) 312 unsigned long offset, size_t size, enum dma_data_direction dir,
313 struct dma_attrs *attrs)
312{ 314{
313 dma_addr_t dma_addr; 315 dma_addr_t dma_addr;
314 int ret; 316 int ret;
@@ -320,21 +322,20 @@ dma_addr_t __dma_map_page(struct device *dev, struct page *page,
320 322
321 ret = needs_bounce(dev, dma_addr, size); 323 ret = needs_bounce(dev, dma_addr, size);
322 if (ret < 0) 324 if (ret < 0)
323 return ~0; 325 return DMA_ERROR_CODE;
324 326
325 if (ret == 0) { 327 if (ret == 0) {
326 __dma_page_cpu_to_dev(page, offset, size, dir); 328 arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir);
327 return dma_addr; 329 return dma_addr;
328 } 330 }
329 331
330 if (PageHighMem(page)) { 332 if (PageHighMem(page)) {
331 dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n"); 333 dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n");
332 return ~0; 334 return DMA_ERROR_CODE;
333 } 335 }
334 336
335 return map_single(dev, page_address(page) + offset, size, dir); 337 return map_single(dev, page_address(page) + offset, size, dir);
336} 338}
337EXPORT_SYMBOL(__dma_map_page);
338 339
339/* 340/*
340 * see if a mapped address was really a "safe" buffer and if so, copy 341 * see if a mapped address was really a "safe" buffer and if so, copy
@@ -342,8 +343,8 @@ EXPORT_SYMBOL(__dma_map_page);
342 * the safe buffer. (basically return things back to the way they 343 * the safe buffer. (basically return things back to the way they
343 * should be) 344 * should be)
344 */ 345 */
345void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, 346static void dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
346 enum dma_data_direction dir) 347 enum dma_data_direction dir, struct dma_attrs *attrs)
347{ 348{
348 struct safe_buffer *buf; 349 struct safe_buffer *buf;
349 350
@@ -352,19 +353,18 @@ void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
352 353
353 buf = find_safe_buffer_dev(dev, dma_addr, __func__); 354 buf = find_safe_buffer_dev(dev, dma_addr, __func__);
354 if (!buf) { 355 if (!buf) {
355 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)), 356 arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir);
356 dma_addr & ~PAGE_MASK, size, dir);
357 return; 357 return;
358 } 358 }
359 359
360 unmap_single(dev, buf, size, dir); 360 unmap_single(dev, buf, size, dir);
361} 361}
362EXPORT_SYMBOL(__dma_unmap_page);
363 362
364int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, 363static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
365 unsigned long off, size_t sz, enum dma_data_direction dir) 364 size_t sz, enum dma_data_direction dir)
366{ 365{
367 struct safe_buffer *buf; 366 struct safe_buffer *buf;
367 unsigned long off;
368 368
369 dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", 369 dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
370 __func__, addr, off, sz, dir); 370 __func__, addr, off, sz, dir);
@@ -373,6 +373,8 @@ int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
373 if (!buf) 373 if (!buf)
374 return 1; 374 return 1;
375 375
376 off = addr - buf->safe_dma_addr;
377
376 BUG_ON(buf->direction != dir); 378 BUG_ON(buf->direction != dir);
377 379
378 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", 380 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
@@ -388,12 +390,21 @@ int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
388 } 390 }
389 return 0; 391 return 0;
390} 392}
391EXPORT_SYMBOL(dmabounce_sync_for_cpu);
392 393
393int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr, 394static void dmabounce_sync_for_cpu(struct device *dev,
394 unsigned long off, size_t sz, enum dma_data_direction dir) 395 dma_addr_t handle, size_t size, enum dma_data_direction dir)
396{
397 if (!__dmabounce_sync_for_cpu(dev, handle, size, dir))
398 return;
399
400 arm_dma_ops.sync_single_for_cpu(dev, handle, size, dir);
401}
402
403static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
404 size_t sz, enum dma_data_direction dir)
395{ 405{
396 struct safe_buffer *buf; 406 struct safe_buffer *buf;
407 unsigned long off;
397 408
398 dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n", 409 dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
399 __func__, addr, off, sz, dir); 410 __func__, addr, off, sz, dir);
@@ -402,6 +413,8 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
402 if (!buf) 413 if (!buf)
403 return 1; 414 return 1;
404 415
416 off = addr - buf->safe_dma_addr;
417
405 BUG_ON(buf->direction != dir); 418 BUG_ON(buf->direction != dir);
406 419
407 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", 420 dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
@@ -417,7 +430,38 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
417 } 430 }
418 return 0; 431 return 0;
419} 432}
420EXPORT_SYMBOL(dmabounce_sync_for_device); 433
434static void dmabounce_sync_for_device(struct device *dev,
435 dma_addr_t handle, size_t size, enum dma_data_direction dir)
436{
437 if (!__dmabounce_sync_for_device(dev, handle, size, dir))
438 return;
439
440 arm_dma_ops.sync_single_for_device(dev, handle, size, dir);
441}
442
443static int dmabounce_set_mask(struct device *dev, u64 dma_mask)
444{
445 if (dev->archdata.dmabounce)
446 return 0;
447
448 return arm_dma_ops.set_dma_mask(dev, dma_mask);
449}
450
451static struct dma_map_ops dmabounce_ops = {
452 .alloc = arm_dma_alloc,
453 .free = arm_dma_free,
454 .mmap = arm_dma_mmap,
455 .map_page = dmabounce_map_page,
456 .unmap_page = dmabounce_unmap_page,
457 .sync_single_for_cpu = dmabounce_sync_for_cpu,
458 .sync_single_for_device = dmabounce_sync_for_device,
459 .map_sg = arm_dma_map_sg,
460 .unmap_sg = arm_dma_unmap_sg,
461 .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
462 .sync_sg_for_device = arm_dma_sync_sg_for_device,
463 .set_dma_mask = dmabounce_set_mask,
464};
421 465
422static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, 466static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
423 const char *name, unsigned long size) 467 const char *name, unsigned long size)
@@ -479,6 +523,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
479#endif 523#endif
480 524
481 dev->archdata.dmabounce = device_info; 525 dev->archdata.dmabounce = device_info;
526 set_dma_ops(dev, &dmabounce_ops);
482 527
483 dev_info(dev, "dmabounce: registered device\n"); 528 dev_info(dev, "dmabounce: registered device\n");
484 529
@@ -497,6 +542,7 @@ void dmabounce_unregister_dev(struct device *dev)
497 struct dmabounce_device_info *device_info = dev->archdata.dmabounce; 542 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
498 543
499 dev->archdata.dmabounce = NULL; 544 dev->archdata.dmabounce = NULL;
545 set_dma_ops(dev, NULL);
500 546
501 if (!device_info) { 547 if (!device_info) {
502 dev_warn(dev, 548 dev_warn(dev,
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 09a02963cf5..e05a2f1665a 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -33,6 +33,7 @@ CONFIG_MACH_IMX27LITE=y
33CONFIG_MACH_PCA100=y 33CONFIG_MACH_PCA100=y
34CONFIG_MACH_MXT_TD60=y 34CONFIG_MACH_MXT_TD60=y
35CONFIG_MACH_IMX27IPCAM=y 35CONFIG_MACH_IMX27IPCAM=y
36CONFIG_MACH_IMX27_DT=y
36CONFIG_MXC_IRQ_PRIOR=y 37CONFIG_MXC_IRQ_PRIOR=y
37CONFIG_MXC_PWM=y 38CONFIG_MXC_PWM=y
38CONFIG_NO_HZ=y 39CONFIG_NO_HZ=y
@@ -172,7 +173,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
172CONFIG_RTC_CLASS=y 173CONFIG_RTC_CLASS=y
173CONFIG_RTC_DRV_PCF8563=y 174CONFIG_RTC_DRV_PCF8563=y
174CONFIG_RTC_DRV_IMXDI=y 175CONFIG_RTC_DRV_IMXDI=y
175CONFIG_RTC_MXC=y 176CONFIG_RTC_DRV_MXC=y
176CONFIG_DMADEVICES=y 177CONFIG_DMADEVICES=y
177CONFIG_IMX_SDMA=y 178CONFIG_IMX_SDMA=y
178CONFIG_IMX_DMA=y 179CONFIG_IMX_DMA=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index dc6f6411bbf..b1d3675df72 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -64,6 +64,12 @@ CONFIG_IPV6=y
64# CONFIG_WIRELESS is not set 64# CONFIG_WIRELESS is not set
65CONFIG_DEVTMPFS=y 65CONFIG_DEVTMPFS=y
66CONFIG_DEVTMPFS_MOUNT=y 66CONFIG_DEVTMPFS_MOUNT=y
67CONFIG_MTD=y
68CONFIG_MTD_OF_PARTS=y
69CONFIG_MTD_CHAR=y
70CONFIG_MTD_DATAFLASH=y
71CONFIG_MTD_M25P80=y
72CONFIG_MTD_SST25L=y
67# CONFIG_STANDALONE is not set 73# CONFIG_STANDALONE is not set
68CONFIG_CONNECTOR=y 74CONFIG_CONNECTOR=y
69CONFIG_BLK_DEV_LOOP=y 75CONFIG_BLK_DEV_LOOP=y
@@ -172,7 +178,7 @@ CONFIG_NEW_LEDS=y
172CONFIG_LEDS_CLASS=y 178CONFIG_LEDS_CLASS=y
173CONFIG_RTC_CLASS=y 179CONFIG_RTC_CLASS=y
174CONFIG_RTC_INTF_DEV_UIE_EMUL=y 180CONFIG_RTC_INTF_DEV_UIE_EMUL=y
175CONFIG_RTC_MXC=y 181CONFIG_RTC_DRV_MXC=y
176CONFIG_DMADEVICES=y 182CONFIG_DMADEVICES=y
177CONFIG_IMX_SDMA=y 183CONFIG_IMX_SDMA=y
178CONFIG_EXT2_FS=y 184CONFIG_EXT2_FS=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 1ebbf451c48..5406c23a02e 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -22,6 +22,7 @@ CONFIG_BLK_DEV_INTEGRITY=y
22# CONFIG_IOSCHED_DEADLINE is not set 22# CONFIG_IOSCHED_DEADLINE is not set
23# CONFIG_IOSCHED_CFQ is not set 23# CONFIG_IOSCHED_CFQ is not set
24CONFIG_ARCH_MXS=y 24CONFIG_ARCH_MXS=y
25CONFIG_MACH_MXS_DT=y
25CONFIG_MACH_MX23EVK=y 26CONFIG_MACH_MX23EVK=y
26CONFIG_MACH_MX28EVK=y 27CONFIG_MACH_MX28EVK=y
27CONFIG_MACH_STMP378X_DEVB=y 28CONFIG_MACH_STMP378X_DEVB=y
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig
new file mode 100644
index 00000000000..c328ac65479
--- /dev/null
+++ b/arch/arm/configs/prima2_defconfig
@@ -0,0 +1,69 @@
1CONFIG_EXPERIMENTAL=y
2CONFIG_RELAY=y
3CONFIG_BLK_DEV_INITRD=y
4CONFIG_KALLSYMS_ALL=y
5CONFIG_MODULES=y
6CONFIG_MODULE_UNLOAD=y
7# CONFIG_BLK_DEV_BSG is not set
8CONFIG_PARTITION_ADVANCED=y
9CONFIG_BSD_DISKLABEL=y
10CONFIG_SOLARIS_X86_PARTITION=y
11CONFIG_ARCH_PRIMA2=y
12CONFIG_NO_HZ=y
13CONFIG_HIGH_RES_TIMERS=y
14CONFIG_PREEMPT=y
15CONFIG_AEABI=y
16CONFIG_KEXEC=y
17CONFIG_BINFMT_MISC=y
18CONFIG_PM_RUNTIME=y
19CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
20CONFIG_BLK_DEV_LOOP=y
21CONFIG_BLK_DEV_RAM=y
22CONFIG_BLK_DEV_RAM_SIZE=8192
23CONFIG_SCSI=y
24CONFIG_BLK_DEV_SD=y
25CONFIG_CHR_DEV_SG=y
26CONFIG_INPUT_EVDEV=y
27# CONFIG_INPUT_MOUSE is not set
28CONFIG_INPUT_TOUCHSCREEN=y
29CONFIG_SERIAL_SIRFSOC=y
30CONFIG_SERIAL_SIRFSOC_CONSOLE=y
31CONFIG_HW_RANDOM=y
32CONFIG_I2C=y
33CONFIG_I2C_CHARDEV=y
34CONFIG_I2C_SIRF=y
35CONFIG_SPI=y
36CONFIG_SPI_SIRF=y
37CONFIG_SPI_SPIDEV=y
38# CONFIG_HWMON is not set
39# CONFIG_HID_SUPPORT is not set
40CONFIG_USB_GADGET=y
41CONFIG_USB_FILE_STORAGE=m
42CONFIG_USB_MASS_STORAGE=m
43CONFIG_MMC=y
44CONFIG_MMC_SDHCI=y
45CONFIG_MMC_SDHCI_PLTFM=y
46CONFIG_DMADEVICES=y
47CONFIG_DMADEVICES_DEBUG=y
48CONFIG_DMADEVICES_VDEBUG=y
49CONFIG_SIRF_DMA=y
50# CONFIG_IOMMU_SUPPORT is not set
51CONFIG_EXT2_FS=y
52CONFIG_MSDOS_FS=y
53CONFIG_VFAT_FS=y
54CONFIG_TMPFS=y
55CONFIG_TMPFS_POSIX_ACL=y
56CONFIG_CRAMFS=y
57CONFIG_ROMFS_FS=y
58CONFIG_NLS_CODEPAGE_437=y
59CONFIG_NLS_ASCII=y
60CONFIG_NLS_ISO8859_1=y
61CONFIG_MAGIC_SYSRQ=y
62CONFIG_DEBUG_SECTION_MISMATCH=y
63CONFIG_DEBUG_KERNEL=y
64# CONFIG_DEBUG_PREEMPT is not set
65CONFIG_DEBUG_RT_MUTEXES=y
66CONFIG_DEBUG_SPINLOCK=y
67CONFIG_DEBUG_MUTEXES=y
68CONFIG_DEBUG_INFO=y
69CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
new file mode 100644
index 00000000000..1fdb82694ca
--- /dev/null
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -0,0 +1,95 @@
1CONFIG_EXPERIMENTAL=y
2CONFIG_SYSVIPC=y
3CONFIG_BSD_PROCESS_ACCT=y
4CONFIG_BLK_DEV_INITRD=y
5CONFIG_MODULES=y
6CONFIG_MODULE_UNLOAD=y
7CONFIG_MODVERSIONS=y
8CONFIG_PARTITION_ADVANCED=y
9CONFIG_PLAT_SPEAR=y
10CONFIG_ARCH_SPEAR13XX=y
11CONFIG_MACH_SPEAR1310=y
12CONFIG_MACH_SPEAR1340=y
13# CONFIG_SWP_EMULATE is not set
14CONFIG_SMP=y
15# CONFIG_SMP_ON_UP is not set
16# CONFIG_ARM_CPU_TOPOLOGY is not set
17CONFIG_ARM_APPENDED_DTB=y
18CONFIG_ARM_ATAG_DTB_COMPAT=y
19CONFIG_BINFMT_MISC=y
20CONFIG_NET=y
21CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
22CONFIG_MTD=y
23CONFIG_MTD_OF_PARTS=y
24CONFIG_MTD_CHAR=y
25CONFIG_MTD_BLOCK=y
26CONFIG_MTD_NAND=y
27CONFIG_MTD_NAND_FSMC=y
28CONFIG_BLK_DEV_RAM=y
29CONFIG_BLK_DEV_RAM_SIZE=16384
30CONFIG_ATA=y
31# CONFIG_SATA_PMP is not set
32CONFIG_SATA_AHCI_PLATFORM=y
33CONFIG_PATA_ARASAN_CF=y
34CONFIG_NETDEVICES=y
35# CONFIG_NET_VENDOR_BROADCOM is not set
36# CONFIG_NET_VENDOR_CIRRUS is not set
37# CONFIG_NET_VENDOR_FARADAY is not set
38# CONFIG_NET_VENDOR_INTEL is not set
39# CONFIG_NET_VENDOR_MICREL is not set
40# CONFIG_NET_VENDOR_NATSEMI is not set
41# CONFIG_NET_VENDOR_SEEQ is not set
42# CONFIG_NET_VENDOR_SMSC is not set
43CONFIG_STMMAC_ETH=y
44# CONFIG_WLAN is not set
45CONFIG_INPUT_FF_MEMLESS=y
46# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
47# CONFIG_KEYBOARD_ATKBD is not set
48CONFIG_KEYBOARD_SPEAR=y
49# CONFIG_INPUT_MOUSE is not set
50# CONFIG_LEGACY_PTYS is not set
51CONFIG_SERIAL_AMBA_PL011=y
52CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
53# CONFIG_HW_RANDOM is not set
54CONFIG_RAW_DRIVER=y
55CONFIG_MAX_RAW_DEVS=8192
56CONFIG_I2C=y
57CONFIG_I2C_DESIGNWARE_PLATFORM=y
58CONFIG_SPI=y
59CONFIG_SPI_PL022=y
60CONFIG_GPIO_SYSFS=y
61CONFIG_GPIO_PL061=y
62# CONFIG_HWMON is not set
63CONFIG_WATCHDOG=y
64CONFIG_MPCORE_WATCHDOG=y
65# CONFIG_HID_SUPPORT is not set
66CONFIG_USB=y
67# CONFIG_USB_DEVICE_CLASS is not set
68CONFIG_USB_EHCI_HCD=y
69CONFIG_USB_OHCI_HCD=y
70CONFIG_MMC=y
71CONFIG_MMC_SDHCI=y
72CONFIG_MMC_SDHCI_SPEAR=y
73CONFIG_RTC_CLASS=y
74CONFIG_DMADEVICES=y
75CONFIG_DW_DMAC=y
76CONFIG_DMATEST=m
77CONFIG_EXT2_FS=y
78CONFIG_EXT2_FS_XATTR=y
79CONFIG_EXT2_FS_SECURITY=y
80CONFIG_EXT3_FS=y
81CONFIG_EXT3_FS_SECURITY=y
82CONFIG_AUTOFS4_FS=m
83CONFIG_MSDOS_FS=m
84CONFIG_VFAT_FS=m
85CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
86CONFIG_TMPFS=y
87CONFIG_JFFS2_FS=y
88CONFIG_NLS_DEFAULT="utf8"
89CONFIG_NLS_CODEPAGE_437=y
90CONFIG_NLS_ASCII=m
91CONFIG_MAGIC_SYSRQ=y
92CONFIG_DEBUG_FS=y
93CONFIG_DEBUG_KERNEL=y
94CONFIG_DEBUG_SPINLOCK=y
95CONFIG_DEBUG_INFO=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
index 7ed42912d69..865980c5f21 100644
--- a/arch/arm/configs/spear3xx_defconfig
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -14,6 +14,9 @@ CONFIG_BINFMT_MISC=y
14CONFIG_NET=y 14CONFIG_NET=y
15CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 15CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
16CONFIG_MTD=y 16CONFIG_MTD=y
17CONFIG_MTD_OF_PARTS=y
18CONFIG_MTD_CHAR=y
19CONFIG_MTD_BLOCK=y
17CONFIG_MTD_NAND=y 20CONFIG_MTD_NAND=y
18CONFIG_MTD_NAND_FSMC=y 21CONFIG_MTD_NAND_FSMC=y
19CONFIG_BLK_DEV_RAM=y 22CONFIG_BLK_DEV_RAM=y
@@ -73,6 +76,7 @@ CONFIG_MSDOS_FS=m
73CONFIG_VFAT_FS=m 76CONFIG_VFAT_FS=m
74CONFIG_FAT_DEFAULT_IOCHARSET="ascii" 77CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
75CONFIG_TMPFS=y 78CONFIG_TMPFS=y
79CONFIG_JFFS2_FS=y
76CONFIG_NLS_DEFAULT="utf8" 80CONFIG_NLS_DEFAULT="utf8"
77CONFIG_NLS_CODEPAGE_437=y 81CONFIG_NLS_CODEPAGE_437=y
78CONFIG_NLS_ASCII=m 82CONFIG_NLS_ASCII=m
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
index cf94bc73a0e..a2a1265f86b 100644
--- a/arch/arm/configs/spear6xx_defconfig
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -8,11 +8,13 @@ CONFIG_MODVERSIONS=y
8CONFIG_PARTITION_ADVANCED=y 8CONFIG_PARTITION_ADVANCED=y
9CONFIG_PLAT_SPEAR=y 9CONFIG_PLAT_SPEAR=y
10CONFIG_ARCH_SPEAR6XX=y 10CONFIG_ARCH_SPEAR6XX=y
11CONFIG_BOARD_SPEAR600_DT=y
12CONFIG_BINFMT_MISC=y 11CONFIG_BINFMT_MISC=y
13CONFIG_NET=y 12CONFIG_NET=y
14CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 13CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
15CONFIG_MTD=y 14CONFIG_MTD=y
15CONFIG_MTD_OF_PARTS=y
16CONFIG_MTD_CHAR=y
17CONFIG_MTD_BLOCK=y
16CONFIG_MTD_NAND=y 18CONFIG_MTD_NAND=y
17CONFIG_MTD_NAND_FSMC=y 19CONFIG_MTD_NAND_FSMC=y
18CONFIG_BLK_DEV_RAM=y 20CONFIG_BLK_DEV_RAM=y
@@ -64,6 +66,7 @@ CONFIG_MSDOS_FS=m
64CONFIG_VFAT_FS=m 66CONFIG_VFAT_FS=m
65CONFIG_FAT_DEFAULT_IOCHARSET="ascii" 67CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
66CONFIG_TMPFS=y 68CONFIG_TMPFS=y
69CONFIG_JFFS2_FS=y
67CONFIG_NLS_DEFAULT="utf8" 70CONFIG_NLS_DEFAULT="utf8"
68CONFIG_NLS_CODEPAGE_437=y 71CONFIG_NLS_CODEPAGE_437=y
69CONFIG_NLS_ASCII=m 72CONFIG_NLS_ASCII=m
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 351d6708c3a..1198dd61c7c 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -45,6 +45,7 @@ CONFIG_CPU_FREQ=y
45CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y 45CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
46CONFIG_CPU_IDLE=y 46CONFIG_CPU_IDLE=y
47CONFIG_VFP=y 47CONFIG_VFP=y
48CONFIG_PM_RUNTIME=y
48CONFIG_NET=y 49CONFIG_NET=y
49CONFIG_PACKET=y 50CONFIG_PACKET=y
50CONFIG_UNIX=y 51CONFIG_UNIX=y
@@ -91,6 +92,8 @@ CONFIG_USB_NET_SMSC75XX=y
91CONFIG_USB_NET_SMSC95XX=y 92CONFIG_USB_NET_SMSC95XX=y
92# CONFIG_WLAN is not set 93# CONFIG_WLAN is not set
93CONFIG_INPUT_EVDEV=y 94CONFIG_INPUT_EVDEV=y
95CONFIG_INPUT_MISC=y
96CONFIG_INPUT_MPU3050=y
94# CONFIG_VT is not set 97# CONFIG_VT is not set
95# CONFIG_LEGACY_PTYS is not set 98# CONFIG_LEGACY_PTYS is not set
96# CONFIG_DEVKMEM is not set 99# CONFIG_DEVKMEM is not set
@@ -103,12 +106,15 @@ CONFIG_I2C=y
103CONFIG_I2C_TEGRA=y 106CONFIG_I2C_TEGRA=y
104CONFIG_SPI=y 107CONFIG_SPI=y
105CONFIG_SPI_TEGRA=y 108CONFIG_SPI_TEGRA=y
109CONFIG_POWER_SUPPLY=y
110CONFIG_BATTERY_SBS=y
106CONFIG_SENSORS_LM90=y 111CONFIG_SENSORS_LM90=y
107CONFIG_MFD_TPS6586X=y 112CONFIG_MFD_TPS6586X=y
108CONFIG_REGULATOR=y 113CONFIG_REGULATOR=y
109CONFIG_REGULATOR_FIXED_VOLTAGE=y 114CONFIG_REGULATOR_FIXED_VOLTAGE=y
110CONFIG_REGULATOR_VIRTUAL_CONSUMER=y 115CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
111CONFIG_REGULATOR_GPIO=y 116CONFIG_REGULATOR_GPIO=y
117CONFIG_REGULATOR_TPS62360=y
112CONFIG_REGULATOR_TPS6586X=y 118CONFIG_REGULATOR_TPS6586X=y
113CONFIG_SOUND=y 119CONFIG_SOUND=y
114CONFIG_SND=y 120CONFIG_SND=y
@@ -133,16 +139,19 @@ CONFIG_MMC_SDHCI=y
133CONFIG_MMC_SDHCI_PLTFM=y 139CONFIG_MMC_SDHCI_PLTFM=y
134CONFIG_MMC_SDHCI_TEGRA=y 140CONFIG_MMC_SDHCI_TEGRA=y
135CONFIG_RTC_CLASS=y 141CONFIG_RTC_CLASS=y
142CONFIG_RTC_DRV_EM3027=y
136CONFIG_RTC_DRV_TEGRA=y 143CONFIG_RTC_DRV_TEGRA=y
137CONFIG_STAGING=y 144CONFIG_STAGING=y
138CONFIG_IIO=y
139CONFIG_SENSORS_ISL29018=y 145CONFIG_SENSORS_ISL29018=y
146CONFIG_SENSORS_ISL29028=y
140CONFIG_SENSORS_AK8975=y 147CONFIG_SENSORS_AK8975=y
141CONFIG_MFD_NVEC=y 148CONFIG_MFD_NVEC=y
142CONFIG_KEYBOARD_NVEC=y 149CONFIG_KEYBOARD_NVEC=y
143CONFIG_SERIO_NVEC_PS2=y 150CONFIG_SERIO_NVEC_PS2=y
144CONFIG_TEGRA_IOMMU_GART=y 151CONFIG_TEGRA_IOMMU_GART=y
145CONFIG_TEGRA_IOMMU_SMMU=y 152CONFIG_TEGRA_IOMMU_SMMU=y
153CONFIG_MEMORY=y
154CONFIG_IIO=y
146CONFIG_EXT2_FS=y 155CONFIG_EXT2_FS=y
147CONFIG_EXT2_FS_XATTR=y 156CONFIG_EXT2_FS_XATTR=y
148CONFIG_EXT2_FS_POSIX_ACL=y 157CONFIG_EXT2_FS_POSIX_ACL=y
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 7aa368003b0..b69c0d3285f 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -7,12 +7,16 @@
7#define ASMARM_DEVICE_H 7#define ASMARM_DEVICE_H
8 8
9struct dev_archdata { 9struct dev_archdata {
10 struct dma_map_ops *dma_ops;
10#ifdef CONFIG_DMABOUNCE 11#ifdef CONFIG_DMABOUNCE
11 struct dmabounce_device_info *dmabounce; 12 struct dmabounce_device_info *dmabounce;
12#endif 13#endif
13#ifdef CONFIG_IOMMU_API 14#ifdef CONFIG_IOMMU_API
14 void *iommu; /* private IOMMU data */ 15 void *iommu; /* private IOMMU data */
15#endif 16#endif
17#ifdef CONFIG_ARM_DMA_USE_IOMMU
18 struct dma_iommu_mapping *mapping;
19#endif
16}; 20};
17 21
18struct omap_device; 22struct omap_device;
diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h
new file mode 100644
index 00000000000..3ed37b4d93d
--- /dev/null
+++ b/arch/arm/include/asm/dma-contiguous.h
@@ -0,0 +1,15 @@
1#ifndef ASMARM_DMA_CONTIGUOUS_H
2#define ASMARM_DMA_CONTIGUOUS_H
3
4#ifdef __KERNEL__
5#ifdef CONFIG_CMA
6
7#include <linux/types.h>
8#include <asm-generic/dma-contiguous.h>
9
10void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
11
12#endif
13#endif
14
15#endif
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
new file mode 100644
index 00000000000..799b09409fa
--- /dev/null
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -0,0 +1,34 @@
1#ifndef ASMARM_DMA_IOMMU_H
2#define ASMARM_DMA_IOMMU_H
3
4#ifdef __KERNEL__
5
6#include <linux/mm_types.h>
7#include <linux/scatterlist.h>
8#include <linux/dma-debug.h>
9#include <linux/kmemcheck.h>
10
11struct dma_iommu_mapping {
12 /* iommu specific data */
13 struct iommu_domain *domain;
14
15 void *bitmap;
16 size_t bits;
17 unsigned int order;
18 dma_addr_t base;
19
20 spinlock_t lock;
21 struct kref kref;
22};
23
24struct dma_iommu_mapping *
25arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
26 int order);
27
28void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
29
30int arm_iommu_attach_device(struct device *dev,
31 struct dma_iommu_mapping *mapping);
32
33#endif /* __KERNEL__ */
34#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index cb3b7c981c4..bbef15d0489 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,11 +5,35 @@
5 5
6#include <linux/mm_types.h> 6#include <linux/mm_types.h>
7#include <linux/scatterlist.h> 7#include <linux/scatterlist.h>
8#include <linux/dma-attrs.h>
8#include <linux/dma-debug.h> 9#include <linux/dma-debug.h>
9 10
10#include <asm-generic/dma-coherent.h> 11#include <asm-generic/dma-coherent.h>
11#include <asm/memory.h> 12#include <asm/memory.h>
12 13
14#define DMA_ERROR_CODE (~0)
15extern struct dma_map_ops arm_dma_ops;
16
17static inline struct dma_map_ops *get_dma_ops(struct device *dev)
18{
19 if (dev && dev->archdata.dma_ops)
20 return dev->archdata.dma_ops;
21 return &arm_dma_ops;
22}
23
24static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
25{
26 BUG_ON(!dev);
27 dev->archdata.dma_ops = ops;
28}
29
30#include <asm-generic/dma-mapping-common.h>
31
32static inline int dma_set_mask(struct device *dev, u64 mask)
33{
34 return get_dma_ops(dev)->set_dma_mask(dev, mask);
35}
36
13#ifdef __arch_page_to_dma 37#ifdef __arch_page_to_dma
14#error Please update to __arch_pfn_to_dma 38#error Please update to __arch_pfn_to_dma
15#endif 39#endif
@@ -62,68 +86,11 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
62#endif 86#endif
63 87
64/* 88/*
65 * The DMA API is built upon the notion of "buffer ownership". A buffer
66 * is either exclusively owned by the CPU (and therefore may be accessed
67 * by it) or exclusively owned by the DMA device. These helper functions
68 * represent the transitions between these two ownership states.
69 *
70 * Note, however, that on later ARMs, this notion does not work due to
71 * speculative prefetches. We model our approach on the assumption that
72 * the CPU does do speculative prefetches, which means we clean caches
73 * before transfers and delay cache invalidation until transfer completion.
74 *
75 * Private support functions: these are not part of the API and are
76 * liable to change. Drivers must not use these.
77 */
78static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
79 enum dma_data_direction dir)
80{
81 extern void ___dma_single_cpu_to_dev(const void *, size_t,
82 enum dma_data_direction);
83
84 if (!arch_is_coherent())
85 ___dma_single_cpu_to_dev(kaddr, size, dir);
86}
87
88static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
89 enum dma_data_direction dir)
90{
91 extern void ___dma_single_dev_to_cpu(const void *, size_t,
92 enum dma_data_direction);
93
94 if (!arch_is_coherent())
95 ___dma_single_dev_to_cpu(kaddr, size, dir);
96}
97
98static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
99 size_t size, enum dma_data_direction dir)
100{
101 extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
102 size_t, enum dma_data_direction);
103
104 if (!arch_is_coherent())
105 ___dma_page_cpu_to_dev(page, off, size, dir);
106}
107
108static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
109 size_t size, enum dma_data_direction dir)
110{
111 extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
112 size_t, enum dma_data_direction);
113
114 if (!arch_is_coherent())
115 ___dma_page_dev_to_cpu(page, off, size, dir);
116}
117
118extern int dma_supported(struct device *, u64);
119extern int dma_set_mask(struct device *, u64);
120
121/*
122 * DMA errors are defined by all-bits-set in the DMA address. 89 * DMA errors are defined by all-bits-set in the DMA address.
123 */ 90 */
124static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 91static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
125{ 92{
126 return dma_addr == ~0; 93 return dma_addr == DMA_ERROR_CODE;
127} 94}
128 95
129/* 96/*
@@ -141,69 +108,118 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
141{ 108{
142} 109}
143 110
111extern int dma_supported(struct device *dev, u64 mask);
112
144/** 113/**
145 * dma_alloc_coherent - allocate consistent memory for DMA 114 * arm_dma_alloc - allocate consistent memory for DMA
146 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 115 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
147 * @size: required memory size 116 * @size: required memory size
148 * @handle: bus-specific DMA address 117 * @handle: bus-specific DMA address
118 * @attrs: optinal attributes that specific mapping properties
149 * 119 *
150 * Allocate some uncached, unbuffered memory for a device for 120 * Allocate some memory for a device for performing DMA. This function
151 * performing DMA. This function allocates pages, and will 121 * allocates pages, and will return the CPU-viewed address, and sets @handle
152 * return the CPU-viewed address, and sets @handle to be the 122 * to be the device-viewed address.
153 * device-viewed address.
154 */ 123 */
155extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); 124extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
125 gfp_t gfp, struct dma_attrs *attrs);
126
127#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
128
129static inline void *dma_alloc_attrs(struct device *dev, size_t size,
130 dma_addr_t *dma_handle, gfp_t flag,
131 struct dma_attrs *attrs)
132{
133 struct dma_map_ops *ops = get_dma_ops(dev);
134 void *cpu_addr;
135 BUG_ON(!ops);
136
137 cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
138 debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
139 return cpu_addr;
140}
156 141
157/** 142/**
158 * dma_free_coherent - free memory allocated by dma_alloc_coherent 143 * arm_dma_free - free memory allocated by arm_dma_alloc
159 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 144 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
160 * @size: size of memory originally requested in dma_alloc_coherent 145 * @size: size of memory originally requested in dma_alloc_coherent
161 * @cpu_addr: CPU-view address returned from dma_alloc_coherent 146 * @cpu_addr: CPU-view address returned from dma_alloc_coherent
162 * @handle: device-view address returned from dma_alloc_coherent 147 * @handle: device-view address returned from dma_alloc_coherent
148 * @attrs: optinal attributes that specific mapping properties
163 * 149 *
164 * Free (and unmap) a DMA buffer previously allocated by 150 * Free (and unmap) a DMA buffer previously allocated by
165 * dma_alloc_coherent(). 151 * arm_dma_alloc().
166 * 152 *
167 * References to memory and mappings associated with cpu_addr/handle 153 * References to memory and mappings associated with cpu_addr/handle
168 * during and after this call executing are illegal. 154 * during and after this call executing are illegal.
169 */ 155 */
170extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); 156extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
157 dma_addr_t handle, struct dma_attrs *attrs);
158
159#define dma_free_coherent(d, s, c, h) dma_free_attrs(d, s, c, h, NULL)
160
161static inline void dma_free_attrs(struct device *dev, size_t size,
162 void *cpu_addr, dma_addr_t dma_handle,
163 struct dma_attrs *attrs)
164{
165 struct dma_map_ops *ops = get_dma_ops(dev);
166 BUG_ON(!ops);
167
168 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
169 ops->free(dev, size, cpu_addr, dma_handle, attrs);
170}
171 171
172/** 172/**
173 * dma_mmap_coherent - map a coherent DMA allocation into user space 173 * arm_dma_mmap - map a coherent DMA allocation into user space
174 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 174 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
175 * @vma: vm_area_struct describing requested user mapping 175 * @vma: vm_area_struct describing requested user mapping
176 * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent 176 * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent
177 * @handle: device-view address returned from dma_alloc_coherent 177 * @handle: device-view address returned from dma_alloc_coherent
178 * @size: size of memory originally requested in dma_alloc_coherent 178 * @size: size of memory originally requested in dma_alloc_coherent
179 * @attrs: optinal attributes that specific mapping properties
179 * 180 *
180 * Map a coherent DMA buffer previously allocated by dma_alloc_coherent 181 * Map a coherent DMA buffer previously allocated by dma_alloc_coherent
181 * into user space. The coherent DMA buffer must not be freed by the 182 * into user space. The coherent DMA buffer must not be freed by the
182 * driver until the user space mapping has been released. 183 * driver until the user space mapping has been released.
183 */ 184 */
184int dma_mmap_coherent(struct device *, struct vm_area_struct *, 185extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
185 void *, dma_addr_t, size_t); 186 void *cpu_addr, dma_addr_t dma_addr, size_t size,
187 struct dma_attrs *attrs);
186 188
189#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
187 190
188/** 191static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
189 * dma_alloc_writecombine - allocate writecombining memory for DMA 192 void *cpu_addr, dma_addr_t dma_addr,
190 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 193 size_t size, struct dma_attrs *attrs)
191 * @size: required memory size 194{
192 * @handle: bus-specific DMA address 195 struct dma_map_ops *ops = get_dma_ops(dev);
193 * 196 BUG_ON(!ops);
194 * Allocate some uncached, buffered memory for a device for 197 return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
195 * performing DMA. This function allocates pages, and will 198}
196 * return the CPU-viewed address, and sets @handle to be the 199
197 * device-viewed address. 200static inline void *dma_alloc_writecombine(struct device *dev, size_t size,
198 */ 201 dma_addr_t *dma_handle, gfp_t flag)
199extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *, 202{
200 gfp_t); 203 DEFINE_DMA_ATTRS(attrs);
204 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
205 return dma_alloc_attrs(dev, size, dma_handle, flag, &attrs);
206}
201 207
202#define dma_free_writecombine(dev,size,cpu_addr,handle) \ 208static inline void dma_free_writecombine(struct device *dev, size_t size,
203 dma_free_coherent(dev,size,cpu_addr,handle) 209 void *cpu_addr, dma_addr_t dma_handle)
210{
211 DEFINE_DMA_ATTRS(attrs);
212 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
213 return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
214}
204 215
205int dma_mmap_writecombine(struct device *, struct vm_area_struct *, 216static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
206 void *, dma_addr_t, size_t); 217 void *cpu_addr, dma_addr_t dma_addr, size_t size)
218{
219 DEFINE_DMA_ATTRS(attrs);
220 dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
221 return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
222}
207 223
208/* 224/*
209 * This can be called during boot to increase the size of the consistent 225 * This can be called during boot to increase the size of the consistent
@@ -212,8 +228,6 @@ int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
212 */ 228 */
213extern void __init init_consistent_dma_size(unsigned long size); 229extern void __init init_consistent_dma_size(unsigned long size);
214 230
215
216#ifdef CONFIG_DMABOUNCE
217/* 231/*
218 * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" 232 * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
219 * and utilize bounce buffers as needed to work around limited DMA windows. 233 * and utilize bounce buffers as needed to work around limited DMA windows.
@@ -253,222 +267,19 @@ extern int dmabounce_register_dev(struct device *, unsigned long,
253 */ 267 */
254extern void dmabounce_unregister_dev(struct device *); 268extern void dmabounce_unregister_dev(struct device *);
255 269
256/*
257 * The DMA API, implemented by dmabounce.c. See below for descriptions.
258 */
259extern dma_addr_t __dma_map_page(struct device *, struct page *,
260 unsigned long, size_t, enum dma_data_direction);
261extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
262 enum dma_data_direction);
263
264/*
265 * Private functions
266 */
267int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
268 size_t, enum dma_data_direction);
269int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
270 size_t, enum dma_data_direction);
271#else
272static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr,
273 unsigned long offset, size_t size, enum dma_data_direction dir)
274{
275 return 1;
276}
277 270
278static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
279 unsigned long offset, size_t size, enum dma_data_direction dir)
280{
281 return 1;
282}
283
284
285static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
286 unsigned long offset, size_t size, enum dma_data_direction dir)
287{
288 __dma_page_cpu_to_dev(page, offset, size, dir);
289 return pfn_to_dma(dev, page_to_pfn(page)) + offset;
290}
291
292static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
293 size_t size, enum dma_data_direction dir)
294{
295 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
296 handle & ~PAGE_MASK, size, dir);
297}
298#endif /* CONFIG_DMABOUNCE */
299
300/**
301 * dma_map_single - map a single buffer for streaming DMA
302 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
303 * @cpu_addr: CPU direct mapped address of buffer
304 * @size: size of buffer to map
305 * @dir: DMA transfer direction
306 *
307 * Ensure that any data held in the cache is appropriately discarded
308 * or written back.
309 *
310 * The device owns this memory once this call has completed. The CPU
311 * can regain ownership by calling dma_unmap_single() or
312 * dma_sync_single_for_cpu().
313 */
314static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
315 size_t size, enum dma_data_direction dir)
316{
317 unsigned long offset;
318 struct page *page;
319 dma_addr_t addr;
320
321 BUG_ON(!virt_addr_valid(cpu_addr));
322 BUG_ON(!virt_addr_valid(cpu_addr + size - 1));
323 BUG_ON(!valid_dma_direction(dir));
324
325 page = virt_to_page(cpu_addr);
326 offset = (unsigned long)cpu_addr & ~PAGE_MASK;
327 addr = __dma_map_page(dev, page, offset, size, dir);
328 debug_dma_map_page(dev, page, offset, size, dir, addr, true);
329
330 return addr;
331}
332
333/**
334 * dma_map_page - map a portion of a page for streaming DMA
335 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
336 * @page: page that buffer resides in
337 * @offset: offset into page for start of buffer
338 * @size: size of buffer to map
339 * @dir: DMA transfer direction
340 *
341 * Ensure that any data held in the cache is appropriately discarded
342 * or written back.
343 *
344 * The device owns this memory once this call has completed. The CPU
345 * can regain ownership by calling dma_unmap_page().
346 */
347static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
348 unsigned long offset, size_t size, enum dma_data_direction dir)
349{
350 dma_addr_t addr;
351
352 BUG_ON(!valid_dma_direction(dir));
353
354 addr = __dma_map_page(dev, page, offset, size, dir);
355 debug_dma_map_page(dev, page, offset, size, dir, addr, false);
356
357 return addr;
358}
359
360/**
361 * dma_unmap_single - unmap a single buffer previously mapped
362 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
363 * @handle: DMA address of buffer
364 * @size: size of buffer (same as passed to dma_map_single)
365 * @dir: DMA transfer direction (same as passed to dma_map_single)
366 *
367 * Unmap a single streaming mode DMA translation. The handle and size
368 * must match what was provided in the previous dma_map_single() call.
369 * All other usages are undefined.
370 *
371 * After this call, reads by the CPU to the buffer are guaranteed to see
372 * whatever the device wrote there.
373 */
374static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
375 size_t size, enum dma_data_direction dir)
376{
377 debug_dma_unmap_page(dev, handle, size, dir, true);
378 __dma_unmap_page(dev, handle, size, dir);
379}
380
381/**
382 * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
383 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
384 * @handle: DMA address of buffer
385 * @size: size of buffer (same as passed to dma_map_page)
386 * @dir: DMA transfer direction (same as passed to dma_map_page)
387 *
388 * Unmap a page streaming mode DMA translation. The handle and size
389 * must match what was provided in the previous dma_map_page() call.
390 * All other usages are undefined.
391 *
392 * After this call, reads by the CPU to the buffer are guaranteed to see
393 * whatever the device wrote there.
394 */
395static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
396 size_t size, enum dma_data_direction dir)
397{
398 debug_dma_unmap_page(dev, handle, size, dir, false);
399 __dma_unmap_page(dev, handle, size, dir);
400}
401
402/**
403 * dma_sync_single_range_for_cpu
404 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
405 * @handle: DMA address of buffer
406 * @offset: offset of region to start sync
407 * @size: size of region to sync
408 * @dir: DMA transfer direction (same as passed to dma_map_single)
409 *
410 * Make physical memory consistent for a single streaming mode DMA
411 * translation after a transfer.
412 *
413 * If you perform a dma_map_single() but wish to interrogate the
414 * buffer using the cpu, yet do not wish to teardown the PCI dma
415 * mapping, you must call this function before doing so. At the
416 * next point you give the PCI dma address back to the card, you
417 * must first the perform a dma_sync_for_device, and then the
418 * device again owns the buffer.
419 */
420static inline void dma_sync_single_range_for_cpu(struct device *dev,
421 dma_addr_t handle, unsigned long offset, size_t size,
422 enum dma_data_direction dir)
423{
424 BUG_ON(!valid_dma_direction(dir));
425
426 debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
427
428 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
429 return;
430
431 __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
432}
433
434static inline void dma_sync_single_range_for_device(struct device *dev,
435 dma_addr_t handle, unsigned long offset, size_t size,
436 enum dma_data_direction dir)
437{
438 BUG_ON(!valid_dma_direction(dir));
439
440 debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
441
442 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
443 return;
444
445 __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
446}
447
448static inline void dma_sync_single_for_cpu(struct device *dev,
449 dma_addr_t handle, size_t size, enum dma_data_direction dir)
450{
451 dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
452}
453
454static inline void dma_sync_single_for_device(struct device *dev,
455 dma_addr_t handle, size_t size, enum dma_data_direction dir)
456{
457 dma_sync_single_range_for_device(dev, handle, 0, size, dir);
458}
459 271
460/* 272/*
461 * The scatter list versions of the above methods. 273 * The scatter list versions of the above methods.
462 */ 274 */
463extern int dma_map_sg(struct device *, struct scatterlist *, int, 275extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
464 enum dma_data_direction); 276 enum dma_data_direction, struct dma_attrs *attrs);
465extern void dma_unmap_sg(struct device *, struct scatterlist *, int, 277extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
278 enum dma_data_direction, struct dma_attrs *attrs);
279extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
466 enum dma_data_direction); 280 enum dma_data_direction);
467extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int, 281extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
468 enum dma_data_direction); 282 enum dma_data_direction);
469extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
470 enum dma_data_direction);
471
472 283
473#endif /* __KERNEL__ */ 284#endif /* __KERNEL__ */
474#endif 285#endif
diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h
index 33c78d7af2e..4eea2107214 100644
--- a/arch/arm/include/asm/hardware/pl080.h
+++ b/arch/arm/include/asm/hardware/pl080.h
@@ -102,6 +102,8 @@
102#define PL080_WIDTH_16BIT (0x1) 102#define PL080_WIDTH_16BIT (0x1)
103#define PL080_WIDTH_32BIT (0x2) 103#define PL080_WIDTH_32BIT (0x2)
104 104
105#define PL080N_CONFIG_ITPROT (1 << 20)
106#define PL080N_CONFIG_SECPROT (1 << 19)
105#define PL080_CONFIG_HALT (1 << 18) 107#define PL080_CONFIG_HALT (1 << 18)
106#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */ 108#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */
107#define PL080_CONFIG_LOCK (1 << 16) 109#define PL080_CONFIG_LOCK (1 << 16)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 9af5563dd3e..815c669fec0 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -47,9 +47,9 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
47extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); 47extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
48extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); 48extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
49 49
50#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) 50#define __raw_writeb(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)))
51#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) 51#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
52#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) 52#define __raw_writel(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)))
53 53
54#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) 54#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
55#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) 55#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
@@ -229,11 +229,9 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
229#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ 229#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
230 __raw_readl(c)); __r; }) 230 __raw_readl(c)); __r; })
231 231
232#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c)) 232#define writeb_relaxed(v,c) __raw_writeb(v,c)
233#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ 233#define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c)
234 cpu_to_le16(v),c)) 234#define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c)
235#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
236 cpu_to_le32(v),c))
237 235
238#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) 236#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
239#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) 237#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
@@ -281,12 +279,12 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
281#define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) 279#define ioread16be(p) ({ unsigned int __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
282#define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) 280#define ioread32be(p) ({ unsigned int __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
283 281
284#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); }) 282#define iowrite8(v,p) ({ __iowmb(); __raw_writeb(v, p); })
285#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); }) 283#define iowrite16(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_le16(v), p); })
286#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); }) 284#define iowrite32(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_le32(v), p); })
287 285
288#define iowrite16be(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_be16(v), p); }) 286#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
289#define iowrite32be(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_be32(v), p); }) 287#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
290 288
291#define ioread8_rep(p,d,c) __raw_readsb(p,d,c) 289#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
292#define ioread16_rep(p,d,c) __raw_readsw(p,d,c) 290#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
diff --git a/arch/arm/include/asm/kvm_para.h b/arch/arm/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/arm/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index d7692cafde7..0b1c94b8c65 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -43,6 +43,7 @@ struct machine_desc {
43 void (*init_irq)(void); 43 void (*init_irq)(void);
44 struct sys_timer *timer; /* system tick timer */ 44 struct sys_timer *timer; /* system tick timer */
45 void (*init_machine)(void); 45 void (*init_machine)(void);
46 void (*init_late)(void);
46#ifdef CONFIG_MULTI_IRQ_HANDLER 47#ifdef CONFIG_MULTI_IRQ_HANDLER
47 void (*handle_irq)(struct pt_regs *); 48 void (*handle_irq)(struct pt_regs *);
48#endif 49#endif
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index b36f3654bf5..a6efcdd6fd2 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -30,6 +30,7 @@ struct map_desc {
30#define MT_MEMORY_DTCM 12 30#define MT_MEMORY_DTCM 12
31#define MT_MEMORY_ITCM 13 31#define MT_MEMORY_ITCM 13
32#define MT_MEMORY_SO 14 32#define MT_MEMORY_SO 14
33#define MT_MEMORY_DMA_READY 15
33 34
34#ifdef CONFIG_MMU 35#ifdef CONFIG_MMU
35extern void iotable_init(struct map_desc *, int); 36extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 68388eb4946..b79f8e97f77 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -148,6 +148,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
148#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ 148#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
149#define TIF_SYSCALL_TRACE 8 149#define TIF_SYSCALL_TRACE 8
150#define TIF_SYSCALL_AUDIT 9 150#define TIF_SYSCALL_AUDIT 9
151#define TIF_SYSCALL_RESTARTSYS 10
151#define TIF_POLLING_NRFLAG 16 152#define TIF_POLLING_NRFLAG 16
152#define TIF_USING_IWMMXT 17 153#define TIF_USING_IWMMXT 17
153#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ 154#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@@ -162,16 +163,17 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
162#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) 163#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
163#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) 164#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
164#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) 165#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
165#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
166#define _TIF_SECCOMP (1 << TIF_SECCOMP) 166#define _TIF_SECCOMP (1 << TIF_SECCOMP)
167#define _TIF_SYSCALL_RESTARTSYS (1 << TIF_SYSCALL_RESTARTSYS)
167 168
168/* Checks for any syscall work in entry-common.S */ 169/* Checks for any syscall work in entry-common.S */
169#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) 170#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
171 _TIF_SYSCALL_RESTARTSYS)
170 172
171/* 173/*
172 * Change these and you break ASM code in entry-common.S 174 * Change these and you break ASM code in entry-common.S
173 */ 175 */
174#define _TIF_WORK_MASK 0x000000ff 176#define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | _TIF_NOTIFY_RESUME)
175 177
176#endif /* __KERNEL__ */ 178#endif /* __KERNEL__ */
177#endif /* __ASM_ARM_THREAD_INFO_H */ 179#endif /* __ASM_ARM_THREAD_INFO_H */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7bd2d3cb895..4afed88d250 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -53,9 +53,13 @@ fast_work_pending:
53work_pending: 53work_pending:
54 tst r1, #_TIF_NEED_RESCHED 54 tst r1, #_TIF_NEED_RESCHED
55 bne work_resched 55 bne work_resched
56 tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME 56 /*
57 beq no_work_pending 57 * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here
58 */
59 ldr r2, [sp, #S_PSR]
58 mov r0, sp @ 'regs' 60 mov r0, sp @ 'regs'
61 tst r2, #15 @ are we returning to user mode?
62 bne no_work_pending @ no? just leave, then...
59 mov r2, why @ 'syscall' 63 mov r2, why @ 'syscall'
60 tst r1, #_TIF_SIGPENDING @ delivering a signal? 64 tst r1, #_TIF_SIGPENDING @ delivering a signal?
61 movne why, #0 @ prevent further restarts 65 movne why, #0 @ prevent further restarts
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 14e38261cd3..5700a7ae7f0 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -25,6 +25,7 @@
25#include <linux/regset.h> 25#include <linux/regset.h>
26#include <linux/audit.h> 26#include <linux/audit.h>
27#include <linux/tracehook.h> 27#include <linux/tracehook.h>
28#include <linux/unistd.h>
28 29
29#include <asm/pgtable.h> 30#include <asm/pgtable.h>
30#include <asm/traps.h> 31#include <asm/traps.h>
@@ -917,6 +918,8 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
917 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, 918 audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0,
918 regs->ARM_r1, regs->ARM_r2, regs->ARM_r3); 919 regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
919 920
921 if (why == 0 && test_and_clear_thread_flag(TIF_SYSCALL_RESTARTSYS))
922 scno = __NR_restart_syscall - __NR_SYSCALL_BASE;
920 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 923 if (!test_thread_flag(TIF_SYSCALL_TRACE))
921 return scno; 924 return scno;
922 925
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ebfac782593..e15d83bb4ea 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -81,6 +81,7 @@ __setup("fpe=", fpe_setup);
81extern void paging_init(struct machine_desc *desc); 81extern void paging_init(struct machine_desc *desc);
82extern void sanity_check_meminfo(void); 82extern void sanity_check_meminfo(void);
83extern void reboot_setup(char *str); 83extern void reboot_setup(char *str);
84extern void setup_dma_zone(struct machine_desc *desc);
84 85
85unsigned int processor_id; 86unsigned int processor_id;
86EXPORT_SYMBOL(processor_id); 87EXPORT_SYMBOL(processor_id);
@@ -800,6 +801,14 @@ static int __init customize_machine(void)
800} 801}
801arch_initcall(customize_machine); 802arch_initcall(customize_machine);
802 803
804static int __init init_machine_late(void)
805{
806 if (machine_desc->init_late)
807 machine_desc->init_late();
808 return 0;
809}
810late_initcall(init_machine_late);
811
803#ifdef CONFIG_KEXEC 812#ifdef CONFIG_KEXEC
804static inline unsigned long long get_total_mem(void) 813static inline unsigned long long get_total_mem(void)
805{ 814{
@@ -939,12 +948,8 @@ void __init setup_arch(char **cmdline_p)
939 machine_desc = mdesc; 948 machine_desc = mdesc;
940 machine_name = mdesc->name; 949 machine_name = mdesc->name;
941 950
942#ifdef CONFIG_ZONE_DMA 951 setup_dma_zone(mdesc);
943 if (mdesc->dma_zone_size) { 952
944 extern unsigned long arm_dma_zone_size;
945 arm_dma_zone_size = mdesc->dma_zone_size;
946 }
947#endif
948 if (mdesc->restart_mode) 953 if (mdesc->restart_mode)
949 reboot_setup(&mdesc->restart_mode); 954 reboot_setup(&mdesc->restart_mode);
950 955
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 4e5fdd9bd9e..17fc36c41cf 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -29,7 +29,6 @@
29 */ 29 */
30#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 30#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
31#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) 31#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
32#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
33 32
34/* 33/*
35 * With EABI, the syscall number has to be loaded into r7. 34 * With EABI, the syscall number has to be loaded into r7.
@@ -50,18 +49,6 @@ const unsigned long sigreturn_codes[7] = {
50}; 49};
51 50
52/* 51/*
53 * Either we support OABI only, or we have EABI with the OABI
54 * compat layer enabled. In the later case we don't know if
55 * user space is EABI or not, and if not we must not clobber r7.
56 * Always using the OABI syscall solves that issue and works for
57 * all those cases.
58 */
59const unsigned long syscall_restart_code[2] = {
60 SWI_SYS_RESTART, /* swi __NR_restart_syscall */
61 0xe49df004, /* ldr pc, [sp], #4 */
62};
63
64/*
65 * atomically swap in the new signal mask, and wait for a signal. 52 * atomically swap in the new signal mask, and wait for a signal.
66 */ 53 */
67asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) 54asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
@@ -82,10 +69,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
82 old_sigset_t mask; 69 old_sigset_t mask;
83 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 70 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
84 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 71 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
85 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 72 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
73 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
74 __get_user(mask, &act->sa_mask))
86 return -EFAULT; 75 return -EFAULT;
87 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
88 __get_user(mask, &act->sa_mask);
89 siginitset(&new_ka.sa.sa_mask, mask); 76 siginitset(&new_ka.sa.sa_mask, mask);
90 } 77 }
91 78
@@ -94,10 +81,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
94 if (!ret && oact) { 81 if (!ret && oact) {
95 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 82 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
96 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 83 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
97 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 84 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
85 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
86 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
98 return -EFAULT; 87 return -EFAULT;
99 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
100 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
101 } 88 }
102 89
103 return ret; 90 return ret;
@@ -602,15 +589,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
602 int signr; 589 int signr;
603 590
604 /* 591 /*
605 * We want the common case to go fast, which
606 * is why we may in certain cases get here from
607 * kernel mode. Just return without doing anything
608 * if so.
609 */
610 if (!user_mode(regs))
611 return;
612
613 /*
614 * If we were from a system call, check for system call restarting... 592 * If we were from a system call, check for system call restarting...
615 */ 593 */
616 if (syscall) { 594 if (syscall) {
@@ -626,18 +604,13 @@ static void do_signal(struct pt_regs *regs, int syscall)
626 case -ERESTARTNOHAND: 604 case -ERESTARTNOHAND:
627 case -ERESTARTSYS: 605 case -ERESTARTSYS:
628 case -ERESTARTNOINTR: 606 case -ERESTARTNOINTR:
607 case -ERESTART_RESTARTBLOCK:
629 regs->ARM_r0 = regs->ARM_ORIG_r0; 608 regs->ARM_r0 = regs->ARM_ORIG_r0;
630 regs->ARM_pc = restart_addr; 609 regs->ARM_pc = restart_addr;
631 break; 610 break;
632 case -ERESTART_RESTARTBLOCK:
633 regs->ARM_r0 = -EINTR;
634 break;
635 } 611 }
636 } 612 }
637 613
638 if (try_to_freeze())
639 goto no_signal;
640
641 /* 614 /*
642 * Get the signal to deliver. When running under ptrace, at this 615 * Get the signal to deliver. When running under ptrace, at this
643 * point the debugger may change all our registers ... 616 * point the debugger may change all our registers ...
@@ -652,12 +625,14 @@ static void do_signal(struct pt_regs *regs, int syscall)
652 * debugger has chosen to restart at a different PC. 625 * debugger has chosen to restart at a different PC.
653 */ 626 */
654 if (regs->ARM_pc == restart_addr) { 627 if (regs->ARM_pc == restart_addr) {
655 if (retval == -ERESTARTNOHAND 628 if (retval == -ERESTARTNOHAND ||
629 retval == -ERESTART_RESTARTBLOCK
656 || (retval == -ERESTARTSYS 630 || (retval == -ERESTARTSYS
657 && !(ka.sa.sa_flags & SA_RESTART))) { 631 && !(ka.sa.sa_flags & SA_RESTART))) {
658 regs->ARM_r0 = -EINTR; 632 regs->ARM_r0 = -EINTR;
659 regs->ARM_pc = continue_addr; 633 regs->ARM_pc = continue_addr;
660 } 634 }
635 clear_thread_flag(TIF_SYSCALL_RESTARTSYS);
661 } 636 }
662 637
663 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 638 if (test_thread_flag(TIF_RESTORE_SIGMASK))
@@ -677,7 +652,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
677 return; 652 return;
678 } 653 }
679 654
680 no_signal:
681 if (syscall) { 655 if (syscall) {
682 /* 656 /*
683 * Handle restarting a different system call. As above, 657 * Handle restarting a different system call. As above,
@@ -685,38 +659,15 @@ static void do_signal(struct pt_regs *regs, int syscall)
685 * ignore the restart. 659 * ignore the restart.
686 */ 660 */
687 if (retval == -ERESTART_RESTARTBLOCK 661 if (retval == -ERESTART_RESTARTBLOCK
688 && regs->ARM_pc == continue_addr) { 662 && regs->ARM_pc == restart_addr)
689 if (thumb_mode(regs)) { 663 set_thread_flag(TIF_SYSCALL_RESTARTSYS);
690 regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
691 regs->ARM_pc -= 2;
692 } else {
693#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
694 regs->ARM_r7 = __NR_restart_syscall;
695 regs->ARM_pc -= 4;
696#else
697 u32 __user *usp;
698
699 regs->ARM_sp -= 4;
700 usp = (u32 __user *)regs->ARM_sp;
701
702 if (put_user(regs->ARM_pc, usp) == 0) {
703 regs->ARM_pc = KERN_RESTART_CODE;
704 } else {
705 regs->ARM_sp += 4;
706 force_sigsegv(0, current);
707 }
708#endif
709 }
710 }
711
712 /* If there's no signal to deliver, we just put the saved sigmask
713 * back.
714 */
715 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
716 clear_thread_flag(TIF_RESTORE_SIGMASK);
717 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
718 }
719 } 664 }
665
666 /* If there's no signal to deliver, we just put the saved sigmask
667 * back.
668 */
669 if (test_and_clear_thread_flag(TIF_RESTORE_SIGMASK))
670 set_current_blocked(&current->saved_sigmask);
720} 671}
721 672
722asmlinkage void 673asmlinkage void
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 6fcfe8398aa..5ff067b7c75 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -8,7 +8,5 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) 10#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
11#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
12 11
13extern const unsigned long sigreturn_codes[7]; 12extern const unsigned long sigreturn_codes[7];
14extern const unsigned long syscall_restart_code[2];
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3647170e9a1..4928d89758f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -820,8 +820,6 @@ void __init early_trap_init(void *vectors_base)
820 */ 820 */
821 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), 821 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
822 sigreturn_codes, sizeof(sigreturn_codes)); 822 sigreturn_codes, sizeof(sigreturn_codes));
823 memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
824 syscall_restart_code, sizeof(syscall_restart_code));
825 823
826 flush_icache_range(vectors, vectors + PAGE_SIZE); 824 flush_icache_range(vectors, vectors + PAGE_SIZE);
827 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 825 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index f6747246d64..933fc9afe7d 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -436,7 +436,6 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
436 atslave->dma_dev = &at_hdmac_device.dev; 436 atslave->dma_dev = &at_hdmac_device.dev;
437 atslave->cfg = ATC_FIFOCFG_HALFFIFO 437 atslave->cfg = ATC_FIFOCFG_HALFFIFO
438 | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; 438 | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
439 atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
440 if (mmc_id == 0) /* MCI0 */ 439 if (mmc_id == 0) /* MCI0 */
441 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0) 440 atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
442 | ATC_DST_PER(AT_DMA_ID_MCI0); 441 | ATC_DST_PER(AT_DMA_ID_MCI0);
diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
index fff48d1a0f4..cab0997be3d 100644
--- a/arch/arm/mach-at91/include/mach/at_hdmac.h
+++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
@@ -26,18 +26,11 @@ struct at_dma_platform_data {
26/** 26/**
27 * struct at_dma_slave - Controller-specific information about a slave 27 * struct at_dma_slave - Controller-specific information about a slave
28 * @dma_dev: required DMA master device 28 * @dma_dev: required DMA master device
29 * @tx_reg: physical address of data register used for
30 * memory-to-peripheral transfers
31 * @rx_reg: physical address of data register used for
32 * peripheral-to-memory transfers
33 * @reg_width: peripheral register width
34 * @cfg: Platform-specific initializer for the CFG register 29 * @cfg: Platform-specific initializer for the CFG register
35 * @ctrla: Platform-specific initializer for the CTRLA register
36 */ 30 */
37struct at_dma_slave { 31struct at_dma_slave {
38 struct device *dma_dev; 32 struct device *dma_dev;
39 u32 cfg; 33 u32 cfg;
40 u32 ctrla;
41}; 34};
42 35
43 36
@@ -64,24 +57,5 @@ struct at_dma_slave {
64#define ATC_FIFOCFG_HALFFIFO (0x1 << 28) 57#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)
65#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28) 58#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28)
66 59
67/* Platform-configurable bits in CTRLA */
68#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */
69#define ATC_SCSIZE_1 (0x0 << 16)
70#define ATC_SCSIZE_4 (0x1 << 16)
71#define ATC_SCSIZE_8 (0x2 << 16)
72#define ATC_SCSIZE_16 (0x3 << 16)
73#define ATC_SCSIZE_32 (0x4 << 16)
74#define ATC_SCSIZE_64 (0x5 << 16)
75#define ATC_SCSIZE_128 (0x6 << 16)
76#define ATC_SCSIZE_256 (0x7 << 16)
77#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */
78#define ATC_DCSIZE_1 (0x0 << 20)
79#define ATC_DCSIZE_4 (0x1 << 20)
80#define ATC_DCSIZE_8 (0x2 << 20)
81#define ATC_DCSIZE_16 (0x3 << 20)
82#define ATC_DCSIZE_32 (0x4 << 20)
83#define ATC_DCSIZE_64 (0x5 << 20)
84#define ATC_DCSIZE_128 (0x6 << 20)
85#define ATC_DCSIZE_256 (0x7 << 20)
86 60
87#endif /* AT_HDMAC_H */ 61#endif /* AT_HDMAC_H */
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
index dc1afe5be20..0031864e7f1 100644
--- a/arch/arm/mach-davinci/board-da830-evm.c
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -681,6 +681,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
681 .init_irq = cp_intc_init, 681 .init_irq = cp_intc_init,
682 .timer = &davinci_timer, 682 .timer = &davinci_timer,
683 .init_machine = da830_evm_init, 683 .init_machine = da830_evm_init,
684 .init_late = davinci_init_late,
684 .dma_zone_size = SZ_128M, 685 .dma_zone_size = SZ_128M,
685 .restart = da8xx_restart, 686 .restart = da8xx_restart,
686MACHINE_END 687MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 09f61073c8d..0149fb453be 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -1411,6 +1411,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
1411 .init_irq = cp_intc_init, 1411 .init_irq = cp_intc_init,
1412 .timer = &davinci_timer, 1412 .timer = &davinci_timer,
1413 .init_machine = da850_evm_init, 1413 .init_machine = da850_evm_init,
1414 .init_late = davinci_init_late,
1414 .dma_zone_size = SZ_128M, 1415 .dma_zone_size = SZ_128M,
1415 .restart = da8xx_restart, 1416 .restart = da8xx_restart,
1416MACHINE_END 1417MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 82ed753fb36..1c7b1f46a8f 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -357,6 +357,7 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
357 .init_irq = davinci_irq_init, 357 .init_irq = davinci_irq_init,
358 .timer = &davinci_timer, 358 .timer = &davinci_timer,
359 .init_machine = dm355_evm_init, 359 .init_machine = dm355_evm_init,
360 .init_late = davinci_init_late,
360 .dma_zone_size = SZ_128M, 361 .dma_zone_size = SZ_128M,
361 .restart = davinci_restart, 362 .restart = davinci_restart,
362MACHINE_END 363MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index d74a8b3445f..8e7703213b0 100644
--- a/arch/arm/mach-davinci/board-dm355-leopard.c
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -276,6 +276,7 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
276 .init_irq = davinci_irq_init, 276 .init_irq = davinci_irq_init,
277 .timer = &davinci_timer, 277 .timer = &davinci_timer,
278 .init_machine = dm355_leopard_init, 278 .init_machine = dm355_leopard_init,
279 .init_late = davinci_init_late,
279 .dma_zone_size = SZ_128M, 280 .dma_zone_size = SZ_128M,
280 .restart = davinci_restart, 281 .restart = davinci_restart,
281MACHINE_END 282MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 5bce2b83bb4..688a9c556dc 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -618,6 +618,7 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
618 .init_irq = davinci_irq_init, 618 .init_irq = davinci_irq_init,
619 .timer = &davinci_timer, 619 .timer = &davinci_timer,
620 .init_machine = dm365_evm_init, 620 .init_machine = dm365_evm_init,
621 .init_late = davinci_init_late,
621 .dma_zone_size = SZ_128M, 622 .dma_zone_size = SZ_128M,
622 .restart = davinci_restart, 623 .restart = davinci_restart,
623MACHINE_END 624MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 3683306e024..d34ed55912b 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -825,6 +825,7 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
825 .init_irq = davinci_irq_init, 825 .init_irq = davinci_irq_init,
826 .timer = &davinci_timer, 826 .timer = &davinci_timer,
827 .init_machine = davinci_evm_init, 827 .init_machine = davinci_evm_init,
828 .init_late = davinci_init_late,
828 .dma_zone_size = SZ_128M, 829 .dma_zone_size = SZ_128M,
829 .restart = davinci_restart, 830 .restart = davinci_restart,
830MACHINE_END 831MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index d72ab948d63..958679a20e1 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -788,6 +788,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
788 .init_irq = davinci_irq_init, 788 .init_irq = davinci_irq_init,
789 .timer = &davinci_timer, 789 .timer = &davinci_timer,
790 .init_machine = evm_init, 790 .init_machine = evm_init,
791 .init_late = davinci_init_late,
791 .dma_zone_size = SZ_128M, 792 .dma_zone_size = SZ_128M,
792 .restart = davinci_restart, 793 .restart = davinci_restart,
793MACHINE_END 794MACHINE_END
@@ -798,6 +799,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
798 .init_irq = davinci_irq_init, 799 .init_irq = davinci_irq_init,
799 .timer = &davinci_timer, 800 .timer = &davinci_timer,
800 .init_machine = evm_init, 801 .init_machine = evm_init,
802 .init_late = davinci_init_late,
801 .dma_zone_size = SZ_128M, 803 .dma_zone_size = SZ_128M,
802 .restart = davinci_restart, 804 .restart = davinci_restart,
803MACHINE_END 805MACHINE_END
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 672d820e2aa..beecde3a1d2 100644
--- a/arch/arm/mach-davinci/board-mityomapl138.c
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -572,6 +572,7 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
572 .init_irq = cp_intc_init, 572 .init_irq = cp_intc_init,
573 .timer = &davinci_timer, 573 .timer = &davinci_timer,
574 .init_machine = mityomapl138_init, 574 .init_machine = mityomapl138_init,
575 .init_late = davinci_init_late,
575 .dma_zone_size = SZ_128M, 576 .dma_zone_size = SZ_128M,
576 .restart = da8xx_restart, 577 .restart = da8xx_restart,
577MACHINE_END 578MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index a772bb45570..5de69f2fcca 100644
--- a/arch/arm/mach-davinci/board-neuros-osd2.c
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -278,6 +278,7 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
278 .init_irq = davinci_irq_init, 278 .init_irq = davinci_irq_init,
279 .timer = &davinci_timer, 279 .timer = &davinci_timer,
280 .init_machine = davinci_ntosd2_init, 280 .init_machine = davinci_ntosd2_init,
281 .init_late = davinci_init_late,
281 .dma_zone_size = SZ_128M, 282 .dma_zone_size = SZ_128M,
282 .restart = davinci_restart, 283 .restart = davinci_restart,
283MACHINE_END 284MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 45e815760a2..dc1208e9e66 100644
--- a/arch/arm/mach-davinci/board-omapl138-hawk.c
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -343,6 +343,7 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
343 .init_irq = cp_intc_init, 343 .init_irq = cp_intc_init,
344 .timer = &davinci_timer, 344 .timer = &davinci_timer,
345 .init_machine = omapl138_hawk_init, 345 .init_machine = omapl138_hawk_init,
346 .init_late = davinci_init_late,
346 .dma_zone_size = SZ_128M, 347 .dma_zone_size = SZ_128M,
347 .restart = da8xx_restart, 348 .restart = da8xx_restart,
348MACHINE_END 349MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 76e67509610..9078acf94ba 100644
--- a/arch/arm/mach-davinci/board-sffsdr.c
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -157,6 +157,7 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
157 .init_irq = davinci_irq_init, 157 .init_irq = davinci_irq_init,
158 .timer = &davinci_timer, 158 .timer = &davinci_timer,
159 .init_machine = davinci_sffsdr_init, 159 .init_machine = davinci_sffsdr_init,
160 .init_late = davinci_init_late,
160 .dma_zone_size = SZ_128M, 161 .dma_zone_size = SZ_128M,
161 .restart = davinci_restart, 162 .restart = davinci_restart,
162MACHINE_END 163MACHINE_END
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
index 5f14e30b00d..ac4e003ad86 100644
--- a/arch/arm/mach-davinci/board-tnetv107x-evm.c
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -282,6 +282,7 @@ MACHINE_START(TNETV107X, "TNETV107X EVM")
282 .init_irq = cp_intc_init, 282 .init_irq = cp_intc_init,
283 .timer = &davinci_timer, 283 .timer = &davinci_timer,
284 .init_machine = tnetv107x_evm_board_init, 284 .init_machine = tnetv107x_evm_board_init,
285 .init_late = davinci_init_late,
285 .dma_zone_size = SZ_128M, 286 .dma_zone_size = SZ_128M,
286 .restart = tnetv107x_restart, 287 .restart = tnetv107x_restart,
287MACHINE_END 288MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 008772e3b84..34668ead53c 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -213,7 +213,7 @@ EXPORT_SYMBOL(clk_unregister);
213/* 213/*
214 * Disable any unused clocks left on by the bootloader 214 * Disable any unused clocks left on by the bootloader
215 */ 215 */
216static int __init clk_disable_unused(void) 216int __init davinci_clk_disable_unused(void)
217{ 217{
218 struct clk *ck; 218 struct clk *ck;
219 219
@@ -237,7 +237,6 @@ static int __init clk_disable_unused(void)
237 237
238 return 0; 238 return 0;
239} 239}
240late_initcall(clk_disable_unused);
241#endif 240#endif
242 241
243static unsigned long clk_sysclk_recalc(struct clk *clk) 242static unsigned long clk_sysclk_recalc(struct clk *clk)
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index cb9b2e47510..64b0f65a863 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -117,3 +117,10 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
117err: 117err:
118 panic("davinci_common_init: SoC Initialization failed\n"); 118 panic("davinci_common_init: SoC Initialization failed\n");
119} 119}
120
121void __init davinci_init_late(void)
122{
123 davinci_cpufreq_init();
124 davinci_pm_init();
125 davinci_clk_disable_unused();
126}
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
index 031048fec9f..4729eaab0f4 100644
--- a/arch/arm/mach-davinci/cpufreq.c
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -240,10 +240,9 @@ static struct platform_driver davinci_cpufreq_driver = {
240 .remove = __exit_p(davinci_cpufreq_remove), 240 .remove = __exit_p(davinci_cpufreq_remove),
241}; 241};
242 242
243static int __init davinci_cpufreq_init(void) 243int __init davinci_cpufreq_init(void)
244{ 244{
245 return platform_driver_probe(&davinci_cpufreq_driver, 245 return platform_driver_probe(&davinci_cpufreq_driver,
246 davinci_cpufreq_probe); 246 davinci_cpufreq_probe);
247} 247}
248late_initcall(davinci_cpufreq_init);
249 248
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 95ce019c9b9..a685e9706b7 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -353,9 +353,10 @@ static int irq2ctlr(int irq)
353 *****************************************************************************/ 353 *****************************************************************************/
354static irqreturn_t dma_irq_handler(int irq, void *data) 354static irqreturn_t dma_irq_handler(int irq, void *data)
355{ 355{
356 int i;
357 int ctlr; 356 int ctlr;
358 unsigned int cnt = 0; 357 u32 sh_ier;
358 u32 sh_ipr;
359 u32 bank;
359 360
360 ctlr = irq2ctlr(irq); 361 ctlr = irq2ctlr(irq);
361 if (ctlr < 0) 362 if (ctlr < 0)
@@ -363,41 +364,39 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
363 364
364 dev_dbg(data, "dma_irq_handler\n"); 365 dev_dbg(data, "dma_irq_handler\n");
365 366
366 if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) && 367 sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
367 (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0)) 368 if (!sh_ipr) {
368 return IRQ_NONE; 369 sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
370 if (!sh_ipr)
371 return IRQ_NONE;
372 sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
373 bank = 1;
374 } else {
375 sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
376 bank = 0;
377 }
369 378
370 while (1) { 379 do {
371 int j; 380 u32 slot;
372 if (edma_shadow0_read_array(ctlr, SH_IPR, 0) & 381 u32 channel;
373 edma_shadow0_read_array(ctlr, SH_IER, 0)) 382
374 j = 0; 383 dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
375 else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) & 384
376 edma_shadow0_read_array(ctlr, SH_IER, 1)) 385 slot = __ffs(sh_ipr);
377 j = 1; 386 sh_ipr &= ~(BIT(slot));
378 else 387
379 break; 388 if (sh_ier & BIT(slot)) {
380 dev_dbg(data, "IPR%d %08x\n", j, 389 channel = (bank << 5) | slot;
381 edma_shadow0_read_array(ctlr, SH_IPR, j)); 390 /* Clear the corresponding IPR bits */
382 for (i = 0; i < 32; i++) { 391 edma_shadow0_write_array(ctlr, SH_ICR, bank,
383 int k = (j << 5) + i; 392 BIT(slot));
384 if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i)) 393 if (edma_cc[ctlr]->intr_data[channel].callback)
385 && (edma_shadow0_read_array(ctlr, 394 edma_cc[ctlr]->intr_data[channel].callback(
386 SH_IER, j) & BIT(i))) { 395 channel, DMA_COMPLETE,
387 /* Clear the corresponding IPR bits */ 396 edma_cc[ctlr]->intr_data[channel].data);
388 edma_shadow0_write_array(ctlr, SH_ICR, j,
389 BIT(i));
390 if (edma_cc[ctlr]->intr_data[k].callback)
391 edma_cc[ctlr]->intr_data[k].callback(
392 k, DMA_COMPLETE,
393 edma_cc[ctlr]->intr_data[k].
394 data);
395 }
396 } 397 }
397 cnt++; 398 } while (sh_ipr);
398 if (cnt > 10) 399
399 break;
400 }
401 edma_shadow0_write(ctlr, SH_IEVAL, 1); 400 edma_shadow0_write(ctlr, SH_IEVAL, 1);
402 return IRQ_HANDLED; 401 return IRQ_HANDLED;
403} 402}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 5cd39a4e0c9..bdc4aa8e672 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -84,6 +84,25 @@ extern struct davinci_soc_info davinci_soc_info;
84extern void davinci_common_init(struct davinci_soc_info *soc_info); 84extern void davinci_common_init(struct davinci_soc_info *soc_info);
85extern void davinci_init_ide(void); 85extern void davinci_init_ide(void);
86void davinci_restart(char mode, const char *cmd); 86void davinci_restart(char mode, const char *cmd);
87void davinci_init_late(void);
88
89#ifdef CONFIG_DAVINCI_RESET_CLOCKS
90int davinci_clk_disable_unused(void);
91#else
92static inline int davinci_clk_disable_unused(void) { return 0; }
93#endif
94
95#ifdef CONFIG_CPU_FREQ
96int davinci_cpufreq_init(void);
97#else
98static inline int davinci_cpufreq_init(void) { return 0; }
99#endif
100
101#ifdef CONFIG_SUSPEND
102int davinci_pm_init(void);
103#else
104static inline int davinci_pm_init(void) { return 0; }
105#endif
87 106
88/* standard place to map on-chip SRAMs; they *may* support DMA */ 107/* standard place to map on-chip SRAMs; they *may* support DMA */
89#define SRAM_VIRT 0xfffe0000 108#define SRAM_VIRT 0xfffe0000
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index cf94552d527..34290d14754 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -22,46 +22,28 @@
22 22
23#define UART_SHIFT 2 23#define UART_SHIFT 2
24 24
25 .pushsection .data 25#if defined(CONFIG_DEBUG_DAVINCI_DMx_UART0)
26davinci_uart_phys: .word 0 26#define UART_BASE DAVINCI_UART0_BASE
27davinci_uart_virt: .word 0 27#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART0)
28 .popsection 28#define UART_BASE DA8XX_UART0_BASE
29 29#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART1)
30 .macro addruart, rp, rv, tmp 30#define UART_BASE DA8XX_UART1_BASE
31 31#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART2)
32 /* Use davinci_uart_phys/virt if already configured */ 32#define UART_BASE DA8XX_UART2_BASE
3310: adr \rp, 99f @ get effective addr of 99f 33#elif defined(CONFIG_DEBUG_DAVINCI_TNETV107X_UART1)
34 ldr \rv, [\rp] @ get absolute addr of 99f 34#define UART_BASE TNETV107X_UART2_BASE
35 sub \rv, \rv, \rp @ offset between the two 35#define UART_VIRTBASE TNETV107X_UART2_VIRT
36 ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys 36#else
37 sub \tmp, \rp, \rv @ make it effective 37#error "Select a specifc port for DEBUG_LL"
38 ldr \rp, [\tmp, #0] @ davinci_uart_phys 38#endif
39 ldr \rv, [\tmp, #4] @ davinci_uart_virt
40 cmp \rp, #0 @ is port configured?
41 cmpne \rv, #0
42 bne 100f @ already configured
43
44 /* Check the debug UART address set in uncompress.h */
45 and \rp, pc, #0xff000000
46 ldr \rv, =DAVINCI_UART_INFO_OFS
47 add \rp, \rp, \rv
48
49 /* Copy uart phys address from decompressor uart info */
50 ldr \rv, [\rp, #0]
51 str \rv, [\tmp, #0]
52
53 /* Copy uart virt address from decompressor uart info */
54 ldr \rv, [\rp, #4]
55 str \rv, [\tmp, #4]
56
57 b 10b
58 39
59 .align 40#ifndef UART_VIRTBASE
6099: .word . 41#define UART_VIRTBASE IO_ADDRESS(UART_BASE)
61 .word davinci_uart_phys 42#endif
62 .ltorg
63 43
64100: 44 .macro addruart, rp, rv, tmp
45 ldr \rp, =UART_BASE
46 ldr \rv, =UART_VIRTBASE
65 .endm 47 .endm
66 48
67 .macro senduart,rd,rx 49 .macro senduart,rd,rx
diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h
index 2184691ebc2..16bb42291d3 100644
--- a/arch/arm/mach-davinci/include/mach/hardware.h
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -22,7 +22,7 @@
22/* 22/*
23 * I/O mapping 23 * I/O mapping
24 */ 24 */
25#define IO_PHYS 0x01c00000UL 25#define IO_PHYS UL(0x01c00000)
26#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */ 26#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
27#define IO_SIZE 0x00400000 27#define IO_SIZE 0x00400000
28#define IO_VIRT (IO_PHYS + IO_OFFSET) 28#define IO_VIRT (IO_PHYS + IO_OFFSET)
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
index e347d88fef9..46b3cd11c3c 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -15,16 +15,6 @@
15 15
16#include <mach/hardware.h> 16#include <mach/hardware.h>
17 17
18/*
19 * Stolen area that contains debug uart physical and virtual addresses. These
20 * addresses are filled in by the uncompress.h code, and are used by the debug
21 * macros in debug-macro.S.
22 *
23 * This area sits just below the page tables (see arch/arm/kernel/head.S).
24 * We define it as a relative offset from start of usable RAM.
25 */
26#define DAVINCI_UART_INFO_OFS 0x3ff8
27
28#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) 18#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
29#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) 19#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
30#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) 20#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index da2fb2c2155..18cfd497715 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -43,37 +43,27 @@ static inline void flush(void)
43 barrier(); 43 barrier();
44} 44}
45 45
46static inline void set_uart_info(u32 phys, void * __iomem virt) 46static inline void set_uart_info(u32 phys)
47{ 47{
48 /*
49 * Get address of some.bss variable and round it down
50 * a la CONFIG_AUTO_ZRELADDR.
51 */
52 u32 ram_start = (u32)&uart & 0xf8000000;
53 u32 *uart_info = (u32 *)(ram_start + DAVINCI_UART_INFO_OFS);
54
55 uart = (u32 *)phys; 48 uart = (u32 *)phys;
56 uart_info[0] = phys;
57 uart_info[1] = (u32)virt;
58} 49}
59 50
60#define _DEBUG_LL_ENTRY(machine, phys, virt) \ 51#define _DEBUG_LL_ENTRY(machine, phys) \
61 if (machine_is_##machine()) { \ 52 { \
62 set_uart_info(phys, virt); \ 53 if (machine_is_##machine()) { \
63 break; \ 54 set_uart_info(phys); \
55 break; \
56 } \
64 } 57 }
65 58
66#define DEBUG_LL_DAVINCI(machine, port) \ 59#define DEBUG_LL_DAVINCI(machine, port) \
67 _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \ 60 _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE)
68 IO_ADDRESS(DAVINCI_UART##port##_BASE))
69 61
70#define DEBUG_LL_DA8XX(machine, port) \ 62#define DEBUG_LL_DA8XX(machine, port) \
71 _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \ 63 _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE)
72 IO_ADDRESS(DA8XX_UART##port##_BASE))
73 64
74#define DEBUG_LL_TNETV107X(machine, port) \ 65#define DEBUG_LL_TNETV107X(machine, port) \
75 _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \ 66 _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE)
76 TNETV107X_UART##port##_VIRT)
77 67
78static inline void __arch_decomp_setup(unsigned long arch_id) 68static inline void __arch_decomp_setup(unsigned long arch_id)
79{ 69{
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 04c49f7543e..eb8360b33aa 100644
--- a/arch/arm/mach-davinci/pm.c
+++ b/arch/arm/mach-davinci/pm.c
@@ -152,8 +152,7 @@ static struct platform_driver davinci_pm_driver = {
152 .remove = __exit_p(davinci_pm_remove), 152 .remove = __exit_p(davinci_pm_remove),
153}; 153};
154 154
155static int __init davinci_pm_init(void) 155int __init davinci_pm_init(void)
156{ 156{
157 return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe); 157 return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
158} 158}
159late_initcall(davinci_pm_init);
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 42ab1e7c4ec..9493076fc59 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/clk.h> 16#include <linux/clk-provider.h>
17#include <linux/ata_platform.h> 17#include <linux/ata_platform.h>
18#include <linux/gpio.h> 18#include <linux/gpio.h>
19#include <asm/page.h> 19#include <asm/page.h>
@@ -68,6 +68,19 @@ void __init dove_map_io(void)
68} 68}
69 69
70/***************************************************************************** 70/*****************************************************************************
71 * CLK tree
72 ****************************************************************************/
73static struct clk *tclk;
74
75static void __init clk_init(void)
76{
77 tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
78 get_tclk());
79
80 orion_clkdev_init(tclk);
81}
82
83/*****************************************************************************
71 * EHCI0 84 * EHCI0
72 ****************************************************************************/ 85 ****************************************************************************/
73void __init dove_ehci0_init(void) 86void __init dove_ehci0_init(void)
@@ -89,8 +102,7 @@ void __init dove_ehci1_init(void)
89void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) 102void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
90{ 103{
91 orion_ge00_init(eth_data, 104 orion_ge00_init(eth_data,
92 DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 105 DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0);
93 0, get_tclk());
94} 106}
95 107
96/***************************************************************************** 108/*****************************************************************************
@@ -116,7 +128,7 @@ void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
116void __init dove_uart0_init(void) 128void __init dove_uart0_init(void)
117{ 129{
118 orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE, 130 orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE,
119 IRQ_DOVE_UART_0, get_tclk()); 131 IRQ_DOVE_UART_0, tclk);
120} 132}
121 133
122/***************************************************************************** 134/*****************************************************************************
@@ -125,7 +137,7 @@ void __init dove_uart0_init(void)
125void __init dove_uart1_init(void) 137void __init dove_uart1_init(void)
126{ 138{
127 orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE, 139 orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
128 IRQ_DOVE_UART_1, get_tclk()); 140 IRQ_DOVE_UART_1, tclk);
129} 141}
130 142
131/***************************************************************************** 143/*****************************************************************************
@@ -134,7 +146,7 @@ void __init dove_uart1_init(void)
134void __init dove_uart2_init(void) 146void __init dove_uart2_init(void)
135{ 147{
136 orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE, 148 orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
137 IRQ_DOVE_UART_2, get_tclk()); 149 IRQ_DOVE_UART_2, tclk);
138} 150}
139 151
140/***************************************************************************** 152/*****************************************************************************
@@ -143,7 +155,7 @@ void __init dove_uart2_init(void)
143void __init dove_uart3_init(void) 155void __init dove_uart3_init(void)
144{ 156{
145 orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE, 157 orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
146 IRQ_DOVE_UART_3, get_tclk()); 158 IRQ_DOVE_UART_3, tclk);
147} 159}
148 160
149/***************************************************************************** 161/*****************************************************************************
@@ -151,12 +163,12 @@ void __init dove_uart3_init(void)
151 ****************************************************************************/ 163 ****************************************************************************/
152void __init dove_spi0_init(void) 164void __init dove_spi0_init(void)
153{ 165{
154 orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk()); 166 orion_spi_init(DOVE_SPI0_PHYS_BASE);
155} 167}
156 168
157void __init dove_spi1_init(void) 169void __init dove_spi1_init(void)
158{ 170{
159 orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk()); 171 orion_spi_1_init(DOVE_SPI1_PHYS_BASE);
160} 172}
161 173
162/***************************************************************************** 174/*****************************************************************************
@@ -272,18 +284,17 @@ void __init dove_sdio1_init(void)
272 284
273void __init dove_init(void) 285void __init dove_init(void)
274{ 286{
275 int tclk;
276
277 tclk = get_tclk();
278
279 printk(KERN_INFO "Dove 88AP510 SoC, "); 287 printk(KERN_INFO "Dove 88AP510 SoC, ");
280 printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000); 288 printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
281 289
282#ifdef CONFIG_CACHE_TAUROS2 290#ifdef CONFIG_CACHE_TAUROS2
283 tauros2_init(); 291 tauros2_init();
284#endif 292#endif
285 dove_setup_cpu_mbus(); 293 dove_setup_cpu_mbus();
286 294
295 /* Setup root of clk tree */
296 clk_init();
297
287 /* internal devices that every board has */ 298 /* internal devices that every board has */
288 dove_rtc_init(); 299 dove_rtc_init();
289 dove_xor0_init(); 300 dove_xor0_init();
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
index ea77ae430b2..bc2867f1134 100644
--- a/arch/arm/mach-dove/dove-db-setup.c
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -20,7 +20,6 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/spi/orion_spi.h>
24#include <linux/spi/flash.h> 23#include <linux/spi/flash.h>
25#include <linux/gpio.h> 24#include <linux/gpio.h>
26#include <asm/mach-types.h> 25#include <asm/mach-types.h>
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 2d45947a303..a472777e9eb 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -41,5 +41,6 @@ MACHINE_START(ADSSPHERE, "ADS Sphere board")
41 .handle_irq = vic_handle_irq, 41 .handle_irq = vic_handle_irq,
42 .timer = &ep93xx_timer, 42 .timer = &ep93xx_timer,
43 .init_machine = adssphere_init_machine, 43 .init_machine = adssphere_init_machine,
44 .init_late = ep93xx_init_late,
44 .restart = ep93xx_restart, 45 .restart = ep93xx_restart,
45MACHINE_END 46MACHINE_END
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 66b1494f23a..4dd07a0e360 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -675,7 +675,7 @@ int ep93xx_keypad_acquire_gpio(struct platform_device *pdev)
675fail_gpio_d: 675fail_gpio_d:
676 gpio_free(EP93XX_GPIO_LINE_C(i)); 676 gpio_free(EP93XX_GPIO_LINE_C(i));
677fail_gpio_c: 677fail_gpio_c:
678 for ( ; i >= 0; --i) { 678 for (--i; i >= 0; --i) {
679 gpio_free(EP93XX_GPIO_LINE_C(i)); 679 gpio_free(EP93XX_GPIO_LINE_C(i));
680 gpio_free(EP93XX_GPIO_LINE_D(i)); 680 gpio_free(EP93XX_GPIO_LINE_D(i));
681 } 681 }
@@ -834,3 +834,8 @@ void ep93xx_restart(char mode, const char *cmd)
834 while (1) 834 while (1)
835 ; 835 ;
836} 836}
837
838void __init ep93xx_init_late(void)
839{
840 crunch_init();
841}
diff --git a/arch/arm/mach-ep93xx/crunch.c b/arch/arm/mach-ep93xx/crunch.c
index 74753e2df60..a4a2ab9648c 100644
--- a/arch/arm/mach-ep93xx/crunch.c
+++ b/arch/arm/mach-ep93xx/crunch.c
@@ -79,12 +79,10 @@ static struct notifier_block crunch_notifier_block = {
79 .notifier_call = crunch_do, 79 .notifier_call = crunch_do,
80}; 80};
81 81
82static int __init crunch_init(void) 82int __init crunch_init(void)
83{ 83{
84 thread_register_notifier(&crunch_notifier_block); 84 thread_register_notifier(&crunch_notifier_block);
85 elf_hwcap |= HWCAP_CRUNCH; 85 elf_hwcap |= HWCAP_CRUNCH;
86 86
87 return 0; 87 return 0;
88} 88}
89
90late_initcall(crunch_init);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index da9047d726f..d74c5cddb98 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -255,6 +255,7 @@ MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
255 .handle_irq = vic_handle_irq, 255 .handle_irq = vic_handle_irq,
256 .timer = &ep93xx_timer, 256 .timer = &ep93xx_timer,
257 .init_machine = edb93xx_init_machine, 257 .init_machine = edb93xx_init_machine,
258 .init_late = ep93xx_init_late,
258 .restart = ep93xx_restart, 259 .restart = ep93xx_restart,
259MACHINE_END 260MACHINE_END
260#endif 261#endif
@@ -268,6 +269,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
268 .handle_irq = vic_handle_irq, 269 .handle_irq = vic_handle_irq,
269 .timer = &ep93xx_timer, 270 .timer = &ep93xx_timer,
270 .init_machine = edb93xx_init_machine, 271 .init_machine = edb93xx_init_machine,
272 .init_late = ep93xx_init_late,
271 .restart = ep93xx_restart, 273 .restart = ep93xx_restart,
272MACHINE_END 274MACHINE_END
273#endif 275#endif
@@ -281,6 +283,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
281 .handle_irq = vic_handle_irq, 283 .handle_irq = vic_handle_irq,
282 .timer = &ep93xx_timer, 284 .timer = &ep93xx_timer,
283 .init_machine = edb93xx_init_machine, 285 .init_machine = edb93xx_init_machine,
286 .init_late = ep93xx_init_late,
284 .restart = ep93xx_restart, 287 .restart = ep93xx_restart,
285MACHINE_END 288MACHINE_END
286#endif 289#endif
@@ -294,6 +297,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
294 .handle_irq = vic_handle_irq, 297 .handle_irq = vic_handle_irq,
295 .timer = &ep93xx_timer, 298 .timer = &ep93xx_timer,
296 .init_machine = edb93xx_init_machine, 299 .init_machine = edb93xx_init_machine,
300 .init_late = ep93xx_init_late,
297 .restart = ep93xx_restart, 301 .restart = ep93xx_restart,
298MACHINE_END 302MACHINE_END
299#endif 303#endif
@@ -307,6 +311,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
307 .handle_irq = vic_handle_irq, 311 .handle_irq = vic_handle_irq,
308 .timer = &ep93xx_timer, 312 .timer = &ep93xx_timer,
309 .init_machine = edb93xx_init_machine, 313 .init_machine = edb93xx_init_machine,
314 .init_late = ep93xx_init_late,
310 .restart = ep93xx_restart, 315 .restart = ep93xx_restart,
311MACHINE_END 316MACHINE_END
312#endif 317#endif
@@ -320,6 +325,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
320 .handle_irq = vic_handle_irq, 325 .handle_irq = vic_handle_irq,
321 .timer = &ep93xx_timer, 326 .timer = &ep93xx_timer,
322 .init_machine = edb93xx_init_machine, 327 .init_machine = edb93xx_init_machine,
328 .init_late = ep93xx_init_late,
323 .restart = ep93xx_restart, 329 .restart = ep93xx_restart,
324MACHINE_END 330MACHINE_END
325#endif 331#endif
@@ -333,6 +339,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
333 .handle_irq = vic_handle_irq, 339 .handle_irq = vic_handle_irq,
334 .timer = &ep93xx_timer, 340 .timer = &ep93xx_timer,
335 .init_machine = edb93xx_init_machine, 341 .init_machine = edb93xx_init_machine,
342 .init_late = ep93xx_init_late,
336 .restart = ep93xx_restart, 343 .restart = ep93xx_restart,
337MACHINE_END 344MACHINE_END
338#endif 345#endif
@@ -346,6 +353,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
346 .handle_irq = vic_handle_irq, 353 .handle_irq = vic_handle_irq,
347 .timer = &ep93xx_timer, 354 .timer = &ep93xx_timer,
348 .init_machine = edb93xx_init_machine, 355 .init_machine = edb93xx_init_machine,
356 .init_late = ep93xx_init_late,
349 .restart = ep93xx_restart, 357 .restart = ep93xx_restart,
350MACHINE_END 358MACHINE_END
351#endif 359#endif
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index fcdffbe49dc..437c3411115 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -41,5 +41,6 @@ MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
41 .handle_irq = vic_handle_irq, 41 .handle_irq = vic_handle_irq,
42 .timer = &ep93xx_timer, 42 .timer = &ep93xx_timer,
43 .init_machine = gesbc9312_init_machine, 43 .init_machine = gesbc9312_init_machine,
44 .init_late = ep93xx_init_late,
44 .restart = ep93xx_restart, 45 .restart = ep93xx_restart,
45MACHINE_END 46MACHINE_END
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 602bd87fd0a..1ecb040d98b 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -53,5 +53,12 @@ void ep93xx_init_devices(void);
53extern struct sys_timer ep93xx_timer; 53extern struct sys_timer ep93xx_timer;
54 54
55void ep93xx_restart(char, const char *); 55void ep93xx_restart(char, const char *);
56void ep93xx_init_late(void);
57
58#ifdef CONFIG_CRUNCH
59int crunch_init(void);
60#else
61static inline int crunch_init(void) { return 0; }
62#endif
56 63
57#endif 64#endif
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index dc431c5f04c..3d7cdab725b 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -85,6 +85,7 @@ MACHINE_START(MICRO9, "Contec Micro9-High")
85 .handle_irq = vic_handle_irq, 85 .handle_irq = vic_handle_irq,
86 .timer = &ep93xx_timer, 86 .timer = &ep93xx_timer,
87 .init_machine = micro9_init_machine, 87 .init_machine = micro9_init_machine,
88 .init_late = ep93xx_init_late,
88 .restart = ep93xx_restart, 89 .restart = ep93xx_restart,
89MACHINE_END 90MACHINE_END
90#endif 91#endif
@@ -98,6 +99,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid")
98 .handle_irq = vic_handle_irq, 99 .handle_irq = vic_handle_irq,
99 .timer = &ep93xx_timer, 100 .timer = &ep93xx_timer,
100 .init_machine = micro9_init_machine, 101 .init_machine = micro9_init_machine,
102 .init_late = ep93xx_init_late,
101 .restart = ep93xx_restart, 103 .restart = ep93xx_restart,
102MACHINE_END 104MACHINE_END
103#endif 105#endif
@@ -111,6 +113,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite")
111 .handle_irq = vic_handle_irq, 113 .handle_irq = vic_handle_irq,
112 .timer = &ep93xx_timer, 114 .timer = &ep93xx_timer,
113 .init_machine = micro9_init_machine, 115 .init_machine = micro9_init_machine,
116 .init_late = ep93xx_init_late,
114 .restart = ep93xx_restart, 117 .restart = ep93xx_restart,
115MACHINE_END 118MACHINE_END
116#endif 119#endif
@@ -124,6 +127,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim")
124 .handle_irq = vic_handle_irq, 127 .handle_irq = vic_handle_irq,
125 .timer = &ep93xx_timer, 128 .timer = &ep93xx_timer,
126 .init_machine = micro9_init_machine, 129 .init_machine = micro9_init_machine,
130 .init_late = ep93xx_init_late,
127 .restart = ep93xx_restart, 131 .restart = ep93xx_restart,
128MACHINE_END 132MACHINE_END
129#endif 133#endif
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index f40c2987e54..33dc0791741 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -86,5 +86,6 @@ MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
86 .handle_irq = vic_handle_irq, 86 .handle_irq = vic_handle_irq,
87 .timer = &ep93xx_timer, 87 .timer = &ep93xx_timer,
88 .init_machine = simone_init_machine, 88 .init_machine = simone_init_machine,
89 .init_late = ep93xx_init_late,
89 .restart = ep93xx_restart, 90 .restart = ep93xx_restart,
90MACHINE_END 91MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index 0c00852ef16..eb282378fa7 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -183,5 +183,6 @@ MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
183 .handle_irq = vic_handle_irq, 183 .handle_irq = vic_handle_irq,
184 .timer = &ep93xx_timer, 184 .timer = &ep93xx_timer,
185 .init_machine = snappercl15_init_machine, 185 .init_machine = snappercl15_init_machine,
186 .init_late = ep93xx_init_late,
186 .restart = ep93xx_restart, 187 .restart = ep93xx_restart,
187MACHINE_END 188MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 5ea790942e9..d4ef339d961 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -252,5 +252,6 @@ MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
252 .handle_irq = vic_handle_irq, 252 .handle_irq = vic_handle_irq,
253 .timer = &ep93xx_timer, 253 .timer = &ep93xx_timer,
254 .init_machine = ts72xx_init_machine, 254 .init_machine = ts72xx_init_machine,
255 .init_late = ep93xx_init_late,
255 .restart = ep93xx_restart, 256 .restart = ep93xx_restart,
256MACHINE_END 257MACHINE_END
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index ba156eb225e..2905a4929bd 100644
--- a/arch/arm/mach-ep93xx/vision_ep9307.c
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -367,5 +367,6 @@ MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
367 .handle_irq = vic_handle_irq, 367 .handle_irq = vic_handle_irq,
368 .timer = &ep93xx_timer, 368 .timer = &ep93xx_timer,
369 .init_machine = vision_init_machine, 369 .init_machine = vision_init_machine,
370 .init_late = ep93xx_init_late,
370 .restart = ep93xx_restart, 371 .restart = ep93xx_restart,
371MACHINE_END 372MACHINE_END
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 15b05b89cc3..43ebe909441 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -61,6 +61,7 @@ config SOC_EXYNOS5250
61 bool "SAMSUNG EXYNOS5250" 61 bool "SAMSUNG EXYNOS5250"
62 default y 62 default y
63 depends on ARCH_EXYNOS5 63 depends on ARCH_EXYNOS5
64 select SAMSUNG_DMADEV
64 help 65 help
65 Enable EXYNOS5250 SoC support 66 Enable EXYNOS5250 SoC support
66 67
@@ -70,7 +71,7 @@ config EXYNOS4_MCT
70 help 71 help
71 Use MCT (Multi Core Timer) as kernel timers 72 Use MCT (Multi Core Timer) as kernel timers
72 73
73config EXYNOS4_DEV_DMA 74config EXYNOS_DEV_DMA
74 bool 75 bool
75 help 76 help
76 Compile in amba device definitions for DMA controller 77 Compile in amba device definitions for DMA controller
@@ -80,15 +81,20 @@ config EXYNOS4_DEV_AHCI
80 help 81 help
81 Compile in platform device definitions for AHCI 82 Compile in platform device definitions for AHCI
82 83
84config EXYNOS_DEV_DRM
85 bool
86 help
87 Compile in platform device definitions for core DRM device
88
83config EXYNOS4_SETUP_FIMD0 89config EXYNOS4_SETUP_FIMD0
84 bool 90 bool
85 help 91 help
86 Common setup code for FIMD0. 92 Common setup code for FIMD0.
87 93
88config EXYNOS4_DEV_SYSMMU 94config EXYNOS_DEV_SYSMMU
89 bool 95 bool
90 help 96 help
91 Common setup code for SYSTEM MMU in EXYNOS4 97 Common setup code for SYSTEM MMU in EXYNOS platforms
92 98
93config EXYNOS4_DEV_DWMCI 99config EXYNOS4_DEV_DWMCI
94 bool 100 bool
@@ -161,7 +167,7 @@ config EXYNOS4_SETUP_USB_PHY
161 help 167 help
162 Common setup code for USB PHY controller 168 Common setup code for USB PHY controller
163 169
164config EXYNOS4_SETUP_SPI 170config EXYNOS_SETUP_SPI
165 bool 171 bool
166 help 172 help
167 Common setup code for SPI GPIO configurations. 173 Common setup code for SPI GPIO configurations.
@@ -201,12 +207,12 @@ config MACH_SMDKV310
201 select S3C_DEV_HSMMC3 207 select S3C_DEV_HSMMC3
202 select SAMSUNG_DEV_BACKLIGHT 208 select SAMSUNG_DEV_BACKLIGHT
203 select EXYNOS_DEV_DRM 209 select EXYNOS_DEV_DRM
210 select EXYNOS_DEV_SYSMMU
204 select EXYNOS4_DEV_AHCI 211 select EXYNOS4_DEV_AHCI
205 select SAMSUNG_DEV_KEYPAD 212 select SAMSUNG_DEV_KEYPAD
206 select EXYNOS4_DEV_DMA 213 select EXYNOS4_DEV_DMA
207 select SAMSUNG_DEV_PWM 214 select SAMSUNG_DEV_PWM
208 select EXYNOS4_DEV_USB_OHCI 215 select EXYNOS4_DEV_USB_OHCI
209 select EXYNOS4_DEV_SYSMMU
210 select EXYNOS4_SETUP_FIMD0 216 select EXYNOS4_SETUP_FIMD0
211 select EXYNOS4_SETUP_I2C1 217 select EXYNOS4_SETUP_I2C1
212 select EXYNOS4_SETUP_KEYPAD 218 select EXYNOS4_SETUP_KEYPAD
@@ -224,8 +230,7 @@ config MACH_ARMLEX4210
224 select S3C_DEV_HSMMC2 230 select S3C_DEV_HSMMC2
225 select S3C_DEV_HSMMC3 231 select S3C_DEV_HSMMC3
226 select EXYNOS4_DEV_AHCI 232 select EXYNOS4_DEV_AHCI
227 select EXYNOS4_DEV_DMA 233 select EXYNOS_DEV_DMA
228 select EXYNOS4_DEV_SYSMMU
229 select EXYNOS4_SETUP_SDHCI 234 select EXYNOS4_SETUP_SDHCI
230 help 235 help
231 Machine support for Samsung ARMLEX4210 based on EXYNOS4210 236 Machine support for Samsung ARMLEX4210 based on EXYNOS4210
@@ -256,6 +261,7 @@ config MACH_UNIVERSAL_C210
256 select S5P_DEV_MFC 261 select S5P_DEV_MFC
257 select S5P_DEV_ONENAND 262 select S5P_DEV_ONENAND
258 select S5P_DEV_TV 263 select S5P_DEV_TV
264 select EXYNOS_DEV_SYSMMU
259 select EXYNOS4_DEV_DMA 265 select EXYNOS4_DEV_DMA
260 select EXYNOS_DEV_DRM 266 select EXYNOS_DEV_DRM
261 select EXYNOS4_SETUP_FIMD0 267 select EXYNOS4_SETUP_FIMD0
@@ -332,6 +338,7 @@ config MACH_ORIGEN
332 select SAMSUNG_DEV_BACKLIGHT 338 select SAMSUNG_DEV_BACKLIGHT
333 select SAMSUNG_DEV_PWM 339 select SAMSUNG_DEV_PWM
334 select EXYNOS_DEV_DRM 340 select EXYNOS_DEV_DRM
341 select EXYNOS_DEV_SYSMMU
335 select EXYNOS4_DEV_DMA 342 select EXYNOS4_DEV_DMA
336 select EXYNOS4_DEV_USB_OHCI 343 select EXYNOS4_DEV_USB_OHCI
337 select EXYNOS4_SETUP_FIMD0 344 select EXYNOS4_SETUP_FIMD0
@@ -360,7 +367,8 @@ config MACH_SMDK4212
360 select SAMSUNG_DEV_BACKLIGHT 367 select SAMSUNG_DEV_BACKLIGHT
361 select SAMSUNG_DEV_KEYPAD 368 select SAMSUNG_DEV_KEYPAD
362 select SAMSUNG_DEV_PWM 369 select SAMSUNG_DEV_PWM
363 select EXYNOS4_DEV_DMA 370 select EXYNOS_DEV_SYSMMU
371 select EXYNOS_DEV_DMA
364 select EXYNOS4_SETUP_I2C1 372 select EXYNOS4_SETUP_I2C1
365 select EXYNOS4_SETUP_I2C3 373 select EXYNOS4_SETUP_I2C3
366 select EXYNOS4_SETUP_I2C7 374 select EXYNOS4_SETUP_I2C7
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 8631840d1b5..440a637c76f 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -50,10 +50,11 @@ obj-$(CONFIG_MACH_EXYNOS5_DT) += mach-exynos5-dt.o
50obj-y += dev-uart.o 50obj-y += dev-uart.o
51obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o 51obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
52obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o 52obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
53obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
54obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o 53obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
55obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o 54obj-$(CONFIG_EXYNOS_DEV_DMA) += dma.o
56obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o 55obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
56obj-$(CONFIG_EXYNOS_DEV_DRM) += dev-drm.o
57obj-$(CONFIG_EXYNOS_DEV_SYSMMU) += dev-sysmmu.o
57 58
58obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o 59obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o
59obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o 60obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
@@ -68,4 +69,4 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
68obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o 69obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
69obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 70obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
70obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o 71obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
71obj-$(CONFIG_EXYNOS4_SETUP_SPI) += setup-spi.o 72obj-$(CONFIG_EXYNOS_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
index b9862e22bf1..31bd181b051 100644
--- a/arch/arm/mach-exynos/Makefile.boot
+++ b/arch/arm/mach-exynos/Makefile.boot
@@ -1,2 +1,5 @@
1 zreladdr-y += 0x40008000 1 zreladdr-y += 0x40008000
2params_phys-y := 0x40000100 2params_phys-y := 0x40000100
3
4dtb-$(CONFIG_MACH_EXYNOS4_DT) += exynos4210-origen.dtb exynos4210-smdkv310.dtb
5dtb-$(CONFIG_MACH_EXYNOS5_DT) += exynos5250-smdk5250.dtb
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 6efd1e5919f..bcb7db45314 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -168,7 +168,7 @@ static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
168 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable); 168 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
169} 169}
170 170
171static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) 171int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
172{ 172{
173 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable); 173 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
174} 174}
@@ -198,6 +198,11 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
198 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable); 198 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
199} 199}
200 200
201int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
202{
203 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
204}
205
201static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable) 206static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
202{ 207{
203 return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); 208 return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
@@ -678,61 +683,55 @@ static struct clk exynos4_init_clocks_off[] = {
678 .enable = exynos4_clk_ip_peril_ctrl, 683 .enable = exynos4_clk_ip_peril_ctrl,
679 .ctrlbit = (1 << 14), 684 .ctrlbit = (1 << 14),
680 }, { 685 }, {
681 .name = "SYSMMU_MDMA", 686 .name = SYSMMU_CLOCK_NAME,
687 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
688 .enable = exynos4_clk_ip_mfc_ctrl,
689 .ctrlbit = (1 << 1),
690 }, {
691 .name = SYSMMU_CLOCK_NAME,
692 .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
693 .enable = exynos4_clk_ip_mfc_ctrl,
694 .ctrlbit = (1 << 2),
695 }, {
696 .name = SYSMMU_CLOCK_NAME,
697 .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
698 .enable = exynos4_clk_ip_tv_ctrl,
699 .ctrlbit = (1 << 4),
700 }, {
701 .name = SYSMMU_CLOCK_NAME,
702 .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
703 .enable = exynos4_clk_ip_cam_ctrl,
704 .ctrlbit = (1 << 11),
705 }, {
706 .name = SYSMMU_CLOCK_NAME,
707 .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
682 .enable = exynos4_clk_ip_image_ctrl, 708 .enable = exynos4_clk_ip_image_ctrl,
683 .ctrlbit = (1 << 5), 709 .ctrlbit = (1 << 4),
684 }, { 710 }, {
685 .name = "SYSMMU_FIMC0", 711 .name = SYSMMU_CLOCK_NAME,
712 .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5),
686 .enable = exynos4_clk_ip_cam_ctrl, 713 .enable = exynos4_clk_ip_cam_ctrl,
687 .ctrlbit = (1 << 7), 714 .ctrlbit = (1 << 7),
688 }, { 715 }, {
689 .name = "SYSMMU_FIMC1", 716 .name = SYSMMU_CLOCK_NAME,
717 .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6),
690 .enable = exynos4_clk_ip_cam_ctrl, 718 .enable = exynos4_clk_ip_cam_ctrl,
691 .ctrlbit = (1 << 8), 719 .ctrlbit = (1 << 8),
692 }, { 720 }, {
693 .name = "SYSMMU_FIMC2", 721 .name = SYSMMU_CLOCK_NAME,
722 .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7),
694 .enable = exynos4_clk_ip_cam_ctrl, 723 .enable = exynos4_clk_ip_cam_ctrl,
695 .ctrlbit = (1 << 9), 724 .ctrlbit = (1 << 9),
696 }, { 725 }, {
697 .name = "SYSMMU_FIMC3", 726 .name = SYSMMU_CLOCK_NAME,
727 .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8),
698 .enable = exynos4_clk_ip_cam_ctrl, 728 .enable = exynos4_clk_ip_cam_ctrl,
699 .ctrlbit = (1 << 10), 729 .ctrlbit = (1 << 10),
700 }, { 730 }, {
701 .name = "SYSMMU_JPEG", 731 .name = SYSMMU_CLOCK_NAME,
702 .enable = exynos4_clk_ip_cam_ctrl, 732 .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
703 .ctrlbit = (1 << 11),
704 }, {
705 .name = "SYSMMU_FIMD0",
706 .enable = exynos4_clk_ip_lcd0_ctrl, 733 .enable = exynos4_clk_ip_lcd0_ctrl,
707 .ctrlbit = (1 << 4), 734 .ctrlbit = (1 << 4),
708 }, {
709 .name = "SYSMMU_FIMD1",
710 .enable = exynos4_clk_ip_lcd1_ctrl,
711 .ctrlbit = (1 << 4),
712 }, {
713 .name = "SYSMMU_PCIe",
714 .enable = exynos4_clk_ip_fsys_ctrl,
715 .ctrlbit = (1 << 18),
716 }, {
717 .name = "SYSMMU_G2D",
718 .enable = exynos4_clk_ip_image_ctrl,
719 .ctrlbit = (1 << 3),
720 }, {
721 .name = "SYSMMU_ROTATOR",
722 .enable = exynos4_clk_ip_image_ctrl,
723 .ctrlbit = (1 << 4),
724 }, {
725 .name = "SYSMMU_TV",
726 .enable = exynos4_clk_ip_tv_ctrl,
727 .ctrlbit = (1 << 4),
728 }, {
729 .name = "SYSMMU_MFC_L",
730 .enable = exynos4_clk_ip_mfc_ctrl,
731 .ctrlbit = (1 << 1),
732 }, {
733 .name = "SYSMMU_MFC_R",
734 .enable = exynos4_clk_ip_mfc_ctrl,
735 .ctrlbit = (1 << 2),
736 } 735 }
737}; 736};
738 737
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
index cb71c29c14d..28a11970118 100644
--- a/arch/arm/mach-exynos/clock-exynos4.h
+++ b/arch/arm/mach-exynos/clock-exynos4.h
@@ -26,5 +26,7 @@ extern struct clk *exynos4_clkset_group_list[];
26extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable); 26extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
27extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable); 27extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
28extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable); 28extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
29extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
30extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
29 31
30#endif /* __ASM_ARCH_CLOCK_H */ 32#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index 3b131e4b6ef..b8689ff60ba 100644
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -26,6 +26,7 @@
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/map.h> 27#include <mach/map.h>
28#include <mach/regs-clock.h> 28#include <mach/regs-clock.h>
29#include <mach/sysmmu.h>
29 30
30#include "common.h" 31#include "common.h"
31#include "clock-exynos4.h" 32#include "clock-exynos4.h"
@@ -94,6 +95,16 @@ static struct clk init_clocks_off[] = {
94 .devname = "exynos4-fb.1", 95 .devname = "exynos4-fb.1",
95 .enable = exynos4_clk_ip_lcd1_ctrl, 96 .enable = exynos4_clk_ip_lcd1_ctrl,
96 .ctrlbit = (1 << 0), 97 .ctrlbit = (1 << 0),
98 }, {
99 .name = SYSMMU_CLOCK_NAME,
100 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
101 .enable = exynos4_clk_ip_image_ctrl,
102 .ctrlbit = (1 << 3),
103 }, {
104 .name = SYSMMU_CLOCK_NAME,
105 .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11),
106 .enable = exynos4_clk_ip_lcd1_ctrl,
107 .ctrlbit = (1 << 4),
97 }, 108 },
98}; 109};
99 110
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index 3ecc01e06f7..da397d21bbc 100644
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -26,6 +26,7 @@
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/map.h> 27#include <mach/map.h>
28#include <mach/regs-clock.h> 28#include <mach/regs-clock.h>
29#include <mach/sysmmu.h>
29 30
30#include "common.h" 31#include "common.h"
31#include "clock-exynos4.h" 32#include "clock-exynos4.h"
@@ -39,6 +40,16 @@ static struct sleep_save exynos4212_clock_save[] = {
39}; 40};
40#endif 41#endif
41 42
43static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
44{
45 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
46}
47
48static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
49{
50 return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
51}
52
42static struct clk *clk_src_mpll_user_list[] = { 53static struct clk *clk_src_mpll_user_list[] = {
43 [0] = &clk_fin_mpll, 54 [0] = &clk_fin_mpll,
44 [1] = &exynos4_clk_mout_mpll.clk, 55 [1] = &exynos4_clk_mout_mpll.clk,
@@ -66,7 +77,32 @@ static struct clksrc_clk clksrcs[] = {
66}; 77};
67 78
68static struct clk init_clocks_off[] = { 79static struct clk init_clocks_off[] = {
69 /* nothing here yet */ 80 {
81 .name = SYSMMU_CLOCK_NAME,
82 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
83 .enable = exynos4_clk_ip_dmc_ctrl,
84 .ctrlbit = (1 << 24),
85 }, {
86 .name = SYSMMU_CLOCK_NAME,
87 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
88 .enable = exynos4212_clk_ip_isp0_ctrl,
89 .ctrlbit = (7 << 8),
90 }, {
91 .name = SYSMMU_CLOCK_NAME2,
92 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
93 .enable = exynos4212_clk_ip_isp1_ctrl,
94 .ctrlbit = (1 << 4),
95 }, {
96 .name = "flite",
97 .devname = "exynos-fimc-lite.0",
98 .enable = exynos4212_clk_ip_isp0_ctrl,
99 .ctrlbit = (1 << 4),
100 }, {
101 .name = "flite",
102 .devname = "exynos-fimc-lite.1",
103 .enable = exynos4212_clk_ip_isp0_ctrl,
104 .ctrlbit = (1 << 3),
105 }
70}; 106};
71 107
72#ifdef CONFIG_PM_SLEEP 108#ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 7ac6ff4c46b..5aa460b01fd 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -82,6 +82,11 @@ static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
82 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable); 82 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
83} 83}
84 84
85static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
86{
87 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
88}
89
85static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable) 90static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
86{ 91{
87 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable); 92 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
@@ -127,6 +132,21 @@ static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
127 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable); 132 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
128} 133}
129 134
135static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
136{
137 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
138}
139
140static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
141{
142 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable);
143}
144
145static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
146{
147 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
148}
149
130/* Core list of CMU_CPU side */ 150/* Core list of CMU_CPU side */
131 151
132static struct clksrc_clk exynos5_clk_mout_apll = { 152static struct clksrc_clk exynos5_clk_mout_apll = {
@@ -145,11 +165,29 @@ static struct clksrc_clk exynos5_clk_sclk_apll = {
145 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 }, 165 .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
146}; 166};
147 167
168static struct clksrc_clk exynos5_clk_mout_bpll_fout = {
169 .clk = {
170 .name = "mout_bpll_fout",
171 },
172 .sources = &clk_src_bpll_fout,
173 .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 },
174};
175
176static struct clk *exynos5_clk_src_bpll_list[] = {
177 [0] = &clk_fin_bpll,
178 [1] = &exynos5_clk_mout_bpll_fout.clk,
179};
180
181static struct clksrc_sources exynos5_clk_src_bpll = {
182 .sources = exynos5_clk_src_bpll_list,
183 .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_list),
184};
185
148static struct clksrc_clk exynos5_clk_mout_bpll = { 186static struct clksrc_clk exynos5_clk_mout_bpll = {
149 .clk = { 187 .clk = {
150 .name = "mout_bpll", 188 .name = "mout_bpll",
151 }, 189 },
152 .sources = &clk_src_bpll, 190 .sources = &exynos5_clk_src_bpll,
153 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 }, 191 .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
154}; 192};
155 193
@@ -187,11 +225,29 @@ static struct clksrc_clk exynos5_clk_mout_epll = {
187 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 }, 225 .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
188}; 226};
189 227
228static struct clksrc_clk exynos5_clk_mout_mpll_fout = {
229 .clk = {
230 .name = "mout_mpll_fout",
231 },
232 .sources = &clk_src_mpll_fout,
233 .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 },
234};
235
236static struct clk *exynos5_clk_src_mpll_list[] = {
237 [0] = &clk_fin_mpll,
238 [1] = &exynos5_clk_mout_mpll_fout.clk,
239};
240
241static struct clksrc_sources exynos5_clk_src_mpll = {
242 .sources = exynos5_clk_src_mpll_list,
243 .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_list),
244};
245
190struct clksrc_clk exynos5_clk_mout_mpll = { 246struct clksrc_clk exynos5_clk_mout_mpll = {
191 .clk = { 247 .clk = {
192 .name = "mout_mpll", 248 .name = "mout_mpll",
193 }, 249 },
194 .sources = &clk_src_mpll, 250 .sources = &exynos5_clk_src_mpll,
195 .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 }, 251 .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
196}; 252};
197 253
@@ -454,6 +510,11 @@ static struct clk exynos5_init_clocks_off[] = {
454 .enable = exynos5_clk_ip_peris_ctrl, 510 .enable = exynos5_clk_ip_peris_ctrl,
455 .ctrlbit = (1 << 20), 511 .ctrlbit = (1 << 20),
456 }, { 512 }, {
513 .name = "watchdog",
514 .parent = &exynos5_clk_aclk_66.clk,
515 .enable = exynos5_clk_ip_peris_ctrl,
516 .ctrlbit = (1 << 19),
517 }, {
457 .name = "hsmmc", 518 .name = "hsmmc",
458 .devname = "exynos4-sdhci.0", 519 .devname = "exynos4-sdhci.0",
459 .parent = &exynos5_clk_aclk_200.clk, 520 .parent = &exynos5_clk_aclk_200.clk,
@@ -630,6 +691,76 @@ static struct clk exynos5_init_clocks_off[] = {
630 .parent = &exynos5_clk_aclk_66.clk, 691 .parent = &exynos5_clk_aclk_66.clk,
631 .enable = exynos5_clk_ip_peric_ctrl, 692 .enable = exynos5_clk_ip_peric_ctrl,
632 .ctrlbit = (1 << 14), 693 .ctrlbit = (1 << 14),
694 }, {
695 .name = SYSMMU_CLOCK_NAME,
696 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
697 .enable = &exynos5_clk_ip_mfc_ctrl,
698 .ctrlbit = (1 << 1),
699 }, {
700 .name = SYSMMU_CLOCK_NAME,
701 .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
702 .enable = &exynos5_clk_ip_mfc_ctrl,
703 .ctrlbit = (1 << 2),
704 }, {
705 .name = SYSMMU_CLOCK_NAME,
706 .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
707 .enable = &exynos5_clk_ip_disp1_ctrl,
708 .ctrlbit = (1 << 9)
709 }, {
710 .name = SYSMMU_CLOCK_NAME,
711 .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
712 .enable = &exynos5_clk_ip_gen_ctrl,
713 .ctrlbit = (1 << 7),
714 }, {
715 .name = SYSMMU_CLOCK_NAME,
716 .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
717 .enable = &exynos5_clk_ip_gen_ctrl,
718 .ctrlbit = (1 << 6)
719 }, {
720 .name = SYSMMU_CLOCK_NAME,
721 .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
722 .enable = &exynos5_clk_ip_gscl_ctrl,
723 .ctrlbit = (1 << 7),
724 }, {
725 .name = SYSMMU_CLOCK_NAME,
726 .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
727 .enable = &exynos5_clk_ip_gscl_ctrl,
728 .ctrlbit = (1 << 8),
729 }, {
730 .name = SYSMMU_CLOCK_NAME,
731 .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
732 .enable = &exynos5_clk_ip_gscl_ctrl,
733 .ctrlbit = (1 << 9),
734 }, {
735 .name = SYSMMU_CLOCK_NAME,
736 .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
737 .enable = &exynos5_clk_ip_gscl_ctrl,
738 .ctrlbit = (1 << 10),
739 }, {
740 .name = SYSMMU_CLOCK_NAME,
741 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
742 .enable = &exynos5_clk_ip_isp0_ctrl,
743 .ctrlbit = (0x3F << 8),
744 }, {
745 .name = SYSMMU_CLOCK_NAME2,
746 .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
747 .enable = &exynos5_clk_ip_isp1_ctrl,
748 .ctrlbit = (0xF << 4),
749 }, {
750 .name = SYSMMU_CLOCK_NAME,
751 .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
752 .enable = &exynos5_clk_ip_gscl_ctrl,
753 .ctrlbit = (1 << 11),
754 }, {
755 .name = SYSMMU_CLOCK_NAME,
756 .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
757 .enable = &exynos5_clk_ip_gscl_ctrl,
758 .ctrlbit = (1 << 12),
759 }, {
760 .name = SYSMMU_CLOCK_NAME,
761 .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
762 .enable = &exynos5_clk_ip_acp_ctrl,
763 .ctrlbit = (1 << 7)
633 } 764 }
634}; 765};
635 766
@@ -941,10 +1072,12 @@ static struct clksrc_clk *exynos5_sysclks[] = {
941 &exynos5_clk_mout_apll, 1072 &exynos5_clk_mout_apll,
942 &exynos5_clk_sclk_apll, 1073 &exynos5_clk_sclk_apll,
943 &exynos5_clk_mout_bpll, 1074 &exynos5_clk_mout_bpll,
1075 &exynos5_clk_mout_bpll_fout,
944 &exynos5_clk_mout_bpll_user, 1076 &exynos5_clk_mout_bpll_user,
945 &exynos5_clk_mout_cpll, 1077 &exynos5_clk_mout_cpll,
946 &exynos5_clk_mout_epll, 1078 &exynos5_clk_mout_epll,
947 &exynos5_clk_mout_mpll, 1079 &exynos5_clk_mout_mpll,
1080 &exynos5_clk_mout_mpll_fout,
948 &exynos5_clk_mout_mpll_user, 1081 &exynos5_clk_mout_mpll_user,
949 &exynos5_clk_vpllsrc, 1082 &exynos5_clk_vpllsrc,
950 &exynos5_clk_sclk_vpll, 1083 &exynos5_clk_sclk_vpll,
@@ -1008,7 +1141,9 @@ static struct clk *exynos5_clks[] __initdata = {
1008 &exynos5_clk_sclk_hdmi27m, 1141 &exynos5_clk_sclk_hdmi27m,
1009 &exynos5_clk_sclk_hdmiphy, 1142 &exynos5_clk_sclk_hdmiphy,
1010 &clk_fout_bpll, 1143 &clk_fout_bpll,
1144 &clk_fout_bpll_div2,
1011 &clk_fout_cpll, 1145 &clk_fout_cpll,
1146 &clk_fout_mpll_div2,
1012 &exynos5_clk_armclk, 1147 &exynos5_clk_armclk,
1013}; 1148};
1014 1149
@@ -1173,8 +1308,10 @@ void __init_or_cpufreq exynos5_setup_clocks(void)
1173 1308
1174 clk_fout_apll.ops = &exynos5_fout_apll_ops; 1309 clk_fout_apll.ops = &exynos5_fout_apll_ops;
1175 clk_fout_bpll.rate = bpll; 1310 clk_fout_bpll.rate = bpll;
1311 clk_fout_bpll_div2.rate = bpll >> 1;
1176 clk_fout_cpll.rate = cpll; 1312 clk_fout_cpll.rate = cpll;
1177 clk_fout_mpll.rate = mpll; 1313 clk_fout_mpll.rate = mpll;
1314 clk_fout_mpll_div2.rate = mpll >> 1;
1178 clk_fout_epll.rate = epll; 1315 clk_fout_epll.rate = epll;
1179 clk_fout_vpll.rate = vpll; 1316 clk_fout_vpll.rate = vpll;
1180 1317
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 5ccd6e80a60..742edd3bbec 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -19,6 +19,9 @@
19#include <linux/serial_core.h> 19#include <linux/serial_core.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_irq.h> 21#include <linux/of_irq.h>
22#include <linux/export.h>
23#include <linux/irqdomain.h>
24#include <linux/of_address.h>
22 25
23#include <asm/proc-fns.h> 26#include <asm/proc-fns.h>
24#include <asm/exception.h> 27#include <asm/exception.h>
@@ -265,12 +268,12 @@ static struct map_desc exynos5_iodesc[] __initdata = {
265 }, { 268 }, {
266 .virtual = (unsigned long)S5P_VA_GIC_CPU, 269 .virtual = (unsigned long)S5P_VA_GIC_CPU,
267 .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU), 270 .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU),
268 .length = SZ_64K, 271 .length = SZ_8K,
269 .type = MT_DEVICE, 272 .type = MT_DEVICE,
270 }, { 273 }, {
271 .virtual = (unsigned long)S5P_VA_GIC_DIST, 274 .virtual = (unsigned long)S5P_VA_GIC_DIST,
272 .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST), 275 .pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST),
273 .length = SZ_64K, 276 .length = SZ_4K,
274 .type = MT_DEVICE, 277 .type = MT_DEVICE,
275 }, 278 },
276}; 279};
@@ -285,6 +288,11 @@ void exynos5_restart(char mode, const char *cmd)
285 __raw_writel(0x1, EXYNOS_SWRESET); 288 __raw_writel(0x1, EXYNOS_SWRESET);
286} 289}
287 290
291void __init exynos_init_late(void)
292{
293 exynos_pm_late_initcall();
294}
295
288/* 296/*
289 * exynos_map_io 297 * exynos_map_io
290 * 298 *
@@ -399,6 +407,7 @@ struct combiner_chip_data {
399 void __iomem *base; 407 void __iomem *base;
400}; 408};
401 409
410static struct irq_domain *combiner_irq_domain;
402static struct combiner_chip_data combiner_data[MAX_COMBINER_NR]; 411static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
403 412
404static inline void __iomem *combiner_base(struct irq_data *data) 413static inline void __iomem *combiner_base(struct irq_data *data)
@@ -411,14 +420,14 @@ static inline void __iomem *combiner_base(struct irq_data *data)
411 420
412static void combiner_mask_irq(struct irq_data *data) 421static void combiner_mask_irq(struct irq_data *data)
413{ 422{
414 u32 mask = 1 << (data->irq % 32); 423 u32 mask = 1 << (data->hwirq % 32);
415 424
416 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR); 425 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
417} 426}
418 427
419static void combiner_unmask_irq(struct irq_data *data) 428static void combiner_unmask_irq(struct irq_data *data)
420{ 429{
421 u32 mask = 1 << (data->irq % 32); 430 u32 mask = 1 << (data->hwirq % 32);
422 431
423 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET); 432 __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
424} 433}
@@ -474,49 +483,131 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i
474 irq_set_chained_handler(irq, combiner_handle_cascade_irq); 483 irq_set_chained_handler(irq, combiner_handle_cascade_irq);
475} 484}
476 485
477static void __init combiner_init(unsigned int combiner_nr, void __iomem *base, 486static void __init combiner_init_one(unsigned int combiner_nr,
478 unsigned int irq_start) 487 void __iomem *base)
479{ 488{
480 unsigned int i;
481 unsigned int max_nr;
482
483 if (soc_is_exynos5250())
484 max_nr = EXYNOS5_MAX_COMBINER_NR;
485 else
486 max_nr = EXYNOS4_MAX_COMBINER_NR;
487
488 if (combiner_nr >= max_nr)
489 BUG();
490
491 combiner_data[combiner_nr].base = base; 489 combiner_data[combiner_nr].base = base;
492 combiner_data[combiner_nr].irq_offset = irq_start; 490 combiner_data[combiner_nr].irq_offset = irq_find_mapping(
491 combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
493 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); 492 combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
494 493
495 /* Disable all interrupts */ 494 /* Disable all interrupts */
496
497 __raw_writel(combiner_data[combiner_nr].irq_mask, 495 __raw_writel(combiner_data[combiner_nr].irq_mask,
498 base + COMBINER_ENABLE_CLEAR); 496 base + COMBINER_ENABLE_CLEAR);
497}
498
499#ifdef CONFIG_OF
500static int combiner_irq_domain_xlate(struct irq_domain *d,
501 struct device_node *controller,
502 const u32 *intspec, unsigned int intsize,
503 unsigned long *out_hwirq,
504 unsigned int *out_type)
505{
506 if (d->of_node != controller)
507 return -EINVAL;
508
509 if (intsize < 2)
510 return -EINVAL;
511
512 *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1];
513 *out_type = 0;
514
515 return 0;
516}
517#else
518static int combiner_irq_domain_xlate(struct irq_domain *d,
519 struct device_node *controller,
520 const u32 *intspec, unsigned int intsize,
521 unsigned long *out_hwirq,
522 unsigned int *out_type)
523{
524 return -EINVAL;
525}
526#endif
527
528static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
529 irq_hw_number_t hw)
530{
531 irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
532 irq_set_chip_data(irq, &combiner_data[hw >> 3]);
533 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
534
535 return 0;
536}
537
538static struct irq_domain_ops combiner_irq_domain_ops = {
539 .xlate = combiner_irq_domain_xlate,
540 .map = combiner_irq_domain_map,
541};
542
543void __init combiner_init(void __iomem *combiner_base, struct device_node *np)
544{
545 int i, irq, irq_base;
546 unsigned int max_nr, nr_irq;
547
548 if (np) {
549 if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
550 pr_warning("%s: number of combiners not specified, "
551 "setting default as %d.\n",
552 __func__, EXYNOS4_MAX_COMBINER_NR);
553 max_nr = EXYNOS4_MAX_COMBINER_NR;
554 }
555 } else {
556 max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
557 EXYNOS4_MAX_COMBINER_NR;
558 }
559 nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
499 560
500 /* Setup the Linux IRQ subsystem */ 561 irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
562 if (IS_ERR_VALUE(irq_base)) {
563 irq_base = COMBINER_IRQ(0, 0);
564 pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
565 }
501 566
502 for (i = irq_start; i < combiner_data[combiner_nr].irq_offset 567 combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
503 + MAX_IRQ_IN_COMBINER; i++) { 568 &combiner_irq_domain_ops, &combiner_data);
504 irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq); 569 if (WARN_ON(!combiner_irq_domain)) {
505 irq_set_chip_data(i, &combiner_data[combiner_nr]); 570 pr_warning("%s: irq domain init failed\n", __func__);
506 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 571 return;
572 }
573
574 for (i = 0; i < max_nr; i++) {
575 combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
576 irq = IRQ_SPI(i);
577#ifdef CONFIG_OF
578 if (np)
579 irq = irq_of_parse_and_map(np, i);
580#endif
581 combiner_cascade_irq(i, irq);
507 } 582 }
508} 583}
509 584
510#ifdef CONFIG_OF 585#ifdef CONFIG_OF
586int __init combiner_of_init(struct device_node *np, struct device_node *parent)
587{
588 void __iomem *combiner_base;
589
590 combiner_base = of_iomap(np, 0);
591 if (!combiner_base) {
592 pr_err("%s: failed to map combiner registers\n", __func__);
593 return -ENXIO;
594 }
595
596 combiner_init(combiner_base, np);
597
598 return 0;
599}
600
511static const struct of_device_id exynos4_dt_irq_match[] = { 601static const struct of_device_id exynos4_dt_irq_match[] = {
512 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, 602 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
603 { .compatible = "samsung,exynos4210-combiner",
604 .data = combiner_of_init, },
513 {}, 605 {},
514}; 606};
515#endif 607#endif
516 608
517void __init exynos4_init_irq(void) 609void __init exynos4_init_irq(void)
518{ 610{
519 int irq;
520 unsigned int gic_bank_offset; 611 unsigned int gic_bank_offset;
521 612
522 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; 613 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
@@ -528,12 +619,8 @@ void __init exynos4_init_irq(void)
528 of_irq_init(exynos4_dt_irq_match); 619 of_irq_init(exynos4_dt_irq_match);
529#endif 620#endif
530 621
531 for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) { 622 if (!of_have_populated_dt())
532 623 combiner_init(S5P_VA_COMBINER_BASE, NULL);
533 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
534 COMBINER_IRQ(irq, 0));
535 combiner_cascade_irq(irq, IRQ_SPI(irq));
536 }
537 624
538 /* 625 /*
539 * The parameters of s5p_init_irq() are for VIC init. 626 * The parameters of s5p_init_irq() are for VIC init.
@@ -545,18 +632,9 @@ void __init exynos4_init_irq(void)
545 632
546void __init exynos5_init_irq(void) 633void __init exynos5_init_irq(void)
547{ 634{
548 int irq;
549
550#ifdef CONFIG_OF 635#ifdef CONFIG_OF
551 of_irq_init(exynos4_dt_irq_match); 636 of_irq_init(exynos4_dt_irq_match);
552#endif 637#endif
553
554 for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) {
555 combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
556 COMBINER_IRQ(irq, 0));
557 combiner_cascade_irq(irq, IRQ_SPI(irq));
558 }
559
560 /* 638 /*
561 * The parameters of s5p_init_irq() are for VIC init. 639 * The parameters of s5p_init_irq() are for VIC init.
562 * Theses parameters should be NULL and 0 because EXYNOS4 640 * Theses parameters should be NULL and 0 because EXYNOS4
@@ -565,30 +643,18 @@ void __init exynos5_init_irq(void)
565 s5p_init_irq(NULL, 0); 643 s5p_init_irq(NULL, 0);
566} 644}
567 645
568struct bus_type exynos4_subsys = { 646struct bus_type exynos_subsys = {
569 .name = "exynos4-core", 647 .name = "exynos-core",
570 .dev_name = "exynos4-core", 648 .dev_name = "exynos-core",
571};
572
573struct bus_type exynos5_subsys = {
574 .name = "exynos5-core",
575 .dev_name = "exynos5-core",
576}; 649};
577 650
578static struct device exynos4_dev = { 651static struct device exynos4_dev = {
579 .bus = &exynos4_subsys, 652 .bus = &exynos_subsys,
580};
581
582static struct device exynos5_dev = {
583 .bus = &exynos5_subsys,
584}; 653};
585 654
586static int __init exynos_core_init(void) 655static int __init exynos_core_init(void)
587{ 656{
588 if (soc_is_exynos5250()) 657 return subsys_system_register(&exynos_subsys, NULL);
589 return subsys_system_register(&exynos5_subsys, NULL);
590 else
591 return subsys_system_register(&exynos4_subsys, NULL);
592} 658}
593core_initcall(exynos_core_init); 659core_initcall(exynos_core_init);
594 660
@@ -675,10 +741,7 @@ static int __init exynos_init(void)
675{ 741{
676 printk(KERN_INFO "EXYNOS: Initializing architecture\n"); 742 printk(KERN_INFO "EXYNOS: Initializing architecture\n");
677 743
678 if (soc_is_exynos5250()) 744 return device_register(&exynos4_dev);
679 return device_register(&exynos5_dev);
680 else
681 return device_register(&exynos4_dev);
682} 745}
683 746
684/* uart registration process */ 747/* uart registration process */
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 677b5467df1..aed2eeb0651 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -19,6 +19,13 @@ void exynos4_init_irq(void);
19void exynos5_init_irq(void); 19void exynos5_init_irq(void);
20void exynos4_restart(char mode, const char *cmd); 20void exynos4_restart(char mode, const char *cmd);
21void exynos5_restart(char mode, const char *cmd); 21void exynos5_restart(char mode, const char *cmd);
22void exynos_init_late(void);
23
24#ifdef CONFIG_PM_GENERIC_DOMAINS
25int exynos_pm_late_initcall(void);
26#else
27static int exynos_pm_late_initcall(void) { return 0; }
28#endif
22 29
23#ifdef CONFIG_ARCH_EXYNOS4 30#ifdef CONFIG_ARCH_EXYNOS4
24void exynos4_register_clocks(void); 31void exynos4_register_clocks(void);
diff --git a/arch/arm/mach-exynos/dev-drm.c b/arch/arm/mach-exynos/dev-drm.c
new file mode 100644
index 00000000000..17c9c6ecc2e
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-drm.c
@@ -0,0 +1,29 @@
1/*
2 * linux/arch/arm/mach-exynos/dev-drm.c
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * EXYNOS - core DRM device
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 as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14
15#include <linux/kernel.h>
16#include <linux/dma-mapping.h>
17#include <linux/platform_device.h>
18
19#include <plat/devs.h>
20
21static u64 exynos_drm_dma_mask = DMA_BIT_MASK(32);
22
23struct platform_device exynos_device_drm = {
24 .name = "exynos-drm",
25 .dev = {
26 .dma_mask = &exynos_drm_dma_mask,
27 .coherent_dma_mask = DMA_BIT_MASK(32),
28 }
29};
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 781563fcb15..c5b1ea301df 100644
--- a/arch/arm/mach-exynos/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -1,9 +1,9 @@
1/* linux/arch/arm/mach-exynos4/dev-sysmmu.c 1/* linux/arch/arm/mach-exynos/dev-sysmmu.c
2 * 2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 4 * http://www.samsung.com
5 * 5 *
6 * EXYNOS4 - System MMU support 6 * EXYNOS - System MMU support
7 * 7 *
8 * 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
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -12,222 +12,263 @@
12 12
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/export.h> 15
16#include <plat/cpu.h>
16 17
17#include <mach/map.h> 18#include <mach/map.h>
18#include <mach/irqs.h> 19#include <mach/irqs.h>
19#include <mach/sysmmu.h> 20#include <mach/sysmmu.h>
20#include <plat/s5p-clock.h>
21
22/* These names must be equal to the clock names in mach-exynos4/clock.c */
23const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
24 "SYSMMU_MDMA" ,
25 "SYSMMU_SSS" ,
26 "SYSMMU_FIMC0" ,
27 "SYSMMU_FIMC1" ,
28 "SYSMMU_FIMC2" ,
29 "SYSMMU_FIMC3" ,
30 "SYSMMU_JPEG" ,
31 "SYSMMU_FIMD0" ,
32 "SYSMMU_FIMD1" ,
33 "SYSMMU_PCIe" ,
34 "SYSMMU_G2D" ,
35 "SYSMMU_ROTATOR",
36 "SYSMMU_MDMA2" ,
37 "SYSMMU_TV" ,
38 "SYSMMU_MFC_L" ,
39 "SYSMMU_MFC_R" ,
40};
41 21
42static struct resource exynos4_sysmmu_resource[] = { 22static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
43 [0] = { 23
44 .start = EXYNOS4_PA_SYSMMU_MDMA, 24#define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
45 .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1, 25static struct sysmmu_platform_data platdata_##ipname = { \
46 .flags = IORESOURCE_MEM, 26 .dbgname = #ipname, \
47 }, 27}; \
48 [1] = { 28struct platform_device SYSMMU_PLATDEV(ipname) = \
49 .start = IRQ_SYSMMU_MDMA0_0, 29{ \
50 .end = IRQ_SYSMMU_MDMA0_0, 30 .name = SYSMMU_DEVNAME_BASE, \
51 .flags = IORESOURCE_IRQ, 31 .id = devid, \
52 }, 32 .dev = { \
53 [2] = { 33 .dma_mask = &exynos_sysmmu_dma_mask, \
54 .start = EXYNOS4_PA_SYSMMU_SSS, 34 .coherent_dma_mask = DMA_BIT_MASK(32), \
55 .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1, 35 .platform_data = &platdata_##ipname, \
56 .flags = IORESOURCE_MEM, 36 }, \
57 }, 37}
58 [3] = { 38
59 .start = IRQ_SYSMMU_SSS_0, 39SYSMMU_PLATFORM_DEVICE(mfc_l, 0);
60 .end = IRQ_SYSMMU_SSS_0, 40SYSMMU_PLATFORM_DEVICE(mfc_r, 1);
61 .flags = IORESOURCE_IRQ, 41SYSMMU_PLATFORM_DEVICE(tv, 2);
62 }, 42SYSMMU_PLATFORM_DEVICE(jpeg, 3);
63 [4] = { 43SYSMMU_PLATFORM_DEVICE(rot, 4);
64 .start = EXYNOS4_PA_SYSMMU_FIMC0, 44SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */
65 .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1, 45SYSMMU_PLATFORM_DEVICE(fimc1, 6);
66 .flags = IORESOURCE_MEM, 46SYSMMU_PLATFORM_DEVICE(fimc2, 7);
67 }, 47SYSMMU_PLATFORM_DEVICE(fimc3, 8);
68 [5] = { 48SYSMMU_PLATFORM_DEVICE(gsc0, 5);
69 .start = IRQ_SYSMMU_FIMC0_0, 49SYSMMU_PLATFORM_DEVICE(gsc1, 6);
70 .end = IRQ_SYSMMU_FIMC0_0, 50SYSMMU_PLATFORM_DEVICE(gsc2, 7);
71 .flags = IORESOURCE_IRQ, 51SYSMMU_PLATFORM_DEVICE(gsc3, 8);
72 }, 52SYSMMU_PLATFORM_DEVICE(isp, 9);
73 [6] = { 53SYSMMU_PLATFORM_DEVICE(fimd0, 10);
74 .start = EXYNOS4_PA_SYSMMU_FIMC1, 54SYSMMU_PLATFORM_DEVICE(fimd1, 11);
75 .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1, 55SYSMMU_PLATFORM_DEVICE(camif0, 12);
76 .flags = IORESOURCE_MEM, 56SYSMMU_PLATFORM_DEVICE(camif1, 13);
77 }, 57SYSMMU_PLATFORM_DEVICE(2d, 14);
78 [7] = { 58
79 .start = IRQ_SYSMMU_FIMC1_0, 59#define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
80 .end = IRQ_SYSMMU_FIMC1_0, 60
81 .flags = IORESOURCE_IRQ, 61#define SYSMMU_RESOURCE(core, ipname) \
82 }, 62 static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
83 [8] = { 63
84 .start = EXYNOS4_PA_SYSMMU_FIMC2, 64#define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
85 .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1, 65 DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \
86 .flags = IORESOURCE_MEM, 66 DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem)
87 }, 67
88 [9] = { 68#define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
89 .start = IRQ_SYSMMU_FIMC2_0, 69 SYSMMU_RESOURCE(core, ipname) { \
90 .end = IRQ_SYSMMU_FIMC2_0, 70 DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
91 .flags = IORESOURCE_IRQ, 71 }
92 },
93 [10] = {
94 .start = EXYNOS4_PA_SYSMMU_FIMC3,
95 .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
96 .flags = IORESOURCE_MEM,
97 },
98 [11] = {
99 .start = IRQ_SYSMMU_FIMC3_0,
100 .end = IRQ_SYSMMU_FIMC3_0,
101 .flags = IORESOURCE_IRQ,
102 },
103 [12] = {
104 .start = EXYNOS4_PA_SYSMMU_JPEG,
105 .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
106 .flags = IORESOURCE_MEM,
107 },
108 [13] = {
109 .start = IRQ_SYSMMU_JPEG_0,
110 .end = IRQ_SYSMMU_JPEG_0,
111 .flags = IORESOURCE_IRQ,
112 },
113 [14] = {
114 .start = EXYNOS4_PA_SYSMMU_FIMD0,
115 .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
116 .flags = IORESOURCE_MEM,
117 },
118 [15] = {
119 .start = IRQ_SYSMMU_LCD0_M0_0,
120 .end = IRQ_SYSMMU_LCD0_M0_0,
121 .flags = IORESOURCE_IRQ,
122 },
123 [16] = {
124 .start = EXYNOS4_PA_SYSMMU_FIMD1,
125 .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
126 .flags = IORESOURCE_MEM,
127 },
128 [17] = {
129 .start = IRQ_SYSMMU_LCD1_M1_0,
130 .end = IRQ_SYSMMU_LCD1_M1_0,
131 .flags = IORESOURCE_IRQ,
132 },
133 [18] = {
134 .start = EXYNOS4_PA_SYSMMU_PCIe,
135 .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
136 .flags = IORESOURCE_MEM,
137 },
138 [19] = {
139 .start = IRQ_SYSMMU_PCIE_0,
140 .end = IRQ_SYSMMU_PCIE_0,
141 .flags = IORESOURCE_IRQ,
142 },
143 [20] = {
144 .start = EXYNOS4_PA_SYSMMU_G2D,
145 .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
146 .flags = IORESOURCE_MEM,
147 },
148 [21] = {
149 .start = IRQ_SYSMMU_2D_0,
150 .end = IRQ_SYSMMU_2D_0,
151 .flags = IORESOURCE_IRQ,
152 },
153 [22] = {
154 .start = EXYNOS4_PA_SYSMMU_ROTATOR,
155 .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
156 .flags = IORESOURCE_MEM,
157 },
158 [23] = {
159 .start = IRQ_SYSMMU_ROTATOR_0,
160 .end = IRQ_SYSMMU_ROTATOR_0,
161 .flags = IORESOURCE_IRQ,
162 },
163 [24] = {
164 .start = EXYNOS4_PA_SYSMMU_MDMA2,
165 .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
166 .flags = IORESOURCE_MEM,
167 },
168 [25] = {
169 .start = IRQ_SYSMMU_MDMA1_0,
170 .end = IRQ_SYSMMU_MDMA1_0,
171 .flags = IORESOURCE_IRQ,
172 },
173 [26] = {
174 .start = EXYNOS4_PA_SYSMMU_TV,
175 .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
176 .flags = IORESOURCE_MEM,
177 },
178 [27] = {
179 .start = IRQ_SYSMMU_TV_M0_0,
180 .end = IRQ_SYSMMU_TV_M0_0,
181 .flags = IORESOURCE_IRQ,
182 },
183 [28] = {
184 .start = EXYNOS4_PA_SYSMMU_MFC_L,
185 .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
186 .flags = IORESOURCE_MEM,
187 },
188 [29] = {
189 .start = IRQ_SYSMMU_MFC_M0_0,
190 .end = IRQ_SYSMMU_MFC_M0_0,
191 .flags = IORESOURCE_IRQ,
192 },
193 [30] = {
194 .start = EXYNOS4_PA_SYSMMU_MFC_R,
195 .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
196 .flags = IORESOURCE_MEM,
197 },
198 [31] = {
199 .start = IRQ_SYSMMU_MFC_M1_0,
200 .end = IRQ_SYSMMU_MFC_M1_0,
201 .flags = IORESOURCE_IRQ,
202 },
203};
204 72
205struct platform_device exynos4_device_sysmmu = { 73struct sysmmu_resource_map {
206 .name = "s5p-sysmmu", 74 struct platform_device *pdev;
207 .id = 32, 75 struct resource *res;
208 .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource), 76 u32 rnum;
209 .resource = exynos4_sysmmu_resource, 77 struct device *pdd;
78 char *clocknames;
210}; 79};
211EXPORT_SYMBOL(exynos4_device_sysmmu);
212 80
213static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM]; 81#define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \
214void sysmmu_clk_init(struct device *dev, sysmmu_ips ips) 82 .pdev = &SYSMMU_PLATDEV(ipname), \
215{ 83 .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
216 sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]); 84 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
217 if (IS_ERR(sysmmu_clk[ips])) 85 .clocknames = SYSMMU_CLOCK_NAME, \
218 sysmmu_clk[ips] = NULL;
219 else
220 clk_put(sysmmu_clk[ips]);
221} 86}
222 87
223void sysmmu_clk_enable(sysmmu_ips ips) 88#define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \
224{ 89 .pdev = &SYSMMU_PLATDEV(ipname), \
225 if (sysmmu_clk[ips]) 90 .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
226 clk_enable(sysmmu_clk[ips]); 91 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
92 .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
93}
94
95#ifdef CONFIG_EXYNOS_DEV_PD
96#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \
97 .pdev = &SYSMMU_PLATDEV(ipname), \
98 .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
99 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
100 .clocknames = SYSMMU_CLOCK_NAME, \
101 .pdd = &exynos##core##_device_pd[pd].dev, \
102}
103
104#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\
105 .pdev = &SYSMMU_PLATDEV(ipname), \
106 .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
107 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
108 .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
109 .pdd = &exynos##core##_device_pd[pd].dev, \
227} 110}
111#else
112#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \
113 SYSMMU_RESOURCE_MAPPING(core, ipname, resname)
114#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \
115 SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata)
116
117#endif /* CONFIG_EXYNOS_DEV_PD */
118
119#ifdef CONFIG_ARCH_EXYNOS4
120SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0);
121SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1);
122SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2);
123SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3);
124SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG);
125SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D);
126SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0);
127SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, 2D_ACP, 2D);
128SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR);
129SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0);
130SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1);
131SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0);
132SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1);
133SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r, MFC_R, MFC_M0);
134SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l, MFC_L, MFC_M1);
135SYSMMU_RESOURCE(EXYNOS4, isp) {
136 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_ISP, FIMC_ISP),
137 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_DRC, FIMC_DRC),
138 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_FD, FIMC_FD),
139 DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX),
140};
141
142static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = {
143 SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM),
144 SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM),
145 SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM),
146 SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM),
147 SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV),
148 SYSMMU_RESOURCE_MAPPING_PD(4, mfc_r, mfc_r, PD_MFC),
149 SYSMMU_RESOURCE_MAPPING_PD(4, mfc_l, mfc_l, PD_MFC),
150 SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0),
151 SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM),
152 SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0),
153};
154
155static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = {
156 SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0),
157 SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1),
158};
159
160static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = {
161 SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp),
162 SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP),
163 SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP),
164 SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP),
165};
166#endif /* CONFIG_ARCH_EXYNOS4 */
228 167
229void sysmmu_clk_disable(sysmmu_ips ips) 168#ifdef CONFIG_ARCH_EXYNOS5
169SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG);
170SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1);
171SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D);
172SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR);
173SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV);
174SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0);
175SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1);
176SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0);
177SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1);
178SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2);
179SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3);
180SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r, MFC_R, MFC_R);
181SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l, MFC_L, MFC_L);
182SYSMMU_RESOURCE(EXYNOS5, isp) {
183 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP),
184 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC),
185 DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD),
186 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP),
187 DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP),
188 DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP),
189 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC),
190 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0),
191 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1),
192 DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR),
193};
194
195static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = {
196 SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg),
197 SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1),
198 SYSMMU_RESOURCE_MAPPING(5, 2d, 2d),
199 SYSMMU_RESOURCE_MAPPING(5, rot, rot),
200 SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1),
201 SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL),
202 SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL),
203 SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL),
204 SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL),
205 SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL),
206 SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL),
207 SYSMMU_RESOURCE_MAPPING_PD(5, mfc_r, mfc_r, PD_MFC),
208 SYSMMU_RESOURCE_MAPPING_PD(5, mfc_l, mfc_l, PD_MFC),
209 SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata),
210};
211#endif /* CONFIG_ARCH_EXYNOS5 */
212
213static int __init init_sysmmu_platform_device(void)
230{ 214{
231 if (sysmmu_clk[ips]) 215 int i, j;
232 clk_disable(sysmmu_clk[ips]); 216 struct sysmmu_resource_map *resmap[2] = {NULL, NULL};
217 int nmap[2] = {0, 0};
218
219#ifdef CONFIG_ARCH_EXYNOS5
220 if (soc_is_exynos5250()) {
221 resmap[0] = sysmmu_resmap5;
222 nmap[0] = ARRAY_SIZE(sysmmu_resmap5);
223 nmap[1] = 0;
224 }
225#endif
226
227#ifdef CONFIG_ARCH_EXYNOS4
228 if (resmap[0] == NULL) {
229 resmap[0] = sysmmu_resmap4;
230 nmap[0] = ARRAY_SIZE(sysmmu_resmap4);
231 }
232
233 if (soc_is_exynos4210()) {
234 resmap[1] = sysmmu_resmap4210;
235 nmap[1] = ARRAY_SIZE(sysmmu_resmap4210);
236 }
237
238 if (soc_is_exynos4412() || soc_is_exynos4212()) {
239 resmap[1] = sysmmu_resmap4212;
240 nmap[1] = ARRAY_SIZE(sysmmu_resmap4212);
241 }
242#endif
243
244 for (j = 0; j < 2; j++) {
245 for (i = 0; i < nmap[j]; i++) {
246 struct sysmmu_resource_map *map;
247 struct sysmmu_platform_data *platdata;
248
249 map = &resmap[j][i];
250
251 map->pdev->dev.parent = map->pdd;
252
253 platdata = map->pdev->dev.platform_data;
254 platdata->clockname = map->clocknames;
255
256 if (platform_device_add_resources(map->pdev, map->res,
257 map->rnum)) {
258 pr_err("%s: Failed to add device resources for "
259 "%s.%d\n", __func__,
260 map->pdev->name, map->pdev->id);
261 continue;
262 }
263
264 if (platform_device_register(map->pdev)) {
265 pr_err("%s: Failed to register %s.%d\n",
266 __func__, map->pdev->name,
267 map->pdev->id);
268 }
269 }
270 }
271
272 return 0;
233} 273}
274arch_initcall(init_sysmmu_platform_device);
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 69aaa450320..f60b66dbcf8 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -103,10 +103,45 @@ static u8 exynos4212_pdma0_peri[] = {
103 DMACH_MIPI_HSI5, 103 DMACH_MIPI_HSI5,
104}; 104};
105 105
106struct dma_pl330_platdata exynos4_pdma0_pdata; 106static u8 exynos5250_pdma0_peri[] = {
107 DMACH_PCM0_RX,
108 DMACH_PCM0_TX,
109 DMACH_PCM2_RX,
110 DMACH_PCM2_TX,
111 DMACH_SPI0_RX,
112 DMACH_SPI0_TX,
113 DMACH_SPI2_RX,
114 DMACH_SPI2_TX,
115 DMACH_I2S0S_TX,
116 DMACH_I2S0_RX,
117 DMACH_I2S0_TX,
118 DMACH_I2S2_RX,
119 DMACH_I2S2_TX,
120 DMACH_UART0_RX,
121 DMACH_UART0_TX,
122 DMACH_UART2_RX,
123 DMACH_UART2_TX,
124 DMACH_UART4_RX,
125 DMACH_UART4_TX,
126 DMACH_SLIMBUS0_RX,
127 DMACH_SLIMBUS0_TX,
128 DMACH_SLIMBUS2_RX,
129 DMACH_SLIMBUS2_TX,
130 DMACH_SLIMBUS4_RX,
131 DMACH_SLIMBUS4_TX,
132 DMACH_AC97_MICIN,
133 DMACH_AC97_PCMIN,
134 DMACH_AC97_PCMOUT,
135 DMACH_MIPI_HSI0,
136 DMACH_MIPI_HSI2,
137 DMACH_MIPI_HSI4,
138 DMACH_MIPI_HSI6,
139};
140
141static struct dma_pl330_platdata exynos_pdma0_pdata;
107 142
108static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, 143static AMBA_AHB_DEVICE(exynos_pdma0, "dma-pl330.0", 0x00041330,
109 EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos4_pdma0_pdata); 144 EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos_pdma0_pdata);
110 145
111static u8 exynos4210_pdma1_peri[] = { 146static u8 exynos4210_pdma1_peri[] = {
112 DMACH_PCM0_RX, 147 DMACH_PCM0_RX,
@@ -169,10 +204,45 @@ static u8 exynos4212_pdma1_peri[] = {
169 DMACH_MIPI_HSI7, 204 DMACH_MIPI_HSI7,
170}; 205};
171 206
172static struct dma_pl330_platdata exynos4_pdma1_pdata; 207static u8 exynos5250_pdma1_peri[] = {
208 DMACH_PCM0_RX,
209 DMACH_PCM0_TX,
210 DMACH_PCM1_RX,
211 DMACH_PCM1_TX,
212 DMACH_SPI1_RX,
213 DMACH_SPI1_TX,
214 DMACH_PWM,
215 DMACH_SPDIF,
216 DMACH_I2S0S_TX,
217 DMACH_I2S0_RX,
218 DMACH_I2S0_TX,
219 DMACH_I2S1_RX,
220 DMACH_I2S1_TX,
221 DMACH_UART0_RX,
222 DMACH_UART0_TX,
223 DMACH_UART1_RX,
224 DMACH_UART1_TX,
225 DMACH_UART3_RX,
226 DMACH_UART3_TX,
227 DMACH_SLIMBUS1_RX,
228 DMACH_SLIMBUS1_TX,
229 DMACH_SLIMBUS3_RX,
230 DMACH_SLIMBUS3_TX,
231 DMACH_SLIMBUS5_RX,
232 DMACH_SLIMBUS5_TX,
233 DMACH_SLIMBUS0AUX_RX,
234 DMACH_SLIMBUS0AUX_TX,
235 DMACH_DISP1,
236 DMACH_MIPI_HSI1,
237 DMACH_MIPI_HSI3,
238 DMACH_MIPI_HSI5,
239 DMACH_MIPI_HSI7,
240};
173 241
174static AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330, 242static struct dma_pl330_platdata exynos_pdma1_pdata;
175 EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos4_pdma1_pdata); 243
244static AMBA_AHB_DEVICE(exynos_pdma1, "dma-pl330.1", 0x00041330,
245 EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos_pdma1_pdata);
176 246
177static u8 mdma_peri[] = { 247static u8 mdma_peri[] = {
178 DMACH_MTOM_0, 248 DMACH_MTOM_0,
@@ -185,46 +255,63 @@ static u8 mdma_peri[] = {
185 DMACH_MTOM_7, 255 DMACH_MTOM_7,
186}; 256};
187 257
188static struct dma_pl330_platdata exynos4_mdma1_pdata = { 258static struct dma_pl330_platdata exynos_mdma1_pdata = {
189 .nr_valid_peri = ARRAY_SIZE(mdma_peri), 259 .nr_valid_peri = ARRAY_SIZE(mdma_peri),
190 .peri_id = mdma_peri, 260 .peri_id = mdma_peri,
191}; 261};
192 262
193static AMBA_AHB_DEVICE(exynos4_mdma1, "dma-pl330.2", 0x00041330, 263static AMBA_AHB_DEVICE(exynos_mdma1, "dma-pl330.2", 0x00041330,
194 EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos4_mdma1_pdata); 264 EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos_mdma1_pdata);
195 265
196static int __init exynos4_dma_init(void) 266static int __init exynos_dma_init(void)
197{ 267{
198 if (of_have_populated_dt()) 268 if (of_have_populated_dt())
199 return 0; 269 return 0;
200 270
201 if (soc_is_exynos4210()) { 271 if (soc_is_exynos4210()) {
202 exynos4_pdma0_pdata.nr_valid_peri = 272 exynos_pdma0_pdata.nr_valid_peri =
203 ARRAY_SIZE(exynos4210_pdma0_peri); 273 ARRAY_SIZE(exynos4210_pdma0_peri);
204 exynos4_pdma0_pdata.peri_id = exynos4210_pdma0_peri; 274 exynos_pdma0_pdata.peri_id = exynos4210_pdma0_peri;
205 exynos4_pdma1_pdata.nr_valid_peri = 275 exynos_pdma1_pdata.nr_valid_peri =
206 ARRAY_SIZE(exynos4210_pdma1_peri); 276 ARRAY_SIZE(exynos4210_pdma1_peri);
207 exynos4_pdma1_pdata.peri_id = exynos4210_pdma1_peri; 277 exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
208 } else if (soc_is_exynos4212() || soc_is_exynos4412()) { 278 } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
209 exynos4_pdma0_pdata.nr_valid_peri = 279 exynos_pdma0_pdata.nr_valid_peri =
210 ARRAY_SIZE(exynos4212_pdma0_peri); 280 ARRAY_SIZE(exynos4212_pdma0_peri);
211 exynos4_pdma0_pdata.peri_id = exynos4212_pdma0_peri; 281 exynos_pdma0_pdata.peri_id = exynos4212_pdma0_peri;
212 exynos4_pdma1_pdata.nr_valid_peri = 282 exynos_pdma1_pdata.nr_valid_peri =
213 ARRAY_SIZE(exynos4212_pdma1_peri); 283 ARRAY_SIZE(exynos4212_pdma1_peri);
214 exynos4_pdma1_pdata.peri_id = exynos4212_pdma1_peri; 284 exynos_pdma1_pdata.peri_id = exynos4212_pdma1_peri;
285 } else if (soc_is_exynos5250()) {
286 exynos_pdma0_pdata.nr_valid_peri =
287 ARRAY_SIZE(exynos5250_pdma0_peri);
288 exynos_pdma0_pdata.peri_id = exynos5250_pdma0_peri;
289 exynos_pdma1_pdata.nr_valid_peri =
290 ARRAY_SIZE(exynos5250_pdma1_peri);
291 exynos_pdma1_pdata.peri_id = exynos5250_pdma1_peri;
292
293 exynos_pdma0_device.res.start = EXYNOS5_PA_PDMA0;
294 exynos_pdma0_device.res.end = EXYNOS5_PA_PDMA0 + SZ_4K;
295 exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA0;
296 exynos_pdma1_device.res.start = EXYNOS5_PA_PDMA1;
297 exynos_pdma1_device.res.end = EXYNOS5_PA_PDMA1 + SZ_4K;
298 exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA1;
299 exynos_mdma1_device.res.start = EXYNOS5_PA_MDMA1;
300 exynos_mdma1_device.res.end = EXYNOS5_PA_MDMA1 + SZ_4K;
301 exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_MDMA1;
215 } 302 }
216 303
217 dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask); 304 dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask);
218 dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask); 305 dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask);
219 amba_device_register(&exynos4_pdma0_device, &iomem_resource); 306 amba_device_register(&exynos_pdma0_device, &iomem_resource);
220 307
221 dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask); 308 dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask);
222 dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask); 309 dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask);
223 amba_device_register(&exynos4_pdma1_device, &iomem_resource); 310 amba_device_register(&exynos_pdma1_device, &iomem_resource);
224 311
225 dma_cap_set(DMA_MEMCPY, exynos4_mdma1_pdata.cap_mask); 312 dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask);
226 amba_device_register(&exynos4_mdma1_device, &iomem_resource); 313 amba_device_register(&exynos_mdma1_device, &iomem_resource);
227 314
228 return 0; 315 return 0;
229} 316}
230arch_initcall(exynos4_dma_init); 317arch_initcall(exynos_dma_init);
diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
index d7498afe036..eb24f1eb8e3 100644
--- a/arch/arm/mach-exynos/include/mach/gpio.h
+++ b/arch/arm/mach-exynos/include/mach/gpio.h
@@ -153,10 +153,11 @@ enum exynos4_gpio_number {
153#define EXYNOS5_GPIO_B2_NR (4) 153#define EXYNOS5_GPIO_B2_NR (4)
154#define EXYNOS5_GPIO_B3_NR (4) 154#define EXYNOS5_GPIO_B3_NR (4)
155#define EXYNOS5_GPIO_C0_NR (7) 155#define EXYNOS5_GPIO_C0_NR (7)
156#define EXYNOS5_GPIO_C1_NR (7) 156#define EXYNOS5_GPIO_C1_NR (4)
157#define EXYNOS5_GPIO_C2_NR (7) 157#define EXYNOS5_GPIO_C2_NR (7)
158#define EXYNOS5_GPIO_C3_NR (7) 158#define EXYNOS5_GPIO_C3_NR (7)
159#define EXYNOS5_GPIO_D0_NR (8) 159#define EXYNOS5_GPIO_C4_NR (7)
160#define EXYNOS5_GPIO_D0_NR (4)
160#define EXYNOS5_GPIO_D1_NR (8) 161#define EXYNOS5_GPIO_D1_NR (8)
161#define EXYNOS5_GPIO_Y0_NR (6) 162#define EXYNOS5_GPIO_Y0_NR (6)
162#define EXYNOS5_GPIO_Y1_NR (4) 163#define EXYNOS5_GPIO_Y1_NR (4)
@@ -199,7 +200,8 @@ enum exynos5_gpio_number {
199 EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0), 200 EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
200 EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1), 201 EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
201 EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2), 202 EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
202 EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3), 203 EXYNOS5_GPIO_C4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
204 EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C4),
203 EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0), 205 EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
204 EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1), 206 EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
205 EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0), 207 EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
@@ -242,6 +244,7 @@ enum exynos5_gpio_number {
242#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr)) 244#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr))
243#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr)) 245#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr))
244#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr)) 246#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr))
247#define EXYNOS5_GPC4(_nr) (EXYNOS5_GPIO_C4_START + (_nr))
245#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr)) 248#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr))
246#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr)) 249#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr))
247#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr)) 250#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr))
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index c02dae7bf4a..7a4b4789eb7 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -154,6 +154,13 @@
154#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6) 154#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
155#define EXYNOS4_IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7) 155#define EXYNOS4_IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
156 156
157#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE0_0 COMBINER_IRQ(16, 0)
158#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE1_0 COMBINER_IRQ(16, 1)
159#define EXYNOS4_IRQ_SYSMMU_FIMC_ISP_0 COMBINER_IRQ(16, 2)
160#define EXYNOS4_IRQ_SYSMMU_FIMC_DRC_0 COMBINER_IRQ(16, 3)
161#define EXYNOS4_IRQ_SYSMMU_FIMC_FD_0 COMBINER_IRQ(16, 4)
162#define EXYNOS4_IRQ_SYSMMU_FIMC_CX_0 COMBINER_IRQ(16, 5)
163
157#define EXYNOS4_IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0) 164#define EXYNOS4_IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0)
158#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1) 165#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
159#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2) 166#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
@@ -221,24 +228,6 @@
221#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD 228#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD
222#define IRQ_PMU EXYNOS4_IRQ_PMU 229#define IRQ_PMU EXYNOS4_IRQ_PMU
223 230
224#define IRQ_SYSMMU_MDMA0_0 EXYNOS4_IRQ_SYSMMU_MDMA0_0
225#define IRQ_SYSMMU_SSS_0 EXYNOS4_IRQ_SYSMMU_SSS_0
226#define IRQ_SYSMMU_FIMC0_0 EXYNOS4_IRQ_SYSMMU_FIMC0_0
227#define IRQ_SYSMMU_FIMC1_0 EXYNOS4_IRQ_SYSMMU_FIMC1_0
228#define IRQ_SYSMMU_FIMC2_0 EXYNOS4_IRQ_SYSMMU_FIMC2_0
229#define IRQ_SYSMMU_FIMC3_0 EXYNOS4_IRQ_SYSMMU_FIMC3_0
230#define IRQ_SYSMMU_JPEG_0 EXYNOS4_IRQ_SYSMMU_JPEG_0
231#define IRQ_SYSMMU_2D_0 EXYNOS4_IRQ_SYSMMU_2D_0
232
233#define IRQ_SYSMMU_ROTATOR_0 EXYNOS4_IRQ_SYSMMU_ROTATOR_0
234#define IRQ_SYSMMU_MDMA1_0 EXYNOS4_IRQ_SYSMMU_MDMA1_0
235#define IRQ_SYSMMU_LCD0_M0_0 EXYNOS4_IRQ_SYSMMU_LCD0_M0_0
236#define IRQ_SYSMMU_LCD1_M1_0 EXYNOS4_IRQ_SYSMMU_LCD1_M1_0
237#define IRQ_SYSMMU_TV_M0_0 EXYNOS4_IRQ_SYSMMU_TV_M0_0
238#define IRQ_SYSMMU_MFC_M0_0 EXYNOS4_IRQ_SYSMMU_MFC_M0_0
239#define IRQ_SYSMMU_MFC_M1_0 EXYNOS4_IRQ_SYSMMU_MFC_M1_0
240#define IRQ_SYSMMU_PCIE_0 EXYNOS4_IRQ_SYSMMU_PCIE_0
241
242#define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO 231#define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO
243#define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC 232#define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC
244#define IRQ_FIMD0_SYSTEM EXYNOS4_IRQ_FIMD0_SYSTEM 233#define IRQ_FIMD0_SYSTEM EXYNOS4_IRQ_FIMD0_SYSTEM
@@ -298,6 +287,7 @@
298#define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80) 287#define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80)
299#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81) 288#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81)
300#define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82) 289#define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82)
290#define EXYNOS5_IRQ_WDT_IOP IRQ_SPI(83)
301#define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84) 291#define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84)
302#define EXYNOS5_IRQ_GSC0 IRQ_SPI(85) 292#define EXYNOS5_IRQ_GSC0 IRQ_SPI(85)
303#define EXYNOS5_IRQ_GSC1 IRQ_SPI(86) 293#define EXYNOS5_IRQ_GSC1 IRQ_SPI(86)
@@ -306,8 +296,8 @@
306#define EXYNOS5_IRQ_JPEG IRQ_SPI(89) 296#define EXYNOS5_IRQ_JPEG IRQ_SPI(89)
307#define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90) 297#define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90)
308#define EXYNOS5_IRQ_2D IRQ_SPI(91) 298#define EXYNOS5_IRQ_2D IRQ_SPI(91)
309#define EXYNOS5_IRQ_SFMC0 IRQ_SPI(92) 299#define EXYNOS5_IRQ_EFNFCON_0 IRQ_SPI(92)
310#define EXYNOS5_IRQ_SFMC1 IRQ_SPI(93) 300#define EXYNOS5_IRQ_EFNFCON_1 IRQ_SPI(93)
311#define EXYNOS5_IRQ_MIXER IRQ_SPI(94) 301#define EXYNOS5_IRQ_MIXER IRQ_SPI(94)
312#define EXYNOS5_IRQ_HDMI IRQ_SPI(95) 302#define EXYNOS5_IRQ_HDMI IRQ_SPI(95)
313#define EXYNOS5_IRQ_MFC IRQ_SPI(96) 303#define EXYNOS5_IRQ_MFC IRQ_SPI(96)
@@ -321,7 +311,7 @@
321#define EXYNOS5_IRQ_PCM2 IRQ_SPI(104) 311#define EXYNOS5_IRQ_PCM2 IRQ_SPI(104)
322#define EXYNOS5_IRQ_SPDIF IRQ_SPI(105) 312#define EXYNOS5_IRQ_SPDIF IRQ_SPI(105)
323#define EXYNOS5_IRQ_ADC0 IRQ_SPI(106) 313#define EXYNOS5_IRQ_ADC0 IRQ_SPI(106)
324 314#define EXYNOS5_IRQ_ADC1 IRQ_SPI(107)
325#define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108) 315#define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108)
326#define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109) 316#define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109)
327#define EXYNOS5_IRQ_CAM_C IRQ_SPI(110) 317#define EXYNOS5_IRQ_CAM_C IRQ_SPI(110)
@@ -330,8 +320,9 @@
330#define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113) 320#define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113)
331#define EXYNOS5_IRQ_CEC IRQ_SPI(114) 321#define EXYNOS5_IRQ_CEC IRQ_SPI(114)
332#define EXYNOS5_IRQ_SATA IRQ_SPI(115) 322#define EXYNOS5_IRQ_SATA IRQ_SPI(115)
333#define EXYNOS5_IRQ_NFCON IRQ_SPI(116)
334 323
324#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120)
325#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)
335#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123) 326#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)
336#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124) 327#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)
337#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125) 328#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)
@@ -339,7 +330,6 @@
339#define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127) 330#define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127)
340 331
341#define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2) 332#define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2)
342#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(1, 6)
343 333
344#define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0) 334#define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0)
345#define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1) 335#define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1)
@@ -350,6 +340,8 @@
350#define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6) 340#define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6)
351#define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7) 341#define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7)
352 342
343#define EXYNOS5_IRQ_SYSMMU_LITE2_0 COMBINER_IRQ(3, 0)
344#define EXYNOS5_IRQ_SYSMMU_LITE2_1 COMBINER_IRQ(3, 1)
353#define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2) 345#define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2)
354#define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3) 346#define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3)
355#define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4) 347#define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4)
@@ -373,8 +365,8 @@
373 365
374#define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0) 366#define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0)
375#define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1) 367#define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1)
376#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(6, 2) 368#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(6, 2)
377#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(6, 3) 369#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(6, 3)
378#define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4) 370#define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4)
379#define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5) 371#define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5)
380#define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6) 372#define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6)
@@ -386,11 +378,9 @@
386#define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3) 378#define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3)
387#define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4) 379#define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4)
388#define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5) 380#define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5)
389#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6)
390#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7)
391 381
392#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(8, 5) 382#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(8, 5)
393#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(8, 6) 383#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(8, 6)
394 384
395#define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4) 385#define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4)
396#define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5) 386#define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5)
@@ -406,17 +396,24 @@
406#define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6) 396#define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6)
407#define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7) 397#define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7)
408 398
399#define EXYNOS5_IRQ_MDMA1_ABORT COMBINER_IRQ(13, 1)
400
401#define EXYNOS5_IRQ_MDMA0_ABORT COMBINER_IRQ(15, 3)
402
409#define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4) 403#define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4)
410#define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5) 404#define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5)
411#define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6) 405#define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6)
412 406
407#define EXYNOS5_IRQ_ARMIOP_GIC COMBINER_IRQ(19, 0)
408#define EXYNOS5_IRQ_ARMISP_GIC COMBINER_IRQ(19, 1)
409#define EXYNOS5_IRQ_IOP_GIC COMBINER_IRQ(19, 3)
410#define EXYNOS5_IRQ_ISP_GIC COMBINER_IRQ(19, 4)
411
412#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)
413
413#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0) 414#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0)
414#define EXYNOS5_IRQ_MCT_L0 COMBINER_IRQ(23, 1)
415#define EXYNOS5_IRQ_MCT_L1 COMBINER_IRQ(23, 2)
416#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3) 415#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3)
417#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4) 416#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)
418#define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5)
419#define EXYNOS5_IRQ_MCT_G3 COMBINER_IRQ(23, 6)
420 417
421#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0) 418#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)
422#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1) 419#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
@@ -447,7 +444,7 @@
447 444
448#define EXYNOS5_MAX_COMBINER_NR 32 445#define EXYNOS5_MAX_COMBINER_NR 32
449 446
450#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 13 447#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 14
451#define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9 448#define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9
452#define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5 449#define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5
453#define EXYNOS5_IRQ_GPIO4_NR_GROUPS 1 450#define EXYNOS5_IRQ_GPIO4_NR_GROUPS 1
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index e009a66477f..ca4aa89aa46 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -34,6 +34,9 @@
34 34
35#define EXYNOS4_PA_JPEG 0x11840000 35#define EXYNOS4_PA_JPEG 0x11840000
36 36
37/* x = 0...1 */
38#define EXYNOS4_PA_FIMC_LITE(x) (0x12390000 + ((x) * 0x10000))
39
37#define EXYNOS4_PA_G2D 0x12800000 40#define EXYNOS4_PA_G2D 0x12800000
38 41
39#define EXYNOS4_PA_I2S0 0x03830000 42#define EXYNOS4_PA_I2S0 0x03830000
@@ -78,8 +81,8 @@
78 81
79#define EXYNOS4_PA_GIC_CPU 0x10480000 82#define EXYNOS4_PA_GIC_CPU 0x10480000
80#define EXYNOS4_PA_GIC_DIST 0x10490000 83#define EXYNOS4_PA_GIC_DIST 0x10490000
81#define EXYNOS5_PA_GIC_CPU 0x10480000 84#define EXYNOS5_PA_GIC_CPU 0x10482000
82#define EXYNOS5_PA_GIC_DIST 0x10490000 85#define EXYNOS5_PA_GIC_DIST 0x10481000
83 86
84#define EXYNOS4_PA_COREPERI 0x10500000 87#define EXYNOS4_PA_COREPERI 0x10500000
85#define EXYNOS4_PA_TWD 0x10500600 88#define EXYNOS4_PA_TWD 0x10500600
@@ -95,6 +98,7 @@
95#define EXYNOS5_PA_PDMA1 0x121B0000 98#define EXYNOS5_PA_PDMA1 0x121B0000
96 99
97#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 100#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000
101#define EXYNOS4_PA_SYSMMU_2D_ACP 0x10A40000
98#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 102#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
99#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000 103#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
100#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000 104#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
@@ -103,6 +107,12 @@
103#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000 107#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
104#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000 108#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
105#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000 109#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
110#define EXYNOS4_PA_SYSMMU_FIMC_ISP 0x12260000
111#define EXYNOS4_PA_SYSMMU_FIMC_DRC 0x12270000
112#define EXYNOS4_PA_SYSMMU_FIMC_FD 0x122A0000
113#define EXYNOS4_PA_SYSMMU_ISPCPU 0x122B0000
114#define EXYNOS4_PA_SYSMMU_FIMC_LITE0 0x123B0000
115#define EXYNOS4_PA_SYSMMU_FIMC_LITE1 0x123C0000
106#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000 116#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
107#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000 117#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000
108#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000 118#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
@@ -110,6 +120,37 @@
110#define EXYNOS4_PA_SYSMMU_TV 0x12E20000 120#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
111#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000 121#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
112#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000 122#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
123
124#define EXYNOS5_PA_SYSMMU_MDMA1 0x10A40000
125#define EXYNOS5_PA_SYSMMU_SSS 0x10A50000
126#define EXYNOS5_PA_SYSMMU_2D 0x10A60000
127#define EXYNOS5_PA_SYSMMU_MFC_L 0x11200000
128#define EXYNOS5_PA_SYSMMU_MFC_R 0x11210000
129#define EXYNOS5_PA_SYSMMU_ROTATOR 0x11D40000
130#define EXYNOS5_PA_SYSMMU_MDMA2 0x11D50000
131#define EXYNOS5_PA_SYSMMU_JPEG 0x11F20000
132#define EXYNOS5_PA_SYSMMU_IOP 0x12360000
133#define EXYNOS5_PA_SYSMMU_RTIC 0x12370000
134#define EXYNOS5_PA_SYSMMU_GPS 0x12630000
135#define EXYNOS5_PA_SYSMMU_ISP 0x13260000
136#define EXYNOS5_PA_SYSMMU_DRC 0x12370000
137#define EXYNOS5_PA_SYSMMU_SCALERC 0x13280000
138#define EXYNOS5_PA_SYSMMU_SCALERP 0x13290000
139#define EXYNOS5_PA_SYSMMU_FD 0x132A0000
140#define EXYNOS5_PA_SYSMMU_ISPCPU 0x132B0000
141#define EXYNOS5_PA_SYSMMU_ODC 0x132C0000
142#define EXYNOS5_PA_SYSMMU_DIS0 0x132D0000
143#define EXYNOS5_PA_SYSMMU_DIS1 0x132E0000
144#define EXYNOS5_PA_SYSMMU_3DNR 0x132F0000
145#define EXYNOS5_PA_SYSMMU_LITE0 0x13C40000
146#define EXYNOS5_PA_SYSMMU_LITE1 0x13C50000
147#define EXYNOS5_PA_SYSMMU_GSC0 0x13E80000
148#define EXYNOS5_PA_SYSMMU_GSC1 0x13E90000
149#define EXYNOS5_PA_SYSMMU_GSC2 0x13EA0000
150#define EXYNOS5_PA_SYSMMU_GSC3 0x13EB0000
151#define EXYNOS5_PA_SYSMMU_FIMD1 0x14640000
152#define EXYNOS5_PA_SYSMMU_TV 0x14650000
153
113#define EXYNOS4_PA_SPI0 0x13920000 154#define EXYNOS4_PA_SPI0 0x13920000
114#define EXYNOS4_PA_SPI1 0x13930000 155#define EXYNOS4_PA_SPI1 0x13930000
115#define EXYNOS4_PA_SPI2 0x13940000 156#define EXYNOS4_PA_SPI2 0x13940000
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
index d9578a58ae7..b78b5f3ad9c 100644
--- a/arch/arm/mach-exynos/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
@@ -135,6 +135,9 @@
135#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800) 135#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800)
136#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900) 136#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900)
137 137
138#define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800)
139#define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804)
140
138#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */ 141#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */
139 142
140#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31) 143#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31)
@@ -303,6 +306,8 @@
303#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558) 306#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558)
304 307
305#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800) 308#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800)
309#define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800)
310#define EXYNOS5_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x0C804)
306#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920) 311#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920)
307#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928) 312#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928)
308#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C) 313#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C)
@@ -317,6 +322,8 @@
317#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200) 322#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200)
318#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500) 323#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500)
319 324
325#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24)
326
320#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) 327#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030)
321 328
322#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) 329#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29)
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index d457d052a42..4dbb8629b20 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -180,7 +180,7 @@
180 180
181#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0) 181#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
182 182
183/* Only for EXYNOS4212 */ 183/* Only for EXYNOS4x12 */
184#define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050) 184#define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050)
185#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054) 185#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054)
186#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR S5P_PMUREG(0x1058) 186#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR S5P_PMUREG(0x1058)
@@ -221,4 +221,12 @@
221#define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8) 221#define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8)
222#define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48) 222#define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48)
223 223
224/* Only for EXYNOS4412 */
225#define S5P_ARM_CORE2_LOWPWR S5P_PMUREG(0x1020)
226#define S5P_DIS_IRQ_CORE2 S5P_PMUREG(0x1024)
227#define S5P_DIS_IRQ_CENTRAL2 S5P_PMUREG(0x1028)
228#define S5P_ARM_CORE3_LOWPWR S5P_PMUREG(0x1030)
229#define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034)
230#define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038)
231
224#endif /* __ASM_ARCH_REGS_PMU_H */ 232#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
deleted file mode 100644
index 68ff6ad08a2..00000000000
--- a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - System MMU register
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __ASM_ARCH_REGS_SYSMMU_H
14#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
15
16#define S5P_MMU_CTRL 0x000
17#define S5P_MMU_CFG 0x004
18#define S5P_MMU_STATUS 0x008
19#define S5P_MMU_FLUSH 0x00C
20#define S5P_PT_BASE_ADDR 0x014
21#define S5P_INT_STATUS 0x018
22#define S5P_INT_CLEAR 0x01C
23#define S5P_PAGE_FAULT_ADDR 0x024
24#define S5P_AW_FAULT_ADDR 0x028
25#define S5P_AR_FAULT_ADDR 0x02C
26#define S5P_DEFAULT_SLAVE_ADDR 0x030
27
28#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/spi-clocks.h b/arch/arm/mach-exynos/include/mach/spi-clocks.h
index 576efdf6d09..c71a5fba6a8 100644
--- a/arch/arm/mach-exynos/include/mach/spi-clocks.h
+++ b/arch/arm/mach-exynos/include/mach/spi-clocks.h
@@ -11,6 +11,6 @@
11#define __ASM_ARCH_SPI_CLKS_H __FILE__ 11#define __ASM_ARCH_SPI_CLKS_H __FILE__
12 12
13/* Must source from SCLK_SPI */ 13/* Must source from SCLK_SPI */
14#define EXYNOS4_SPI_SRCCLK_SCLK 0 14#define EXYNOS_SPI_SRCCLK_SCLK 0
15 15
16#endif /* __ASM_ARCH_SPI_CLKS_H */ 16#endif /* __ASM_ARCH_SPI_CLKS_H */
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
index 6a5fbb534e8..998daf2add9 100644
--- a/arch/arm/mach-exynos/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -1,46 +1,66 @@
1/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h 1/*
2 * 2 * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 3 * http://www.samsung.com
5 * 4 *
6 * Samsung sysmmu driver for EXYNOS4 5 * EXYNOS - System MMU support
7 * 6 *
8 * 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
9 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
11*/ 10 */
12 11
13#ifndef __ASM_ARM_ARCH_SYSMMU_H 12#ifndef _ARM_MACH_EXYNOS_SYSMMU_H_
14#define __ASM_ARM_ARCH_SYSMMU_H __FILE__ 13#define _ARM_MACH_EXYNOS_SYSMMU_H_
15 14
16enum exynos4_sysmmu_ips { 15struct sysmmu_platform_data {
17 SYSMMU_MDMA, 16 char *dbgname;
18 SYSMMU_SSS, 17 /* comma(,) separated list of clock names for clock gating */
19 SYSMMU_FIMC0, 18 char *clockname;
20 SYSMMU_FIMC1,
21 SYSMMU_FIMC2,
22 SYSMMU_FIMC3,
23 SYSMMU_JPEG,
24 SYSMMU_FIMD0,
25 SYSMMU_FIMD1,
26 SYSMMU_PCIe,
27 SYSMMU_G2D,
28 SYSMMU_ROTATOR,
29 SYSMMU_MDMA2,
30 SYSMMU_TV,
31 SYSMMU_MFC_L,
32 SYSMMU_MFC_R,
33 EXYNOS4_SYSMMU_TOTAL_IPNUM,
34}; 19};
35 20
36#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM 21#define SYSMMU_DEVNAME_BASE "exynos-sysmmu"
22
23#define SYSMMU_CLOCK_NAME "sysmmu"
24#define SYSMMU_CLOCK_NAME2 "sysmmu_mc"
25
26#ifdef CONFIG_EXYNOS_DEV_SYSMMU
27#include <linux/device.h>
28struct platform_device;
29
30#define SYSMMU_PLATDEV(ipname) exynos_device_sysmmu_##ipname
31
32extern struct platform_device SYSMMU_PLATDEV(mfc_l);
33extern struct platform_device SYSMMU_PLATDEV(mfc_r);
34extern struct platform_device SYSMMU_PLATDEV(tv);
35extern struct platform_device SYSMMU_PLATDEV(jpeg);
36extern struct platform_device SYSMMU_PLATDEV(rot);
37extern struct platform_device SYSMMU_PLATDEV(fimc0);
38extern struct platform_device SYSMMU_PLATDEV(fimc1);
39extern struct platform_device SYSMMU_PLATDEV(fimc2);
40extern struct platform_device SYSMMU_PLATDEV(fimc3);
41extern struct platform_device SYSMMU_PLATDEV(gsc0);
42extern struct platform_device SYSMMU_PLATDEV(gsc1);
43extern struct platform_device SYSMMU_PLATDEV(gsc2);
44extern struct platform_device SYSMMU_PLATDEV(gsc3);
45extern struct platform_device SYSMMU_PLATDEV(isp);
46extern struct platform_device SYSMMU_PLATDEV(fimd0);
47extern struct platform_device SYSMMU_PLATDEV(fimd1);
48extern struct platform_device SYSMMU_PLATDEV(camif0);
49extern struct platform_device SYSMMU_PLATDEV(camif1);
50extern struct platform_device SYSMMU_PLATDEV(2d);
37 51
38extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM]; 52#ifdef CONFIG_IOMMU_API
53static inline void platform_set_sysmmu(
54 struct device *sysmmu, struct device *dev)
55{
56 dev->archdata.iommu = sysmmu;
57}
58#endif
39 59
40typedef enum exynos4_sysmmu_ips sysmmu_ips; 60#else /* !CONFIG_EXYNOS_DEV_SYSMMU */
61#define platform_set_sysmmu(dev, sysmmu) do { } while (0)
62#endif
41 63
42void sysmmu_clk_init(struct device *dev, sysmmu_ips ips); 64#define SYSMMU_CLOCK_DEVNAME(ipname, id) (SYSMMU_DEVNAME_BASE "." #id)
43void sysmmu_clk_enable(sysmmu_ips ips);
44void sysmmu_clk_disable(sysmmu_ips ips);
45 65
46#endif /* __ASM_ARM_ARCH_SYSMMU_H */ 66#endif /* _ARM_MACH_EXYNOS_SYSMMU_H_ */
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index fed7116418e..5a3daa0168d 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -147,7 +147,6 @@ static struct platform_device *armlex4210_devices[] __initdata = {
147 &s3c_device_hsmmc3, 147 &s3c_device_hsmmc3,
148 &s3c_device_rtc, 148 &s3c_device_rtc,
149 &s3c_device_wdt, 149 &s3c_device_wdt,
150 &exynos4_device_sysmmu,
151 &samsung_asoc_dma, 150 &samsung_asoc_dma,
152 &armlex4210_smsc911x, 151 &armlex4210_smsc911x,
153 &exynos4_device_ahci, 152 &exynos4_device_ahci,
@@ -204,6 +203,7 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210")
204 .map_io = armlex4210_map_io, 203 .map_io = armlex4210_map_io,
205 .handle_irq = gic_handle_irq, 204 .handle_irq = gic_handle_irq,
206 .init_machine = armlex4210_machine_init, 205 .init_machine = armlex4210_machine_init,
206 .init_late = exynos_init_late,
207 .timer = &exynos4_timer, 207 .timer = &exynos4_timer,
208 .restart = exynos4_restart, 208 .restart = exynos4_restart,
209MACHINE_END 209MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 8245f1c761d..e7e9743543a 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -83,6 +83,7 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
83 .map_io = exynos4210_dt_map_io, 83 .map_io = exynos4210_dt_map_io,
84 .handle_irq = gic_handle_irq, 84 .handle_irq = gic_handle_irq,
85 .init_machine = exynos4210_dt_machine_init, 85 .init_machine = exynos4210_dt_machine_init,
86 .init_late = exynos_init_late,
86 .timer = &exynos4_timer, 87 .timer = &exynos4_timer,
87 .dt_compat = exynos4210_dt_compat, 88 .dt_compat = exynos4210_dt_compat,
88 .restart = exynos4_restart, 89 .restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 4711c8920e3..7b1e11a228c 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -43,6 +43,10 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
43 "exynos4210-uart.2", NULL), 43 "exynos4210-uart.2", NULL),
44 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3, 44 OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
45 "exynos4210-uart.3", NULL), 45 "exynos4210-uart.3", NULL),
46 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
47 "s3c2440-i2c.0", NULL),
48 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
49 "s3c2440-i2c.1", NULL),
46 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), 50 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
47 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), 51 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
48 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), 52 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
@@ -72,6 +76,7 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
72 .map_io = exynos5250_dt_map_io, 76 .map_io = exynos5250_dt_map_io,
73 .handle_irq = gic_handle_irq, 77 .handle_irq = gic_handle_irq,
74 .init_machine = exynos5250_dt_machine_init, 78 .init_machine = exynos5250_dt_machine_init,
79 .init_late = exynos_init_late,
75 .timer = &exynos4_timer, 80 .timer = &exynos4_timer,
76 .dt_compat = exynos5250_dt_compat, 81 .dt_compat = exynos5250_dt_compat,
77 .restart = exynos5_restart, 82 .restart = exynos5_restart,
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 6c31f2ad765..972983e392b 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1389,6 +1389,7 @@ MACHINE_START(NURI, "NURI")
1389 .map_io = nuri_map_io, 1389 .map_io = nuri_map_io,
1390 .handle_irq = gic_handle_irq, 1390 .handle_irq = gic_handle_irq,
1391 .init_machine = nuri_machine_init, 1391 .init_machine = nuri_machine_init,
1392 .init_late = exynos_init_late,
1392 .timer = &exynos4_timer, 1393 .timer = &exynos4_timer,
1393 .reserve = &nuri_reserve, 1394 .reserve = &nuri_reserve,
1394 .restart = exynos4_restart, 1395 .restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 26124a38bcb..a7f7fd567dd 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -766,6 +766,7 @@ MACHINE_START(ORIGEN, "ORIGEN")
766 .map_io = origen_map_io, 766 .map_io = origen_map_io,
767 .handle_irq = gic_handle_irq, 767 .handle_irq = gic_handle_irq,
768 .init_machine = origen_machine_init, 768 .init_machine = origen_machine_init,
769 .init_late = exynos_init_late,
769 .timer = &exynos4_timer, 770 .timer = &exynos4_timer,
770 .reserve = &origen_reserve, 771 .reserve = &origen_reserve,
771 .restart = exynos4_restart, 772 .restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index fe772d893cc..fb09c70e195 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -316,6 +316,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
316 .map_io = smdk4x12_map_io, 316 .map_io = smdk4x12_map_io,
317 .handle_irq = gic_handle_irq, 317 .handle_irq = gic_handle_irq,
318 .init_machine = smdk4x12_machine_init, 318 .init_machine = smdk4x12_machine_init,
319 .init_late = exynos_init_late,
319 .timer = &exynos4_timer, 320 .timer = &exynos4_timer,
320 .restart = exynos4_restart, 321 .restart = exynos4_restart,
321 .reserve = &smdk4x12_reserve, 322 .reserve = &smdk4x12_reserve,
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 5af96064ca5..70df1a0c211 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -295,7 +295,6 @@ static struct platform_device *smdkv310_devices[] __initdata = {
295 &s5p_device_mfc_l, 295 &s5p_device_mfc_l,
296 &s5p_device_mfc_r, 296 &s5p_device_mfc_r,
297 &exynos4_device_spdif, 297 &exynos4_device_spdif,
298 &exynos4_device_sysmmu,
299 &samsung_asoc_dma, 298 &samsung_asoc_dma,
300 &samsung_asoc_idma, 299 &samsung_asoc_idma,
301 &s5p_device_fimd0, 300 &s5p_device_fimd0,
@@ -412,6 +411,7 @@ MACHINE_START(SMDKC210, "SMDKC210")
412 .map_io = smdkv310_map_io, 411 .map_io = smdkv310_map_io,
413 .handle_irq = gic_handle_irq, 412 .handle_irq = gic_handle_irq,
414 .init_machine = smdkv310_machine_init, 413 .init_machine = smdkv310_machine_init,
414 .init_late = exynos_init_late,
415 .timer = &exynos4_timer, 415 .timer = &exynos4_timer,
416 .restart = exynos4_restart, 416 .restart = exynos4_restart,
417MACHINE_END 417MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 6b731b86327..083b44de9c1 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1157,6 +1157,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
1157 .map_io = universal_map_io, 1157 .map_io = universal_map_io,
1158 .handle_irq = gic_handle_irq, 1158 .handle_irq = gic_handle_irq,
1159 .init_machine = universal_machine_init, 1159 .init_machine = universal_machine_init,
1160 .init_late = exynos_init_late,
1160 .timer = &s5p_timer, 1161 .timer = &s5p_timer,
1161 .reserve = &universal_reserve, 1162 .reserve = &universal_reserve,
1162 .restart = exynos4_restart, 1163 .restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 897d9a9cf22..b601fb8a408 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -388,6 +388,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
388{ 388{
389 struct mct_clock_event_device *mevt; 389 struct mct_clock_event_device *mevt;
390 unsigned int cpu = smp_processor_id(); 390 unsigned int cpu = smp_processor_id();
391 int mct_lx_irq;
391 392
392 mevt = this_cpu_ptr(&percpu_mct_tick); 393 mevt = this_cpu_ptr(&percpu_mct_tick);
393 mevt->evt = evt; 394 mevt->evt = evt;
@@ -414,14 +415,18 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
414 415
415 if (mct_int_type == MCT_INT_SPI) { 416 if (mct_int_type == MCT_INT_SPI) {
416 if (cpu == 0) { 417 if (cpu == 0) {
418 mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L0 :
419 EXYNOS5_IRQ_MCT_L0;
417 mct_tick0_event_irq.dev_id = mevt; 420 mct_tick0_event_irq.dev_id = mevt;
418 evt->irq = EXYNOS4_IRQ_MCT_L0; 421 evt->irq = mct_lx_irq;
419 setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq); 422 setup_irq(mct_lx_irq, &mct_tick0_event_irq);
420 } else { 423 } else {
424 mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L1 :
425 EXYNOS5_IRQ_MCT_L1;
421 mct_tick1_event_irq.dev_id = mevt; 426 mct_tick1_event_irq.dev_id = mevt;
422 evt->irq = EXYNOS4_IRQ_MCT_L1; 427 evt->irq = mct_lx_irq;
423 setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq); 428 setup_irq(mct_lx_irq, &mct_tick1_event_irq);
424 irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1)); 429 irq_set_affinity(mct_lx_irq, cpumask_of(1));
425 } 430 }
426 } else { 431 } else {
427 enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0); 432 enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0);
@@ -473,7 +478,7 @@ static void __init exynos4_timer_resources(void)
473 478
474static void __init exynos4_timer_init(void) 479static void __init exynos4_timer_init(void)
475{ 480{
476 if (soc_is_exynos4210()) 481 if ((soc_is_exynos4210()) || (soc_is_exynos5250()))
477 mct_int_type = MCT_INT_SPI; 482 mct_int_type = MCT_INT_SPI;
478 else 483 else
479 mct_int_type = MCT_INT_PPI; 484 mct_int_type = MCT_INT_PPI;
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 428cfeb5772..563dea9a6db 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -275,7 +275,7 @@ static void exynos4_restore_pll(void)
275 275
276static struct subsys_interface exynos4_pm_interface = { 276static struct subsys_interface exynos4_pm_interface = {
277 .name = "exynos4_pm", 277 .name = "exynos4_pm",
278 .subsys = &exynos4_subsys, 278 .subsys = &exynos_subsys,
279 .add_dev = exynos4_pm_add, 279 .add_dev = exynos4_pm_add,
280}; 280};
281 281
@@ -313,7 +313,7 @@ static int exynos4_pm_suspend(void)
313 tmp &= ~S5P_CENTRAL_LOWPWR_CFG; 313 tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
314 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION); 314 __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
315 315
316 if (soc_is_exynos4212()) { 316 if (soc_is_exynos4212() || soc_is_exynos4412()) {
317 tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION); 317 tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
318 tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM | 318 tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM |
319 S5P_USE_STANDBYWFE_ISP_ARM); 319 S5P_USE_STANDBYWFE_ISP_ARM);
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 13b306808b4..e9fafcf163d 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -193,9 +193,8 @@ static __init int exynos4_pm_init_power_domain(void)
193} 193}
194arch_initcall(exynos4_pm_init_power_domain); 194arch_initcall(exynos4_pm_init_power_domain);
195 195
196static __init int exynos_pm_late_initcall(void) 196int __init exynos_pm_late_initcall(void)
197{ 197{
198 pm_genpd_poweroff_unused(); 198 pm_genpd_poweroff_unused();
199 return 0; 199 return 0;
200} 200}
201late_initcall(exynos_pm_late_initcall);
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index bba48f5c3e8..77c6815eebe 100644
--- a/arch/arm/mach-exynos/pmu.c
+++ b/arch/arm/mach-exynos/pmu.c
@@ -94,7 +94,7 @@ static struct exynos4_pmu_conf exynos4210_pmu_config[] = {
94 { PMU_TABLE_END,}, 94 { PMU_TABLE_END,},
95}; 95};
96 96
97static struct exynos4_pmu_conf exynos4212_pmu_config[] = { 97static struct exynos4_pmu_conf exynos4x12_pmu_config[] = {
98 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, 98 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
99 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, 99 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
100 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, 100 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
@@ -202,6 +202,16 @@ static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
202 { PMU_TABLE_END,}, 202 { PMU_TABLE_END,},
203}; 203};
204 204
205static struct exynos4_pmu_conf exynos4412_pmu_config[] = {
206 { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } },
207 { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } },
208 { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } },
209 { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } },
210 { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } },
211 { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } },
212 { PMU_TABLE_END,},
213};
214
205void exynos4_sys_powerdown_conf(enum sys_powerdown mode) 215void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
206{ 216{
207 unsigned int i; 217 unsigned int i;
@@ -209,6 +219,12 @@ void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
209 for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++) 219 for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++)
210 __raw_writel(exynos4_pmu_config[i].val[mode], 220 __raw_writel(exynos4_pmu_config[i].val[mode],
211 exynos4_pmu_config[i].reg); 221 exynos4_pmu_config[i].reg);
222
223 if (soc_is_exynos4412()) {
224 for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++)
225 __raw_writel(exynos4412_pmu_config[i].val[mode],
226 exynos4412_pmu_config[i].reg);
227 }
212} 228}
213 229
214static int __init exynos4_pmu_init(void) 230static int __init exynos4_pmu_init(void)
@@ -218,9 +234,9 @@ static int __init exynos4_pmu_init(void)
218 if (soc_is_exynos4210()) { 234 if (soc_is_exynos4210()) {
219 exynos4_pmu_config = exynos4210_pmu_config; 235 exynos4_pmu_config = exynos4210_pmu_config;
220 pr_info("EXYNOS4210 PMU Initialize\n"); 236 pr_info("EXYNOS4210 PMU Initialize\n");
221 } else if (soc_is_exynos4212()) { 237 } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
222 exynos4_pmu_config = exynos4212_pmu_config; 238 exynos4_pmu_config = exynos4x12_pmu_config;
223 pr_info("EXYNOS4212 PMU Initialize\n"); 239 pr_info("EXYNOS4x12 PMU Initialize\n");
224 } else { 240 } else {
225 pr_info("EXYNOS4: PMU not supported\n"); 241 pr_info("EXYNOS4: PMU not supported\n");
226 } 242 }
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index cca8c0c7479..0021f726b15 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -34,6 +34,7 @@ config ARCH_MX53
34config SOC_IMX1 34config SOC_IMX1
35 bool 35 bool
36 select ARCH_MX1 36 select ARCH_MX1
37 select COMMON_CLK
37 select CPU_ARM920T 38 select CPU_ARM920T
38 select IMX_HAVE_IOMUX_V1 39 select IMX_HAVE_IOMUX_V1
39 select MXC_AVIC 40 select MXC_AVIC
@@ -42,12 +43,14 @@ config SOC_IMX21
42 bool 43 bool
43 select MACH_MX21 44 select MACH_MX21
44 select CPU_ARM926T 45 select CPU_ARM926T
46 select COMMON_CLK
45 select IMX_HAVE_IOMUX_V1 47 select IMX_HAVE_IOMUX_V1
46 select MXC_AVIC 48 select MXC_AVIC
47 49
48config SOC_IMX25 50config SOC_IMX25
49 bool 51 bool
50 select ARCH_MX25 52 select ARCH_MX25
53 select COMMON_CLK
51 select CPU_ARM926T 54 select CPU_ARM926T
52 select ARCH_MXC_IOMUX_V3 55 select ARCH_MXC_IOMUX_V3
53 select MXC_AVIC 56 select MXC_AVIC
@@ -56,6 +59,7 @@ config SOC_IMX27
56 bool 59 bool
57 select MACH_MX27 60 select MACH_MX27
58 select CPU_ARM926T 61 select CPU_ARM926T
62 select COMMON_CLK
59 select IMX_HAVE_IOMUX_V1 63 select IMX_HAVE_IOMUX_V1
60 select MXC_AVIC 64 select MXC_AVIC
61 65
@@ -64,12 +68,14 @@ config SOC_IMX31
64 select CPU_V6 68 select CPU_V6
65 select IMX_HAVE_PLATFORM_MXC_RNGA 69 select IMX_HAVE_PLATFORM_MXC_RNGA
66 select MXC_AVIC 70 select MXC_AVIC
71 select COMMON_CLK
67 select SMP_ON_UP if SMP 72 select SMP_ON_UP if SMP
68 73
69config SOC_IMX35 74config SOC_IMX35
70 bool 75 bool
71 select CPU_V6 76 select CPU_V6
72 select ARCH_MXC_IOMUX_V3 77 select ARCH_MXC_IOMUX_V3
78 select COMMON_CLK
73 select HAVE_EPIT 79 select HAVE_EPIT
74 select MXC_AVIC 80 select MXC_AVIC
75 select SMP_ON_UP if SMP 81 select SMP_ON_UP if SMP
@@ -77,6 +83,7 @@ config SOC_IMX35
77config SOC_IMX5 83config SOC_IMX5
78 select CPU_V7 84 select CPU_V7
79 select MXC_TZIC 85 select MXC_TZIC
86 select COMMON_CLK
80 select ARCH_MXC_IOMUX_V3 87 select ARCH_MXC_IOMUX_V3
81 select ARCH_HAS_CPUFREQ 88 select ARCH_HAS_CPUFREQ
82 select ARCH_MX5 89 select ARCH_MX5
@@ -815,6 +822,7 @@ config SOC_IMX6Q
815 bool "i.MX6 Quad support" 822 bool "i.MX6 Quad support"
816 select ARM_CPU_SUSPEND if PM 823 select ARM_CPU_SUSPEND if PM
817 select ARM_GIC 824 select ARM_GIC
825 select COMMON_CLK
818 select CPU_V7 826 select CPU_V7
819 select HAVE_ARM_SCU 827 select HAVE_ARM_SCU
820 select HAVE_IMX_GPC 828 select HAVE_IMX_GPC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 4937c070a57..ff29421414f 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,15 +1,18 @@
1obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o 1obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
2obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o 2obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
3 3
4obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o 4obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
5 5
6obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o 6obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
7obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o 7obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
8 8
9obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o 9obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
10obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o 10obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
11 11
12obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o 12obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
13
14obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
15 clk-pfd.o clk-busy.o
13 16
14# Support for CMOS sensor interface 17# Support for CMOS sensor interface
15obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o 18obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
@@ -70,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
70AFLAGS_head-v7.o :=-Wa,-march=armv7-a 73AFLAGS_head-v7.o :=-Wa,-march=armv7-a
71obj-$(CONFIG_SMP) += platsmp.o 74obj-$(CONFIG_SMP) += platsmp.o
72obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 75obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o 76obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
74 77
75ifeq ($(CONFIG_PM),y) 78ifeq ($(CONFIG_PM),y)
76obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o 79obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 3851d8a2787..05541cf4a87 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -42,4 +42,5 @@ dtb-$(CONFIG_MACH_IMX51_DT) += imx51-babbage.dtb
42dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \ 42dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \
43 imx53-qsb.dtb imx53-smd.dtb 43 imx53-qsb.dtb imx53-smd.dtb
44dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \ 44dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \
45 imx6q-sabrelite.dtb 45 imx6q-sabrelite.dtb \
46 imx6q-sabresd.dtb \
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c
new file mode 100644
index 00000000000..1a7a8dd045a
--- /dev/null
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -0,0 +1,189 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <linux/err.h>
19#include "clk.h"
20
21static int clk_busy_wait(void __iomem *reg, u8 shift)
22{
23 unsigned long timeout = jiffies + msecs_to_jiffies(10);
24
25 while (readl_relaxed(reg) & (1 << shift))
26 if (time_after(jiffies, timeout))
27 return -ETIMEDOUT;
28
29 return 0;
30}
31
32struct clk_busy_divider {
33 struct clk_divider div;
34 const struct clk_ops *div_ops;
35 void __iomem *reg;
36 u8 shift;
37};
38
39static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
40{
41 struct clk_divider *div = container_of(hw, struct clk_divider, hw);
42
43 return container_of(div, struct clk_busy_divider, div);
44}
45
46static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
47 unsigned long parent_rate)
48{
49 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
50
51 return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
52}
53
54static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
55 unsigned long *prate)
56{
57 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
58
59 return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
60}
61
62static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
63 unsigned long parent_rate)
64{
65 struct clk_busy_divider *busy = to_clk_busy_divider(hw);
66 int ret;
67
68 ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
69 if (!ret)
70 ret = clk_busy_wait(busy->reg, busy->shift);
71
72 return ret;
73}
74
75static struct clk_ops clk_busy_divider_ops = {
76 .recalc_rate = clk_busy_divider_recalc_rate,
77 .round_rate = clk_busy_divider_round_rate,
78 .set_rate = clk_busy_divider_set_rate,
79};
80
81struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
82 void __iomem *reg, u8 shift, u8 width,
83 void __iomem *busy_reg, u8 busy_shift)
84{
85 struct clk_busy_divider *busy;
86 struct clk *clk;
87 struct clk_init_data init;
88
89 busy = kzalloc(sizeof(*busy), GFP_KERNEL);
90 if (!busy)
91 return ERR_PTR(-ENOMEM);
92
93 busy->reg = busy_reg;
94 busy->shift = busy_shift;
95
96 busy->div.reg = reg;
97 busy->div.shift = shift;
98 busy->div.width = width;
99 busy->div.lock = &imx_ccm_lock;
100 busy->div_ops = &clk_divider_ops;
101
102 init.name = name;
103 init.ops = &clk_busy_divider_ops;
104 init.flags = CLK_SET_RATE_PARENT;
105 init.parent_names = &parent_name;
106 init.num_parents = 1;
107
108 busy->div.hw.init = &init;
109
110 clk = clk_register(NULL, &busy->div.hw);
111 if (!clk)
112 kfree(busy);
113
114 return clk;
115}
116
117struct clk_busy_mux {
118 struct clk_mux mux;
119 const struct clk_ops *mux_ops;
120 void __iomem *reg;
121 u8 shift;
122};
123
124static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
125{
126 struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
127
128 return container_of(mux, struct clk_busy_mux, mux);
129}
130
131static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
132{
133 struct clk_busy_mux *busy = to_clk_busy_mux(hw);
134
135 return busy->mux_ops->get_parent(&busy->mux.hw);
136}
137
138static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
139{
140 struct clk_busy_mux *busy = to_clk_busy_mux(hw);
141 int ret;
142
143 ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
144 if (!ret)
145 ret = clk_busy_wait(busy->reg, busy->shift);
146
147 return ret;
148}
149
150struct clk_ops clk_busy_mux_ops = {
151 .get_parent = clk_busy_mux_get_parent,
152 .set_parent = clk_busy_mux_set_parent,
153};
154
155struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
156 u8 width, void __iomem *busy_reg, u8 busy_shift,
157 const char **parent_names, int num_parents)
158{
159 struct clk_busy_mux *busy;
160 struct clk *clk;
161 struct clk_init_data init;
162
163 busy = kzalloc(sizeof(*busy), GFP_KERNEL);
164 if (!busy)
165 return ERR_PTR(-ENOMEM);
166
167 busy->reg = busy_reg;
168 busy->shift = busy_shift;
169
170 busy->mux.reg = reg;
171 busy->mux.shift = shift;
172 busy->mux.width = width;
173 busy->mux.lock = &imx_ccm_lock;
174 busy->mux_ops = &clk_mux_ops;
175
176 init.name = name;
177 init.ops = &clk_busy_mux_ops;
178 init.flags = 0;
179 init.parent_names = parent_names;
180 init.num_parents = num_parents;
181
182 busy->mux.hw.init = &init;
183
184 clk = clk_register(NULL, &busy->mux.hw);
185 if (IS_ERR(clk))
186 kfree(busy);
187
188 return clk;
189}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
new file mode 100644
index 00000000000..3c1b8ff9a0a
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -0,0 +1,118 @@
1/*
2 * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
3 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Gated clock implementation
10 */
11
12#include <linux/clk-provider.h>
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/io.h>
16#include <linux/err.h>
17#include <linux/string.h>
18
19/**
20 * DOC: basic gatable clock which can gate and ungate it's ouput
21 *
22 * Traits of this clock:
23 * prepare - clk_(un)prepare only ensures parent is (un)prepared
24 * enable - clk_enable and clk_disable are functional & control gating
25 * rate - inherits rate from parent. No clk_set_rate support
26 * parent - fixed parent. No clk_set_parent support
27 */
28
29#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
30
31static int clk_gate2_enable(struct clk_hw *hw)
32{
33 struct clk_gate *gate = to_clk_gate(hw);
34 u32 reg;
35 unsigned long flags = 0;
36
37 if (gate->lock)
38 spin_lock_irqsave(gate->lock, flags);
39
40 reg = readl(gate->reg);
41 reg |= 3 << gate->bit_idx;
42 writel(reg, gate->reg);
43
44 if (gate->lock)
45 spin_unlock_irqrestore(gate->lock, flags);
46
47 return 0;
48}
49
50static void clk_gate2_disable(struct clk_hw *hw)
51{
52 struct clk_gate *gate = to_clk_gate(hw);
53 u32 reg;
54 unsigned long flags = 0;
55
56 if (gate->lock)
57 spin_lock_irqsave(gate->lock, flags);
58
59 reg = readl(gate->reg);
60 reg &= ~(3 << gate->bit_idx);
61 writel(reg, gate->reg);
62
63 if (gate->lock)
64 spin_unlock_irqrestore(gate->lock, flags);
65}
66
67static int clk_gate2_is_enabled(struct clk_hw *hw)
68{
69 u32 reg;
70 struct clk_gate *gate = to_clk_gate(hw);
71
72 reg = readl(gate->reg);
73
74 if (((reg >> gate->bit_idx) & 3) == 3)
75 return 1;
76
77 return 0;
78}
79
80static struct clk_ops clk_gate2_ops = {
81 .enable = clk_gate2_enable,
82 .disable = clk_gate2_disable,
83 .is_enabled = clk_gate2_is_enabled,
84};
85
86struct clk *clk_register_gate2(struct device *dev, const char *name,
87 const char *parent_name, unsigned long flags,
88 void __iomem *reg, u8 bit_idx,
89 u8 clk_gate2_flags, spinlock_t *lock)
90{
91 struct clk_gate *gate;
92 struct clk *clk;
93 struct clk_init_data init;
94
95 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
96 if (!gate)
97 return ERR_PTR(-ENOMEM);
98
99 /* struct clk_gate assignments */
100 gate->reg = reg;
101 gate->bit_idx = bit_idx;
102 gate->flags = clk_gate2_flags;
103 gate->lock = lock;
104
105 init.name = name;
106 init.ops = &clk_gate2_ops;
107 init.flags = flags;
108 init.parent_names = parent_name ? &parent_name : NULL;
109 init.num_parents = parent_name ? 1 : 0;
110
111 gate->hw.init = &init;
112
113 clk = clk_register(dev, &gate->hw);
114 if (IS_ERR(clk))
115 kfree(clk);
116
117 return clk;
118}
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
new file mode 100644
index 00000000000..0f0beb580b7
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -0,0 +1,115 @@
1/*
2 * Copyright (C) 2008 Sascha Hauer <s.hauer@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 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/clk.h>
21#include <linux/io.h>
22#include <linux/clkdev.h>
23#include <linux/err.h>
24
25#include <mach/hardware.h>
26#include <mach/common.h>
27#include "clk.h"
28
29/* CCM register addresses */
30#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
31
32#define CCM_CSCR IO_ADDR_CCM(0x0)
33#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
34#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
35#define CCM_PCDR IO_ADDR_CCM(0x20)
36
37/* SCM register addresses */
38#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
39
40#define SCM_GCCR IO_ADDR_SCM(0xc)
41
42static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
43static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem",
44 "fclk", };
45enum imx1_clks {
46 dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, spll, mcu,
47 fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
48 mma_gate, usbd_gate, clk_max
49};
50
51static struct clk *clk[clk_max];
52
53int __init mx1_clocks_init(unsigned long fref)
54{
55 int i;
56
57 clk[dummy] = imx_clk_fixed("dummy", 0);
58 clk[clk32] = imx_clk_fixed("clk32", fref);
59 clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000);
60 clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
61 clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
62 clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks,
63 ARRAY_SIZE(prem_sel_clks));
64 clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
65 clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
66 clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
67 clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1);
68 clk[hclk] = imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4);
69 clk[clk48m] = imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3);
70 clk[per1] = imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4);
71 clk[per2] = imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4);
72 clk[per3] = imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7);
73 clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks,
74 ARRAY_SIZE(clko_sel_clks));
75 clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4);
76 clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
77 clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
78 clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
79
80 for (i = 0; i < ARRAY_SIZE(clk); i++)
81 if (IS_ERR(clk[i]))
82 pr_err("imx1 clk %d: register failed with %ld\n",
83 i, PTR_ERR(clk[i]));
84
85 clk_register_clkdev(clk[dma_gate], "ahb", "imx-dma");
86 clk_register_clkdev(clk[csi_gate], NULL, "mx1-camera.0");
87 clk_register_clkdev(clk[mma_gate], "mma", NULL);
88 clk_register_clkdev(clk[usbd_gate], NULL, "imx_udc.0");
89 clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
90 clk_register_clkdev(clk[hclk], "ipg", "imx-gpt.0");
91 clk_register_clkdev(clk[per1], "per", "imx1-uart.0");
92 clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.0");
93 clk_register_clkdev(clk[per1], "per", "imx1-uart.1");
94 clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1");
95 clk_register_clkdev(clk[per1], "per", "imx1-uart.2");
96 clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.2");
97 clk_register_clkdev(clk[hclk], NULL, "imx-i2c.0");
98 clk_register_clkdev(clk[per2], "per", "imx1-cspi.0");
99 clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0");
100 clk_register_clkdev(clk[per2], "per", "imx1-cspi.1");
101 clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1");
102 clk_register_clkdev(clk[per2], NULL, "imx-mmc.0");
103 clk_register_clkdev(clk[per2], "per", "imx-fb.0");
104 clk_register_clkdev(clk[dummy], "ipg", "imx-fb.0");
105 clk_register_clkdev(clk[dummy], "ahb", "imx-fb.0");
106 clk_register_clkdev(clk[hclk], "mshc", NULL);
107 clk_register_clkdev(clk[per3], "ssi", NULL);
108 clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0");
109 clk_register_clkdev(clk[clko], "clko", NULL);
110
111 mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
112 MX1_TIM1_INT);
113
114 return 0;
115}
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
new file mode 100644
index 00000000000..4e4f384ee8d
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -0,0 +1,186 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
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
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/clkdev.h>
23#include <linux/clk-provider.h>
24#include <linux/io.h>
25#include <linux/module.h>
26#include <linux/clkdev.h>
27#include <linux/err.h>
28
29#include <mach/hardware.h>
30#include <mach/common.h>
31#include "clk.h"
32
33#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
34
35/* Register offsets */
36#define CCM_CSCR IO_ADDR_CCM(0x0)
37#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
38#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
39#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
40#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
41#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
42#define CCM_PCDR0 IO_ADDR_CCM(0x18)
43#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
44#define CCM_PCCR0 IO_ADDR_CCM(0x20)
45#define CCM_PCCR1 IO_ADDR_CCM(0x24)
46#define CCM_CCSR IO_ADDR_CCM(0x28)
47#define CCM_PMCTL IO_ADDR_CCM(0x2c)
48#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
49#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
50
51static const char *mpll_sel_clks[] = { "fpm", "ckih", };
52static const char *spll_sel_clks[] = { "fpm", "ckih", };
53
54enum imx21_clks {
55 ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
56 per2, per3, per4, uart1_ipg_gate, uart2_ipg_gate, uart3_ipg_gate,
57 uart4_ipg_gate, gpt1_ipg_gate, gpt2_ipg_gate, gpt3_ipg_gate,
58 pwm_ipg_gate, sdhc1_ipg_gate, sdhc2_ipg_gate, lcdc_ipg_gate,
59 lcdc_hclk_gate, cspi3_ipg_gate, cspi2_ipg_gate, cspi1_ipg_gate,
60 per4_gate, csi_hclk_gate, usb_div, usb_gate, usb_hclk_gate, ssi1_gate,
61 ssi2_gate, nfc_div, nfc_gate, dma_gate, dma_hclk_gate, brom_gate,
62 emma_gate, emma_hclk_gate, slcdc_gate, slcdc_hclk_gate, wdog_gate,
63 gpio_gate, i2c_gate, kpp_gate, owire_gate, rtc_gate, clk_max
64};
65
66static struct clk *clk[clk_max];
67
68/*
69 * must be called very early to get information about the
70 * available clock rate when the timer framework starts
71 */
72int __init mx21_clocks_init(unsigned long lref, unsigned long href)
73{
74 int i;
75
76 clk[ckil] = imx_clk_fixed("ckil", lref);
77 clk[ckih] = imx_clk_fixed("ckih", href);
78 clk[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
79 clk[mpll_sel] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks,
80 ARRAY_SIZE(mpll_sel_clks));
81 clk[spll_sel] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks,
82 ARRAY_SIZE(spll_sel_clks));
83 clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
84 clk[spll] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
85 clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3);
86 clk[hclk] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
87 clk[ipg] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
88 clk[per1] = imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6);
89 clk[per2] = imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6);
90 clk[per3] = imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6);
91 clk[per4] = imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6);
92 clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
93 clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
94 clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
95 clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
96 clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
97 clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
98 clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
99 clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
100 clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
101 clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
102 clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
103 clk[lcdc_hclk_gate] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
104 clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
105 clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
106 clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
107 clk[per4_gate] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
108 clk[csi_hclk_gate] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
109 clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3);
110 clk[usb_gate] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
111 clk[usb_hclk_gate] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
112 clk[ssi1_gate] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
113 clk[ssi2_gate] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
114 clk[nfc_div] = imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4);
115 clk[nfc_gate] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
116 clk[dma_gate] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
117 clk[dma_hclk_gate] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
118 clk[brom_gate] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
119 clk[emma_gate] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
120 clk[emma_hclk_gate] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
121 clk[slcdc_gate] = imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25);
122 clk[slcdc_hclk_gate] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
123 clk[wdog_gate] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
124 clk[gpio_gate] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
125 clk[i2c_gate] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
126 clk[kpp_gate] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
127 clk[owire_gate] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
128 clk[rtc_gate] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
129
130 for (i = 0; i < ARRAY_SIZE(clk); i++)
131 if (IS_ERR(clk[i]))
132 pr_err("i.MX21 clk %d: register failed with %ld\n",
133 i, PTR_ERR(clk[i]));
134
135 clk_register_clkdev(clk[per1], "per1", NULL);
136 clk_register_clkdev(clk[per2], "per2", NULL);
137 clk_register_clkdev(clk[per3], "per3", NULL);
138 clk_register_clkdev(clk[per4], "per4", NULL);
139 clk_register_clkdev(clk[per1], "per", "imx21-uart.0");
140 clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
141 clk_register_clkdev(clk[per1], "per", "imx21-uart.1");
142 clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
143 clk_register_clkdev(clk[per1], "per", "imx21-uart.2");
144 clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
145 clk_register_clkdev(clk[per1], "per", "imx21-uart.3");
146 clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
147 clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
148 clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
149 clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
150 clk_register_clkdev(clk[per1], "per", "imx-gpt.1");
151 clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
152 clk_register_clkdev(clk[per1], "per", "imx-gpt.2");
153 clk_register_clkdev(clk[pwm_ipg_gate], "pwm", "mxc_pwm.0");
154 clk_register_clkdev(clk[per2], "per", "imx21-cspi.0");
155 clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx21-cspi.0");
156 clk_register_clkdev(clk[per2], "per", "imx21-cspi.1");
157 clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx21-cspi.1");
158 clk_register_clkdev(clk[per2], "per", "imx21-cspi.2");
159 clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx21-cspi.2");
160 clk_register_clkdev(clk[per3], "per", "imx-fb.0");
161 clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
162 clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx-fb.0");
163 clk_register_clkdev(clk[usb_gate], "per", "imx21-hcd.0");
164 clk_register_clkdev(clk[usb_hclk_gate], "ahb", "imx21-hcd.0");
165 clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand.0");
166 clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx-dma");
167 clk_register_clkdev(clk[dma_gate], "ipg", "imx-dma");
168 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
169 clk_register_clkdev(clk[i2c_gate], NULL, "imx-i2c.0");
170 clk_register_clkdev(clk[kpp_gate], NULL, "mxc-keypad");
171 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
172 clk_register_clkdev(clk[brom_gate], "brom", NULL);
173 clk_register_clkdev(clk[emma_gate], "emma", NULL);
174 clk_register_clkdev(clk[slcdc_gate], "slcdc", NULL);
175 clk_register_clkdev(clk[gpio_gate], "gpio", NULL);
176 clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
177 clk_register_clkdev(clk[csi_hclk_gate], "csi", NULL);
178 clk_register_clkdev(clk[ssi1_gate], "ssi1", NULL);
179 clk_register_clkdev(clk[ssi2_gate], "ssi2", NULL);
180 clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL);
181 clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL);
182
183 mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
184 MX21_INT_GPT1);
185 return 0;
186}
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
new file mode 100644
index 00000000000..d9833bb5fd6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -0,0 +1,248 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
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
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25#include <linux/err.h>
26
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <mach/mx25.h>
30#include "clk.h"
31
32#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
33
34#define CCM_MPCTL 0x00
35#define CCM_UPCTL 0x04
36#define CCM_CCTL 0x08
37#define CCM_CGCR0 0x0C
38#define CCM_CGCR1 0x10
39#define CCM_CGCR2 0x14
40#define CCM_PCDR0 0x18
41#define CCM_PCDR1 0x1C
42#define CCM_PCDR2 0x20
43#define CCM_PCDR3 0x24
44#define CCM_RCSR 0x28
45#define CCM_CRDR 0x2C
46#define CCM_DCVR0 0x30
47#define CCM_DCVR1 0x34
48#define CCM_DCVR2 0x38
49#define CCM_DCVR3 0x3c
50#define CCM_LTR0 0x40
51#define CCM_LTR1 0x44
52#define CCM_LTR2 0x48
53#define CCM_LTR3 0x4c
54#define CCM_MCR 0x64
55
56#define ccm(x) (CRM_BASE + (x))
57
58static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
59static const char *per_sel_clks[] = { "ahb", "upll", };
60
61enum mx25_clks {
62 dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
63 per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
64 per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
65 per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
66 per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
67 csi_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, gpt_ipg_per, i2c_ipg_per,
68 lcdc_ipg_per, nfc_ipg_per, ssi1_ipg_per, ssi2_ipg_per, uart_ipg_per,
69 csi_ahb, esdhc1_ahb, esdhc2_ahb, fec_ahb, lcdc_ahb, sdma_ahb,
70 usbotg_ahb, can1_ipg, can2_ipg, csi_ipg, cspi1_ipg, cspi2_ipg,
71 cspi3_ipg, dryice_ipg, esdhc1_ipg, esdhc2_ipg, fec_ipg, iim_ipg,
72 kpp_ipg, lcdc_ipg, pwm1_ipg, pwm2_ipg, pwm3_ipg, pwm4_ipg, sdma_ipg,
73 ssi1_ipg, ssi2_ipg, tsc_ipg, uart1_ipg, uart2_ipg, uart3_ipg,
74 uart4_ipg, uart5_ipg, wdt_ipg, clk_max
75};
76
77static struct clk *clk[clk_max];
78
79int __init mx25_clocks_init(void)
80{
81 int i;
82
83 clk[dummy] = imx_clk_fixed("dummy", 0);
84 clk[osc] = imx_clk_fixed("osc", 24000000);
85 clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
86 clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
87 clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
88 clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
89 clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
90 clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
91 clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6);
92 clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
93 clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
94 clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
95 clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
96 clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
97 clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
98 clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
99 clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
100 clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
101 clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
102 clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
103 clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
104 clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
105 clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
106 clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
107 clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
108 clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
109 clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
110 clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
111 clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
112 clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
113 clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
114 clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
115 clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
116 clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
117 clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
118 clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
119 clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
120 clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
121 clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
122 clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
123 clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
124 clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
125 clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
126 clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3);
127 clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4);
128 clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5);
129 clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6);
130 clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7);
131 clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8);
132 clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
133 clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
134 clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
135 clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
136 clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
137 clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
138 clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
139 clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
140 clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
141 clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
142 clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2);
143 clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3);
144 clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4);
145 clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5);
146 clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6);
147 clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7);
148 clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8);
149 clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
150 clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
151 clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
152 clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
153 clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
154 clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
155 clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
156 clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0);
157 clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1);
158 clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2);
159 clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6);
160 clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
161 clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
162 clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
163 clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
164 clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
165 clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
166 clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
167 clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
168 clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
169
170 for (i = 0; i < ARRAY_SIZE(clk); i++)
171 if (IS_ERR(clk[i]))
172 pr_err("i.MX25 clk %d: register failed with %ld\n",
173 i, PTR_ERR(clk[i]));
174
175 /* i.mx25 has the i.mx21 type uart */
176 clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
177 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
178 clk_register_clkdev(clk[uart2_ipg], "ipg", "imx21-uart.1");
179 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.1");
180 clk_register_clkdev(clk[uart3_ipg], "ipg", "imx21-uart.2");
181 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.2");
182 clk_register_clkdev(clk[uart4_ipg], "ipg", "imx21-uart.3");
183 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
184 clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
185 clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
186 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
187 clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
188 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
189 clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
190 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
191 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
192 clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.1");
193 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
194 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
195 clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
196 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
197 clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
198 clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
199 clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
200 clk_register_clkdev(clk[nfc_ipg_per], NULL, "mxc_nand.0");
201 /* i.mx25 has the i.mx35 type cspi */
202 clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
203 clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
204 clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2");
205 clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.0");
206 clk_register_clkdev(clk[per10], "per", "mxc_pwm.0");
207 clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.1");
208 clk_register_clkdev(clk[per10], "per", "mxc_pwm.1");
209 clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.2");
210 clk_register_clkdev(clk[per10], "per", "mxc_pwm.2");
211 clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.3");
212 clk_register_clkdev(clk[per10], "per", "mxc_pwm.3");
213 clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
214 clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
215 clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.0");
216 clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.1");
217 clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.2");
218 clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0");
219 clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0");
220 clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0");
221 clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx-fb.0");
222 clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");
223 clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");
224 clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
225 clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0");
226 clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0");
227 clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1");
228 clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1");
229 clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");
230 clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");
231 clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0");
232 clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1");
233 clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1");
234 clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1");
235 clk_register_clkdev(clk[csi_ipg_per], "per", "mx2-camera.0");
236 clk_register_clkdev(clk[csi_ipg], "ipg", "mx2-camera.0");
237 clk_register_clkdev(clk[csi_ahb], "ahb", "mx2-camera.0");
238 clk_register_clkdev(clk[dummy], "audmux", NULL);
239 clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0");
240 clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1");
241 /* i.mx25 has the i.mx35 type sdma */
242 clk_register_clkdev(clk[sdma_ipg], "ipg", "imx35-sdma");
243 clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
244 clk_register_clkdev(clk[iim_ipg], "iim", NULL);
245
246 mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
247 return 0;
248}
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
new file mode 100644
index 00000000000..50a7ebd8d1b
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -0,0 +1,290 @@
1#include <linux/clk.h>
2#include <linux/io.h>
3#include <linux/module.h>
4#include <linux/clkdev.h>
5#include <linux/err.h>
6#include <linux/clk-provider.h>
7#include <linux/of.h>
8
9#include <mach/common.h>
10#include <mach/hardware.h>
11#include "clk.h"
12
13#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
14
15/* Register offsets */
16#define CCM_CSCR IO_ADDR_CCM(0x0)
17#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
18#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
19#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
20#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
21#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
22#define CCM_PCDR0 IO_ADDR_CCM(0x18)
23#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
24#define CCM_PCCR0 IO_ADDR_CCM(0x20)
25#define CCM_PCCR1 IO_ADDR_CCM(0x24)
26#define CCM_CCSR IO_ADDR_CCM(0x28)
27#define CCM_PMCTL IO_ADDR_CCM(0x2c)
28#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
29#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
30
31#define CCM_CSCR_UPDATE_DIS (1 << 31)
32#define CCM_CSCR_SSI2 (1 << 23)
33#define CCM_CSCR_SSI1 (1 << 22)
34#define CCM_CSCR_VPU (1 << 21)
35#define CCM_CSCR_MSHC (1 << 20)
36#define CCM_CSCR_SPLLRES (1 << 19)
37#define CCM_CSCR_MPLLRES (1 << 18)
38#define CCM_CSCR_SP (1 << 17)
39#define CCM_CSCR_MCU (1 << 16)
40#define CCM_CSCR_OSC26MDIV (1 << 4)
41#define CCM_CSCR_OSC26M (1 << 3)
42#define CCM_CSCR_FPM (1 << 2)
43#define CCM_CSCR_SPEN (1 << 1)
44#define CCM_CSCR_MPEN (1 << 0)
45
46/* i.MX27 TO 2+ */
47#define CCM_CSCR_ARM_SRC (1 << 15)
48
49#define CCM_SPCTL1_LF (1 << 15)
50#define CCM_SPCTL1_BRMO (1 << 6)
51
52static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
53static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
54static const char *clko_sel_clks[] = {
55 "ckil", "prem", "ckih", "ckih",
56 "ckih", "mpll", "spll", "cpu_div",
57 "ahb", "ipg", "per1_div", "per2_div",
58 "per3_div", "per4_div", "ssi1_div", "ssi2_div",
59 "nfc_div", "mshc_div", "vpu_div", "60m",
60 "32k", "usb_div", "dptc",
61};
62
63static const char *ssi_sel_clks[] = { "spll", "mpll", };
64
65enum mx27_clks {
66 dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
67 per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
68 clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
69 clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
70 sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
71 rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
72 kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
73 gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
74 gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
75 emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
76 cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
77 vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
78 usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
79 vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
80 csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
81 uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
82 uart2_ipg_gate, uart1_ipg_gate, clk_max
83};
84
85static struct clk *clk[clk_max];
86
87int __init mx27_clocks_init(unsigned long fref)
88{
89 int i;
90
91 clk[dummy] = imx_clk_fixed("dummy", 0);
92 clk[ckih] = imx_clk_fixed("ckih", fref);
93 clk[ckil] = imx_clk_fixed("ckil", 32768);
94 clk[mpll] = imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0);
95 clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
96 clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
97
98 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
99 clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
100 clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
101 } else {
102 clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
103 clk[ipg] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
104 }
105
106 clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
107 clk[per1_div] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
108 clk[per2_div] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
109 clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
110 clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
111 clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
112 clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3);
113 clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
114 clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
115 clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
116 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
117 clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
118 else
119 clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
120 clk[clko_div] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
121 clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
122 clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
123 clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
124 clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3);
125 clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
126 clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
127 clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
128 clk[slcdc_ipg_gate] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
129 clk[sdhc3_ipg_gate] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
130 clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
131 clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
132 clk[scc_ipg_gate] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
133 clk[sahara_ipg_gate] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
134 clk[rtc_ipg_gate] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
135 clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
136 clk[owire_ipg_gate] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
137 clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
138 clk[kpp_ipg_gate] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
139 clk[iim_ipg_gate] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
140 clk[i2c2_ipg_gate] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
141 clk[i2c1_ipg_gate] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
142 clk[gpt6_ipg_gate] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
143 clk[gpt5_ipg_gate] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
144 clk[gpt4_ipg_gate] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
145 clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
146 clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
147 clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
148 clk[gpio_ipg_gate] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
149 clk[fec_ipg_gate] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
150 clk[emma_ipg_gate] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
151 clk[dma_ipg_gate] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
152 clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
153 clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
154 clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
155 clk[nfc_baud_gate] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3);
156 clk[ssi2_baud_gate] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4);
157 clk[ssi1_baud_gate] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5);
158 clk[vpu_baud_gate] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6);
159 clk[per4_gate] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7);
160 clk[per3_gate] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8);
161 clk[per2_gate] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9);
162 clk[per1_gate] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
163 clk[usb_ahb_gate] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
164 clk[slcdc_ahb_gate] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
165 clk[sahara_ahb_gate] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
166 clk[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
167 clk[vpu_ahb_gate] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
168 clk[fec_ahb_gate] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
169 clk[emma_ahb_gate] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
170 clk[emi_ahb_gate] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
171 clk[dma_ahb_gate] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
172 clk[csi_ahb_gate] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
173 clk[brom_ahb_gate] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
174 clk[ata_ahb_gate] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
175 clk[wdog_ipg_gate] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
176 clk[usb_ipg_gate] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
177 clk[uart6_ipg_gate] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
178 clk[uart5_ipg_gate] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
179 clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
180 clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
181 clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
182 clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
183
184 for (i = 0; i < ARRAY_SIZE(clk); i++)
185 if (IS_ERR(clk[i]))
186 pr_err("i.MX27 clk %d: register failed with %ld\n",
187 i, PTR_ERR(clk[i]));
188
189 clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
190 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.0");
191 clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
192 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.1");
193 clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
194 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.2");
195 clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
196 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.3");
197 clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
198 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.4");
199 clk_register_clkdev(clk[uart6_ipg_gate], "ipg", "imx21-uart.5");
200 clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.5");
201 clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
202 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.0");
203 clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
204 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.1");
205 clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
206 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.2");
207 clk_register_clkdev(clk[gpt4_ipg_gate], "ipg", "imx-gpt.3");
208 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.3");
209 clk_register_clkdev(clk[gpt5_ipg_gate], "ipg", "imx-gpt.4");
210 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.4");
211 clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5");
212 clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5");
213 clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0");
214 clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.0");
215 clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "mxc-mmc.0");
216 clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.1");
217 clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.1");
218 clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.2");
219 clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.2");
220 clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0");
221 clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1");
222 clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2");
223 clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0");
224 clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
225 clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
226 clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0");
227 clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
228 clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
229 clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
230 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
231 clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
232 clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
233 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
234 clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.1");
235 clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.1");
236 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
237 clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.2");
238 clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2");
239 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
240 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
241 clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
242 clk_register_clkdev(clk[vpu_baud_gate], "per", "imx-vpu");
243 clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "imx-vpu");
244 clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma");
245 clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma");
246 clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
247 clk_register_clkdev(clk[fec_ahb_gate], "ahb", "imx27-fec.0");
248 clk_register_clkdev(clk[wdog_ipg_gate], NULL, "imx2-wdt.0");
249 clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx-i2c.0");
250 clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1");
251 clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0");
252 clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad");
253 clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma");
254 clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma");
255 clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL);
256 clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL);
257 clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL);
258 clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
259 clk_register_clkdev(clk[rtc_ipg_gate], "rtc", NULL);
260 clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
261 clk_register_clkdev(clk[cpu_div], "cpu", NULL);
262 clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
263 clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0");
264 clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1");
265
266 mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
267 MX27_INT_GPT1);
268
269 clk_prepare_enable(clk[emi_ahb_gate]);
270
271 return 0;
272}
273
274#ifdef CONFIG_OF
275int __init mx27_clocks_init_dt(void)
276{
277 struct device_node *np;
278 u32 fref = 26000000; /* default */
279
280 for_each_compatible_node(np, NULL, "fixed-clock") {
281 if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
282 continue;
283
284 if (!of_property_read_u32(np, "clock-frequency", &fref))
285 break;
286 }
287
288 return mx27_clocks_init(fref);
289}
290#endif
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
new file mode 100644
index 00000000000..a854b9cae5e
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -0,0 +1,182 @@
1/*
2 * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
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
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/clk.h>
20#include <linux/clkdev.h>
21#include <linux/io.h>
22#include <linux/err.h>
23
24#include <mach/hardware.h>
25#include <mach/mx31.h>
26#include <mach/common.h>
27
28#include "clk.h"
29#include "crmregs-imx3.h"
30
31static const char *mcu_main_sel[] = { "spll", "mpll", };
32static const char *per_sel[] = { "per_div", "ipg", };
33static const char *csi_sel[] = { "upll", "spll", };
34static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
35
36enum mx31_clks {
37 ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
38 per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
39 fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
40 iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
41 uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
42 mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
43 sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
44 uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
45 gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
46};
47
48static struct clk *clk[clk_max];
49
50int __init mx31_clocks_init(unsigned long fref)
51{
52 void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
53 int i;
54
55 clk[ckih] = imx_clk_fixed("ckih", fref);
56 clk[ckil] = imx_clk_fixed("ckil", 32768);
57 clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
58 clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
59 clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
60 clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
61 clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
62 clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
63 clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
64 clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
65 clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
66 clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
67 clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
68 clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
69 clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
70 clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
71 clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
72 clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
73 clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
74 clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
75 clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
76 clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
77 clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
78 clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
79 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
80 clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
81 clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
82 clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
83 clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
84 clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
85 clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
86 clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
87 clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
88 clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
89 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
90 clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
91 clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
92 clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
93 clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
94 clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
95 clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
96 clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
97 clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
98 clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
99 clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
100 clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
101 clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
102 clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
103 clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
104 clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
105 clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
106 clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
107 clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
108 clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
109 clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
110 clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
111 clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
112 clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
113
114 for (i = 0; i < ARRAY_SIZE(clk); i++)
115 if (IS_ERR(clk[i]))
116 pr_err("imx31 clk %d: register failed with %ld\n",
117 i, PTR_ERR(clk[i]));
118
119 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
120 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
121 clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
122 clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
123 clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
124 clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
125 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
126 clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
127 clk_register_clkdev(clk[epit1_gate], "epit", NULL);
128 clk_register_clkdev(clk[epit2_gate], "epit", NULL);
129 clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
130 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
131 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
132 clk_register_clkdev(clk[kpp_gate], "kpp", NULL);
133 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
134 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
135 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
136 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
137 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
138 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
139 clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
140 clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
141 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
142 clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
143 clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
144 clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
145 clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
146 /* i.mx31 has the i.mx21 type uart */
147 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
148 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
149 clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
150 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
151 clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
152 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
153 clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
154 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
155 clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
156 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
157 clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
158 clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
159 clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
160 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
161 clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0");
162 clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1");
163 clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
164 clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
165 clk_register_clkdev(clk[firi_gate], "firi", NULL);
166 clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
167 clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
168 clk_register_clkdev(clk[rng_gate], "rng", NULL);
169 clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
170 clk_register_clkdev(clk[iim_gate], "iim", NULL);
171
172 clk_set_parent(clk[csi], clk[upll]);
173 clk_prepare_enable(clk[emi_gate]);
174 clk_prepare_enable(clk[iim_gate]);
175 mx31_revision();
176 clk_disable_unprepare(clk[iim_gate]);
177
178 mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
179 MX31_INT_GPT);
180
181 return 0;
182}
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
new file mode 100644
index 00000000000..a9e60bf7dd7
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -0,0 +1,278 @@
1/*
2 * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
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 */
9#include <linux/mm.h>
10#include <linux/delay.h>
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/clkdev.h>
14#include <linux/of.h>
15#include <linux/err.h>
16
17#include <mach/hardware.h>
18#include <mach/common.h>
19
20#include "crmregs-imx3.h"
21#include "clk.h"
22
23struct arm_ahb_div {
24 unsigned char arm, ahb, sel;
25};
26
27static struct arm_ahb_div clk_consumer[] = {
28 { .arm = 1, .ahb = 4, .sel = 0},
29 { .arm = 1, .ahb = 3, .sel = 1},
30 { .arm = 2, .ahb = 2, .sel = 0},
31 { .arm = 0, .ahb = 0, .sel = 0},
32 { .arm = 0, .ahb = 0, .sel = 0},
33 { .arm = 0, .ahb = 0, .sel = 0},
34 { .arm = 4, .ahb = 1, .sel = 0},
35 { .arm = 1, .ahb = 5, .sel = 0},
36 { .arm = 1, .ahb = 8, .sel = 0},
37 { .arm = 1, .ahb = 6, .sel = 1},
38 { .arm = 2, .ahb = 4, .sel = 0},
39 { .arm = 0, .ahb = 0, .sel = 0},
40 { .arm = 0, .ahb = 0, .sel = 0},
41 { .arm = 0, .ahb = 0, .sel = 0},
42 { .arm = 4, .ahb = 2, .sel = 0},
43 { .arm = 0, .ahb = 0, .sel = 0},
44};
45
46static char hsp_div_532[] = { 4, 8, 3, 0 };
47static char hsp_div_400[] = { 3, 6, 3, 0 };
48
49static const char *std_sel[] = {"ppll", "arm"};
50static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
51
52enum mx35_clks {
53 ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
54 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
55 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
56 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
57 ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
58 audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
59 edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
60 esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
61 gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
62 kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
63 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
64 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
65 wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
66 clk_max
67};
68
69static struct clk *clk[clk_max];
70
71int __init mx35_clocks_init()
72{
73 void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
74 u32 pdr0, consumer_sel, hsp_sel;
75 struct arm_ahb_div *aad;
76 unsigned char *hsp_div;
77 int i;
78
79 pdr0 = __raw_readl(base + MXC_CCM_PDR0);
80 consumer_sel = (pdr0 >> 16) & 0xf;
81 aad = &clk_consumer[consumer_sel];
82 if (!aad->arm) {
83 pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
84 /*
85 * We are basically stuck. Continue with a default entry and hope we
86 * get far enough to actually show the above message
87 */
88 aad = &clk_consumer[0];
89 }
90
91 clk[ckih] = imx_clk_fixed("ckih", 24000000);
92 clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
93 clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
94
95 clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
96
97 if (aad->sel)
98 clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
99 else
100 clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
101
102 if (clk_get_rate(clk[arm]) > 400000000)
103 hsp_div = hsp_div_532;
104 else
105 hsp_div = hsp_div_400;
106
107 hsp_sel = (pdr0 >> 20) & 0x3;
108 if (!hsp_div[hsp_sel]) {
109 pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
110 hsp_sel = 0;
111 }
112
113 clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
114
115 clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
116 clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
117
118 clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
119 clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
120 clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
121
122 clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
123 clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
124
125 clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
126 clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
127 clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
128 clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
129
130 clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
131 clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
132 clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
133
134 clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
135 clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
136 clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
137 clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
138 clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
139
140 clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
141 clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
142
143 clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
144
145 clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
146 clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
147 clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
148 clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6);
149 clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8);
150 clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
151 clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
152 clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
153 clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16);
154 clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
155 clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
156 clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
157 clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24);
158 clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
159 clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
160 clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
161
162 clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0);
163 clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2);
164 clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4);
165 clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6);
166 clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8);
167 clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
168 clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
169 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
170 clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
171 clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
172 clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
173 clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
174 clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
175 clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
176 clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
177 clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
178
179 clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0);
180 clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2);
181 clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4);
182 clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6);
183 clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8);
184 clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
185 clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
186 clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
187 clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
188 clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
189 clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
190 clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
191 clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
192 clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
193 clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
194
195 clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0);
196 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
197 clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
198
199 for (i = 0; i < ARRAY_SIZE(clk); i++)
200 if (IS_ERR(clk[i]))
201 pr_err("i.MX35 clk %d: register failed with %ld\n",
202 i, PTR_ERR(clk[i]));
203
204
205 clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
206 clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
207 clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
208 clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0");
209 clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0");
210 clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1");
211 clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1");
212 clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0");
213 clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1");
214 clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0");
215 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0");
216 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0");
217 clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1");
218 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1");
219 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1");
220 clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2");
221 clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2");
222 clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2");
223 /* i.mx35 has the i.mx27 type fec */
224 clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
225 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
226 clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
227 clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
228 clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
229 clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
230 clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
231 clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
232 clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
233 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
234 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0");
235 clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0");
236 clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1");
237 clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1");
238 /* i.mx35 has the i.mx21 type uart */
239 clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
240 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
241 clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
242 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
243 clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
244 clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
245 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
246 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
247 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0");
248 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
249 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
250 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1");
251 clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
252 clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
253 clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
254 clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
255 clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
256 clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
257 clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
258 clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0");
259
260 clk_prepare_enable(clk[spba_gate]);
261 clk_prepare_enable(clk[gpio1_gate]);
262 clk_prepare_enable(clk[gpio2_gate]);
263 clk_prepare_enable(clk[gpio3_gate]);
264 clk_prepare_enable(clk[iim_gate]);
265 clk_prepare_enable(clk[emi_gate]);
266
267 imx_print_silicon_rev("i.MX35", mx35_revision());
268
269#ifdef CONFIG_MXC_USE_EPIT
270 epit_timer_init(&epit1_clk,
271 MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
272#else
273 mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR),
274 MX35_INT_GPT);
275#endif
276
277 return 0;
278}
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
new file mode 100644
index 00000000000..fcd94f3b0f0
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -0,0 +1,506 @@
1/*
2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
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 */
9#include <linux/mm.h>
10#include <linux/delay.h>
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/clkdev.h>
14#include <linux/of.h>
15#include <linux/err.h>
16
17#include <mach/hardware.h>
18#include <mach/common.h>
19
20#include "crm-regs-imx5.h"
21#include "clk.h"
22
23/* Low-power Audio Playback Mode clock */
24static const char *lp_apm_sel[] = { "osc", };
25
26/* This is used multiple times */
27static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", };
28static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", };
29static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", };
30static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", };
31static const char *per_root_sel[] = { "per_podf", "ipg", };
32static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
33static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
34static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", };
35static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", };
36static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", };
37static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", };
38static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", };
39static const char *emi_slow_sel[] = { "main_bus", "ahb", };
40static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", };
41static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", };
42static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0", };
43static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", };
44static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", };
45static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1", };
46static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
47static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
48static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
49static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
50static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
51static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
52
53enum imx5_clks {
54 dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
55 uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
56 emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
57 usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di,
58 tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
59 uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
60 gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
61 gpt_gate, fec_gate, usboh3_per_gate, esdhc1_ipg_gate, esdhc2_ipg_gate,
62 esdhc3_ipg_gate, esdhc4_ipg_gate, ssi1_ipg_gate, ssi2_ipg_gate,
63 ssi3_ipg_gate, ecspi1_ipg_gate, ecspi1_per_gate, ecspi2_ipg_gate,
64 ecspi2_per_gate, cspi_ipg_gate, sdma_gate, emi_slow_gate, ipu_s,
65 ipu_gate, nfc_gate, ipu_di1_gate, vpu_s, vpu_gate,
66 vpu_reference_gate, uart4_ipg_gate, uart4_per_gate, uart5_ipg_gate,
67 uart5_per_gate, tve_gate, tve_pred, esdhc1_per_gate, esdhc2_per_gate,
68 esdhc3_per_gate, esdhc4_per_gate, usb_phy_gate, hsi2c_gate,
69 mipi_hsc1_gate, mipi_hsc2_gate, mipi_esc_gate, mipi_hsp_gate,
70 ldb_di1_div_3_5, ldb_di1_div, ldb_di0_div_3_5, ldb_di0_div,
71 ldb_di1_gate, can2_serial_gate, can2_ipg_gate, i2c3_gate, lp_apm,
72 periph_apm, main_bus, ahb_max, aips_tz1, aips_tz2, tmax1, tmax2,
73 tmax3, spba, uart_sel, esdhc_a_sel, esdhc_b_sel, esdhc_a_podf,
74 esdhc_b_podf, ecspi_sel, usboh3_sel, usb_phy_sel, iim_gate,
75 usboh3_gate, emi_fast_gate, ipu_di0_gate,gpc_dvfs, pll1_sw, pll2_sw,
76 pll3_sw, ipu_di0_sel, ipu_di1_sel, tve_ext_sel, mx51_mipi, pll4_sw,
77 ldb_di1_sel, di_pll4_podf, ldb_di0_sel, ldb_di0_gate, usb_phy1_gate,
78 usb_phy2_gate, per_lp_apm, per_pred1, per_pred2, per_podf, per_root,
79 ssi_apm, ssi1_root_sel, ssi2_root_sel, ssi3_root_sel, ssi_ext1_sel,
80 ssi_ext2_sel, ssi_ext1_com_sel, ssi_ext2_com_sel, ssi1_root_pred,
81 ssi1_root_podf, ssi2_root_pred, ssi2_root_podf, ssi_ext1_pred,
82 ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate,
83 ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
84 clk_max
85};
86
87static struct clk *clk[clk_max];
88
89static void __init mx5_clocks_common_init(unsigned long rate_ckil,
90 unsigned long rate_osc, unsigned long rate_ckih1,
91 unsigned long rate_ckih2)
92{
93 int i;
94
95 clk[dummy] = imx_clk_fixed("dummy", 0);
96 clk[ckil] = imx_clk_fixed("ckil", rate_ckil);
97 clk[osc] = imx_clk_fixed("osc", rate_osc);
98 clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1);
99 clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2);
100
101 clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
102 lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
103 clk[periph_apm] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
104 periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
105 clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
106 main_bus_sel, ARRAY_SIZE(main_bus_sel));
107 clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCDR, 1, 1,
108 per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
109 clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
110 clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
111 clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
112 clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCDR, 1, 0,
113 per_root_sel, ARRAY_SIZE(per_root_sel));
114 clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
115 clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
116 clk[aips_tz1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
117 clk[aips_tz2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
118 clk[tmax1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
119 clk[tmax2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
120 clk[tmax3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
121 clk[spba] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
122 clk[ipg] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
123 clk[axi_a] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
124 clk[axi_b] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
125 clk[uart_sel] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
126 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
127 clk[uart_pred] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
128 clk[uart_root] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
129
130 clk[esdhc_a_sel] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
131 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
132 clk[esdhc_b_sel] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
133 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
134 clk[esdhc_a_pred] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
135 clk[esdhc_a_podf] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
136 clk[esdhc_b_pred] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
137 clk[esdhc_b_podf] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
138 clk[esdhc_c_s] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
139 clk[esdhc_d_s] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
140
141 clk[emi_sel] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
142 emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
143 clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
144 clk[nfc_podf] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
145 clk[ecspi_sel] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
146 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
147 clk[ecspi_pred] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
148 clk[ecspi_podf] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
149 clk[usboh3_sel] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
150 standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
151 clk[usboh3_pred] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
152 clk[usboh3_podf] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
153 clk[usb_phy_pred] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
154 clk[usb_phy_podf] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
155 clk[usb_phy_sel] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
156 usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
157 clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
158 clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
159 clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
160 clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
161 clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
162 clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
163 clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
164 clk[uart2_ipg_gate] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
165 clk[uart2_per_gate] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
166 clk[uart3_ipg_gate] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
167 clk[uart3_per_gate] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
168 clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
169 clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
170 clk[gpt_ipg_gate] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 20);
171 clk[pwm1_ipg_gate] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
172 clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12);
173 clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
174 clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16);
175 clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18);
176 clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
177 clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
178 clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
179 clk[esdhc1_ipg_gate] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
180 clk[esdhc2_ipg_gate] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
181 clk[esdhc3_ipg_gate] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
182 clk[esdhc4_ipg_gate] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
183 clk[ssi1_ipg_gate] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
184 clk[ssi2_ipg_gate] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
185 clk[ssi3_ipg_gate] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
186 clk[ecspi1_ipg_gate] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
187 clk[ecspi1_per_gate] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
188 clk[ecspi2_ipg_gate] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
189 clk[ecspi2_per_gate] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
190 clk[cspi_ipg_gate] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
191 clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
192 clk[emi_fast_gate] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
193 clk[emi_slow_gate] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
194 clk[ipu_s] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
195 clk[ipu_gate] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
196 clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
197 clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
198 clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
199 clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
200 clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
201 clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
202 clk[uart4_ipg_gate] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
203 clk[uart4_per_gate] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
204 clk[uart5_ipg_gate] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
205 clk[uart5_per_gate] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
206 clk[gpc_dvfs] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
207
208 clk[ssi_apm] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
209 clk[ssi1_root_sel] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
210 clk[ssi2_root_sel] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
211 clk[ssi3_root_sel] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
212 clk[ssi_ext1_sel] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
213 clk[ssi_ext2_sel] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
214 clk[ssi_ext1_com_sel] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels));
215 clk[ssi_ext2_com_sel] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels));
216 clk[ssi1_root_pred] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
217 clk[ssi1_root_podf] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
218 clk[ssi2_root_pred] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
219 clk[ssi2_root_podf] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
220 clk[ssi_ext1_pred] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
221 clk[ssi_ext1_podf] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
222 clk[ssi_ext2_pred] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
223 clk[ssi_ext2_podf] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
224 clk[ssi1_root_gate] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
225 clk[ssi2_root_gate] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
226 clk[ssi3_root_gate] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
227 clk[ssi_ext1_gate] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
228 clk[ssi_ext2_gate] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
229
230 for (i = 0; i < ARRAY_SIZE(clk); i++)
231 if (IS_ERR(clk[i]))
232 pr_err("i.MX5 clk %d: register failed with %ld\n",
233 i, PTR_ERR(clk[i]));
234
235 clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
236 clk_register_clkdev(clk[gpt_ipg_gate], "ipg", "imx-gpt.0");
237 clk_register_clkdev(clk[uart1_per_gate], "per", "imx21-uart.0");
238 clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
239 clk_register_clkdev(clk[uart2_per_gate], "per", "imx21-uart.1");
240 clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
241 clk_register_clkdev(clk[uart3_per_gate], "per", "imx21-uart.2");
242 clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
243 clk_register_clkdev(clk[uart4_per_gate], "per", "imx21-uart.3");
244 clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
245 clk_register_clkdev(clk[uart5_per_gate], "per", "imx21-uart.4");
246 clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
247 clk_register_clkdev(clk[ecspi1_per_gate], "per", "imx51-ecspi.0");
248 clk_register_clkdev(clk[ecspi1_ipg_gate], "ipg", "imx51-ecspi.0");
249 clk_register_clkdev(clk[ecspi2_per_gate], "per", "imx51-ecspi.1");
250 clk_register_clkdev(clk[ecspi2_ipg_gate], "ipg", "imx51-ecspi.1");
251 clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx51-cspi.0");
252 clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0");
253 clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1");
254 clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
255 clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
256 clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0");
257 clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0");
258 clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0");
259 clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.1");
260 clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.1");
261 clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.1");
262 clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
263 clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
264 clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
265 clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc");
266 clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc");
267 clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc");
268 clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand");
269 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
270 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
271 clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
272 clk_register_clkdev(clk[ssi_ext1_gate], "ssi_ext1", NULL);
273 clk_register_clkdev(clk[ssi_ext2_gate], "ssi_ext2", NULL);
274 clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
275 clk_register_clkdev(clk[cpu_podf], "cpu", NULL);
276 clk_register_clkdev(clk[iim_gate], "iim", NULL);
277 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
278 clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
279 clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
280 clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
281 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
282
283 /* Set SDHC parents to be PLL2 */
284 clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]);
285 clk_set_parent(clk[esdhc_b_sel], clk[pll2_sw]);
286
287 /* move usb phy clk to 24MHz */
288 clk_set_parent(clk[usb_phy_sel], clk[osc]);
289
290 clk_prepare_enable(clk[gpc_dvfs]);
291 clk_prepare_enable(clk[ahb_max]); /* esdhc3 */
292 clk_prepare_enable(clk[aips_tz1]);
293 clk_prepare_enable(clk[aips_tz2]); /* fec */
294 clk_prepare_enable(clk[spba]);
295 clk_prepare_enable(clk[emi_fast_gate]); /* fec */
296 clk_prepare_enable(clk[tmax1]);
297 clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */
298 clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */
299}
300
301int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
302 unsigned long rate_ckih1, unsigned long rate_ckih2)
303{
304 int i;
305
306 clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
307 clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
308 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE);
309 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
310 mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
311 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
312 mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
313 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
314 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
315 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
316 clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
317 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
318 clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
319 clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
320 clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
321 clk[usb_phy_gate] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
322 clk[hsi2c_gate] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
323 clk[mipi_hsc1_gate] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
324 clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
325 clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
326 clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
327
328 for (i = 0; i < ARRAY_SIZE(clk); i++)
329 if (IS_ERR(clk[i]))
330 pr_err("i.MX51 clk %d: register failed with %ld\n",
331 i, PTR_ERR(clk[i]));
332
333 mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
334
335 clk_register_clkdev(clk[hsi2c_gate], NULL, "imx-i2c.2");
336 clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL);
337 clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0");
338 clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
339 clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
340 clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu");
341 clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu");
342 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu");
343 clk_register_clkdev(clk[ipu_gate], "hsp", "imx51-ipu");
344 clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0");
345 clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0");
346 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0");
347 clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx51.0");
348 clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx51.1");
349 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.1");
350 clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx51.1");
351 clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx51.2");
352 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.2");
353 clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx51.2");
354 clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3");
355 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3");
356 clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3");
357 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi");
358 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi");
359 clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi");
360
361 /* set the usboh3 parent to pll2_sw */
362 clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
363
364 /* set SDHC root clock to 166.25MHZ*/
365 clk_set_rate(clk[esdhc_a_podf], 166250000);
366 clk_set_rate(clk[esdhc_b_podf], 166250000);
367
368 /* System timer */
369 mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
370 MX51_INT_GPT);
371
372 clk_prepare_enable(clk[iim_gate]);
373 imx_print_silicon_rev("i.MX51", mx51_revision());
374 clk_disable_unprepare(clk[iim_gate]);
375
376 return 0;
377}
378
379int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
380 unsigned long rate_ckih1, unsigned long rate_ckih2)
381{
382 int i;
383 unsigned long r;
384
385 clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
386 clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
387 clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
388 clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
389
390 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
391 mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
392 clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
393 clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1);
394 clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
395 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
396 mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
397 clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
398 clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1);
399 clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
400 clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
401 clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
402 mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
403 clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
404 mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
405 clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
406 mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
407 clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
408 clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
409 clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
410 clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
411 clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
412 clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
413 clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
414 clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
415 clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "ipg", MXC_CCM_CCGR4, 6);
416 clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 8);
417 clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
418
419 for (i = 0; i < ARRAY_SIZE(clk); i++)
420 if (IS_ERR(clk[i]))
421 pr_err("i.MX53 clk %d: register failed with %ld\n",
422 i, PTR_ERR(clk[i]));
423
424 mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
425
426 clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0");
427 clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
428 clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0");
429 clk_register_clkdev(clk[ipu_gate], "bus", "imx53-ipu");
430 clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx53-ipu");
431 clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx53-ipu");
432 clk_register_clkdev(clk[ipu_gate], "hsp", "imx53-ipu");
433 clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0");
434 clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0");
435 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0");
436 clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx53.0");
437 clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx53.1");
438 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.1");
439 clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx53.1");
440 clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx53.2");
441 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.2");
442 clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx53.2");
443 clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3");
444 clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3");
445 clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3");
446 clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
447 clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
448 clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
449
450 /* set SDHC root clock to 200MHZ*/
451 clk_set_rate(clk[esdhc_a_podf], 200000000);
452 clk_set_rate(clk[esdhc_b_podf], 200000000);
453
454 /* System timer */
455 mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
456 MX53_INT_GPT);
457
458 clk_prepare_enable(clk[iim_gate]);
459 imx_print_silicon_rev("i.MX53", mx53_revision());
460 clk_disable_unprepare(clk[iim_gate]);
461
462 r = clk_round_rate(clk[usboh3_per_gate], 54000000);
463 clk_set_rate(clk[usboh3_per_gate], r);
464
465 return 0;
466}
467
468#ifdef CONFIG_OF
469static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
470 unsigned long *ckih1, unsigned long *ckih2)
471{
472 struct device_node *np;
473
474 /* retrieve the freqency of fixed clocks from device tree */
475 for_each_compatible_node(np, NULL, "fixed-clock") {
476 u32 rate;
477 if (of_property_read_u32(np, "clock-frequency", &rate))
478 continue;
479
480 if (of_device_is_compatible(np, "fsl,imx-ckil"))
481 *ckil = rate;
482 else if (of_device_is_compatible(np, "fsl,imx-osc"))
483 *osc = rate;
484 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
485 *ckih1 = rate;
486 else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
487 *ckih2 = rate;
488 }
489}
490
491int __init mx51_clocks_init_dt(void)
492{
493 unsigned long ckil, osc, ckih1, ckih2;
494
495 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
496 return mx51_clocks_init(ckil, osc, ckih1, ckih2);
497}
498
499int __init mx53_clocks_init_dt(void)
500{
501 unsigned long ckil, osc, ckih1, ckih2;
502
503 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
504 return mx53_clocks_init(ckil, osc, ckih1, ckih2);
505}
506#endif
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
new file mode 100644
index 00000000000..cab02d0a15d
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -0,0 +1,444 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/types.h>
15#include <linux/clk.h>
16#include <linux/clkdev.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22#include <mach/common.h>
23#include "clk.h"
24
25#define CCGR0 0x68
26#define CCGR1 0x6c
27#define CCGR2 0x70
28#define CCGR3 0x74
29#define CCGR4 0x78
30#define CCGR5 0x7c
31#define CCGR6 0x80
32#define CCGR7 0x84
33
34#define CLPCR 0x54
35#define BP_CLPCR_LPM 0
36#define BM_CLPCR_LPM (0x3 << 0)
37#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
38#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
39#define BM_CLPCR_SBYOS (0x1 << 6)
40#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
41#define BM_CLPCR_VSTBY (0x1 << 8)
42#define BP_CLPCR_STBY_COUNT 9
43#define BM_CLPCR_STBY_COUNT (0x3 << 9)
44#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
45#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
46#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
47#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
48#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
49#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
50#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
51#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
52#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
53#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
54#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
55
56static void __iomem *ccm_base;
57
58void __init imx6q_clock_map_io(void) { }
59
60int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
61{
62 u32 val = readl_relaxed(ccm_base + CLPCR);
63
64 val &= ~BM_CLPCR_LPM;
65 switch (mode) {
66 case WAIT_CLOCKED:
67 break;
68 case WAIT_UNCLOCKED:
69 val |= 0x1 << BP_CLPCR_LPM;
70 break;
71 case STOP_POWER_ON:
72 val |= 0x2 << BP_CLPCR_LPM;
73 break;
74 case WAIT_UNCLOCKED_POWER_OFF:
75 val |= 0x1 << BP_CLPCR_LPM;
76 val &= ~BM_CLPCR_VSTBY;
77 val &= ~BM_CLPCR_SBYOS;
78 break;
79 case STOP_POWER_OFF:
80 val |= 0x2 << BP_CLPCR_LPM;
81 val |= 0x3 << BP_CLPCR_STBY_COUNT;
82 val |= BM_CLPCR_VSTBY;
83 val |= BM_CLPCR_SBYOS;
84 break;
85 default:
86 return -EINVAL;
87 }
88
89 writel_relaxed(val, ccm_base + CLPCR);
90
91 return 0;
92}
93
94static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
95static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
96static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
97static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", };
98static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
99static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
100static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
101static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
102static const char *gpu_axi_sels[] = { "axi", "ahb", };
103static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
104static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
105static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
106static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
107static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
108static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
109static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
110static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
111static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
112static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
113static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
114static const char *pcie_axi_sels[] = { "axi", "ahb", };
115static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", };
116static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
117static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
118static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
119static const char *vdo_axi_sels[] = { "axi", "ahb", };
120static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
121static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video",
122 "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
123 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", };
124
125static const char * const clks_init_on[] __initconst = {
126 "mmdc_ch0_axi", "mmdc_ch1_axi", "usboh3",
127};
128
129enum mx6q_clks {
130 dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
131 pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m,
132 pll2_198m, pll3_120m, pll3_80m, pll3_60m, twd, step, pll1_sw,
133 periph_pre, periph2_pre, periph_clk2_sel, periph2_clk2_sel, axi_sel,
134 esai_sel, asrc_sel, spdif_sel, gpu2d_axi, gpu3d_axi, gpu2d_core_sel,
135 gpu3d_core_sel, gpu3d_shader_sel, ipu1_sel, ipu2_sel, ldb_di0_sel,
136 ldb_di1_sel, ipu1_di0_pre_sel, ipu1_di1_pre_sel, ipu2_di0_pre_sel,
137 ipu2_di1_pre_sel, ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel,
138 ipu2_di1_sel, hsi_tx_sel, pcie_axi_sel, ssi1_sel, ssi2_sel, ssi3_sel,
139 usdhc1_sel, usdhc2_sel, usdhc3_sel, usdhc4_sel, enfc_sel, emi_sel,
140 emi_slow_sel, vdo_axi_sel, vpu_axi_sel, cko1_sel, periph, periph2,
141 periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf,
142 asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root,
143 gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf,
144 ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre,
145 ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf,
146 ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf,
147 usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf,
148 emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
149 mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial,
150 can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet,
151 esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb,
152 hdmi_isfr, i2c1, i2c2, i2c3, iim, enfc, ipu1, ipu1_di0, ipu1_di1, ipu2,
153 ipu2_di0, ldb_di0, ldb_di1, ipu2_di1, hsi_tx, mlb, mmdc_ch0_axi,
154 mmdc_ch1_axi, ocram, openvg_axi, pcie_axi, pwm1, pwm2, pwm3, pwm4,
155 gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1,
156 ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
157 usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
158 pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg,
159 ssi2_ipg, ssi3_ipg, clk_max
160};
161
162static struct clk *clk[clk_max];
163
164int __init mx6q_clocks_init(void)
165{
166 struct device_node *np;
167 void __iomem *base;
168 struct clk *c;
169 int i, irq;
170
171 clk[dummy] = imx_clk_fixed("dummy", 0);
172
173 /* retrieve the freqency of fixed clocks from device tree */
174 for_each_compatible_node(np, NULL, "fixed-clock") {
175 u32 rate;
176 if (of_property_read_u32(np, "clock-frequency", &rate))
177 continue;
178
179 if (of_device_is_compatible(np, "fsl,imx-ckil"))
180 clk[ckil] = imx_clk_fixed("ckil", rate);
181 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
182 clk[ckih] = imx_clk_fixed("ckih", rate);
183 else if (of_device_is_compatible(np, "fsl,imx-osc"))
184 clk[osc] = imx_clk_fixed("osc", rate);
185 }
186
187 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
188 base = of_iomap(np, 0);
189 WARN_ON(!base);
190
191 /* type name parent_name base gate_mask div_mask */
192 clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x2000, 0x7f);
193 clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x2000, 0x1);
194 clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x2000, 0x3);
195 clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x2000, 0x7f);
196 clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x2000, 0x7f);
197 clk[pll6_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll6_mlb", "osc", base + 0xd0, 0x2000, 0x0);
198 clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3);
199 clk[pll8_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll8_enet", "osc", base + 0xe0, 0x182000, 0x3);
200
201 /* name parent_name reg idx */
202 clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
203 clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
204 clk[pll2_pfd2_396m] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
205 clk[pll3_pfd0_720m] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
206 clk[pll3_pfd1_540m] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
207 clk[pll3_pfd2_508m] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
208 clk[pll3_pfd3_454m] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
209
210 /* name parent_name mult div */
211 clk[pll2_198m] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
212 clk[pll3_120m] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
213 clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
214 clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
215 clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
216
217 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
218 base = of_iomap(np, 0);
219 WARN_ON(!base);
220 ccm_base = base;
221
222 /* name reg shift width parent_names num_parents */
223 clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
224 clk[pll1_sw] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
225 clk[periph_pre] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
226 clk[periph2_pre] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
227 clk[periph_clk2_sel] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
228 clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
229 clk[axi_sel] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
230 clk[esai_sel] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
231 clk[asrc_sel] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
232 clk[spdif_sel] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
233 clk[gpu2d_axi] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
234 clk[gpu3d_axi] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
235 clk[gpu2d_core_sel] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
236 clk[gpu3d_core_sel] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
237 clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
238 clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
239 clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
240 clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
241 clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
242 clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
243 clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
244 clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
245 clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels));
246 clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
247 clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
248 clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
249 clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
250 clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
251 clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
252 clk[ssi1_sel] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
253 clk[ssi2_sel] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
254 clk[ssi3_sel] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
255 clk[usdhc1_sel] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
256 clk[usdhc2_sel] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
257 clk[usdhc3_sel] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
258 clk[usdhc4_sel] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
259 clk[enfc_sel] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
260 clk[emi_sel] = imx_clk_mux("emi_sel", base + 0x1c, 27, 2, emi_sels, ARRAY_SIZE(emi_sels));
261 clk[emi_slow_sel] = imx_clk_mux("emi_slow_sel", base + 0x1c, 29, 2, emi_sels, ARRAY_SIZE(emi_sels));
262 clk[vdo_axi_sel] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
263 clk[vpu_axi_sel] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels));
264 clk[cko1_sel] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
265
266 /* name reg shift width busy: reg, shift parent_names num_parents */
267 clk[periph] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
268 clk[periph2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
269
270 /* name parent_name reg shift width */
271 clk[periph_clk2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
272 clk[periph2_clk2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
273 clk[ipg] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
274 clk[ipg_per] = imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6);
275 clk[esai_pred] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
276 clk[esai_podf] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
277 clk[asrc_pred] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3);
278 clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
279 clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
280 clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
281 clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6);
282 clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
283 clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
284 clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
285 clk[gpu3d_shader] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
286 clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
287 clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
288 clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_sel", base + 0x20, 10, 1);
289 clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_sel", base + 0x20, 11, 1);
290 clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
291 clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
292 clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
293 clk[ipu2_di1_pre] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3);
294 clk[hsi_tx_podf] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3);
295 clk[ssi1_pred] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
296 clk[ssi1_podf] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
297 clk[ssi2_pred] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
298 clk[ssi2_podf] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
299 clk[ssi3_pred] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
300 clk[ssi3_podf] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
301 clk[uart_serial_podf] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
302 clk[usdhc1_podf] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
303 clk[usdhc2_podf] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
304 clk[usdhc3_podf] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
305 clk[usdhc4_podf] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
306 clk[enfc_pred] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
307 clk[enfc_podf] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
308 clk[emi_podf] = imx_clk_divider("emi_podf", "emi_sel", base + 0x1c, 20, 3);
309 clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_slow_sel", base + 0x1c, 23, 3);
310 clk[vpu_axi_podf] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3);
311 clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
312
313 /* name parent_name reg shift width busy: reg, shift */
314 clk[axi] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
315 clk[mmdc_ch0_axi_podf] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
316 clk[mmdc_ch1_axi_podf] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
317 clk[arm] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
318 clk[ahb] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
319
320 /* name parent_name reg shift */
321 clk[apbh_dma] = imx_clk_gate2("apbh_dma", "ahb", base + 0x68, 4);
322 clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6);
323 clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
324 clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
325 clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
326 clk[can2_serial] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
327 clk[ecspi1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
328 clk[ecspi2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
329 clk[ecspi3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
330 clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
331 clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
332 clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
333 clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
334 clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
335 clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
336 clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
337 clk[gpu3d_core] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
338 clk[hdmi_iahb] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
339 clk[hdmi_isfr] = imx_clk_gate2("hdmi_isfr", "pll3_pfd1_540m", base + 0x70, 4);
340 clk[i2c1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
341 clk[i2c2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
342 clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
343 clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
344 clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
345 clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
346 clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
347 clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
348 clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
349 clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
350 clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
351 clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
352 clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
353 clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
354 clk[mlb] = imx_clk_gate2("mlb", "pll6_mlb", base + 0x74, 18);
355 clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
356 clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
357 clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
358 clk[openvg_axi] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30);
359 clk[pcie_axi] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
360 clk[pwm1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
361 clk[pwm2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
362 clk[pwm3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
363 clk[pwm4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
364 clk[gpmi_bch_apb] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
365 clk[gpmi_bch] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
366 clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
367 clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
368 clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4);
369 clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
370 clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
371 clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18);
372 clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20);
373 clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22);
374 clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
375 clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
376 clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
377 clk[usdhc1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
378 clk[usdhc2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
379 clk[usdhc3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
380 clk[usdhc4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
381 clk[vdo_axi] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
382 clk[vpu_axi] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
383 clk[cko1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
384
385 for (i = 0; i < ARRAY_SIZE(clk); i++)
386 if (IS_ERR(clk[i]))
387 pr_err("i.MX6q clk %d: register failed with %ld\n",
388 i, PTR_ERR(clk[i]));
389
390 clk_register_clkdev(clk[mmdc_ch0_axi], NULL, "mmdc_ch0_axi");
391 clk_register_clkdev(clk[mmdc_ch1_axi], NULL, "mmdc_ch1_axi");
392 clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
393 clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
394 clk_register_clkdev(clk[twd], NULL, "smp_twd");
395 clk_register_clkdev(clk[usboh3], NULL, "usboh3");
396 clk_register_clkdev(clk[uart_serial], "per", "2020000.serial");
397 clk_register_clkdev(clk[uart_ipg], "ipg", "2020000.serial");
398 clk_register_clkdev(clk[uart_serial], "per", "21e8000.serial");
399 clk_register_clkdev(clk[uart_ipg], "ipg", "21e8000.serial");
400 clk_register_clkdev(clk[uart_serial], "per", "21ec000.serial");
401 clk_register_clkdev(clk[uart_ipg], "ipg", "21ec000.serial");
402 clk_register_clkdev(clk[uart_serial], "per", "21f0000.serial");
403 clk_register_clkdev(clk[uart_ipg], "ipg", "21f0000.serial");
404 clk_register_clkdev(clk[uart_serial], "per", "21f4000.serial");
405 clk_register_clkdev(clk[uart_ipg], "ipg", "21f4000.serial");
406 clk_register_clkdev(clk[enet], NULL, "2188000.ethernet");
407 clk_register_clkdev(clk[usdhc1], NULL, "2190000.usdhc");
408 clk_register_clkdev(clk[usdhc2], NULL, "2194000.usdhc");
409 clk_register_clkdev(clk[usdhc3], NULL, "2198000.usdhc");
410 clk_register_clkdev(clk[usdhc4], NULL, "219c000.usdhc");
411 clk_register_clkdev(clk[i2c1], NULL, "21a0000.i2c");
412 clk_register_clkdev(clk[i2c2], NULL, "21a4000.i2c");
413 clk_register_clkdev(clk[i2c3], NULL, "21a8000.i2c");
414 clk_register_clkdev(clk[ecspi1], NULL, "2008000.ecspi");
415 clk_register_clkdev(clk[ecspi2], NULL, "200c000.ecspi");
416 clk_register_clkdev(clk[ecspi3], NULL, "2010000.ecspi");
417 clk_register_clkdev(clk[ecspi4], NULL, "2014000.ecspi");
418 clk_register_clkdev(clk[ecspi5], NULL, "2018000.ecspi");
419 clk_register_clkdev(clk[sdma], NULL, "20ec000.sdma");
420 clk_register_clkdev(clk[dummy], NULL, "20bc000.wdog");
421 clk_register_clkdev(clk[dummy], NULL, "20c0000.wdog");
422 clk_register_clkdev(clk[ssi1_ipg], NULL, "2028000.ssi");
423 clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
424 clk_register_clkdev(clk[ahb], "ahb", NULL);
425 clk_register_clkdev(clk[cko1], "cko1", NULL);
426
427 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) {
428 c = clk_get_sys(clks_init_on[i], NULL);
429 if (IS_ERR(c)) {
430 pr_err("%s: failed to get clk %s", __func__,
431 clks_init_on[i]);
432 return PTR_ERR(c);
433 }
434 clk_prepare_enable(c);
435 }
436
437 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
438 base = of_iomap(np, 0);
439 WARN_ON(!base);
440 irq = irq_of_parse_and_map(np, 0);
441 mxc_timer_init(NULL, base, irq);
442
443 return 0;
444}
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
new file mode 100644
index 00000000000..e2ed4160f32
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pfd.c
@@ -0,0 +1,147 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include "clk.h"
19
20/**
21 * struct clk_pfd - IMX PFD clock
22 * @clk_hw: clock source
23 * @reg: PFD register address
24 * @idx: the index of PFD encoded in the register
25 *
26 * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
27 * data encoded, and member idx is used to specify the one. And each
28 * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
29 */
30struct clk_pfd {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 idx;
34};
35
36#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
37
38#define SET 0x4
39#define CLR 0x8
40#define OTG 0xc
41
42static int clk_pfd_enable(struct clk_hw *hw)
43{
44 struct clk_pfd *pfd = to_clk_pfd(hw);
45
46 writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
47
48 return 0;
49}
50
51static void clk_pfd_disable(struct clk_hw *hw)
52{
53 struct clk_pfd *pfd = to_clk_pfd(hw);
54
55 writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
56}
57
58static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
59 unsigned long parent_rate)
60{
61 struct clk_pfd *pfd = to_clk_pfd(hw);
62 u64 tmp = parent_rate;
63 u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
64
65 tmp *= 18;
66 do_div(tmp, frac);
67
68 return tmp;
69}
70
71static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
72 unsigned long *prate)
73{
74 u64 tmp = *prate;
75 u8 frac;
76
77 tmp = tmp * 18 + rate / 2;
78 do_div(tmp, rate);
79 frac = tmp;
80 if (frac < 12)
81 frac = 12;
82 else if (frac > 35)
83 frac = 35;
84 tmp = *prate;
85 tmp *= 18;
86 do_div(tmp, frac);
87
88 return tmp;
89}
90
91static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
92 unsigned long parent_rate)
93{
94 struct clk_pfd *pfd = to_clk_pfd(hw);
95 u64 tmp = parent_rate;
96 u8 frac;
97
98 tmp = tmp * 18 + rate / 2;
99 do_div(tmp, rate);
100 frac = tmp;
101 if (frac < 12)
102 frac = 12;
103 else if (frac > 35)
104 frac = 35;
105
106 writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
107 writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
108
109 return 0;
110}
111
112static const struct clk_ops clk_pfd_ops = {
113 .enable = clk_pfd_enable,
114 .disable = clk_pfd_disable,
115 .recalc_rate = clk_pfd_recalc_rate,
116 .round_rate = clk_pfd_round_rate,
117 .set_rate = clk_pfd_set_rate,
118};
119
120struct clk *imx_clk_pfd(const char *name, const char *parent_name,
121 void __iomem *reg, u8 idx)
122{
123 struct clk_pfd *pfd;
124 struct clk *clk;
125 struct clk_init_data init;
126
127 pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
128 if (!pfd)
129 return ERR_PTR(-ENOMEM);
130
131 pfd->reg = reg;
132 pfd->idx = idx;
133
134 init.name = name;
135 init.ops = &clk_pfd_ops;
136 init.flags = 0;
137 init.parent_names = &parent_name;
138 init.num_parents = 1;
139
140 pfd->hw.init = &init;
141
142 clk = clk_register(NULL, &pfd->hw);
143 if (IS_ERR(clk))
144 kfree(pfd);
145
146 return clk;
147}
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
new file mode 100644
index 00000000000..2d856f9ccf5
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -0,0 +1,66 @@
1#include <linux/clk.h>
2#include <linux/clk-provider.h>
3#include <linux/io.h>
4#include <linux/slab.h>
5#include <linux/kernel.h>
6#include <linux/err.h>
7#include <mach/common.h>
8#include <mach/hardware.h>
9#include <mach/clock.h>
10#include "clk.h"
11
12/**
13 * pll v1
14 *
15 * @clk_hw clock source
16 * @parent the parent clock name
17 * @base base address of pll registers
18 *
19 * PLL clock version 1, found on i.MX1/21/25/27/31/35
20 */
21struct clk_pllv1 {
22 struct clk_hw hw;
23 void __iomem *base;
24};
25
26#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
27
28static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
29 unsigned long parent_rate)
30{
31 struct clk_pllv1 *pll = to_clk_pllv1(hw);
32
33 return mxc_decode_pll(readl(pll->base), parent_rate);
34}
35
36struct clk_ops clk_pllv1_ops = {
37 .recalc_rate = clk_pllv1_recalc_rate,
38};
39
40struct clk *imx_clk_pllv1(const char *name, const char *parent,
41 void __iomem *base)
42{
43 struct clk_pllv1 *pll;
44 struct clk *clk;
45 struct clk_init_data init;
46
47 pll = kmalloc(sizeof(*pll), GFP_KERNEL);
48 if (!pll)
49 return ERR_PTR(-ENOMEM);
50
51 pll->base = base;
52
53 init.name = name;
54 init.ops = &clk_pllv1_ops;
55 init.flags = 0;
56 init.parent_names = &parent;
57 init.num_parents = 1;
58
59 pll->hw.init = &init;
60
61 clk = clk_register(NULL, &pll->hw);
62 if (IS_ERR(clk))
63 kfree(pll);
64
65 return clk;
66}
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
new file mode 100644
index 00000000000..4685919deb6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv2.c
@@ -0,0 +1,249 @@
1#include <linux/kernel.h>
2#include <linux/clk.h>
3#include <linux/io.h>
4#include <linux/errno.h>
5#include <linux/delay.h>
6#include <linux/slab.h>
7#include <linux/err.h>
8
9#include <asm/div64.h>
10
11#include "clk.h"
12
13#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
14
15/* PLL Register Offsets */
16#define MXC_PLL_DP_CTL 0x00
17#define MXC_PLL_DP_CONFIG 0x04
18#define MXC_PLL_DP_OP 0x08
19#define MXC_PLL_DP_MFD 0x0C
20#define MXC_PLL_DP_MFN 0x10
21#define MXC_PLL_DP_MFNMINUS 0x14
22#define MXC_PLL_DP_MFNPLUS 0x18
23#define MXC_PLL_DP_HFS_OP 0x1C
24#define MXC_PLL_DP_HFS_MFD 0x20
25#define MXC_PLL_DP_HFS_MFN 0x24
26#define MXC_PLL_DP_MFN_TOGC 0x28
27#define MXC_PLL_DP_DESTAT 0x2c
28
29/* PLL Register Bit definitions */
30#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
31#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
32#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
33#define MXC_PLL_DP_CTL_ADE 0x800
34#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
35#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
36#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
37#define MXC_PLL_DP_CTL_HFSM 0x80
38#define MXC_PLL_DP_CTL_PRE 0x40
39#define MXC_PLL_DP_CTL_UPEN 0x20
40#define MXC_PLL_DP_CTL_RST 0x10
41#define MXC_PLL_DP_CTL_RCP 0x8
42#define MXC_PLL_DP_CTL_PLM 0x4
43#define MXC_PLL_DP_CTL_BRM0 0x2
44#define MXC_PLL_DP_CTL_LRF 0x1
45
46#define MXC_PLL_DP_CONFIG_BIST 0x8
47#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
48#define MXC_PLL_DP_CONFIG_AREN 0x2
49#define MXC_PLL_DP_CONFIG_LDREQ 0x1
50
51#define MXC_PLL_DP_OP_MFI_OFFSET 4
52#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
53#define MXC_PLL_DP_OP_PDF_OFFSET 0
54#define MXC_PLL_DP_OP_PDF_MASK 0xF
55
56#define MXC_PLL_DP_MFD_OFFSET 0
57#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
58
59#define MXC_PLL_DP_MFN_OFFSET 0x0
60#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
61
62#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
63#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
64#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
65#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
66
67#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
68#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
69
70#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
71
72struct clk_pllv2 {
73 struct clk_hw hw;
74 void __iomem *base;
75};
76
77static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
78 unsigned long parent_rate)
79{
80 long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
81 unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
82 void __iomem *pllbase;
83 s64 temp;
84 struct clk_pllv2 *pll = to_clk_pllv2(hw);
85
86 pllbase = pll->base;
87
88 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
89 pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
90 dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
91
92 if (pll_hfsm == 0) {
93 dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
94 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
95 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
96 } else {
97 dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
98 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
99 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
100 }
101 pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
102 mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
103 mfi = (mfi <= 5) ? 5 : mfi;
104 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
105 mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
106 /* Sign extend to 32-bits */
107 if (mfn >= 0x04000000) {
108 mfn |= 0xFC000000;
109 mfn_abs = -mfn;
110 }
111
112 ref_clk = 2 * parent_rate;
113 if (dbl != 0)
114 ref_clk *= 2;
115
116 ref_clk /= (pdf + 1);
117 temp = (u64) ref_clk * mfn_abs;
118 do_div(temp, mfd + 1);
119 if (mfn < 0)
120 temp = -temp;
121 temp = (ref_clk * mfi) + temp;
122
123 return temp;
124}
125
126static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
127 unsigned long parent_rate)
128{
129 struct clk_pllv2 *pll = to_clk_pllv2(hw);
130 u32 reg;
131 void __iomem *pllbase;
132 long mfi, pdf, mfn, mfd = 999999;
133 s64 temp64;
134 unsigned long quad_parent_rate;
135 unsigned long pll_hfsm, dp_ctl;
136
137 pllbase = pll->base;
138
139 quad_parent_rate = 4 * parent_rate;
140 pdf = mfi = -1;
141 while (++pdf < 16 && mfi < 5)
142 mfi = rate * (pdf+1) / quad_parent_rate;
143 if (mfi > 15)
144 return -EINVAL;
145 pdf--;
146
147 temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
148 do_div(temp64, quad_parent_rate/1000000);
149 mfn = (long)temp64;
150
151 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
152 /* use dpdck0_2 */
153 __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
154 pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
155 if (pll_hfsm == 0) {
156 reg = mfi << 4 | pdf;
157 __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
158 __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
159 __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
160 } else {
161 reg = mfi << 4 | pdf;
162 __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
163 __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
164 __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
165 }
166
167 return 0;
168}
169
170static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
171 unsigned long *prate)
172{
173 return rate;
174}
175
176static int clk_pllv2_prepare(struct clk_hw *hw)
177{
178 struct clk_pllv2 *pll = to_clk_pllv2(hw);
179 u32 reg;
180 void __iomem *pllbase;
181 int i = 0;
182
183 pllbase = pll->base;
184 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
185 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
186
187 /* Wait for lock */
188 do {
189 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
190 if (reg & MXC_PLL_DP_CTL_LRF)
191 break;
192
193 udelay(1);
194 } while (++i < MAX_DPLL_WAIT_TRIES);
195
196 if (i == MAX_DPLL_WAIT_TRIES) {
197 pr_err("MX5: pll locking failed\n");
198 return -EINVAL;
199 }
200
201 return 0;
202}
203
204static void clk_pllv2_unprepare(struct clk_hw *hw)
205{
206 struct clk_pllv2 *pll = to_clk_pllv2(hw);
207 u32 reg;
208 void __iomem *pllbase;
209
210 pllbase = pll->base;
211 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
212 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
213}
214
215struct clk_ops clk_pllv2_ops = {
216 .prepare = clk_pllv2_prepare,
217 .unprepare = clk_pllv2_unprepare,
218 .recalc_rate = clk_pllv2_recalc_rate,
219 .round_rate = clk_pllv2_round_rate,
220 .set_rate = clk_pllv2_set_rate,
221};
222
223struct clk *imx_clk_pllv2(const char *name, const char *parent,
224 void __iomem *base)
225{
226 struct clk_pllv2 *pll;
227 struct clk *clk;
228 struct clk_init_data init;
229
230 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
231 if (!pll)
232 return ERR_PTR(-ENOMEM);
233
234 pll->base = base;
235
236 init.name = name;
237 init.ops = &clk_pllv2_ops;
238 init.flags = 0;
239 init.parent_names = &parent;
240 init.num_parents = 1;
241
242 pll->hw.init = &init;
243
244 clk = clk_register(NULL, &pll->hw);
245 if (IS_ERR(clk))
246 kfree(pll);
247
248 return clk;
249}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
new file mode 100644
index 00000000000..36aac947bce
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -0,0 +1,419 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <linux/err.h>
19#include "clk.h"
20
21#define PLL_NUM_OFFSET 0x10
22#define PLL_DENOM_OFFSET 0x20
23
24#define BM_PLL_POWER (0x1 << 12)
25#define BM_PLL_ENABLE (0x1 << 13)
26#define BM_PLL_BYPASS (0x1 << 16)
27#define BM_PLL_LOCK (0x1 << 31)
28
29/**
30 * struct clk_pllv3 - IMX PLL clock version 3
31 * @clk_hw: clock source
32 * @base: base address of PLL registers
33 * @powerup_set: set POWER bit to power up the PLL
34 * @gate_mask: mask of gate bits
35 * @div_mask: mask of divider bits
36 *
37 * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
38 * is actually a multiplier, and always sits at bit 0.
39 */
40struct clk_pllv3 {
41 struct clk_hw hw;
42 void __iomem *base;
43 bool powerup_set;
44 u32 gate_mask;
45 u32 div_mask;
46};
47
48#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
49
50static int clk_pllv3_prepare(struct clk_hw *hw)
51{
52 struct clk_pllv3 *pll = to_clk_pllv3(hw);
53 unsigned long timeout = jiffies + msecs_to_jiffies(10);
54 u32 val;
55
56 val = readl_relaxed(pll->base);
57 val &= ~BM_PLL_BYPASS;
58 if (pll->powerup_set)
59 val |= BM_PLL_POWER;
60 else
61 val &= ~BM_PLL_POWER;
62 writel_relaxed(val, pll->base);
63
64 /* Wait for PLL to lock */
65 while (!(readl_relaxed(pll->base) & BM_PLL_LOCK))
66 if (time_after(jiffies, timeout))
67 return -ETIMEDOUT;
68
69 return 0;
70}
71
72static void clk_pllv3_unprepare(struct clk_hw *hw)
73{
74 struct clk_pllv3 *pll = to_clk_pllv3(hw);
75 u32 val;
76
77 val = readl_relaxed(pll->base);
78 val |= BM_PLL_BYPASS;
79 if (pll->powerup_set)
80 val &= ~BM_PLL_POWER;
81 else
82 val |= BM_PLL_POWER;
83 writel_relaxed(val, pll->base);
84}
85
86static int clk_pllv3_enable(struct clk_hw *hw)
87{
88 struct clk_pllv3 *pll = to_clk_pllv3(hw);
89 u32 val;
90
91 val = readl_relaxed(pll->base);
92 val |= pll->gate_mask;
93 writel_relaxed(val, pll->base);
94
95 return 0;
96}
97
98static void clk_pllv3_disable(struct clk_hw *hw)
99{
100 struct clk_pllv3 *pll = to_clk_pllv3(hw);
101 u32 val;
102
103 val = readl_relaxed(pll->base);
104 val &= ~pll->gate_mask;
105 writel_relaxed(val, pll->base);
106}
107
108static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
109 unsigned long parent_rate)
110{
111 struct clk_pllv3 *pll = to_clk_pllv3(hw);
112 u32 div = readl_relaxed(pll->base) & pll->div_mask;
113
114 return (div == 1) ? parent_rate * 22 : parent_rate * 20;
115}
116
117static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
118 unsigned long *prate)
119{
120 unsigned long parent_rate = *prate;
121
122 return (rate >= parent_rate * 22) ? parent_rate * 22 :
123 parent_rate * 20;
124}
125
126static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
127 unsigned long parent_rate)
128{
129 struct clk_pllv3 *pll = to_clk_pllv3(hw);
130 u32 val, div;
131
132 if (rate == parent_rate * 22)
133 div = 1;
134 else if (rate == parent_rate * 20)
135 div = 0;
136 else
137 return -EINVAL;
138
139 val = readl_relaxed(pll->base);
140 val &= ~pll->div_mask;
141 val |= div;
142 writel_relaxed(val, pll->base);
143
144 return 0;
145}
146
147static const struct clk_ops clk_pllv3_ops = {
148 .prepare = clk_pllv3_prepare,
149 .unprepare = clk_pllv3_unprepare,
150 .enable = clk_pllv3_enable,
151 .disable = clk_pllv3_disable,
152 .recalc_rate = clk_pllv3_recalc_rate,
153 .round_rate = clk_pllv3_round_rate,
154 .set_rate = clk_pllv3_set_rate,
155};
156
157static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
158 unsigned long parent_rate)
159{
160 struct clk_pllv3 *pll = to_clk_pllv3(hw);
161 u32 div = readl_relaxed(pll->base) & pll->div_mask;
162
163 return parent_rate * div / 2;
164}
165
166static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
167 unsigned long *prate)
168{
169 unsigned long parent_rate = *prate;
170 unsigned long min_rate = parent_rate * 54 / 2;
171 unsigned long max_rate = parent_rate * 108 / 2;
172 u32 div;
173
174 if (rate > max_rate)
175 rate = max_rate;
176 else if (rate < min_rate)
177 rate = min_rate;
178 div = rate * 2 / parent_rate;
179
180 return parent_rate * div / 2;
181}
182
183static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
184 unsigned long parent_rate)
185{
186 struct clk_pllv3 *pll = to_clk_pllv3(hw);
187 unsigned long min_rate = parent_rate * 54 / 2;
188 unsigned long max_rate = parent_rate * 108 / 2;
189 u32 val, div;
190
191 if (rate < min_rate || rate > max_rate)
192 return -EINVAL;
193
194 div = rate * 2 / parent_rate;
195 val = readl_relaxed(pll->base);
196 val &= ~pll->div_mask;
197 val |= div;
198 writel_relaxed(val, pll->base);
199
200 return 0;
201}
202
203static const struct clk_ops clk_pllv3_sys_ops = {
204 .prepare = clk_pllv3_prepare,
205 .unprepare = clk_pllv3_unprepare,
206 .enable = clk_pllv3_enable,
207 .disable = clk_pllv3_disable,
208 .recalc_rate = clk_pllv3_sys_recalc_rate,
209 .round_rate = clk_pllv3_sys_round_rate,
210 .set_rate = clk_pllv3_sys_set_rate,
211};
212
213static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
214 unsigned long parent_rate)
215{
216 struct clk_pllv3 *pll = to_clk_pllv3(hw);
217 u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
218 u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
219 u32 div = readl_relaxed(pll->base) & pll->div_mask;
220
221 return (parent_rate * div) + ((parent_rate / mfd) * mfn);
222}
223
224static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
225 unsigned long *prate)
226{
227 unsigned long parent_rate = *prate;
228 unsigned long min_rate = parent_rate * 27;
229 unsigned long max_rate = parent_rate * 54;
230 u32 div;
231 u32 mfn, mfd = 1000000;
232 s64 temp64;
233
234 if (rate > max_rate)
235 rate = max_rate;
236 else if (rate < min_rate)
237 rate = min_rate;
238
239 div = rate / parent_rate;
240 temp64 = (u64) (rate - div * parent_rate);
241 temp64 *= mfd;
242 do_div(temp64, parent_rate);
243 mfn = temp64;
244
245 return parent_rate * div + parent_rate / mfd * mfn;
246}
247
248static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
249 unsigned long parent_rate)
250{
251 struct clk_pllv3 *pll = to_clk_pllv3(hw);
252 unsigned long min_rate = parent_rate * 27;
253 unsigned long max_rate = parent_rate * 54;
254 u32 val, div;
255 u32 mfn, mfd = 1000000;
256 s64 temp64;
257
258 if (rate < min_rate || rate > max_rate)
259 return -EINVAL;
260
261 div = rate / parent_rate;
262 temp64 = (u64) (rate - div * parent_rate);
263 temp64 *= mfd;
264 do_div(temp64, parent_rate);
265 mfn = temp64;
266
267 val = readl_relaxed(pll->base);
268 val &= ~pll->div_mask;
269 val |= div;
270 writel_relaxed(val, pll->base);
271 writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
272 writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
273
274 return 0;
275}
276
277static const struct clk_ops clk_pllv3_av_ops = {
278 .prepare = clk_pllv3_prepare,
279 .unprepare = clk_pllv3_unprepare,
280 .enable = clk_pllv3_enable,
281 .disable = clk_pllv3_disable,
282 .recalc_rate = clk_pllv3_av_recalc_rate,
283 .round_rate = clk_pllv3_av_round_rate,
284 .set_rate = clk_pllv3_av_set_rate,
285};
286
287static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
288 unsigned long parent_rate)
289{
290 struct clk_pllv3 *pll = to_clk_pllv3(hw);
291 u32 div = readl_relaxed(pll->base) & pll->div_mask;
292
293 switch (div) {
294 case 0:
295 return 25000000;
296 case 1:
297 return 50000000;
298 case 2:
299 return 100000000;
300 case 3:
301 return 125000000;
302 }
303
304 return 0;
305}
306
307static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
308 unsigned long *prate)
309{
310 if (rate >= 125000000)
311 rate = 125000000;
312 else if (rate >= 100000000)
313 rate = 100000000;
314 else if (rate >= 50000000)
315 rate = 50000000;
316 else
317 rate = 25000000;
318 return rate;
319}
320
321static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate,
322 unsigned long parent_rate)
323{
324 struct clk_pllv3 *pll = to_clk_pllv3(hw);
325 u32 val, div;
326
327 switch (rate) {
328 case 25000000:
329 div = 0;
330 break;
331 case 50000000:
332 div = 1;
333 break;
334 case 100000000:
335 div = 2;
336 break;
337 case 125000000:
338 div = 3;
339 break;
340 default:
341 return -EINVAL;
342 }
343
344 val = readl_relaxed(pll->base);
345 val &= ~pll->div_mask;
346 val |= div;
347 writel_relaxed(val, pll->base);
348
349 return 0;
350}
351
352static const struct clk_ops clk_pllv3_enet_ops = {
353 .prepare = clk_pllv3_prepare,
354 .unprepare = clk_pllv3_unprepare,
355 .enable = clk_pllv3_enable,
356 .disable = clk_pllv3_disable,
357 .recalc_rate = clk_pllv3_enet_recalc_rate,
358 .round_rate = clk_pllv3_enet_round_rate,
359 .set_rate = clk_pllv3_enet_set_rate,
360};
361
362static const struct clk_ops clk_pllv3_mlb_ops = {
363 .prepare = clk_pllv3_prepare,
364 .unprepare = clk_pllv3_unprepare,
365 .enable = clk_pllv3_enable,
366 .disable = clk_pllv3_disable,
367};
368
369struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
370 const char *parent_name, void __iomem *base,
371 u32 gate_mask, u32 div_mask)
372{
373 struct clk_pllv3 *pll;
374 const struct clk_ops *ops;
375 struct clk *clk;
376 struct clk_init_data init;
377
378 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
379 if (!pll)
380 return ERR_PTR(-ENOMEM);
381
382 switch (type) {
383 case IMX_PLLV3_SYS:
384 ops = &clk_pllv3_sys_ops;
385 break;
386 case IMX_PLLV3_USB:
387 ops = &clk_pllv3_ops;
388 pll->powerup_set = true;
389 break;
390 case IMX_PLLV3_AV:
391 ops = &clk_pllv3_av_ops;
392 break;
393 case IMX_PLLV3_ENET:
394 ops = &clk_pllv3_enet_ops;
395 break;
396 case IMX_PLLV3_MLB:
397 ops = &clk_pllv3_mlb_ops;
398 break;
399 default:
400 ops = &clk_pllv3_ops;
401 }
402 pll->base = base;
403 pll->gate_mask = gate_mask;
404 pll->div_mask = div_mask;
405
406 init.name = name;
407 init.ops = ops;
408 init.flags = 0;
409 init.parent_names = &parent_name;
410 init.num_parents = 1;
411
412 pll->hw.init = &init;
413
414 clk = clk_register(NULL, &pll->hw);
415 if (IS_ERR(clk))
416 kfree(pll);
417
418 return clk;
419}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
new file mode 100644
index 00000000000..1bf64fe2523
--- /dev/null
+++ b/arch/arm/mach-imx/clk.h
@@ -0,0 +1,83 @@
1#ifndef __MACH_IMX_CLK_H
2#define __MACH_IMX_CLK_H
3
4#include <linux/spinlock.h>
5#include <linux/clk-provider.h>
6#include <mach/clock.h>
7
8struct clk *imx_clk_pllv1(const char *name, const char *parent,
9 void __iomem *base);
10
11struct clk *imx_clk_pllv2(const char *name, const char *parent,
12 void __iomem *base);
13
14enum imx_pllv3_type {
15 IMX_PLLV3_GENERIC,
16 IMX_PLLV3_SYS,
17 IMX_PLLV3_USB,
18 IMX_PLLV3_AV,
19 IMX_PLLV3_ENET,
20 IMX_PLLV3_MLB,
21};
22
23struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
24 const char *parent_name, void __iomem *base, u32 gate_mask,
25 u32 div_mask);
26
27struct clk *clk_register_gate2(struct device *dev, const char *name,
28 const char *parent_name, unsigned long flags,
29 void __iomem *reg, u8 bit_idx,
30 u8 clk_gate_flags, spinlock_t *lock);
31
32static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
33 void __iomem *reg, u8 shift)
34{
35 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
36 shift, 0, &imx_ccm_lock);
37}
38
39struct clk *imx_clk_pfd(const char *name, const char *parent_name,
40 void __iomem *reg, u8 idx);
41
42struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
43 void __iomem *reg, u8 shift, u8 width,
44 void __iomem *busy_reg, u8 busy_shift);
45
46struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
47 u8 width, void __iomem *busy_reg, u8 busy_shift,
48 const char **parent_names, int num_parents);
49
50static inline struct clk *imx_clk_fixed(const char *name, int rate)
51{
52 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
53}
54
55static inline struct clk *imx_clk_divider(const char *name, const char *parent,
56 void __iomem *reg, u8 shift, u8 width)
57{
58 return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
59 reg, shift, width, 0, &imx_ccm_lock);
60}
61
62static inline struct clk *imx_clk_gate(const char *name, const char *parent,
63 void __iomem *reg, u8 shift)
64{
65 return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
66 shift, 0, &imx_ccm_lock);
67}
68
69static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
70 u8 shift, u8 width, const char **parents, int num_parents)
71{
72 return clk_register_mux(NULL, name, parents, num_parents, 0, reg, shift,
73 width, 0, &imx_ccm_lock);
74}
75
76static inline struct clk *imx_clk_fixed_factor(const char *name,
77 const char *parent, unsigned int mult, unsigned int div)
78{
79 return clk_register_fixed_factor(NULL, name, parent,
80 CLK_SET_RATE_PARENT, mult, div);
81}
82
83#endif
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
deleted file mode 100644
index 4aabeb24156..00000000000
--- a/arch/arm/mach-imx/clock-imx1.c
+++ /dev/null
@@ -1,636 +0,0 @@
1/*
2 * Copyright (C) 2008 Sascha Hauer <s.hauer@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 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/list.h>
21#include <linux/math64.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/io.h>
25#include <linux/clkdev.h>
26
27#include <mach/clock.h>
28#include <mach/hardware.h>
29#include <mach/common.h>
30
31#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
32
33/* CCM register addresses */
34#define CCM_CSCR IO_ADDR_CCM(0x0)
35#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
37#define CCM_PCDR IO_ADDR_CCM(0x20)
38
39#define CCM_CSCR_CLKO_OFFSET 29
40#define CCM_CSCR_CLKO_MASK (0x7 << 29)
41#define CCM_CSCR_USB_OFFSET 26
42#define CCM_CSCR_USB_MASK (0x7 << 26)
43#define CCM_CSCR_OSC_EN_SHIFT 17
44#define CCM_CSCR_SYSTEM_SEL (1 << 16)
45#define CCM_CSCR_BCLK_OFFSET 10
46#define CCM_CSCR_BCLK_MASK (0xf << 10)
47#define CCM_CSCR_PRESC (1 << 15)
48
49#define CCM_PCDR_PCLK3_OFFSET 16
50#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
51#define CCM_PCDR_PCLK2_OFFSET 4
52#define CCM_PCDR_PCLK2_MASK (0xf << 4)
53#define CCM_PCDR_PCLK1_OFFSET 0
54#define CCM_PCDR_PCLK1_MASK 0xf
55
56#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
57
58/* SCM register addresses */
59#define SCM_GCCR IO_ADDR_SCM(0xc)
60
61#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
62#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
63#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
64#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
65
66static int _clk_enable(struct clk *clk)
67{
68 unsigned int reg;
69
70 reg = __raw_readl(clk->enable_reg);
71 reg |= 1 << clk->enable_shift;
72 __raw_writel(reg, clk->enable_reg);
73
74 return 0;
75}
76
77static void _clk_disable(struct clk *clk)
78{
79 unsigned int reg;
80
81 reg = __raw_readl(clk->enable_reg);
82 reg &= ~(1 << clk->enable_shift);
83 __raw_writel(reg, clk->enable_reg);
84}
85
86static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size,
87 struct clk *parent)
88{
89 int i;
90
91 for (i = 0; i < size; i++)
92 if (parent == clk_arr[i])
93 return i;
94
95 return -EINVAL;
96}
97
98static unsigned long
99_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit)
100{
101 int div;
102 unsigned long parent_rate;
103
104 parent_rate = clk_get_rate(clk->parent);
105
106 div = parent_rate / rate;
107 if (parent_rate % rate)
108 div++;
109
110 if (div > limit)
111 div = limit;
112
113 return parent_rate / div;
114}
115
116static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
117{
118 return clk->parent->round_rate(clk->parent, rate);
119}
120
121static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
122{
123 return clk->parent->set_rate(clk->parent, rate);
124}
125
126static unsigned long clk16m_get_rate(struct clk *clk)
127{
128 return 16000000;
129}
130
131static struct clk clk16m = {
132 .get_rate = clk16m_get_rate,
133 .enable = _clk_enable,
134 .enable_reg = CCM_CSCR,
135 .enable_shift = CCM_CSCR_OSC_EN_SHIFT,
136 .disable = _clk_disable,
137};
138
139/* in Hz */
140static unsigned long clk32_rate;
141
142static unsigned long clk32_get_rate(struct clk *clk)
143{
144 return clk32_rate;
145}
146
147static struct clk clk32 = {
148 .get_rate = clk32_get_rate,
149};
150
151static unsigned long clk32_premult_get_rate(struct clk *clk)
152{
153 return clk_get_rate(clk->parent) * 512;
154}
155
156static struct clk clk32_premult = {
157 .parent = &clk32,
158 .get_rate = clk32_premult_get_rate,
159};
160
161static const struct clk *prem_clk_clocks[] = {
162 &clk32_premult,
163 &clk16m,
164};
165
166static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
167{
168 int i;
169 unsigned int reg = __raw_readl(CCM_CSCR);
170
171 i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks),
172 parent);
173
174 switch (i) {
175 case 0:
176 reg &= ~CCM_CSCR_SYSTEM_SEL;
177 break;
178 case 1:
179 reg |= CCM_CSCR_SYSTEM_SEL;
180 break;
181 default:
182 return i;
183 }
184
185 __raw_writel(reg, CCM_CSCR);
186
187 return 0;
188}
189
190static struct clk prem_clk = {
191 .set_parent = prem_clk_set_parent,
192};
193
194static unsigned long system_clk_get_rate(struct clk *clk)
195{
196 return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
197 clk_get_rate(clk->parent));
198}
199
200static struct clk system_clk = {
201 .parent = &prem_clk,
202 .get_rate = system_clk_get_rate,
203};
204
205static unsigned long mcu_clk_get_rate(struct clk *clk)
206{
207 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
208 clk_get_rate(clk->parent));
209}
210
211static struct clk mcu_clk = {
212 .parent = &clk32_premult,
213 .get_rate = mcu_clk_get_rate,
214};
215
216static unsigned long fclk_get_rate(struct clk *clk)
217{
218 unsigned long fclk = clk_get_rate(clk->parent);
219
220 if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC)
221 fclk /= 2;
222
223 return fclk;
224}
225
226static struct clk fclk = {
227 .parent = &mcu_clk,
228 .get_rate = fclk_get_rate,
229};
230
231/*
232 * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
233 */
234static unsigned long hclk_get_rate(struct clk *clk)
235{
236 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
237 CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1);
238}
239
240static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate)
241{
242 return _clk_simple_round_rate(clk, rate, 16);
243}
244
245static int hclk_set_rate(struct clk *clk, unsigned long rate)
246{
247 unsigned int div;
248 unsigned int reg;
249 unsigned long parent_rate;
250
251 parent_rate = clk_get_rate(clk->parent);
252
253 div = parent_rate / rate;
254
255 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
256 return -EINVAL;
257
258 div--;
259
260 reg = __raw_readl(CCM_CSCR);
261 reg &= ~CCM_CSCR_BCLK_MASK;
262 reg |= div << CCM_CSCR_BCLK_OFFSET;
263 __raw_writel(reg, CCM_CSCR);
264
265 return 0;
266}
267
268static struct clk hclk = {
269 .parent = &system_clk,
270 .get_rate = hclk_get_rate,
271 .round_rate = hclk_round_rate,
272 .set_rate = hclk_set_rate,
273};
274
275static unsigned long clk48m_get_rate(struct clk *clk)
276{
277 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
278 CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1);
279}
280
281static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate)
282{
283 return _clk_simple_round_rate(clk, rate, 8);
284}
285
286static int clk48m_set_rate(struct clk *clk, unsigned long rate)
287{
288 unsigned int div;
289 unsigned int reg;
290 unsigned long parent_rate;
291
292 parent_rate = clk_get_rate(clk->parent);
293
294 div = parent_rate / rate;
295
296 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
297 return -EINVAL;
298
299 div--;
300
301 reg = __raw_readl(CCM_CSCR);
302 reg &= ~CCM_CSCR_USB_MASK;
303 reg |= div << CCM_CSCR_USB_OFFSET;
304 __raw_writel(reg, CCM_CSCR);
305
306 return 0;
307}
308
309static struct clk clk48m = {
310 .parent = &system_clk,
311 .get_rate = clk48m_get_rate,
312 .round_rate = clk48m_round_rate,
313 .set_rate = clk48m_set_rate,
314};
315
316/*
317 * get peripheral clock 1 ( UART[12], Timer[12], PWM )
318 */
319static unsigned long perclk1_get_rate(struct clk *clk)
320{
321 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
322 CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1);
323}
324
325static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate)
326{
327 return _clk_simple_round_rate(clk, rate, 16);
328}
329
330static int perclk1_set_rate(struct clk *clk, unsigned long rate)
331{
332 unsigned int div;
333 unsigned int reg;
334 unsigned long parent_rate;
335
336 parent_rate = clk_get_rate(clk->parent);
337
338 div = parent_rate / rate;
339
340 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
341 return -EINVAL;
342
343 div--;
344
345 reg = __raw_readl(CCM_PCDR);
346 reg &= ~CCM_PCDR_PCLK1_MASK;
347 reg |= div << CCM_PCDR_PCLK1_OFFSET;
348 __raw_writel(reg, CCM_PCDR);
349
350 return 0;
351}
352
353/*
354 * get peripheral clock 2 ( LCD, SD, SPI[12] )
355 */
356static unsigned long perclk2_get_rate(struct clk *clk)
357{
358 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
359 CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1);
360}
361
362static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate)
363{
364 return _clk_simple_round_rate(clk, rate, 16);
365}
366
367static int perclk2_set_rate(struct clk *clk, unsigned long rate)
368{
369 unsigned int div;
370 unsigned int reg;
371 unsigned long parent_rate;
372
373 parent_rate = clk_get_rate(clk->parent);
374
375 div = parent_rate / rate;
376
377 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
378 return -EINVAL;
379
380 div--;
381
382 reg = __raw_readl(CCM_PCDR);
383 reg &= ~CCM_PCDR_PCLK2_MASK;
384 reg |= div << CCM_PCDR_PCLK2_OFFSET;
385 __raw_writel(reg, CCM_PCDR);
386
387 return 0;
388}
389
390/*
391 * get peripheral clock 3 ( SSI )
392 */
393static unsigned long perclk3_get_rate(struct clk *clk)
394{
395 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
396 CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1);
397}
398
399static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate)
400{
401 return _clk_simple_round_rate(clk, rate, 128);
402}
403
404static int perclk3_set_rate(struct clk *clk, unsigned long rate)
405{
406 unsigned int div;
407 unsigned int reg;
408 unsigned long parent_rate;
409
410 parent_rate = clk_get_rate(clk->parent);
411
412 div = parent_rate / rate;
413
414 if (div > 128 || div < 1 || ((parent_rate / div) != rate))
415 return -EINVAL;
416
417 div--;
418
419 reg = __raw_readl(CCM_PCDR);
420 reg &= ~CCM_PCDR_PCLK3_MASK;
421 reg |= div << CCM_PCDR_PCLK3_OFFSET;
422 __raw_writel(reg, CCM_PCDR);
423
424 return 0;
425}
426
427static struct clk perclk[] = {
428 {
429 .id = 0,
430 .parent = &system_clk,
431 .get_rate = perclk1_get_rate,
432 .round_rate = perclk1_round_rate,
433 .set_rate = perclk1_set_rate,
434 }, {
435 .id = 1,
436 .parent = &system_clk,
437 .get_rate = perclk2_get_rate,
438 .round_rate = perclk2_round_rate,
439 .set_rate = perclk2_set_rate,
440 }, {
441 .id = 2,
442 .parent = &system_clk,
443 .get_rate = perclk3_get_rate,
444 .round_rate = perclk3_round_rate,
445 .set_rate = perclk3_set_rate,
446 }
447};
448
449static const struct clk *clko_clocks[] = {
450 &perclk[0],
451 &hclk,
452 &clk48m,
453 &clk16m,
454 &prem_clk,
455 &fclk,
456};
457
458static int clko_set_parent(struct clk *clk, struct clk *parent)
459{
460 int i;
461 unsigned int reg;
462
463 i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent);
464 if (i < 0)
465 return i;
466
467 reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK;
468 reg |= i << CCM_CSCR_CLKO_OFFSET;
469 __raw_writel(reg, CCM_CSCR);
470
471 if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) {
472 clk->set_rate = _clk_parent_set_rate;
473 clk->round_rate = _clk_parent_round_rate;
474 } else {
475 clk->set_rate = NULL;
476 clk->round_rate = NULL;
477 }
478
479 return 0;
480}
481
482static struct clk clko_clk = {
483 .set_parent = clko_set_parent,
484};
485
486static struct clk dma_clk = {
487 .parent = &hclk,
488 .round_rate = _clk_parent_round_rate,
489 .set_rate = _clk_parent_set_rate,
490 .enable = _clk_enable,
491 .enable_reg = SCM_GCCR,
492 .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET,
493 .disable = _clk_disable,
494};
495
496static struct clk csi_clk = {
497 .parent = &hclk,
498 .round_rate = _clk_parent_round_rate,
499 .set_rate = _clk_parent_set_rate,
500 .enable = _clk_enable,
501 .enable_reg = SCM_GCCR,
502 .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET,
503 .disable = _clk_disable,
504};
505
506static struct clk mma_clk = {
507 .parent = &hclk,
508 .round_rate = _clk_parent_round_rate,
509 .set_rate = _clk_parent_set_rate,
510 .enable = _clk_enable,
511 .enable_reg = SCM_GCCR,
512 .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET,
513 .disable = _clk_disable,
514};
515
516static struct clk usbd_clk = {
517 .parent = &clk48m,
518 .round_rate = _clk_parent_round_rate,
519 .set_rate = _clk_parent_set_rate,
520 .enable = _clk_enable,
521 .enable_reg = SCM_GCCR,
522 .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET,
523 .disable = _clk_disable,
524};
525
526static struct clk gpt_clk = {
527 .parent = &perclk[0],
528 .round_rate = _clk_parent_round_rate,
529 .set_rate = _clk_parent_set_rate,
530};
531
532static struct clk uart_clk = {
533 .parent = &perclk[0],
534 .round_rate = _clk_parent_round_rate,
535 .set_rate = _clk_parent_set_rate,
536};
537
538static struct clk i2c_clk = {
539 .parent = &hclk,
540 .round_rate = _clk_parent_round_rate,
541 .set_rate = _clk_parent_set_rate,
542};
543
544static struct clk spi_clk = {
545 .parent = &perclk[1],
546 .round_rate = _clk_parent_round_rate,
547 .set_rate = _clk_parent_set_rate,
548};
549
550static struct clk sdhc_clk = {
551 .parent = &perclk[1],
552 .round_rate = _clk_parent_round_rate,
553 .set_rate = _clk_parent_set_rate,
554};
555
556static struct clk lcdc_clk = {
557 .parent = &perclk[1],
558 .round_rate = _clk_parent_round_rate,
559 .set_rate = _clk_parent_set_rate,
560};
561
562static struct clk mshc_clk = {
563 .parent = &hclk,
564 .round_rate = _clk_parent_round_rate,
565 .set_rate = _clk_parent_set_rate,
566};
567
568static struct clk ssi_clk = {
569 .parent = &perclk[2],
570 .round_rate = _clk_parent_round_rate,
571 .set_rate = _clk_parent_set_rate,
572};
573
574static struct clk rtc_clk = {
575 .parent = &clk32,
576};
577
578#define _REGISTER_CLOCK(d, n, c) \
579 { \
580 .dev_id = d, \
581 .con_id = n, \
582 .clk = &c, \
583 },
584static struct clk_lookup lookups[] __initdata = {
585 _REGISTER_CLOCK(NULL, "dma", dma_clk)
586 _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
587 _REGISTER_CLOCK(NULL, "mma", mma_clk)
588 _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
589 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
590 _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk)
591 _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk)
592 _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk)
593 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
594 _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
595 _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
596 _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
597 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
598 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
599 _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
600 _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
601};
602
603int __init mx1_clocks_init(unsigned long fref)
604{
605 unsigned int reg;
606
607 /* disable clocks we are able to */
608 __raw_writel(0, SCM_GCCR);
609
610 clk32_rate = fref;
611 reg = __raw_readl(CCM_CSCR);
612
613 /* detect clock reference for system PLL */
614 if (reg & CCM_CSCR_SYSTEM_SEL) {
615 prem_clk.parent = &clk16m;
616 } else {
617 /* ensure that oscillator is disabled */
618 reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT);
619 __raw_writel(reg, CCM_CSCR);
620 prem_clk.parent = &clk32_premult;
621 }
622
623 /* detect reference for CLKO */
624 reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
625 clko_clk.parent = (struct clk *)clko_clocks[reg];
626
627 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
628
629 clk_enable(&hclk);
630 clk_enable(&fclk);
631
632 mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
633 MX1_TIM1_INT);
634
635 return 0;
636}
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
deleted file mode 100644
index ee15d8c9db0..00000000000
--- a/arch/arm/mach-imx/clock-imx21.c
+++ /dev/null
@@ -1,1239 +0,0 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
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
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/module.h>
24#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <asm/div64.h>
30
31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
32
33/* Register offsets */
34#define CCM_CSCR IO_ADDR_CCM(0x0)
35#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
37#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
38#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
39#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
40#define CCM_PCDR0 IO_ADDR_CCM(0x18)
41#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
42#define CCM_PCCR0 IO_ADDR_CCM(0x20)
43#define CCM_PCCR1 IO_ADDR_CCM(0x24)
44#define CCM_CCSR IO_ADDR_CCM(0x28)
45#define CCM_PMCTL IO_ADDR_CCM(0x2c)
46#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
47#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
48
49#define CCM_CSCR_PRESC_OFFSET 29
50#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
51
52#define CCM_CSCR_USB_OFFSET 26
53#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
54#define CCM_CSCR_SD_OFFSET 24
55#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
56#define CCM_CSCR_SPLLRES (1 << 22)
57#define CCM_CSCR_MPLLRES (1 << 21)
58#define CCM_CSCR_SSI2_OFFSET 20
59#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
60#define CCM_CSCR_SSI1_OFFSET 19
61#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
62#define CCM_CSCR_FIR_OFFSET 18
63#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
64#define CCM_CSCR_SP (1 << 17)
65#define CCM_CSCR_MCU (1 << 16)
66#define CCM_CSCR_BCLK_OFFSET 10
67#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
68#define CCM_CSCR_IPDIV_OFFSET 9
69#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
70
71#define CCM_CSCR_OSC26MDIV (1 << 4)
72#define CCM_CSCR_OSC26M (1 << 3)
73#define CCM_CSCR_FPM (1 << 2)
74#define CCM_CSCR_SPEN (1 << 1)
75#define CCM_CSCR_MPEN 1
76
77#define CCM_MPCTL0_CPLM (1 << 31)
78#define CCM_MPCTL0_PD_OFFSET 26
79#define CCM_MPCTL0_PD_MASK (0xf << 26)
80#define CCM_MPCTL0_MFD_OFFSET 16
81#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
82#define CCM_MPCTL0_MFI_OFFSET 10
83#define CCM_MPCTL0_MFI_MASK (0xf << 10)
84#define CCM_MPCTL0_MFN_OFFSET 0
85#define CCM_MPCTL0_MFN_MASK 0x3ff
86
87#define CCM_MPCTL1_LF (1 << 15)
88#define CCM_MPCTL1_BRMO (1 << 6)
89
90#define CCM_SPCTL0_CPLM (1 << 31)
91#define CCM_SPCTL0_PD_OFFSET 26
92#define CCM_SPCTL0_PD_MASK (0xf << 26)
93#define CCM_SPCTL0_MFD_OFFSET 16
94#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
95#define CCM_SPCTL0_MFI_OFFSET 10
96#define CCM_SPCTL0_MFI_MASK (0xf << 10)
97#define CCM_SPCTL0_MFN_OFFSET 0
98#define CCM_SPCTL0_MFN_MASK 0x3ff
99
100#define CCM_SPCTL1_LF (1 << 15)
101#define CCM_SPCTL1_BRMO (1 << 6)
102
103#define CCM_OSC26MCTL_PEAK_OFFSET 16
104#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
105#define CCM_OSC26MCTL_AGC_OFFSET 8
106#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
107#define CCM_OSC26MCTL_ANATEST_OFFSET 0
108#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
109
110#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
111#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
112#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
113#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
114#define CCM_PCDR0_NFCDIV_OFFSET 12
115#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
116#define CCM_PCDR0_48MDIV_OFFSET 5
117#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
118#define CCM_PCDR0_FIRIDIV_OFFSET 0
119#define CCM_PCDR0_FIRIDIV_MASK 0x1f
120#define CCM_PCDR1_PERDIV4_OFFSET 24
121#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
122#define CCM_PCDR1_PERDIV3_OFFSET 16
123#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
124#define CCM_PCDR1_PERDIV2_OFFSET 8
125#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
126#define CCM_PCDR1_PERDIV1_OFFSET 0
127#define CCM_PCDR1_PERDIV1_MASK 0x3f
128
129#define CCM_PCCR_HCLK_CSI_OFFSET 31
130#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
131#define CCM_PCCR_HCLK_DMA_OFFSET 30
132#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
133#define CCM_PCCR_HCLK_BROM_OFFSET 28
134#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
135#define CCM_PCCR_HCLK_EMMA_OFFSET 27
136#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
137#define CCM_PCCR_HCLK_LCDC_OFFSET 26
138#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
139#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
140#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
141#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
142#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
143#define CCM_PCCR_HCLK_BMI_OFFSET 23
144#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
145#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
146#define CCM_PCCR_PERCLK4_OFFSET 22
147#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
148#define CCM_PCCR_SLCDC_OFFSET 21
149#define CCM_PCCR_SLCDC_REG CCM_PCCR0
150#define CCM_PCCR_FIRI_BAUD_OFFSET 20
151#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
152#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
153#define CCM_PCCR_NFC_OFFSET 19
154#define CCM_PCCR_NFC_REG CCM_PCCR0
155#define CCM_PCCR_LCDC_OFFSET 18
156#define CCM_PCCR_LCDC_REG CCM_PCCR0
157#define CCM_PCCR_SSI1_BAUD_OFFSET 17
158#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
159#define CCM_PCCR_SSI2_BAUD_OFFSET 16
160#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
161#define CCM_PCCR_EMMA_OFFSET 15
162#define CCM_PCCR_EMMA_REG CCM_PCCR0
163#define CCM_PCCR_USBOTG_OFFSET 14
164#define CCM_PCCR_USBOTG_REG CCM_PCCR0
165#define CCM_PCCR_DMA_OFFSET 13
166#define CCM_PCCR_DMA_REG CCM_PCCR0
167#define CCM_PCCR_I2C1_OFFSET 12
168#define CCM_PCCR_I2C1_REG CCM_PCCR0
169#define CCM_PCCR_GPIO_OFFSET 11
170#define CCM_PCCR_GPIO_REG CCM_PCCR0
171#define CCM_PCCR_SDHC2_OFFSET 10
172#define CCM_PCCR_SDHC2_REG CCM_PCCR0
173#define CCM_PCCR_SDHC1_OFFSET 9
174#define CCM_PCCR_SDHC1_REG CCM_PCCR0
175#define CCM_PCCR_FIRI_OFFSET 8
176#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
177#define CCM_PCCR_FIRI_REG CCM_PCCR0
178#define CCM_PCCR_SSI2_IPG_OFFSET 7
179#define CCM_PCCR_SSI2_REG CCM_PCCR0
180#define CCM_PCCR_SSI1_IPG_OFFSET 6
181#define CCM_PCCR_SSI1_REG CCM_PCCR0
182#define CCM_PCCR_CSPI2_OFFSET 5
183#define CCM_PCCR_CSPI2_REG CCM_PCCR0
184#define CCM_PCCR_CSPI1_OFFSET 4
185#define CCM_PCCR_CSPI1_REG CCM_PCCR0
186#define CCM_PCCR_UART4_OFFSET 3
187#define CCM_PCCR_UART4_REG CCM_PCCR0
188#define CCM_PCCR_UART3_OFFSET 2
189#define CCM_PCCR_UART3_REG CCM_PCCR0
190#define CCM_PCCR_UART2_OFFSET 1
191#define CCM_PCCR_UART2_REG CCM_PCCR0
192#define CCM_PCCR_UART1_OFFSET 0
193#define CCM_PCCR_UART1_REG CCM_PCCR0
194
195#define CCM_PCCR_OWIRE_OFFSET 31
196#define CCM_PCCR_OWIRE_REG CCM_PCCR1
197#define CCM_PCCR_KPP_OFFSET 30
198#define CCM_PCCR_KPP_REG CCM_PCCR1
199#define CCM_PCCR_RTC_OFFSET 29
200#define CCM_PCCR_RTC_REG CCM_PCCR1
201#define CCM_PCCR_PWM_OFFSET 28
202#define CCM_PCCR_PWM_REG CCM_PCCR1
203#define CCM_PCCR_GPT3_OFFSET 27
204#define CCM_PCCR_GPT3_REG CCM_PCCR1
205#define CCM_PCCR_GPT2_OFFSET 26
206#define CCM_PCCR_GPT2_REG CCM_PCCR1
207#define CCM_PCCR_GPT1_OFFSET 25
208#define CCM_PCCR_GPT1_REG CCM_PCCR1
209#define CCM_PCCR_WDT_OFFSET 24
210#define CCM_PCCR_WDT_REG CCM_PCCR1
211#define CCM_PCCR_CSPI3_OFFSET 23
212#define CCM_PCCR_CSPI3_REG CCM_PCCR1
213
214#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
215#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
216#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
217#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
218#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
219#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
220#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
221#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
222#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
223#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
224#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
225#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
226#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
227#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
228#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
229#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
230#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
231#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
232#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
233#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
234#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
235#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
236#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
237#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
238#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
239#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
240#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
241#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
242#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
243#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
244#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
245#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
246#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
247#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
248#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
249#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
250#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
251
252#define CCM_CCSR_32KSR (1 << 15)
253
254#define CCM_CCSR_CLKMODE1 (1 << 9)
255#define CCM_CCSR_CLKMODE0 (1 << 8)
256
257#define CCM_CCSR_CLKOSEL_OFFSET 0
258#define CCM_CCSR_CLKOSEL_MASK 0x1f
259
260#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
261#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
262
263static int _clk_enable(struct clk *clk)
264{
265 u32 reg;
266
267 reg = __raw_readl(clk->enable_reg);
268 reg |= 1 << clk->enable_shift;
269 __raw_writel(reg, clk->enable_reg);
270 return 0;
271}
272
273static void _clk_disable(struct clk *clk)
274{
275 u32 reg;
276
277 reg = __raw_readl(clk->enable_reg);
278 reg &= ~(1 << clk->enable_shift);
279 __raw_writel(reg, clk->enable_reg);
280}
281
282static unsigned long _clk_generic_round_rate(struct clk *clk,
283 unsigned long rate,
284 u32 max_divisor)
285{
286 u32 div;
287 unsigned long parent_rate;
288
289 parent_rate = clk_get_rate(clk->parent);
290
291 div = parent_rate / rate;
292 if (parent_rate % rate)
293 div++;
294
295 if (div > max_divisor)
296 div = max_divisor;
297
298 return parent_rate / div;
299}
300
301static int _clk_spll_enable(struct clk *clk)
302{
303 u32 reg;
304
305 reg = __raw_readl(CCM_CSCR);
306 reg |= CCM_CSCR_SPEN;
307 __raw_writel(reg, CCM_CSCR);
308
309 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
310 ;
311 return 0;
312}
313
314static void _clk_spll_disable(struct clk *clk)
315{
316 u32 reg;
317
318 reg = __raw_readl(CCM_CSCR);
319 reg &= ~CCM_CSCR_SPEN;
320 __raw_writel(reg, CCM_CSCR);
321}
322
323
324#define CSCR() (__raw_readl(CCM_CSCR))
325#define PCDR0() (__raw_readl(CCM_PCDR0))
326#define PCDR1() (__raw_readl(CCM_PCDR1))
327
328static unsigned long _clk_perclkx_round_rate(struct clk *clk,
329 unsigned long rate)
330{
331 return _clk_generic_round_rate(clk, rate, 64);
332}
333
334static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
335{
336 u32 reg;
337 u32 div;
338 unsigned long parent_rate;
339
340 parent_rate = clk_get_rate(clk->parent);
341
342 if (clk->id < 0 || clk->id > 3)
343 return -EINVAL;
344
345 div = parent_rate / rate;
346 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
347 return -EINVAL;
348 div--;
349
350 reg =
351 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
352 (clk->id << 3));
353 reg |= div << (clk->id << 3);
354 __raw_writel(reg, CCM_PCDR1);
355
356 return 0;
357}
358
359static unsigned long _clk_usb_recalc(struct clk *clk)
360{
361 unsigned long usb_pdf;
362 unsigned long parent_rate;
363
364 parent_rate = clk_get_rate(clk->parent);
365
366 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
367
368 return parent_rate / (usb_pdf + 1U);
369}
370
371static unsigned long _clk_usb_round_rate(struct clk *clk,
372 unsigned long rate)
373{
374 return _clk_generic_round_rate(clk, rate, 8);
375}
376
377static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
378{
379 u32 reg;
380 u32 div;
381 unsigned long parent_rate;
382
383 parent_rate = clk_get_rate(clk->parent);
384
385 div = parent_rate / rate;
386 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
387 return -EINVAL;
388 div--;
389
390 reg = CSCR() & ~CCM_CSCR_USB_MASK;
391 reg |= div << CCM_CSCR_USB_OFFSET;
392 __raw_writel(reg, CCM_CSCR);
393
394 return 0;
395}
396
397static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
398{
399 unsigned long parent_rate;
400
401 parent_rate = clk_get_rate(clk->parent);
402
403 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
404
405 return 2UL * parent_rate / pdf;
406}
407
408static unsigned long _clk_ssi1_recalc(struct clk *clk)
409{
410 return _clk_ssix_recalc(clk,
411 (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
412 >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
413}
414
415static unsigned long _clk_ssi2_recalc(struct clk *clk)
416{
417 return _clk_ssix_recalc(clk,
418 (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
419 CCM_PCDR0_SSI2BAUDDIV_OFFSET);
420}
421
422static unsigned long _clk_nfc_recalc(struct clk *clk)
423{
424 unsigned long nfc_pdf;
425 unsigned long parent_rate;
426
427 parent_rate = clk_get_rate(clk->parent);
428
429 nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
430 >> CCM_PCDR0_NFCDIV_OFFSET;
431
432 return parent_rate / (nfc_pdf + 1);
433}
434
435static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
436{
437 return clk->parent->round_rate(clk->parent, rate);
438}
439
440static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
441{
442 return clk->parent->set_rate(clk->parent, rate);
443}
444
445static unsigned long external_high_reference; /* in Hz */
446
447static unsigned long get_high_reference_clock_rate(struct clk *clk)
448{
449 return external_high_reference;
450}
451
452/*
453 * the high frequency external clock reference
454 * Default case is 26MHz.
455 */
456static struct clk ckih_clk = {
457 .get_rate = get_high_reference_clock_rate,
458};
459
460static unsigned long external_low_reference; /* in Hz */
461
462static unsigned long get_low_reference_clock_rate(struct clk *clk)
463{
464 return external_low_reference;
465}
466
467/*
468 * the low frequency external clock reference
469 * Default case is 32.768kHz.
470 */
471static struct clk ckil_clk = {
472 .get_rate = get_low_reference_clock_rate,
473};
474
475
476static unsigned long _clk_fpm_recalc(struct clk *clk)
477{
478 return clk_get_rate(clk->parent) * 512;
479}
480
481/* Output of frequency pre multiplier */
482static struct clk fpm_clk = {
483 .parent = &ckil_clk,
484 .get_rate = _clk_fpm_recalc,
485};
486
487static unsigned long get_mpll_clk(struct clk *clk)
488{
489 uint32_t reg;
490 unsigned long ref_clk;
491 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
492 unsigned long long temp;
493
494 ref_clk = clk_get_rate(clk->parent);
495
496 reg = __raw_readl(CCM_MPCTL0);
497 pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
498 mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
499 mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
500 mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
501
502 mfi = (mfi <= 5) ? 5 : mfi;
503 temp = 2LL * ref_clk * mfn;
504 do_div(temp, mfd + 1);
505 temp = 2LL * ref_clk * mfi + temp;
506 do_div(temp, pdf + 1);
507
508 return (unsigned long)temp;
509}
510
511static struct clk mpll_clk = {
512 .parent = &ckih_clk,
513 .get_rate = get_mpll_clk,
514};
515
516static unsigned long _clk_fclk_get_rate(struct clk *clk)
517{
518 unsigned long parent_rate;
519 u32 div;
520
521 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
522 parent_rate = clk_get_rate(clk->parent);
523
524 return parent_rate / (div+1);
525}
526
527static struct clk fclk_clk = {
528 .parent = &mpll_clk,
529 .get_rate = _clk_fclk_get_rate
530};
531
532static unsigned long get_spll_clk(struct clk *clk)
533{
534 uint32_t reg;
535 unsigned long ref_clk;
536 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
537 unsigned long long temp;
538
539 ref_clk = clk_get_rate(clk->parent);
540
541 reg = __raw_readl(CCM_SPCTL0);
542 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
543 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
544 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
545 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
546
547 mfi = (mfi <= 5) ? 5 : mfi;
548 temp = 2LL * ref_clk * mfn;
549 do_div(temp, mfd + 1);
550 temp = 2LL * ref_clk * mfi + temp;
551 do_div(temp, pdf + 1);
552
553 return (unsigned long)temp;
554}
555
556static struct clk spll_clk = {
557 .parent = &ckih_clk,
558 .get_rate = get_spll_clk,
559 .enable = _clk_spll_enable,
560 .disable = _clk_spll_disable,
561};
562
563static unsigned long get_hclk_clk(struct clk *clk)
564{
565 unsigned long rate;
566 unsigned long bclk_pdf;
567
568 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
569 >> CCM_CSCR_BCLK_OFFSET;
570
571 rate = clk_get_rate(clk->parent);
572 return rate / (bclk_pdf + 1);
573}
574
575static struct clk hclk_clk = {
576 .parent = &fclk_clk,
577 .get_rate = get_hclk_clk,
578};
579
580static unsigned long get_ipg_clk(struct clk *clk)
581{
582 unsigned long rate;
583 unsigned long ipg_pdf;
584
585 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
586
587 rate = clk_get_rate(clk->parent);
588 return rate / (ipg_pdf + 1);
589}
590
591static struct clk ipg_clk = {
592 .parent = &hclk_clk,
593 .get_rate = get_ipg_clk,
594};
595
596static unsigned long _clk_perclkx_recalc(struct clk *clk)
597{
598 unsigned long perclk_pdf;
599 unsigned long parent_rate;
600
601 parent_rate = clk_get_rate(clk->parent);
602
603 if (clk->id < 0 || clk->id > 3)
604 return 0;
605
606 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
607
608 return parent_rate / (perclk_pdf + 1);
609}
610
611static struct clk per_clk[] = {
612 {
613 .id = 0,
614 .parent = &mpll_clk,
615 .get_rate = _clk_perclkx_recalc,
616 }, {
617 .id = 1,
618 .parent = &mpll_clk,
619 .get_rate = _clk_perclkx_recalc,
620 }, {
621 .id = 2,
622 .parent = &mpll_clk,
623 .round_rate = _clk_perclkx_round_rate,
624 .set_rate = _clk_perclkx_set_rate,
625 .get_rate = _clk_perclkx_recalc,
626 /* Enable/Disable done via lcd_clkc[1] */
627 }, {
628 .id = 3,
629 .parent = &mpll_clk,
630 .round_rate = _clk_perclkx_round_rate,
631 .set_rate = _clk_perclkx_set_rate,
632 .get_rate = _clk_perclkx_recalc,
633 /* Enable/Disable done via csi_clk[1] */
634 },
635};
636
637static struct clk uart_ipg_clk[];
638
639static struct clk uart_clk[] = {
640 {
641 .id = 0,
642 .parent = &per_clk[0],
643 .secondary = &uart_ipg_clk[0],
644 }, {
645 .id = 1,
646 .parent = &per_clk[0],
647 .secondary = &uart_ipg_clk[1],
648 }, {
649 .id = 2,
650 .parent = &per_clk[0],
651 .secondary = &uart_ipg_clk[2],
652 }, {
653 .id = 3,
654 .parent = &per_clk[0],
655 .secondary = &uart_ipg_clk[3],
656 },
657};
658
659static struct clk uart_ipg_clk[] = {
660 {
661 .id = 0,
662 .parent = &ipg_clk,
663 .enable = _clk_enable,
664 .enable_reg = CCM_PCCR_UART1_REG,
665 .enable_shift = CCM_PCCR_UART1_OFFSET,
666 .disable = _clk_disable,
667 }, {
668 .id = 1,
669 .parent = &ipg_clk,
670 .enable = _clk_enable,
671 .enable_reg = CCM_PCCR_UART2_REG,
672 .enable_shift = CCM_PCCR_UART2_OFFSET,
673 .disable = _clk_disable,
674 }, {
675 .id = 2,
676 .parent = &ipg_clk,
677 .enable = _clk_enable,
678 .enable_reg = CCM_PCCR_UART3_REG,
679 .enable_shift = CCM_PCCR_UART3_OFFSET,
680 .disable = _clk_disable,
681 }, {
682 .id = 3,
683 .parent = &ipg_clk,
684 .enable = _clk_enable,
685 .enable_reg = CCM_PCCR_UART4_REG,
686 .enable_shift = CCM_PCCR_UART4_OFFSET,
687 .disable = _clk_disable,
688 },
689};
690
691static struct clk gpt_ipg_clk[];
692
693static struct clk gpt_clk[] = {
694 {
695 .id = 0,
696 .parent = &per_clk[0],
697 .secondary = &gpt_ipg_clk[0],
698 }, {
699 .id = 1,
700 .parent = &per_clk[0],
701 .secondary = &gpt_ipg_clk[1],
702 }, {
703 .id = 2,
704 .parent = &per_clk[0],
705 .secondary = &gpt_ipg_clk[2],
706 },
707};
708
709static struct clk gpt_ipg_clk[] = {
710 {
711 .id = 0,
712 .parent = &ipg_clk,
713 .enable = _clk_enable,
714 .enable_reg = CCM_PCCR_GPT1_REG,
715 .enable_shift = CCM_PCCR_GPT1_OFFSET,
716 .disable = _clk_disable,
717 }, {
718 .id = 1,
719 .parent = &ipg_clk,
720 .enable = _clk_enable,
721 .enable_reg = CCM_PCCR_GPT2_REG,
722 .enable_shift = CCM_PCCR_GPT2_OFFSET,
723 .disable = _clk_disable,
724 }, {
725 .id = 2,
726 .parent = &ipg_clk,
727 .enable = _clk_enable,
728 .enable_reg = CCM_PCCR_GPT3_REG,
729 .enable_shift = CCM_PCCR_GPT3_OFFSET,
730 .disable = _clk_disable,
731 },
732};
733
734static struct clk pwm_clk[] = {
735 {
736 .parent = &per_clk[0],
737 .secondary = &pwm_clk[1],
738 }, {
739 .parent = &ipg_clk,
740 .enable = _clk_enable,
741 .enable_reg = CCM_PCCR_PWM_REG,
742 .enable_shift = CCM_PCCR_PWM_OFFSET,
743 .disable = _clk_disable,
744 },
745};
746
747static struct clk sdhc_ipg_clk[];
748
749static struct clk sdhc_clk[] = {
750 {
751 .id = 0,
752 .parent = &per_clk[1],
753 .secondary = &sdhc_ipg_clk[0],
754 }, {
755 .id = 1,
756 .parent = &per_clk[1],
757 .secondary = &sdhc_ipg_clk[1],
758 },
759};
760
761static struct clk sdhc_ipg_clk[] = {
762 {
763 .id = 0,
764 .parent = &ipg_clk,
765 .enable = _clk_enable,
766 .enable_reg = CCM_PCCR_SDHC1_REG,
767 .enable_shift = CCM_PCCR_SDHC1_OFFSET,
768 .disable = _clk_disable,
769 }, {
770 .id = 1,
771 .parent = &ipg_clk,
772 .enable = _clk_enable,
773 .enable_reg = CCM_PCCR_SDHC2_REG,
774 .enable_shift = CCM_PCCR_SDHC2_OFFSET,
775 .disable = _clk_disable,
776 },
777};
778
779static struct clk cspi_ipg_clk[];
780
781static struct clk cspi_clk[] = {
782 {
783 .id = 0,
784 .parent = &per_clk[1],
785 .secondary = &cspi_ipg_clk[0],
786 }, {
787 .id = 1,
788 .parent = &per_clk[1],
789 .secondary = &cspi_ipg_clk[1],
790 }, {
791 .id = 2,
792 .parent = &per_clk[1],
793 .secondary = &cspi_ipg_clk[2],
794 },
795};
796
797static struct clk cspi_ipg_clk[] = {
798 {
799 .id = 0,
800 .parent = &ipg_clk,
801 .enable = _clk_enable,
802 .enable_reg = CCM_PCCR_CSPI1_REG,
803 .enable_shift = CCM_PCCR_CSPI1_OFFSET,
804 .disable = _clk_disable,
805 }, {
806 .id = 1,
807 .parent = &ipg_clk,
808 .enable = _clk_enable,
809 .enable_reg = CCM_PCCR_CSPI2_REG,
810 .enable_shift = CCM_PCCR_CSPI2_OFFSET,
811 .disable = _clk_disable,
812 }, {
813 .id = 3,
814 .parent = &ipg_clk,
815 .enable = _clk_enable,
816 .enable_reg = CCM_PCCR_CSPI3_REG,
817 .enable_shift = CCM_PCCR_CSPI3_OFFSET,
818 .disable = _clk_disable,
819 },
820};
821
822static struct clk lcdc_clk[] = {
823 {
824 .parent = &per_clk[2],
825 .secondary = &lcdc_clk[1],
826 .round_rate = _clk_parent_round_rate,
827 .set_rate = _clk_parent_set_rate,
828 }, {
829 .parent = &ipg_clk,
830 .secondary = &lcdc_clk[2],
831 .enable = _clk_enable,
832 .enable_reg = CCM_PCCR_LCDC_REG,
833 .enable_shift = CCM_PCCR_LCDC_OFFSET,
834 .disable = _clk_disable,
835 }, {
836 .parent = &hclk_clk,
837 .enable = _clk_enable,
838 .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
839 .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
840 .disable = _clk_disable,
841 },
842};
843
844static struct clk csi_clk[] = {
845 {
846 .parent = &per_clk[3],
847 .secondary = &csi_clk[1],
848 .round_rate = _clk_parent_round_rate,
849 .set_rate = _clk_parent_set_rate,
850 }, {
851 .parent = &hclk_clk,
852 .enable = _clk_enable,
853 .enable_reg = CCM_PCCR_HCLK_CSI_REG,
854 .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
855 .disable = _clk_disable,
856 },
857};
858
859static struct clk usb_clk[] = {
860 {
861 .parent = &spll_clk,
862 .secondary = &usb_clk[1],
863 .get_rate = _clk_usb_recalc,
864 .enable = _clk_enable,
865 .enable_reg = CCM_PCCR_USBOTG_REG,
866 .enable_shift = CCM_PCCR_USBOTG_OFFSET,
867 .disable = _clk_disable,
868 .round_rate = _clk_usb_round_rate,
869 .set_rate = _clk_usb_set_rate,
870 }, {
871 .parent = &hclk_clk,
872 .enable = _clk_enable,
873 .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
874 .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
875 .disable = _clk_disable,
876 }
877};
878
879static struct clk ssi_ipg_clk[];
880
881static struct clk ssi_clk[] = {
882 {
883 .id = 0,
884 .parent = &mpll_clk,
885 .secondary = &ssi_ipg_clk[0],
886 .get_rate = _clk_ssi1_recalc,
887 .enable = _clk_enable,
888 .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
889 .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
890 .disable = _clk_disable,
891 }, {
892 .id = 1,
893 .parent = &mpll_clk,
894 .secondary = &ssi_ipg_clk[1],
895 .get_rate = _clk_ssi2_recalc,
896 .enable = _clk_enable,
897 .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
898 .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
899 .disable = _clk_disable,
900 },
901};
902
903static struct clk ssi_ipg_clk[] = {
904 {
905 .id = 0,
906 .parent = &ipg_clk,
907 .enable = _clk_enable,
908 .enable_reg = CCM_PCCR_SSI1_REG,
909 .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
910 .disable = _clk_disable,
911 }, {
912 .id = 1,
913 .parent = &ipg_clk,
914 .enable = _clk_enable,
915 .enable_reg = CCM_PCCR_SSI2_REG,
916 .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
917 .disable = _clk_disable,
918 },
919};
920
921
922static struct clk nfc_clk = {
923 .parent = &fclk_clk,
924 .get_rate = _clk_nfc_recalc,
925 .enable = _clk_enable,
926 .enable_reg = CCM_PCCR_NFC_REG,
927 .enable_shift = CCM_PCCR_NFC_OFFSET,
928 .disable = _clk_disable,
929};
930
931static struct clk dma_clk[] = {
932 {
933 .parent = &hclk_clk,
934 .enable = _clk_enable,
935 .enable_reg = CCM_PCCR_DMA_REG,
936 .enable_shift = CCM_PCCR_DMA_OFFSET,
937 .disable = _clk_disable,
938 .secondary = &dma_clk[1],
939 }, {
940 .enable = _clk_enable,
941 .enable_reg = CCM_PCCR_HCLK_DMA_REG,
942 .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
943 .disable = _clk_disable,
944 },
945};
946
947static struct clk brom_clk = {
948 .parent = &hclk_clk,
949 .enable = _clk_enable,
950 .enable_reg = CCM_PCCR_HCLK_BROM_REG,
951 .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
952 .disable = _clk_disable,
953};
954
955static struct clk emma_clk[] = {
956 {
957 .parent = &hclk_clk,
958 .enable = _clk_enable,
959 .enable_reg = CCM_PCCR_EMMA_REG,
960 .enable_shift = CCM_PCCR_EMMA_OFFSET,
961 .disable = _clk_disable,
962 .secondary = &emma_clk[1],
963 }, {
964 .enable = _clk_enable,
965 .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
966 .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
967 .disable = _clk_disable,
968 }
969};
970
971static struct clk slcdc_clk[] = {
972 {
973 .parent = &hclk_clk,
974 .enable = _clk_enable,
975 .enable_reg = CCM_PCCR_SLCDC_REG,
976 .enable_shift = CCM_PCCR_SLCDC_OFFSET,
977 .disable = _clk_disable,
978 .secondary = &slcdc_clk[1],
979 }, {
980 .enable = _clk_enable,
981 .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
982 .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
983 .disable = _clk_disable,
984 }
985};
986
987static struct clk wdog_clk = {
988 .parent = &ipg_clk,
989 .enable = _clk_enable,
990 .enable_reg = CCM_PCCR_WDT_REG,
991 .enable_shift = CCM_PCCR_WDT_OFFSET,
992 .disable = _clk_disable,
993};
994
995static struct clk gpio_clk = {
996 .parent = &ipg_clk,
997 .enable = _clk_enable,
998 .enable_reg = CCM_PCCR_GPIO_REG,
999 .enable_shift = CCM_PCCR_GPIO_OFFSET,
1000 .disable = _clk_disable,
1001};
1002
1003static struct clk i2c_clk = {
1004 .id = 0,
1005 .parent = &ipg_clk,
1006 .enable = _clk_enable,
1007 .enable_reg = CCM_PCCR_I2C1_REG,
1008 .enable_shift = CCM_PCCR_I2C1_OFFSET,
1009 .disable = _clk_disable,
1010};
1011
1012static struct clk kpp_clk = {
1013 .parent = &ipg_clk,
1014 .enable = _clk_enable,
1015 .enable_reg = CCM_PCCR_KPP_REG,
1016 .enable_shift = CCM_PCCR_KPP_OFFSET,
1017 .disable = _clk_disable,
1018};
1019
1020static struct clk owire_clk = {
1021 .parent = &ipg_clk,
1022 .enable = _clk_enable,
1023 .enable_reg = CCM_PCCR_OWIRE_REG,
1024 .enable_shift = CCM_PCCR_OWIRE_OFFSET,
1025 .disable = _clk_disable,
1026};
1027
1028static struct clk rtc_clk = {
1029 .parent = &ipg_clk,
1030 .enable = _clk_enable,
1031 .enable_reg = CCM_PCCR_RTC_REG,
1032 .enable_shift = CCM_PCCR_RTC_OFFSET,
1033 .disable = _clk_disable,
1034};
1035
1036static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1037{
1038 return _clk_generic_round_rate(clk, rate, 8);
1039}
1040
1041static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1042{
1043 u32 reg;
1044 u32 div;
1045 unsigned long parent_rate;
1046
1047 parent_rate = clk_get_rate(clk->parent);
1048
1049 div = parent_rate / rate;
1050
1051 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1052 return -EINVAL;
1053 div--;
1054
1055 reg = __raw_readl(CCM_PCDR0);
1056
1057 if (clk->parent == &usb_clk[0]) {
1058 reg &= ~CCM_PCDR0_48MDIV_MASK;
1059 reg |= div << CCM_PCDR0_48MDIV_OFFSET;
1060 }
1061 __raw_writel(reg, CCM_PCDR0);
1062
1063 return 0;
1064}
1065
1066static unsigned long _clk_clko_recalc(struct clk *clk)
1067{
1068 u32 div = 0;
1069 unsigned long parent_rate;
1070
1071 parent_rate = clk_get_rate(clk->parent);
1072
1073 if (clk->parent == &usb_clk[0]) /* 48M */
1074 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
1075 >> CCM_PCDR0_48MDIV_OFFSET;
1076 div++;
1077
1078 return parent_rate / div;
1079}
1080
1081static struct clk clko_clk;
1082
1083static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1084{
1085 u32 reg;
1086
1087 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1088
1089 if (parent == &ckil_clk)
1090 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1091 else if (parent == &fpm_clk)
1092 reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
1093 else if (parent == &ckih_clk)
1094 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1095 else if (parent == mpll_clk.parent)
1096 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1097 else if (parent == spll_clk.parent)
1098 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1099 else if (parent == &mpll_clk)
1100 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1101 else if (parent == &spll_clk)
1102 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1103 else if (parent == &fclk_clk)
1104 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1105 else if (parent == &hclk_clk)
1106 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1107 else if (parent == &ipg_clk)
1108 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1109 else if (parent == &per_clk[0])
1110 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1111 else if (parent == &per_clk[1])
1112 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1113 else if (parent == &per_clk[2])
1114 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1115 else if (parent == &per_clk[3])
1116 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1117 else if (parent == &ssi_clk[0])
1118 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1119 else if (parent == &ssi_clk[1])
1120 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1121 else if (parent == &nfc_clk)
1122 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1123 else if (parent == &usb_clk[0])
1124 reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
1125 else if (parent == &clko_clk)
1126 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1127 else
1128 return -EINVAL;
1129
1130 __raw_writel(reg, CCM_CCSR);
1131
1132 return 0;
1133}
1134
1135static struct clk clko_clk = {
1136 .get_rate = _clk_clko_recalc,
1137 .set_rate = _clk_clko_set_rate,
1138 .round_rate = _clk_clko_round_rate,
1139 .set_parent = _clk_clko_set_parent,
1140};
1141
1142
1143#define _REGISTER_CLOCK(d, n, c) \
1144 { \
1145 .dev_id = d, \
1146 .con_id = n, \
1147 .clk = &c, \
1148 },
1149static struct clk_lookup lookups[] = {
1150/* It's unlikely that any driver wants one of them directly:
1151 _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1152 _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
1153 _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
1154 _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
1155 _REGISTER_CLOCK(NULL, "spll", spll_clk)
1156 _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
1157 _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
1158 _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
1159*/
1160 _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
1161 _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
1162 _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
1163 _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
1164 _REGISTER_CLOCK(NULL, "clko", clko_clk)
1165 _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0])
1166 _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1])
1167 _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2])
1168 _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3])
1169 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
1170 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
1171 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
1172 _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
1173 _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
1174 _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
1175 _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
1176 _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
1177 _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
1178 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
1179 _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
1180 _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
1181 _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
1182 _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
1183 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1184 _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
1185 _REGISTER_CLOCK(NULL, "brom", brom_clk)
1186 _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
1187 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
1188 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
1189 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1190 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
1191 _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
1192 _REGISTER_CLOCK(NULL, "owire", owire_clk)
1193 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1194};
1195
1196/*
1197 * must be called very early to get information about the
1198 * available clock rate when the timer framework starts
1199 */
1200int __init mx21_clocks_init(unsigned long lref, unsigned long href)
1201{
1202 u32 cscr;
1203
1204 external_low_reference = lref;
1205 external_high_reference = href;
1206
1207 /* detect clock reference for both system PLL */
1208 cscr = CSCR();
1209 if (cscr & CCM_CSCR_MCU)
1210 mpll_clk.parent = &ckih_clk;
1211 else
1212 mpll_clk.parent = &fpm_clk;
1213
1214 if (cscr & CCM_CSCR_SP)
1215 spll_clk.parent = &ckih_clk;
1216 else
1217 spll_clk.parent = &fpm_clk;
1218
1219 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
1220
1221 /* Turn off all clock gates */
1222 __raw_writel(0, CCM_PCCR0);
1223 __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
1224
1225 /* This turns of the serial PLL as well */
1226 spll_clk.disable(&spll_clk);
1227
1228 /* This will propagate to all children and init all the clock rates. */
1229 clk_enable(&per_clk[0]);
1230 clk_enable(&gpio_clk);
1231
1232#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
1233 clk_enable(&uart_clk[0]);
1234#endif
1235
1236 mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
1237 MX21_INT_GPT1);
1238 return 0;
1239}
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
deleted file mode 100644
index b0fec74c8c9..00000000000
--- a/arch/arm/mach-imx/clock-imx25.c
+++ /dev/null
@@ -1,346 +0,0 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
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
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <mach/mx25.h>
30
31#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
32
33#define CCM_MPCTL 0x00
34#define CCM_UPCTL 0x04
35#define CCM_CCTL 0x08
36#define CCM_CGCR0 0x0C
37#define CCM_CGCR1 0x10
38#define CCM_CGCR2 0x14
39#define CCM_PCDR0 0x18
40#define CCM_PCDR1 0x1C
41#define CCM_PCDR2 0x20
42#define CCM_PCDR3 0x24
43#define CCM_RCSR 0x28
44#define CCM_CRDR 0x2C
45#define CCM_DCVR0 0x30
46#define CCM_DCVR1 0x34
47#define CCM_DCVR2 0x38
48#define CCM_DCVR3 0x3c
49#define CCM_LTR0 0x40
50#define CCM_LTR1 0x44
51#define CCM_LTR2 0x48
52#define CCM_LTR3 0x4c
53
54static unsigned long get_rate_mpll(void)
55{
56 ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
57
58 return mxc_decode_pll(mpctl, 24000000);
59}
60
61static unsigned long get_rate_upll(void)
62{
63 ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
64
65 return mxc_decode_pll(mpctl, 24000000);
66}
67
68unsigned long get_rate_arm(struct clk *clk)
69{
70 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
71 unsigned long rate = get_rate_mpll();
72
73 if (cctl & (1 << 14))
74 rate = (rate * 3) >> 2;
75
76 return rate / ((cctl >> 30) + 1);
77}
78
79static unsigned long get_rate_ahb(struct clk *clk)
80{
81 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
82
83 return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
84}
85
86static unsigned long get_rate_ipg(struct clk *clk)
87{
88 return get_rate_ahb(NULL) >> 1;
89}
90
91static unsigned long get_rate_per(int per)
92{
93 unsigned long ofs = (per & 0x3) * 8;
94 unsigned long reg = per & ~0x3;
95 unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
96 unsigned long fref;
97
98 if (readl(CRM_BASE + 0x64) & (1 << per))
99 fref = get_rate_upll();
100 else
101 fref = get_rate_ahb(NULL);
102
103 return fref / (val + 1);
104}
105
106static unsigned long get_rate_uart(struct clk *clk)
107{
108 return get_rate_per(15);
109}
110
111static unsigned long get_rate_ssi2(struct clk *clk)
112{
113 return get_rate_per(14);
114}
115
116static unsigned long get_rate_ssi1(struct clk *clk)
117{
118 return get_rate_per(13);
119}
120
121static unsigned long get_rate_i2c(struct clk *clk)
122{
123 return get_rate_per(6);
124}
125
126static unsigned long get_rate_nfc(struct clk *clk)
127{
128 return get_rate_per(8);
129}
130
131static unsigned long get_rate_gpt(struct clk *clk)
132{
133 return get_rate_per(5);
134}
135
136static unsigned long get_rate_lcdc(struct clk *clk)
137{
138 return get_rate_per(7);
139}
140
141static unsigned long get_rate_esdhc1(struct clk *clk)
142{
143 return get_rate_per(3);
144}
145
146static unsigned long get_rate_esdhc2(struct clk *clk)
147{
148 return get_rate_per(4);
149}
150
151static unsigned long get_rate_csi(struct clk *clk)
152{
153 return get_rate_per(0);
154}
155
156static unsigned long get_rate_otg(struct clk *clk)
157{
158 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
159 unsigned long rate = get_rate_upll();
160
161 return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
162}
163
164static int clk_cgcr_enable(struct clk *clk)
165{
166 u32 reg;
167
168 reg = __raw_readl(clk->enable_reg);
169 reg |= 1 << clk->enable_shift;
170 __raw_writel(reg, clk->enable_reg);
171
172 return 0;
173}
174
175static void clk_cgcr_disable(struct clk *clk)
176{
177 u32 reg;
178
179 reg = __raw_readl(clk->enable_reg);
180 reg &= ~(1 << clk->enable_shift);
181 __raw_writel(reg, clk->enable_reg);
182}
183
184#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
185 static struct clk name = { \
186 .id = i, \
187 .enable_reg = CRM_BASE + er, \
188 .enable_shift = es, \
189 .get_rate = gr, \
190 .set_rate = sr, \
191 .enable = clk_cgcr_enable, \
192 .disable = clk_cgcr_disable, \
193 .secondary = s, \
194 }
195
196/*
197 * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
198 * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
199 * taken from the Freescale released BSP.
200 *
201 * bit reg offset clock
202 *
203 * 0 CGCR1 0 AUDMUX
204 * 12 CGCR1 12 ESAI
205 * 16 CGCR1 16 GPIO1
206 * 17 CGCR1 17 GPIO2
207 * 18 CGCR1 18 GPIO3
208 * 23 CGCR1 23 I2C1
209 * 24 CGCR1 24 I2C2
210 * 25 CGCR1 25 I2C3
211 * 27 CGCR1 27 IOMUXC
212 * 28 CGCR1 28 KPP
213 * 30 CGCR1 30 OWIRE
214 * 36 CGCR2 4 RTIC
215 * 51 CGCR2 19 WDOG
216 */
217
218DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
219DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
220DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
221DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
222DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
223DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
224DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
225DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
226DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
227 &esdhc1_ahb_clk);
228DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
229DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
230 &esdhc2_ahb_clk);
231DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
232DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
233DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
234DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
235DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
236DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
237DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
238DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
239DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
240DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
241DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
242DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
243DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
244DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
245DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
246DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
247DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL);
248DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
249DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
250DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
251DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
252DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
253DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
254DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
255DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
256DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
257DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
258DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
259 &esdhc1_per_clk);
260DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
261 &esdhc2_per_clk);
262DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
263DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
264DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
265DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
266DEFINE_CLOCK(iim_clk, 0, CCM_CGCR1, 26, NULL, NULL, NULL);
267
268#define _REGISTER_CLOCK(d, n, c) \
269 { \
270 .dev_id = d, \
271 .con_id = n, \
272 .clk = &c, \
273 },
274
275static struct clk_lookup lookups[] = {
276 /* i.mx25 has the i.mx21 type uart */
277 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
278 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
279 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
280 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
281 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
282 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
283 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
284 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
285 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
286 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
287 /* i.mx25 has the i.mx35 type cspi */
288 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
289 _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
290 _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk)
291 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
292 _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
293 _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
294 _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
295 _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
296 _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
297 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
298 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
299 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
300 _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
301 _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
302 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
303 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
304 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
305 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
306 _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk)
307 _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk)
308 _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
309 _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
310 _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
311 _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
312 /* i.mx25 has the i.mx35 type sdma */
313 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
314 _REGISTER_CLOCK(NULL, "iim", iim_clk)
315};
316
317int __init mx25_clocks_init(void)
318{
319 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
320
321 /* Turn off all clocks except the ones we need to survive, namely:
322 * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
323 * SCC
324 */
325 __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
326 __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
327 __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
328#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
329 clk_enable(&uart1_clk);
330#endif
331
332 /* Clock source for lcdc and csi is upll */
333 __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
334 CRM_BASE + 0x64);
335
336 /* Clock source for gpt is ahb_div */
337 __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64);
338
339 clk_enable(&iim_clk);
340 imx_print_silicon_rev("i.MX25", mx25_revision());
341 clk_disable(&iim_clk);
342
343 mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
344
345 return 0;
346}
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
deleted file mode 100644
index 98e04f5a87d..00000000000
--- a/arch/arm/mach-imx/clock-imx27.c
+++ /dev/null
@@ -1,785 +0,0 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
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
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/module.h>
24#include <linux/clkdev.h>
25#include <linux/of.h>
26
27#include <asm/div64.h>
28
29#include <mach/clock.h>
30#include <mach/common.h>
31#include <mach/hardware.h>
32
33#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
34
35/* Register offsets */
36#define CCM_CSCR IO_ADDR_CCM(0x0)
37#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
38#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
39#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
40#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
41#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
42#define CCM_PCDR0 IO_ADDR_CCM(0x18)
43#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
44#define CCM_PCCR0 IO_ADDR_CCM(0x20)
45#define CCM_PCCR1 IO_ADDR_CCM(0x24)
46#define CCM_CCSR IO_ADDR_CCM(0x28)
47#define CCM_PMCTL IO_ADDR_CCM(0x2c)
48#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
49#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
50
51#define CCM_CSCR_UPDATE_DIS (1 << 31)
52#define CCM_CSCR_SSI2 (1 << 23)
53#define CCM_CSCR_SSI1 (1 << 22)
54#define CCM_CSCR_VPU (1 << 21)
55#define CCM_CSCR_MSHC (1 << 20)
56#define CCM_CSCR_SPLLRES (1 << 19)
57#define CCM_CSCR_MPLLRES (1 << 18)
58#define CCM_CSCR_SP (1 << 17)
59#define CCM_CSCR_MCU (1 << 16)
60#define CCM_CSCR_OSC26MDIV (1 << 4)
61#define CCM_CSCR_OSC26M (1 << 3)
62#define CCM_CSCR_FPM (1 << 2)
63#define CCM_CSCR_SPEN (1 << 1)
64#define CCM_CSCR_MPEN (1 << 0)
65
66/* i.MX27 TO 2+ */
67#define CCM_CSCR_ARM_SRC (1 << 15)
68
69#define CCM_SPCTL1_LF (1 << 15)
70#define CCM_SPCTL1_BRMO (1 << 6)
71
72static struct clk mpll_main1_clk, mpll_main2_clk;
73
74static int clk_pccr_enable(struct clk *clk)
75{
76 unsigned long reg;
77
78 if (!clk->enable_reg)
79 return 0;
80
81 reg = __raw_readl(clk->enable_reg);
82 reg |= 1 << clk->enable_shift;
83 __raw_writel(reg, clk->enable_reg);
84
85 return 0;
86}
87
88static void clk_pccr_disable(struct clk *clk)
89{
90 unsigned long reg;
91
92 if (!clk->enable_reg)
93 return;
94
95 reg = __raw_readl(clk->enable_reg);
96 reg &= ~(1 << clk->enable_shift);
97 __raw_writel(reg, clk->enable_reg);
98}
99
100static int clk_spll_enable(struct clk *clk)
101{
102 unsigned long reg;
103
104 reg = __raw_readl(CCM_CSCR);
105 reg |= CCM_CSCR_SPEN;
106 __raw_writel(reg, CCM_CSCR);
107
108 while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
109
110 return 0;
111}
112
113static void clk_spll_disable(struct clk *clk)
114{
115 unsigned long reg;
116
117 reg = __raw_readl(CCM_CSCR);
118 reg &= ~CCM_CSCR_SPEN;
119 __raw_writel(reg, CCM_CSCR);
120}
121
122static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
123{
124 int cscr = __raw_readl(CCM_CSCR);
125
126 if (clk->parent == parent)
127 return 0;
128
129 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
130 if (parent == &mpll_main1_clk) {
131 cscr |= CCM_CSCR_ARM_SRC;
132 } else {
133 if (parent == &mpll_main2_clk)
134 cscr &= ~CCM_CSCR_ARM_SRC;
135 else
136 return -EINVAL;
137 }
138 __raw_writel(cscr, CCM_CSCR);
139 clk->parent = parent;
140 return 0;
141 }
142 return -ENODEV;
143}
144
145static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
146{
147 int div;
148 unsigned long parent_rate;
149
150 parent_rate = clk_get_rate(clk->parent);
151
152 div = parent_rate / rate;
153 if (parent_rate % rate)
154 div++;
155
156 if (div > 4)
157 div = 4;
158
159 return parent_rate / div;
160}
161
162static int set_rate_cpu(struct clk *clk, unsigned long rate)
163{
164 unsigned int div;
165 uint32_t reg;
166 unsigned long parent_rate;
167
168 parent_rate = clk_get_rate(clk->parent);
169
170 div = parent_rate / rate;
171
172 if (div > 4 || div < 1 || ((parent_rate / div) != rate))
173 return -EINVAL;
174
175 div--;
176
177 reg = __raw_readl(CCM_CSCR);
178 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
179 reg &= ~(3 << 12);
180 reg |= div << 12;
181 reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
182 __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
183 } else {
184 printk(KERN_ERR "Can't set CPU frequency!\n");
185 }
186
187 return 0;
188}
189
190static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
191{
192 u32 div;
193 unsigned long parent_rate;
194
195 parent_rate = clk_get_rate(clk->parent);
196
197 div = parent_rate / rate;
198 if (parent_rate % rate)
199 div++;
200
201 if (div > 64)
202 div = 64;
203
204 return parent_rate / div;
205}
206
207static int set_rate_per(struct clk *clk, unsigned long rate)
208{
209 u32 reg;
210 u32 div;
211 unsigned long parent_rate;
212
213 parent_rate = clk_get_rate(clk->parent);
214
215 if (clk->id < 0 || clk->id > 3)
216 return -EINVAL;
217
218 div = parent_rate / rate;
219 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
220 return -EINVAL;
221 div--;
222
223 reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
224 reg |= div << (clk->id << 3);
225 __raw_writel(reg, CCM_PCDR1);
226
227 return 0;
228}
229
230static unsigned long get_rate_usb(struct clk *clk)
231{
232 unsigned long usb_pdf;
233 unsigned long parent_rate;
234
235 parent_rate = clk_get_rate(clk->parent);
236
237 usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
238
239 return parent_rate / (usb_pdf + 1U);
240}
241
242static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
243{
244 unsigned long parent_rate;
245
246 parent_rate = clk_get_rate(clk->parent);
247
248 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
249 pdf += 4; /* MX27 TO2+ */
250 else
251 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
252
253 return 2UL * parent_rate / pdf;
254}
255
256static unsigned long get_rate_ssi1(struct clk *clk)
257{
258 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
259}
260
261static unsigned long get_rate_ssi2(struct clk *clk)
262{
263 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
264}
265
266static unsigned long get_rate_nfc(struct clk *clk)
267{
268 unsigned long nfc_pdf;
269 unsigned long parent_rate;
270
271 parent_rate = clk_get_rate(clk->parent);
272
273 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
274 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
275 else
276 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
277
278 return parent_rate / (nfc_pdf + 1);
279}
280
281static unsigned long get_rate_vpu(struct clk *clk)
282{
283 unsigned long vpu_pdf;
284 unsigned long parent_rate;
285
286 parent_rate = clk_get_rate(clk->parent);
287
288 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
289 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
290 vpu_pdf += 4;
291 } else {
292 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
293 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
294 }
295
296 return 2UL * parent_rate / vpu_pdf;
297}
298
299static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
300{
301 return clk->parent->round_rate(clk->parent, rate);
302}
303
304static unsigned long get_rate_parent(struct clk *clk)
305{
306 return clk_get_rate(clk->parent);
307}
308
309static int set_rate_parent(struct clk *clk, unsigned long rate)
310{
311 return clk->parent->set_rate(clk->parent, rate);
312}
313
314/* in Hz */
315static unsigned long external_high_reference = 26000000;
316
317static unsigned long get_rate_high_reference(struct clk *clk)
318{
319 return external_high_reference;
320}
321
322/* in Hz */
323static unsigned long external_low_reference = 32768;
324
325static unsigned long get_rate_low_reference(struct clk *clk)
326{
327 return external_low_reference;
328}
329
330static unsigned long get_rate_fpm(struct clk *clk)
331{
332 return clk_get_rate(clk->parent) * 1024;
333}
334
335static unsigned long get_rate_mpll(struct clk *clk)
336{
337 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
338 clk_get_rate(clk->parent));
339}
340
341static unsigned long get_rate_mpll_main(struct clk *clk)
342{
343 unsigned long parent_rate;
344
345 parent_rate = clk_get_rate(clk->parent);
346
347 /* i.MX27 TO2:
348 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
349 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
350 */
351 if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1)
352 return 2UL * parent_rate / 3UL;
353
354 return parent_rate;
355}
356
357static unsigned long get_rate_spll(struct clk *clk)
358{
359 uint32_t reg;
360 unsigned long rate;
361
362 rate = clk_get_rate(clk->parent);
363
364 reg = __raw_readl(CCM_SPCTL0);
365
366 /* On TO2 we have to write the value back. Otherwise we
367 * read 0 from this register the next time.
368 */
369 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
370 __raw_writel(reg, CCM_SPCTL0);
371
372 return mxc_decode_pll(reg, rate);
373}
374
375static unsigned long get_rate_cpu(struct clk *clk)
376{
377 u32 div;
378 unsigned long rate;
379
380 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
381 div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
382 else
383 div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
384
385 rate = clk_get_rate(clk->parent);
386 return rate / (div + 1);
387}
388
389static unsigned long get_rate_ahb(struct clk *clk)
390{
391 unsigned long rate, bclk_pdf;
392
393 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
394 bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
395 else
396 bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
397
398 rate = clk_get_rate(clk->parent);
399 return rate / (bclk_pdf + 1);
400}
401
402static unsigned long get_rate_ipg(struct clk *clk)
403{
404 unsigned long rate, ipg_pdf;
405
406 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
407 return clk_get_rate(clk->parent);
408 else
409 ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
410
411 rate = clk_get_rate(clk->parent);
412 return rate / (ipg_pdf + 1);
413}
414
415static unsigned long get_rate_per(struct clk *clk)
416{
417 unsigned long perclk_pdf, parent_rate;
418
419 parent_rate = clk_get_rate(clk->parent);
420
421 if (clk->id < 0 || clk->id > 3)
422 return 0;
423
424 perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
425
426 return parent_rate / (perclk_pdf + 1);
427}
428
429/*
430 * the high frequency external clock reference
431 * Default case is 26MHz. Could be changed at runtime
432 * with a call to change_external_high_reference()
433 */
434static struct clk ckih_clk = {
435 .get_rate = get_rate_high_reference,
436};
437
438static struct clk mpll_clk = {
439 .parent = &ckih_clk,
440 .get_rate = get_rate_mpll,
441};
442
443/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
444 * It provides the clock source whose rate is same as MPLL
445 */
446static struct clk mpll_main1_clk = {
447 .id = 0,
448 .parent = &mpll_clk,
449 .get_rate = get_rate_mpll_main,
450};
451
452/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
453 * It provides the clock source whose rate is same MPLL * 2 / 3
454 */
455static struct clk mpll_main2_clk = {
456 .id = 1,
457 .parent = &mpll_clk,
458 .get_rate = get_rate_mpll_main,
459};
460
461static struct clk ahb_clk = {
462 .parent = &mpll_main2_clk,
463 .get_rate = get_rate_ahb,
464};
465
466static struct clk ipg_clk = {
467 .parent = &ahb_clk,
468 .get_rate = get_rate_ipg,
469};
470
471static struct clk cpu_clk = {
472 .parent = &mpll_main2_clk,
473 .set_parent = clk_cpu_set_parent,
474 .round_rate = round_rate_cpu,
475 .get_rate = get_rate_cpu,
476 .set_rate = set_rate_cpu,
477};
478
479static struct clk spll_clk = {
480 .parent = &ckih_clk,
481 .get_rate = get_rate_spll,
482 .enable = clk_spll_enable,
483 .disable = clk_spll_disable,
484};
485
486/*
487 * the low frequency external clock reference
488 * Default case is 32.768kHz.
489 */
490static struct clk ckil_clk = {
491 .get_rate = get_rate_low_reference,
492};
493
494/* Output of frequency pre multiplier */
495static struct clk fpm_clk = {
496 .parent = &ckil_clk,
497 .get_rate = get_rate_fpm,
498};
499
500#define PCCR0 CCM_PCCR0
501#define PCCR1 CCM_PCCR1
502
503#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
504 static struct clk name = { \
505 .id = i, \
506 .enable_reg = er, \
507 .enable_shift = es, \
508 .get_rate = gr, \
509 .enable = clk_pccr_enable, \
510 .disable = clk_pccr_disable, \
511 .secondary = s, \
512 .parent = p, \
513 }
514
515#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
516 static struct clk name = { \
517 .id = i, \
518 .enable_reg = er, \
519 .enable_shift = es, \
520 .get_rate = get_rate_##getsetround, \
521 .set_rate = set_rate_##getsetround, \
522 .round_rate = round_rate_##getsetround, \
523 .enable = clk_pccr_enable, \
524 .disable = clk_pccr_disable, \
525 .secondary = s, \
526 .parent = p, \
527 }
528
529/* Forward declaration to keep the following list in order */
530static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
531 dma_clk1, lcdc_clk2, vpu_clk1;
532
533/* All clocks we can gate through PCCRx in the order of PCCRx bits */
534DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
535DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
536DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
537DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
538DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
539DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
540DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
541DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
542DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
543DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
544DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
545DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
546DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
547DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
548DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
549DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
550DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
551DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
552DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
553DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
554DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
555DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
556DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
557DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
558DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
559DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
560DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
561DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
562DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
563DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
564DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
565
566DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
567DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
568DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
569DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
570DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
571DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
572DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
573DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
574DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
575DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
576DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
577DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
578DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
579DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
580DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
581DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
582DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
583DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
584DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
585DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
586DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
587DEFINE_CLOCK(pata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
588DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
589DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
590DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
591DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
592DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
593DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
594DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
595DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
596
597/* Clocks we cannot directly gate, but drivers need their rates */
598DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
599DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
600DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
601DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
602DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
603DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
604DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
605DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
606DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
607DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
608DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
609DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
610DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
611DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
612DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
613DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
614DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
615DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
616DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
617DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
618DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
619
620#define _REGISTER_CLOCK(d, n, c) \
621 { \
622 .dev_id = d, \
623 .con_id = n, \
624 .clk = &c, \
625 },
626
627static struct clk_lookup lookups[] = {
628 /* i.mx27 has the i.mx21 type uart */
629 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
630 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
631 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
632 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
633 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
634 _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk)
635 _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
636 _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
637 _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
638 _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
639 _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
640 _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
641 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
642 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
643 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
644 _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
645 _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
646 _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
647 _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
648 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
649 _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
650 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
651 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
652 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
653 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
654 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
655 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
656 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
657 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
658 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
659 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
660 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
661 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
662 _REGISTER_CLOCK(NULL, "dma", dma_clk)
663 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
664 _REGISTER_CLOCK(NULL, "brom", brom_clk)
665 _REGISTER_CLOCK(NULL, "emma", emma_clk)
666 _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk)
667 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
668 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
669 _REGISTER_CLOCK(NULL, "emi", emi_clk)
670 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
671 _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
672 _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
673 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
674 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
675 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
676 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
677 _REGISTER_CLOCK(NULL, "iim", iim_clk)
678 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
679 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
680 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
681 _REGISTER_CLOCK(NULL, "scc", scc_clk)
682};
683
684/* Adjust the clock path for TO2 and later */
685static void __init to2_adjust_clocks(void)
686{
687 unsigned long cscr = __raw_readl(CCM_CSCR);
688
689 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
690 if (cscr & CCM_CSCR_ARM_SRC)
691 cpu_clk.parent = &mpll_main1_clk;
692
693 if (!(cscr & CCM_CSCR_SSI2))
694 ssi1_clk.parent = &spll_clk;
695
696 if (!(cscr & CCM_CSCR_SSI1))
697 ssi1_clk.parent = &spll_clk;
698
699 if (!(cscr & CCM_CSCR_VPU))
700 vpu_clk.parent = &spll_clk;
701 } else {
702 cpu_clk.parent = &mpll_clk;
703 cpu_clk.set_parent = NULL;
704 cpu_clk.round_rate = NULL;
705 cpu_clk.set_rate = NULL;
706 ahb_clk.parent = &mpll_clk;
707
708 per1_clk.parent = &mpll_clk;
709 per2_clk.parent = &mpll_clk;
710 per3_clk.parent = &mpll_clk;
711 per4_clk.parent = &mpll_clk;
712
713 ssi1_clk.parent = &mpll_clk;
714 ssi2_clk.parent = &mpll_clk;
715
716 vpu_clk.parent = &mpll_clk;
717 }
718}
719
720/*
721 * must be called very early to get information about the
722 * available clock rate when the timer framework starts
723 */
724int __init mx27_clocks_init(unsigned long fref)
725{
726 u32 cscr = __raw_readl(CCM_CSCR);
727
728 external_high_reference = fref;
729
730 /* detect clock reference for both system PLLs */
731 if (cscr & CCM_CSCR_MCU)
732 mpll_clk.parent = &ckih_clk;
733 else
734 mpll_clk.parent = &fpm_clk;
735
736 if (cscr & CCM_CSCR_SP)
737 spll_clk.parent = &ckih_clk;
738 else
739 spll_clk.parent = &fpm_clk;
740
741 to2_adjust_clocks();
742
743 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
744
745 /* Turn off all clocks we do not need */
746 __raw_writel(0, CCM_PCCR0);
747 __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
748
749 spll_clk.disable(&spll_clk);
750
751 /* enable basic clocks */
752 clk_enable(&per1_clk);
753 clk_enable(&gpio_clk);
754 clk_enable(&emi_clk);
755 clk_enable(&iim_clk);
756 imx_print_silicon_rev("i.MX27", mx27_revision());
757 clk_disable(&iim_clk);
758
759#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
760 clk_enable(&uart1_clk);
761#endif
762
763 mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
764 MX27_INT_GPT1);
765
766 return 0;
767}
768
769#ifdef CONFIG_OF
770int __init mx27_clocks_init_dt(void)
771{
772 struct device_node *np;
773 u32 fref = 26000000; /* default */
774
775 for_each_compatible_node(np, NULL, "fixed-clock") {
776 if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
777 continue;
778
779 if (!of_property_read_u32(np, "clock-frequency", &fref))
780 break;
781 }
782
783 return mx27_clocks_init(fref);
784}
785#endif
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c
deleted file mode 100644
index 3a943cd4159..00000000000
--- a/arch/arm/mach-imx/clock-imx31.c
+++ /dev/null
@@ -1,630 +0,0 @@
1/*
2 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/clkdev.h>
27
28#include <asm/div64.h>
29
30#include <mach/clock.h>
31#include <mach/hardware.h>
32#include <mach/mx31.h>
33#include <mach/common.h>
34
35#include "crmregs-imx3.h"
36
37#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
38
39static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
40{
41 u32 min_pre, temp_pre, old_err, err;
42
43 if (div >= 512) {
44 *pre = 8;
45 *post = 64;
46 } else if (div >= 64) {
47 min_pre = (div - 1) / 64 + 1;
48 old_err = 8;
49 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
50 err = div % temp_pre;
51 if (err == 0) {
52 *pre = temp_pre;
53 break;
54 }
55 err = temp_pre - err;
56 if (err < old_err) {
57 old_err = err;
58 *pre = temp_pre;
59 }
60 }
61 *post = (div + *pre - 1) / *pre;
62 } else if (div <= 8) {
63 *pre = div;
64 *post = 1;
65 } else {
66 *pre = 1;
67 *post = div;
68 }
69}
70
71static struct clk mcu_pll_clk;
72static struct clk serial_pll_clk;
73static struct clk ipg_clk;
74static struct clk ckih_clk;
75
76static int cgr_enable(struct clk *clk)
77{
78 u32 reg;
79
80 if (!clk->enable_reg)
81 return 0;
82
83 reg = __raw_readl(clk->enable_reg);
84 reg |= 3 << clk->enable_shift;
85 __raw_writel(reg, clk->enable_reg);
86
87 return 0;
88}
89
90static void cgr_disable(struct clk *clk)
91{
92 u32 reg;
93
94 if (!clk->enable_reg)
95 return;
96
97 reg = __raw_readl(clk->enable_reg);
98 reg &= ~(3 << clk->enable_shift);
99
100 /* special case for EMI clock */
101 if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
102 reg |= (1 << clk->enable_shift);
103
104 __raw_writel(reg, clk->enable_reg);
105}
106
107static unsigned long pll_ref_get_rate(void)
108{
109 unsigned long ccmr;
110 unsigned int prcs;
111
112 ccmr = __raw_readl(MXC_CCM_CCMR);
113 prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
114 if (prcs == 0x1)
115 return CKIL_CLK_FREQ * 1024;
116 else
117 return clk_get_rate(&ckih_clk);
118}
119
120static unsigned long usb_pll_get_rate(struct clk *clk)
121{
122 unsigned long reg;
123
124 reg = __raw_readl(MXC_CCM_UPCTL);
125
126 return mxc_decode_pll(reg, pll_ref_get_rate());
127}
128
129static unsigned long serial_pll_get_rate(struct clk *clk)
130{
131 unsigned long reg;
132
133 reg = __raw_readl(MXC_CCM_SRPCTL);
134
135 return mxc_decode_pll(reg, pll_ref_get_rate());
136}
137
138static unsigned long mcu_pll_get_rate(struct clk *clk)
139{
140 unsigned long reg, ccmr;
141
142 ccmr = __raw_readl(MXC_CCM_CCMR);
143
144 if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
145 return clk_get_rate(&ckih_clk);
146
147 reg = __raw_readl(MXC_CCM_MPCTL);
148
149 return mxc_decode_pll(reg, pll_ref_get_rate());
150}
151
152static int usb_pll_enable(struct clk *clk)
153{
154 u32 reg;
155
156 reg = __raw_readl(MXC_CCM_CCMR);
157 reg |= MXC_CCM_CCMR_UPE;
158 __raw_writel(reg, MXC_CCM_CCMR);
159
160 /* No lock bit on MX31, so using max time from spec */
161 udelay(80);
162
163 return 0;
164}
165
166static void usb_pll_disable(struct clk *clk)
167{
168 u32 reg;
169
170 reg = __raw_readl(MXC_CCM_CCMR);
171 reg &= ~MXC_CCM_CCMR_UPE;
172 __raw_writel(reg, MXC_CCM_CCMR);
173}
174
175static int serial_pll_enable(struct clk *clk)
176{
177 u32 reg;
178
179 reg = __raw_readl(MXC_CCM_CCMR);
180 reg |= MXC_CCM_CCMR_SPE;
181 __raw_writel(reg, MXC_CCM_CCMR);
182
183 /* No lock bit on MX31, so using max time from spec */
184 udelay(80);
185
186 return 0;
187}
188
189static void serial_pll_disable(struct clk *clk)
190{
191 u32 reg;
192
193 reg = __raw_readl(MXC_CCM_CCMR);
194 reg &= ~MXC_CCM_CCMR_SPE;
195 __raw_writel(reg, MXC_CCM_CCMR);
196}
197
198#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
199#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
200#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
201
202static unsigned long mcu_main_get_rate(struct clk *clk)
203{
204 u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
205
206 if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
207 return clk_get_rate(&serial_pll_clk);
208 else
209 return clk_get_rate(&mcu_pll_clk);
210}
211
212static unsigned long ahb_get_rate(struct clk *clk)
213{
214 unsigned long max_pdf;
215
216 max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
217 MXC_CCM_PDR0_MAX_PODF_OFFSET);
218 return clk_get_rate(clk->parent) / (max_pdf + 1);
219}
220
221static unsigned long ipg_get_rate(struct clk *clk)
222{
223 unsigned long ipg_pdf;
224
225 ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
226 MXC_CCM_PDR0_IPG_PODF_OFFSET);
227 return clk_get_rate(clk->parent) / (ipg_pdf + 1);
228}
229
230static unsigned long nfc_get_rate(struct clk *clk)
231{
232 unsigned long nfc_pdf;
233
234 nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
235 MXC_CCM_PDR0_NFC_PODF_OFFSET);
236 return clk_get_rate(clk->parent) / (nfc_pdf + 1);
237}
238
239static unsigned long hsp_get_rate(struct clk *clk)
240{
241 unsigned long hsp_pdf;
242
243 hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
244 MXC_CCM_PDR0_HSP_PODF_OFFSET);
245 return clk_get_rate(clk->parent) / (hsp_pdf + 1);
246}
247
248static unsigned long usb_get_rate(struct clk *clk)
249{
250 unsigned long usb_pdf, usb_prepdf;
251
252 usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
253 MXC_CCM_PDR1_USB_PODF_OFFSET);
254 usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
255 MXC_CCM_PDR1_USB_PRDF_OFFSET);
256 return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
257}
258
259static unsigned long csi_get_rate(struct clk *clk)
260{
261 u32 reg, pre, post;
262
263 reg = __raw_readl(MXC_CCM_PDR0);
264 pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
265 MXC_CCM_PDR0_CSI_PRDF_OFFSET;
266 pre++;
267 post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
268 MXC_CCM_PDR0_CSI_PODF_OFFSET;
269 post++;
270 return clk_get_rate(clk->parent) / (pre * post);
271}
272
273static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
274{
275 u32 pre, post, parent = clk_get_rate(clk->parent);
276 u32 div = parent / rate;
277
278 if (parent % rate)
279 div++;
280
281 __calc_pre_post_dividers(div, &pre, &post);
282
283 return parent / (pre * post);
284}
285
286static int csi_set_rate(struct clk *clk, unsigned long rate)
287{
288 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
289
290 div = parent / rate;
291
292 if ((parent / div) != rate)
293 return -EINVAL;
294
295 __calc_pre_post_dividers(div, &pre, &post);
296
297 /* Set CSI clock divider */
298 reg = __raw_readl(MXC_CCM_PDR0) &
299 ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
300 reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
301 reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
302 __raw_writel(reg, MXC_CCM_PDR0);
303
304 return 0;
305}
306
307static unsigned long ssi1_get_rate(struct clk *clk)
308{
309 unsigned long ssi1_pdf, ssi1_prepdf;
310
311 ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
312 MXC_CCM_PDR1_SSI1_PODF_OFFSET);
313 ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
314 MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
315 return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
316}
317
318static unsigned long ssi2_get_rate(struct clk *clk)
319{
320 unsigned long ssi2_pdf, ssi2_prepdf;
321
322 ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
323 MXC_CCM_PDR1_SSI2_PODF_OFFSET);
324 ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
325 MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
326 return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
327}
328
329static unsigned long firi_get_rate(struct clk *clk)
330{
331 unsigned long firi_pdf, firi_prepdf;
332
333 firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
334 MXC_CCM_PDR1_FIRI_PODF_OFFSET);
335 firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
336 MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
337 return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
338}
339
340static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
341{
342 u32 pre, post;
343 u32 parent = clk_get_rate(clk->parent);
344 u32 div = parent / rate;
345
346 if (parent % rate)
347 div++;
348
349 __calc_pre_post_dividers(div, &pre, &post);
350
351 return parent / (pre * post);
352
353}
354
355static int firi_set_rate(struct clk *clk, unsigned long rate)
356{
357 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
358
359 div = parent / rate;
360
361 if ((parent / div) != rate)
362 return -EINVAL;
363
364 __calc_pre_post_dividers(div, &pre, &post);
365
366 /* Set FIRI clock divider */
367 reg = __raw_readl(MXC_CCM_PDR1) &
368 ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
369 reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
370 reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
371 __raw_writel(reg, MXC_CCM_PDR1);
372
373 return 0;
374}
375
376static unsigned long mbx_get_rate(struct clk *clk)
377{
378 return clk_get_rate(clk->parent) / 2;
379}
380
381static unsigned long mstick1_get_rate(struct clk *clk)
382{
383 unsigned long msti_pdf;
384
385 msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
386 MXC_CCM_PDR2_MST1_PDF_OFFSET);
387 return clk_get_rate(clk->parent) / (msti_pdf + 1);
388}
389
390static unsigned long mstick2_get_rate(struct clk *clk)
391{
392 unsigned long msti_pdf;
393
394 msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
395 MXC_CCM_PDR2_MST2_PDF_OFFSET);
396 return clk_get_rate(clk->parent) / (msti_pdf + 1);
397}
398
399static unsigned long ckih_rate;
400
401static unsigned long clk_ckih_get_rate(struct clk *clk)
402{
403 return ckih_rate;
404}
405
406static unsigned long clk_ckil_get_rate(struct clk *clk)
407{
408 return CKIL_CLK_FREQ;
409}
410
411static struct clk ckih_clk = {
412 .get_rate = clk_ckih_get_rate,
413};
414
415static struct clk mcu_pll_clk = {
416 .parent = &ckih_clk,
417 .get_rate = mcu_pll_get_rate,
418};
419
420static struct clk mcu_main_clk = {
421 .parent = &mcu_pll_clk,
422 .get_rate = mcu_main_get_rate,
423};
424
425static struct clk serial_pll_clk = {
426 .parent = &ckih_clk,
427 .get_rate = serial_pll_get_rate,
428 .enable = serial_pll_enable,
429 .disable = serial_pll_disable,
430};
431
432static struct clk usb_pll_clk = {
433 .parent = &ckih_clk,
434 .get_rate = usb_pll_get_rate,
435 .enable = usb_pll_enable,
436 .disable = usb_pll_disable,
437};
438
439static struct clk ahb_clk = {
440 .parent = &mcu_main_clk,
441 .get_rate = ahb_get_rate,
442};
443
444#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
445 static struct clk name = { \
446 .id = i, \
447 .enable_reg = er, \
448 .enable_shift = es, \
449 .get_rate = gr, \
450 .enable = cgr_enable, \
451 .disable = cgr_disable, \
452 .secondary = s, \
453 .parent = p, \
454 }
455
456#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
457 static struct clk name = { \
458 .id = i, \
459 .enable_reg = er, \
460 .enable_shift = es, \
461 .get_rate = getsetround##_get_rate, \
462 .set_rate = getsetround##_set_rate, \
463 .round_rate = getsetround##_round_rate, \
464 .enable = cgr_enable, \
465 .disable = cgr_disable, \
466 .secondary = s, \
467 .parent = p, \
468 }
469
470DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
471DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
472
473DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
474DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
475DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
476DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
477DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
478DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
479DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
480DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
481DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
482DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
483DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
484DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
485DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
486DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
487DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
488DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
489
490DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
491DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
492DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
493DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
494DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
495DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
496DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
497DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
498DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
499DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
500DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
501DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
502DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
503DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
504
505DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
506DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
507DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
508DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
509DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
510DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
511DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
512
513DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
514DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
515DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
516DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
517DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
518
519#define _REGISTER_CLOCK(d, n, c) \
520 { \
521 .dev_id = d, \
522 .con_id = n, \
523 .clk = &c, \
524 },
525
526static struct clk_lookup lookups[] = {
527 _REGISTER_CLOCK(NULL, "emi", emi_clk)
528 _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
529 _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
530 _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
531 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
532 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
533 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
534 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
535 _REGISTER_CLOCK(NULL, "epit", epit1_clk)
536 _REGISTER_CLOCK(NULL, "epit", epit2_clk)
537 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
538 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
539 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
540 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
541 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
542 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
543 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
544 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
545 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
546 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
547 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
548 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
549 _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
550 /* i.mx31 has the i.mx21 type uart */
551 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
552 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
553 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
554 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
555 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
556 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
557 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
558 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
559 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
560 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
561 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
562 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
563 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
564 _REGISTER_CLOCK(NULL, "firi", firi_clk)
565 _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
566 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
567 _REGISTER_CLOCK(NULL, "rng", rng_clk)
568 _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1)
569 _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
570 _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
571 _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
572 _REGISTER_CLOCK(NULL, "scc", scc_clk)
573 _REGISTER_CLOCK(NULL, "iim", iim_clk)
574 _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
575 _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
576};
577
578int __init mx31_clocks_init(unsigned long fref)
579{
580 u32 reg;
581
582 ckih_rate = fref;
583
584 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
585
586 /* change the csi_clk parent if necessary */
587 reg = __raw_readl(MXC_CCM_CCMR);
588 if (!(reg & MXC_CCM_CCMR_CSCS))
589 if (clk_set_parent(&csi_clk, &usb_pll_clk))
590 pr_err("%s: error changing csi_clk parent\n", __func__);
591
592
593 /* Turn off all possible clocks */
594 __raw_writel((3 << 4), MXC_CCM_CGR0);
595 __raw_writel(0, MXC_CCM_CGR1);
596 __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
597 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
598 MX32, but still required to be set */
599 MXC_CCM_CGR2);
600
601 /*
602 * Before turning off usb_pll make sure ipg_per_clk is generated
603 * by ipg_clk and not usb_pll.
604 */
605 __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
606
607 usb_pll_disable(&usb_pll_clk);
608
609 pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
610
611 clk_enable(&gpt_clk);
612 clk_enable(&emi_clk);
613 clk_enable(&iim_clk);
614 mx31_revision();
615 clk_disable(&iim_clk);
616
617 clk_enable(&serial_pll_clk);
618
619 if (mx31_revision() >= IMX_CHIP_REVISION_2_0) {
620 reg = __raw_readl(MXC_CCM_PMCR1);
621 /* No PLL restart on DVFS switch; enable auto EMI handshake */
622 reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
623 __raw_writel(reg, MXC_CCM_PMCR1);
624 }
625
626 mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
627 MX31_INT_GPT);
628
629 return 0;
630}
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
deleted file mode 100644
index e56c1a83eee..00000000000
--- a/arch/arm/mach-imx/clock-imx35.c
+++ /dev/null
@@ -1,536 +0,0 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
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
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29
30#include "crmregs-imx3.h"
31
32#ifdef HAVE_SET_RATE_SUPPORT
33static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
34{
35 u32 min_pre, temp_pre, old_err, err;
36
37 min_pre = (div - 1) / maxpost + 1;
38 old_err = 8;
39
40 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
41 if (div > (temp_pre * maxpost))
42 break;
43
44 if (div < (temp_pre * temp_pre))
45 continue;
46
47 err = div % temp_pre;
48
49 if (err == 0) {
50 *pre = temp_pre;
51 break;
52 }
53
54 err = temp_pre - err;
55
56 if (err < old_err) {
57 old_err = err;
58 *pre = temp_pre;
59 }
60 }
61
62 *post = (div + *pre - 1) / *pre;
63}
64
65/* get the best values for a 3-bit divider combined with a 6-bit divider */
66static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
67{
68 if (div >= 512) {
69 *pre = 8;
70 *post = 64;
71 } else if (div >= 64) {
72 calc_dividers(div, pre, post, 64);
73 } else if (div <= 8) {
74 *pre = div;
75 *post = 1;
76 } else {
77 *pre = 1;
78 *post = div;
79 }
80}
81
82/* get the best values for two cascaded 3-bit dividers */
83static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
84{
85 if (div >= 64) {
86 *pre = *post = 8;
87 } else if (div > 8) {
88 calc_dividers(div, pre, post, 8);
89 } else {
90 *pre = 1;
91 *post = div;
92 }
93}
94#endif
95
96static unsigned long get_rate_mpll(void)
97{
98 ulong mpctl = __raw_readl(MX35_CCM_MPCTL);
99
100 return mxc_decode_pll(mpctl, 24000000);
101}
102
103static unsigned long get_rate_ppll(void)
104{
105 ulong ppctl = __raw_readl(MX35_CCM_PPCTL);
106
107 return mxc_decode_pll(ppctl, 24000000);
108}
109
110struct arm_ahb_div {
111 unsigned char arm, ahb, sel;
112};
113
114static struct arm_ahb_div clk_consumer[] = {
115 { .arm = 1, .ahb = 4, .sel = 0},
116 { .arm = 1, .ahb = 3, .sel = 1},
117 { .arm = 2, .ahb = 2, .sel = 0},
118 { .arm = 0, .ahb = 0, .sel = 0},
119 { .arm = 0, .ahb = 0, .sel = 0},
120 { .arm = 0, .ahb = 0, .sel = 0},
121 { .arm = 4, .ahb = 1, .sel = 0},
122 { .arm = 1, .ahb = 5, .sel = 0},
123 { .arm = 1, .ahb = 8, .sel = 0},
124 { .arm = 1, .ahb = 6, .sel = 1},
125 { .arm = 2, .ahb = 4, .sel = 0},
126 { .arm = 0, .ahb = 0, .sel = 0},
127 { .arm = 0, .ahb = 0, .sel = 0},
128 { .arm = 0, .ahb = 0, .sel = 0},
129 { .arm = 4, .ahb = 2, .sel = 0},
130 { .arm = 0, .ahb = 0, .sel = 0},
131};
132
133static unsigned long get_rate_arm(void)
134{
135 unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
136 struct arm_ahb_div *aad;
137 unsigned long fref = get_rate_mpll();
138
139 aad = &clk_consumer[(pdr0 >> 16) & 0xf];
140 if (aad->sel)
141 fref = fref * 3 / 4;
142
143 return fref / aad->arm;
144}
145
146static unsigned long get_rate_ahb(struct clk *clk)
147{
148 unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
149 struct arm_ahb_div *aad;
150 unsigned long fref = get_rate_arm();
151
152 aad = &clk_consumer[(pdr0 >> 16) & 0xf];
153
154 return fref / aad->ahb;
155}
156
157static unsigned long get_rate_ipg(struct clk *clk)
158{
159 return get_rate_ahb(NULL) >> 1;
160}
161
162static unsigned long get_rate_uart(struct clk *clk)
163{
164 unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
165 unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
166 unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
167
168 if (pdr3 & (1 << 14))
169 return get_rate_arm() / div;
170 else
171 return get_rate_ppll() / div;
172}
173
174static unsigned long get_rate_sdhc(struct clk *clk)
175{
176 unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
177 unsigned long div, rate;
178
179 if (pdr3 & (1 << 6))
180 rate = get_rate_arm();
181 else
182 rate = get_rate_ppll();
183
184 switch (clk->id) {
185 default:
186 case 0:
187 div = pdr3 & 0x3f;
188 break;
189 case 1:
190 div = (pdr3 >> 8) & 0x3f;
191 break;
192 case 2:
193 div = (pdr3 >> 16) & 0x3f;
194 break;
195 }
196
197 return rate / (div + 1);
198}
199
200static unsigned long get_rate_mshc(struct clk *clk)
201{
202 unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1);
203 unsigned long div1, div2, rate;
204
205 if (pdr1 & (1 << 7))
206 rate = get_rate_arm();
207 else
208 rate = get_rate_ppll();
209
210 div1 = (pdr1 >> 29) & 0x7;
211 div2 = (pdr1 >> 22) & 0x3f;
212
213 return rate / ((div1 + 1) * (div2 + 1));
214}
215
216static unsigned long get_rate_ssi(struct clk *clk)
217{
218 unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
219 unsigned long div1, div2, rate;
220
221 if (pdr2 & (1 << 6))
222 rate = get_rate_arm();
223 else
224 rate = get_rate_ppll();
225
226 switch (clk->id) {
227 default:
228 case 0:
229 div1 = pdr2 & 0x3f;
230 div2 = (pdr2 >> 24) & 0x7;
231 break;
232 case 1:
233 div1 = (pdr2 >> 8) & 0x3f;
234 div2 = (pdr2 >> 27) & 0x7;
235 break;
236 }
237
238 return rate / ((div1 + 1) * (div2 + 1));
239}
240
241static unsigned long get_rate_csi(struct clk *clk)
242{
243 unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
244 unsigned long rate;
245
246 if (pdr2 & (1 << 7))
247 rate = get_rate_arm();
248 else
249 rate = get_rate_ppll();
250
251 return rate / (((pdr2 >> 16) & 0x3f) + 1);
252}
253
254static unsigned long get_rate_otg(struct clk *clk)
255{
256 unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
257 unsigned long rate;
258
259 if (pdr4 & (1 << 9))
260 rate = get_rate_arm();
261 else
262 rate = get_rate_ppll();
263
264 return rate / (((pdr4 >> 22) & 0x3f) + 1);
265}
266
267static unsigned long get_rate_ipg_per(struct clk *clk)
268{
269 unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
270 unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
271 unsigned long div;
272
273 if (pdr0 & (1 << 26)) {
274 div = (pdr4 >> 16) & 0x3f;
275 return get_rate_arm() / (div + 1);
276 } else {
277 div = (pdr0 >> 12) & 0x7;
278 return get_rate_ahb(NULL) / (div + 1);
279 }
280}
281
282static unsigned long get_rate_hsp(struct clk *clk)
283{
284 unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03;
285 unsigned long fref = get_rate_mpll();
286
287 if (fref > 400 * 1000 * 1000) {
288 switch (hsp_podf) {
289 case 0:
290 return fref >> 2;
291 case 1:
292 return fref >> 3;
293 case 2:
294 return fref / 3;
295 }
296 } else {
297 switch (hsp_podf) {
298 case 0:
299 case 2:
300 return fref / 3;
301 case 1:
302 return fref / 6;
303 }
304 }
305
306 return 0;
307}
308
309static int clk_cgr_enable(struct clk *clk)
310{
311 u32 reg;
312
313 reg = __raw_readl(clk->enable_reg);
314 reg |= 3 << clk->enable_shift;
315 __raw_writel(reg, clk->enable_reg);
316
317 return 0;
318}
319
320static void clk_cgr_disable(struct clk *clk)
321{
322 u32 reg;
323
324 reg = __raw_readl(clk->enable_reg);
325 reg &= ~(3 << clk->enable_shift);
326 __raw_writel(reg, clk->enable_reg);
327}
328
329#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
330 static struct clk name = { \
331 .id = i, \
332 .enable_reg = er, \
333 .enable_shift = es, \
334 .get_rate = gr, \
335 .set_rate = sr, \
336 .enable = clk_cgr_enable, \
337 .disable = clk_cgr_disable, \
338 }
339
340DEFINE_CLOCK(asrc_clk, 0, MX35_CCM_CGR0, 0, NULL, NULL);
341DEFINE_CLOCK(pata_clk, 0, MX35_CCM_CGR0, 2, get_rate_ipg, NULL);
342/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */
343DEFINE_CLOCK(can1_clk, 0, MX35_CCM_CGR0, 6, get_rate_ipg, NULL);
344DEFINE_CLOCK(can2_clk, 1, MX35_CCM_CGR0, 8, get_rate_ipg, NULL);
345DEFINE_CLOCK(cspi1_clk, 0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL);
346DEFINE_CLOCK(cspi2_clk, 1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL);
347DEFINE_CLOCK(ect_clk, 0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL);
348DEFINE_CLOCK(edio_clk, 0, MX35_CCM_CGR0, 16, NULL, NULL);
349DEFINE_CLOCK(emi_clk, 0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL);
350DEFINE_CLOCK(epit1_clk, 0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL);
351DEFINE_CLOCK(epit2_clk, 1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL);
352DEFINE_CLOCK(esai_clk, 0, MX35_CCM_CGR0, 24, NULL, NULL);
353DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL);
354DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL);
355DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL);
356
357DEFINE_CLOCK(fec_clk, 0, MX35_CCM_CGR1, 0, get_rate_ipg, NULL);
358DEFINE_CLOCK(gpio1_clk, 0, MX35_CCM_CGR1, 2, NULL, NULL);
359DEFINE_CLOCK(gpio2_clk, 1, MX35_CCM_CGR1, 4, NULL, NULL);
360DEFINE_CLOCK(gpio3_clk, 2, MX35_CCM_CGR1, 6, NULL, NULL);
361DEFINE_CLOCK(gpt_clk, 0, MX35_CCM_CGR1, 8, get_rate_ipg, NULL);
362DEFINE_CLOCK(i2c1_clk, 0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL);
363DEFINE_CLOCK(i2c2_clk, 1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL);
364DEFINE_CLOCK(i2c3_clk, 2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL);
365DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL);
366DEFINE_CLOCK(ipu_clk, 0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL);
367DEFINE_CLOCK(kpp_clk, 0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL);
368DEFINE_CLOCK(mlb_clk, 0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL);
369DEFINE_CLOCK(mshc_clk, 0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL);
370DEFINE_CLOCK(owire_clk, 0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL);
371DEFINE_CLOCK(pwm_clk, 0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL);
372DEFINE_CLOCK(rngc_clk, 0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL);
373
374DEFINE_CLOCK(rtc_clk, 0, MX35_CCM_CGR2, 0, get_rate_ipg, NULL);
375DEFINE_CLOCK(rtic_clk, 0, MX35_CCM_CGR2, 2, get_rate_ahb, NULL);
376DEFINE_CLOCK(scc_clk, 0, MX35_CCM_CGR2, 4, get_rate_ipg, NULL);
377DEFINE_CLOCK(sdma_clk, 0, MX35_CCM_CGR2, 6, NULL, NULL);
378DEFINE_CLOCK(spba_clk, 0, MX35_CCM_CGR2, 8, get_rate_ipg, NULL);
379DEFINE_CLOCK(spdif_clk, 0, MX35_CCM_CGR2, 10, NULL, NULL);
380DEFINE_CLOCK(ssi1_clk, 0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL);
381DEFINE_CLOCK(ssi2_clk, 1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL);
382DEFINE_CLOCK(uart1_clk, 0, MX35_CCM_CGR2, 16, get_rate_uart, NULL);
383DEFINE_CLOCK(uart2_clk, 1, MX35_CCM_CGR2, 18, get_rate_uart, NULL);
384DEFINE_CLOCK(uart3_clk, 2, MX35_CCM_CGR2, 20, get_rate_uart, NULL);
385DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL);
386DEFINE_CLOCK(wdog_clk, 0, MX35_CCM_CGR2, 24, NULL, NULL);
387DEFINE_CLOCK(max_clk, 0, MX35_CCM_CGR2, 26, NULL, NULL);
388DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL);
389
390DEFINE_CLOCK(csi_clk, 0, MX35_CCM_CGR3, 0, get_rate_csi, NULL);
391DEFINE_CLOCK(iim_clk, 0, MX35_CCM_CGR3, 2, NULL, NULL);
392DEFINE_CLOCK(gpu2d_clk, 0, MX35_CCM_CGR3, 4, NULL, NULL);
393
394DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL);
395
396static int clk_dummy_enable(struct clk *clk)
397{
398 return 0;
399}
400
401static void clk_dummy_disable(struct clk *clk)
402{
403}
404
405static unsigned long get_rate_nfc(struct clk *clk)
406{
407 unsigned long div1;
408
409 div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1;
410
411 return get_rate_ahb(NULL) / div1;
412}
413
414/* NAND Controller: It seems it can't be disabled */
415static struct clk nfc_clk = {
416 .id = 0,
417 .enable_reg = 0,
418 .enable_shift = 0,
419 .get_rate = get_rate_nfc,
420 .set_rate = NULL, /* set_rate_nfc, */
421 .enable = clk_dummy_enable,
422 .disable = clk_dummy_disable
423};
424
425#define _REGISTER_CLOCK(d, n, c) \
426 { \
427 .dev_id = d, \
428 .con_id = n, \
429 .clk = &c, \
430 },
431
432static struct clk_lookup lookups[] = {
433 _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
434 _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
435 _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
436 _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
437 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
438 _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
439 _REGISTER_CLOCK(NULL, "ect", ect_clk)
440 _REGISTER_CLOCK(NULL, "edio", edio_clk)
441 _REGISTER_CLOCK(NULL, "emi", emi_clk)
442 _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
443 _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
444 _REGISTER_CLOCK(NULL, "esai", esai_clk)
445 _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk)
446 _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk)
447 _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk)
448 /* i.mx35 has the i.mx27 type fec */
449 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
450 _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
451 _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
452 _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
453 _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
454 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
455 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
456 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
457 _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
458 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
459 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
460 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
461 _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
462 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
463 _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
464 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
465 _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
466 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
467 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
468 _REGISTER_CLOCK(NULL, "scc", scc_clk)
469 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
470 _REGISTER_CLOCK(NULL, "spba", spba_clk)
471 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
472 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
473 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
474 /* i.mx35 has the i.mx21 type uart */
475 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
476 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
477 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
478 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
479 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
480 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
481 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
482 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
483 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
484 _REGISTER_CLOCK(NULL, "max", max_clk)
485 _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
486 _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
487 _REGISTER_CLOCK(NULL, "iim", iim_clk)
488 _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
489 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
490};
491
492int __init mx35_clocks_init()
493{
494 unsigned int cgr2 = 3 << 26;
495
496#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
497 cgr2 |= 3 << 16;
498#endif
499
500 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
501
502 /* Turn off all clocks except the ones we need to survive, namely:
503 * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
504 */
505 __raw_writel((3 << 18), MX35_CCM_CGR0);
506 __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
507 MX35_CCM_CGR1);
508 __raw_writel(cgr2, MX35_CCM_CGR2);
509 __raw_writel(0, MX35_CCM_CGR3);
510
511 clk_enable(&iim_clk);
512 imx_print_silicon_rev("i.MX35", mx35_revision());
513 clk_disable(&iim_clk);
514
515 /*
516 * Check if we came up in internal boot mode. If yes, we need some
517 * extra clocks turned on, otherwise the MX35 boot ROM code will
518 * hang after a watchdog reset.
519 */
520 if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) {
521 /* Additionally turn on UART1, SCC, and IIM clocks */
522 clk_enable(&iim_clk);
523 clk_enable(&uart1_clk);
524 clk_enable(&scc_clk);
525 }
526
527#ifdef CONFIG_MXC_USE_EPIT
528 epit_timer_init(&epit1_clk,
529 MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
530#else
531 mxc_timer_init(&gpt_clk,
532 MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
533#endif
534
535 return 0;
536}
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
deleted file mode 100644
index 111c328f542..00000000000
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ /dev/null
@@ -1,2111 +0,0 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/types.h>
15#include <linux/clk.h>
16#include <linux/clkdev.h>
17#include <linux/io.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_irq.h>
21#include <asm/div64.h>
22#include <asm/mach/map.h>
23#include <mach/clock.h>
24#include <mach/common.h>
25#include <mach/hardware.h>
26
27#define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR)
28#define PLL1_SYS (PLL_BASE + 0x000)
29#define PLL2_BUS (PLL_BASE + 0x030)
30#define PLL3_USB_OTG (PLL_BASE + 0x010)
31#define PLL4_AUDIO (PLL_BASE + 0x070)
32#define PLL5_VIDEO (PLL_BASE + 0x0a0)
33#define PLL6_MLB (PLL_BASE + 0x0d0)
34#define PLL7_USB_HOST (PLL_BASE + 0x020)
35#define PLL8_ENET (PLL_BASE + 0x0e0)
36#define PFD_480 (PLL_BASE + 0x0f0)
37#define PFD_528 (PLL_BASE + 0x100)
38#define PLL_NUM_OFFSET 0x010
39#define PLL_DENOM_OFFSET 0x020
40
41#define PFD0 7
42#define PFD1 15
43#define PFD2 23
44#define PFD3 31
45#define PFD_FRAC_MASK 0x3f
46
47#define BM_PLL_BYPASS (0x1 << 16)
48#define BM_PLL_ENABLE (0x1 << 13)
49#define BM_PLL_POWER_DOWN (0x1 << 12)
50#define BM_PLL_LOCK (0x1 << 31)
51#define BP_PLL_SYS_DIV_SELECT 0
52#define BM_PLL_SYS_DIV_SELECT (0x7f << 0)
53#define BP_PLL_BUS_DIV_SELECT 0
54#define BM_PLL_BUS_DIV_SELECT (0x1 << 0)
55#define BP_PLL_USB_DIV_SELECT 0
56#define BM_PLL_USB_DIV_SELECT (0x3 << 0)
57#define BP_PLL_AV_DIV_SELECT 0
58#define BM_PLL_AV_DIV_SELECT (0x7f << 0)
59#define BP_PLL_ENET_DIV_SELECT 0
60#define BM_PLL_ENET_DIV_SELECT (0x3 << 0)
61#define BM_PLL_ENET_EN_PCIE (0x1 << 19)
62#define BM_PLL_ENET_EN_SATA (0x1 << 20)
63
64#define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR)
65#define CCR (CCM_BASE + 0x00)
66#define CCDR (CCM_BASE + 0x04)
67#define CSR (CCM_BASE + 0x08)
68#define CCSR (CCM_BASE + 0x0c)
69#define CACRR (CCM_BASE + 0x10)
70#define CBCDR (CCM_BASE + 0x14)
71#define CBCMR (CCM_BASE + 0x18)
72#define CSCMR1 (CCM_BASE + 0x1c)
73#define CSCMR2 (CCM_BASE + 0x20)
74#define CSCDR1 (CCM_BASE + 0x24)
75#define CS1CDR (CCM_BASE + 0x28)
76#define CS2CDR (CCM_BASE + 0x2c)
77#define CDCDR (CCM_BASE + 0x30)
78#define CHSCCDR (CCM_BASE + 0x34)
79#define CSCDR2 (CCM_BASE + 0x38)
80#define CSCDR3 (CCM_BASE + 0x3c)
81#define CSCDR4 (CCM_BASE + 0x40)
82#define CWDR (CCM_BASE + 0x44)
83#define CDHIPR (CCM_BASE + 0x48)
84#define CDCR (CCM_BASE + 0x4c)
85#define CTOR (CCM_BASE + 0x50)
86#define CLPCR (CCM_BASE + 0x54)
87#define CISR (CCM_BASE + 0x58)
88#define CIMR (CCM_BASE + 0x5c)
89#define CCOSR (CCM_BASE + 0x60)
90#define CGPR (CCM_BASE + 0x64)
91#define CCGR0 (CCM_BASE + 0x68)
92#define CCGR1 (CCM_BASE + 0x6c)
93#define CCGR2 (CCM_BASE + 0x70)
94#define CCGR3 (CCM_BASE + 0x74)
95#define CCGR4 (CCM_BASE + 0x78)
96#define CCGR5 (CCM_BASE + 0x7c)
97#define CCGR6 (CCM_BASE + 0x80)
98#define CCGR7 (CCM_BASE + 0x84)
99#define CMEOR (CCM_BASE + 0x88)
100
101#define CG0 0
102#define CG1 2
103#define CG2 4
104#define CG3 6
105#define CG4 8
106#define CG5 10
107#define CG6 12
108#define CG7 14
109#define CG8 16
110#define CG9 18
111#define CG10 20
112#define CG11 22
113#define CG12 24
114#define CG13 26
115#define CG14 28
116#define CG15 30
117
118#define BM_CCSR_PLL1_SW_SEL (0x1 << 2)
119#define BM_CCSR_STEP_SEL (0x1 << 8)
120
121#define BP_CACRR_ARM_PODF 0
122#define BM_CACRR_ARM_PODF (0x7 << 0)
123
124#define BP_CBCDR_PERIPH2_CLK2_PODF 0
125#define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0)
126#define BP_CBCDR_MMDC_CH1_AXI_PODF 3
127#define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3)
128#define BP_CBCDR_AXI_SEL 6
129#define BM_CBCDR_AXI_SEL (0x3 << 6)
130#define BP_CBCDR_IPG_PODF 8
131#define BM_CBCDR_IPG_PODF (0x3 << 8)
132#define BP_CBCDR_AHB_PODF 10
133#define BM_CBCDR_AHB_PODF (0x7 << 10)
134#define BP_CBCDR_AXI_PODF 16
135#define BM_CBCDR_AXI_PODF (0x7 << 16)
136#define BP_CBCDR_MMDC_CH0_AXI_PODF 19
137#define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19)
138#define BP_CBCDR_PERIPH_CLK_SEL 25
139#define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
140#define BP_CBCDR_PERIPH2_CLK_SEL 26
141#define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26)
142#define BP_CBCDR_PERIPH_CLK2_PODF 27
143#define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27)
144
145#define BP_CBCMR_GPU2D_AXI_SEL 0
146#define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0)
147#define BP_CBCMR_GPU3D_AXI_SEL 1
148#define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1)
149#define BP_CBCMR_GPU3D_CORE_SEL 4
150#define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4)
151#define BP_CBCMR_GPU3D_SHADER_SEL 8
152#define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8)
153#define BP_CBCMR_PCIE_AXI_SEL 10
154#define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10)
155#define BP_CBCMR_VDO_AXI_SEL 11
156#define BM_CBCMR_VDO_AXI_SEL (0x1 << 11)
157#define BP_CBCMR_PERIPH_CLK2_SEL 12
158#define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12)
159#define BP_CBCMR_VPU_AXI_SEL 14
160#define BM_CBCMR_VPU_AXI_SEL (0x3 << 14)
161#define BP_CBCMR_GPU2D_CORE_SEL 16
162#define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16)
163#define BP_CBCMR_PRE_PERIPH_CLK_SEL 18
164#define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18)
165#define BP_CBCMR_PERIPH2_CLK2_SEL 20
166#define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20)
167#define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21
168#define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21)
169#define BP_CBCMR_GPU2D_CORE_PODF 23
170#define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23)
171#define BP_CBCMR_GPU3D_CORE_PODF 26
172#define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26)
173#define BP_CBCMR_GPU3D_SHADER_PODF 29
174#define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29)
175
176#define BP_CSCMR1_PERCLK_PODF 0
177#define BM_CSCMR1_PERCLK_PODF (0x3f << 0)
178#define BP_CSCMR1_SSI1_SEL 10
179#define BM_CSCMR1_SSI1_SEL (0x3 << 10)
180#define BP_CSCMR1_SSI2_SEL 12
181#define BM_CSCMR1_SSI2_SEL (0x3 << 12)
182#define BP_CSCMR1_SSI3_SEL 14
183#define BM_CSCMR1_SSI3_SEL (0x3 << 14)
184#define BP_CSCMR1_USDHC1_SEL 16
185#define BM_CSCMR1_USDHC1_SEL (0x1 << 16)
186#define BP_CSCMR1_USDHC2_SEL 17
187#define BM_CSCMR1_USDHC2_SEL (0x1 << 17)
188#define BP_CSCMR1_USDHC3_SEL 18
189#define BM_CSCMR1_USDHC3_SEL (0x1 << 18)
190#define BP_CSCMR1_USDHC4_SEL 19
191#define BM_CSCMR1_USDHC4_SEL (0x1 << 19)
192#define BP_CSCMR1_EMI_PODF 20
193#define BM_CSCMR1_EMI_PODF (0x7 << 20)
194#define BP_CSCMR1_EMI_SLOW_PODF 23
195#define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23)
196#define BP_CSCMR1_EMI_SEL 27
197#define BM_CSCMR1_EMI_SEL (0x3 << 27)
198#define BP_CSCMR1_EMI_SLOW_SEL 29
199#define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29)
200
201#define BP_CSCMR2_CAN_PODF 2
202#define BM_CSCMR2_CAN_PODF (0x3f << 2)
203#define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10)
204#define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11)
205#define BP_CSCMR2_ESAI_SEL 19
206#define BM_CSCMR2_ESAI_SEL (0x3 << 19)
207
208#define BP_CSCDR1_UART_PODF 0
209#define BM_CSCDR1_UART_PODF (0x3f << 0)
210#define BP_CSCDR1_USDHC1_PODF 11
211#define BM_CSCDR1_USDHC1_PODF (0x7 << 11)
212#define BP_CSCDR1_USDHC2_PODF 16
213#define BM_CSCDR1_USDHC2_PODF (0x7 << 16)
214#define BP_CSCDR1_USDHC3_PODF 19
215#define BM_CSCDR1_USDHC3_PODF (0x7 << 19)
216#define BP_CSCDR1_USDHC4_PODF 22
217#define BM_CSCDR1_USDHC4_PODF (0x7 << 22)
218#define BP_CSCDR1_VPU_AXI_PODF 25
219#define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25)
220
221#define BP_CS1CDR_SSI1_PODF 0
222#define BM_CS1CDR_SSI1_PODF (0x3f << 0)
223#define BP_CS1CDR_SSI1_PRED 6
224#define BM_CS1CDR_SSI1_PRED (0x7 << 6)
225#define BP_CS1CDR_ESAI_PRED 9
226#define BM_CS1CDR_ESAI_PRED (0x7 << 9)
227#define BP_CS1CDR_SSI3_PODF 16
228#define BM_CS1CDR_SSI3_PODF (0x3f << 16)
229#define BP_CS1CDR_SSI3_PRED 22
230#define BM_CS1CDR_SSI3_PRED (0x7 << 22)
231#define BP_CS1CDR_ESAI_PODF 25
232#define BM_CS1CDR_ESAI_PODF (0x7 << 25)
233
234#define BP_CS2CDR_SSI2_PODF 0
235#define BM_CS2CDR_SSI2_PODF (0x3f << 0)
236#define BP_CS2CDR_SSI2_PRED 6
237#define BM_CS2CDR_SSI2_PRED (0x7 << 6)
238#define BP_CS2CDR_LDB_DI0_SEL 9
239#define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9)
240#define BP_CS2CDR_LDB_DI1_SEL 12
241#define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12)
242#define BP_CS2CDR_ENFC_SEL 16
243#define BM_CS2CDR_ENFC_SEL (0x3 << 16)
244#define BP_CS2CDR_ENFC_PRED 18
245#define BM_CS2CDR_ENFC_PRED (0x7 << 18)
246#define BP_CS2CDR_ENFC_PODF 21
247#define BM_CS2CDR_ENFC_PODF (0x3f << 21)
248
249#define BP_CDCDR_ASRC_SERIAL_SEL 7
250#define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7)
251#define BP_CDCDR_ASRC_SERIAL_PODF 9
252#define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9)
253#define BP_CDCDR_ASRC_SERIAL_PRED 12
254#define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12)
255#define BP_CDCDR_SPDIF_SEL 20
256#define BM_CDCDR_SPDIF_SEL (0x3 << 20)
257#define BP_CDCDR_SPDIF_PODF 22
258#define BM_CDCDR_SPDIF_PODF (0x7 << 22)
259#define BP_CDCDR_SPDIF_PRED 25
260#define BM_CDCDR_SPDIF_PRED (0x7 << 25)
261#define BP_CDCDR_HSI_TX_PODF 29
262#define BM_CDCDR_HSI_TX_PODF (0x7 << 29)
263#define BP_CDCDR_HSI_TX_SEL 28
264#define BM_CDCDR_HSI_TX_SEL (0x1 << 28)
265
266#define BP_CHSCCDR_IPU1_DI0_SEL 0
267#define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0)
268#define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3
269#define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3)
270#define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6
271#define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6)
272#define BP_CHSCCDR_IPU1_DI1_SEL 9
273#define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9)
274#define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12
275#define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12)
276#define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15
277#define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15)
278
279#define BP_CSCDR2_IPU2_DI0_SEL 0
280#define BM_CSCDR2_IPU2_DI0_SEL (0x7)
281#define BP_CSCDR2_IPU2_DI0_PRE_PODF 3
282#define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3)
283#define BP_CSCDR2_IPU2_DI0_PRE_SEL 6
284#define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6)
285#define BP_CSCDR2_IPU2_DI1_SEL 9
286#define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9)
287#define BP_CSCDR2_IPU2_DI1_PRE_PODF 12
288#define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12)
289#define BP_CSCDR2_IPU2_DI1_PRE_SEL 15
290#define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15)
291#define BP_CSCDR2_ECSPI_CLK_PODF 19
292#define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19)
293
294#define BP_CSCDR3_IPU1_HSP_SEL 9
295#define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9)
296#define BP_CSCDR3_IPU1_HSP_PODF 11
297#define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11)
298#define BP_CSCDR3_IPU2_HSP_SEL 14
299#define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14)
300#define BP_CSCDR3_IPU2_HSP_PODF 16
301#define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16)
302
303#define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0)
304#define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1)
305#define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2)
306#define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3)
307#define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4)
308#define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5)
309#define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16)
310
311#define BP_CLPCR_LPM 0
312#define BM_CLPCR_LPM (0x3 << 0)
313#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
314#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
315#define BM_CLPCR_SBYOS (0x1 << 6)
316#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
317#define BM_CLPCR_VSTBY (0x1 << 8)
318#define BP_CLPCR_STBY_COUNT 9
319#define BM_CLPCR_STBY_COUNT (0x3 << 9)
320#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
321#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
322#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
323#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
324#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
325#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
326#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
327#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
328#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
329#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
330#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
331
332#define BP_CCOSR_CKO1_EN 7
333#define BP_CCOSR_CKO1_PODF 4
334#define BM_CCOSR_CKO1_PODF (0x7 << 4)
335#define BP_CCOSR_CKO1_SEL 0
336#define BM_CCOSR_CKO1_SEL (0xf << 0)
337
338#define FREQ_480M 480000000
339#define FREQ_528M 528000000
340#define FREQ_594M 594000000
341#define FREQ_650M 650000000
342#define FREQ_1300M 1300000000
343
344static struct clk pll1_sys;
345static struct clk pll2_bus;
346static struct clk pll3_usb_otg;
347static struct clk pll4_audio;
348static struct clk pll5_video;
349static struct clk pll6_mlb;
350static struct clk pll7_usb_host;
351static struct clk pll8_enet;
352static struct clk apbh_dma_clk;
353static struct clk arm_clk;
354static struct clk ipg_clk;
355static struct clk ahb_clk;
356static struct clk axi_clk;
357static struct clk mmdc_ch0_axi_clk;
358static struct clk mmdc_ch1_axi_clk;
359static struct clk periph_clk;
360static struct clk periph_pre_clk;
361static struct clk periph_clk2_clk;
362static struct clk periph2_clk;
363static struct clk periph2_pre_clk;
364static struct clk periph2_clk2_clk;
365static struct clk gpu2d_core_clk;
366static struct clk gpu3d_core_clk;
367static struct clk gpu3d_shader_clk;
368static struct clk ipg_perclk;
369static struct clk emi_clk;
370static struct clk emi_slow_clk;
371static struct clk can1_clk;
372static struct clk uart_clk;
373static struct clk usdhc1_clk;
374static struct clk usdhc2_clk;
375static struct clk usdhc3_clk;
376static struct clk usdhc4_clk;
377static struct clk vpu_clk;
378static struct clk hsi_tx_clk;
379static struct clk ipu1_di0_pre_clk;
380static struct clk ipu1_di1_pre_clk;
381static struct clk ipu2_di0_pre_clk;
382static struct clk ipu2_di1_pre_clk;
383static struct clk ipu1_clk;
384static struct clk ipu2_clk;
385static struct clk ssi1_clk;
386static struct clk ssi3_clk;
387static struct clk esai_clk;
388static struct clk ssi2_clk;
389static struct clk spdif_clk;
390static struct clk asrc_serial_clk;
391static struct clk gpu2d_axi_clk;
392static struct clk gpu3d_axi_clk;
393static struct clk pcie_clk;
394static struct clk vdo_axi_clk;
395static struct clk ldb_di0_clk;
396static struct clk ldb_di1_clk;
397static struct clk ipu1_di0_clk;
398static struct clk ipu1_di1_clk;
399static struct clk ipu2_di0_clk;
400static struct clk ipu2_di1_clk;
401static struct clk enfc_clk;
402static struct clk cko1_clk;
403static struct clk dummy_clk = {};
404
405static unsigned long external_high_reference;
406static unsigned long external_low_reference;
407static unsigned long oscillator_reference;
408
409static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
410{
411 return oscillator_reference;
412}
413
414static unsigned long get_high_reference_clock_rate(struct clk *clk)
415{
416 return external_high_reference;
417}
418
419static unsigned long get_low_reference_clock_rate(struct clk *clk)
420{
421 return external_low_reference;
422}
423
424static struct clk ckil_clk = {
425 .get_rate = get_low_reference_clock_rate,
426};
427
428static struct clk ckih_clk = {
429 .get_rate = get_high_reference_clock_rate,
430};
431
432static struct clk osc_clk = {
433 .get_rate = get_oscillator_reference_clock_rate,
434};
435
436static inline void __iomem *pll_get_reg_addr(struct clk *pll)
437{
438 if (pll == &pll1_sys)
439 return PLL1_SYS;
440 else if (pll == &pll2_bus)
441 return PLL2_BUS;
442 else if (pll == &pll3_usb_otg)
443 return PLL3_USB_OTG;
444 else if (pll == &pll4_audio)
445 return PLL4_AUDIO;
446 else if (pll == &pll5_video)
447 return PLL5_VIDEO;
448 else if (pll == &pll6_mlb)
449 return PLL6_MLB;
450 else if (pll == &pll7_usb_host)
451 return PLL7_USB_HOST;
452 else if (pll == &pll8_enet)
453 return PLL8_ENET;
454 else
455 BUG();
456
457 return NULL;
458}
459
460static int pll_enable(struct clk *clk)
461{
462 int timeout = 0x100000;
463 void __iomem *reg;
464 u32 val;
465
466 reg = pll_get_reg_addr(clk);
467 val = readl_relaxed(reg);
468 val &= ~BM_PLL_BYPASS;
469 val &= ~BM_PLL_POWER_DOWN;
470 /* 480MHz PLLs have the opposite definition for power bit */
471 if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
472 val |= BM_PLL_POWER_DOWN;
473 writel_relaxed(val, reg);
474
475 /* Wait for PLL to lock */
476 while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout)
477 cpu_relax();
478
479 if (unlikely(!timeout))
480 return -EBUSY;
481
482 /* Enable the PLL output now */
483 val = readl_relaxed(reg);
484 val |= BM_PLL_ENABLE;
485 writel_relaxed(val, reg);
486
487 return 0;
488}
489
490static void pll_disable(struct clk *clk)
491{
492 void __iomem *reg;
493 u32 val;
494
495 reg = pll_get_reg_addr(clk);
496 val = readl_relaxed(reg);
497 val &= ~BM_PLL_ENABLE;
498 val |= BM_PLL_BYPASS;
499 val |= BM_PLL_POWER_DOWN;
500 if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
501 val &= ~BM_PLL_POWER_DOWN;
502 writel_relaxed(val, reg);
503}
504
505static unsigned long pll1_sys_get_rate(struct clk *clk)
506{
507 u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >>
508 BP_PLL_SYS_DIV_SELECT;
509
510 return clk_get_rate(clk->parent) * div / 2;
511}
512
513static int pll1_sys_set_rate(struct clk *clk, unsigned long rate)
514{
515 u32 val, div;
516
517 if (rate < FREQ_650M || rate > FREQ_1300M)
518 return -EINVAL;
519
520 div = rate * 2 / clk_get_rate(clk->parent);
521 val = readl_relaxed(PLL1_SYS);
522 val &= ~BM_PLL_SYS_DIV_SELECT;
523 val |= div << BP_PLL_SYS_DIV_SELECT;
524 writel_relaxed(val, PLL1_SYS);
525
526 return 0;
527}
528
529static unsigned long pll8_enet_get_rate(struct clk *clk)
530{
531 u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >>
532 BP_PLL_ENET_DIV_SELECT;
533
534 switch (div) {
535 case 0:
536 return 25000000;
537 case 1:
538 return 50000000;
539 case 2:
540 return 100000000;
541 case 3:
542 return 125000000;
543 }
544
545 return 0;
546}
547
548static int pll8_enet_set_rate(struct clk *clk, unsigned long rate)
549{
550 u32 val, div;
551
552 switch (rate) {
553 case 25000000:
554 div = 0;
555 break;
556 case 50000000:
557 div = 1;
558 break;
559 case 100000000:
560 div = 2;
561 break;
562 case 125000000:
563 div = 3;
564 break;
565 default:
566 return -EINVAL;
567 }
568
569 val = readl_relaxed(PLL8_ENET);
570 val &= ~BM_PLL_ENET_DIV_SELECT;
571 val |= div << BP_PLL_ENET_DIV_SELECT;
572 writel_relaxed(val, PLL8_ENET);
573
574 return 0;
575}
576
577static unsigned long pll_av_get_rate(struct clk *clk)
578{
579 void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
580 unsigned long parent_rate = clk_get_rate(clk->parent);
581 u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET);
582 u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET);
583 u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >>
584 BP_PLL_AV_DIV_SELECT;
585
586 return (parent_rate * div) + ((parent_rate / mfd) * mfn);
587}
588
589static int pll_av_set_rate(struct clk *clk, unsigned long rate)
590{
591 void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
592 unsigned int parent_rate = clk_get_rate(clk->parent);
593 u32 val, div;
594 u32 mfn, mfd = 1000000;
595 s64 temp64;
596
597 if (rate < FREQ_650M || rate > FREQ_1300M)
598 return -EINVAL;
599
600 div = rate / parent_rate;
601 temp64 = (u64) (rate - div * parent_rate);
602 temp64 *= mfd;
603 do_div(temp64, parent_rate);
604 mfn = temp64;
605
606 val = readl_relaxed(reg);
607 val &= ~BM_PLL_AV_DIV_SELECT;
608 val |= div << BP_PLL_AV_DIV_SELECT;
609 writel_relaxed(val, reg);
610 writel_relaxed(mfn, reg + PLL_NUM_OFFSET);
611 writel_relaxed(mfd, reg + PLL_DENOM_OFFSET);
612
613 return 0;
614}
615
616static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm)
617{
618 void __iomem *reg;
619
620 if (clk == &pll2_bus) {
621 reg = PLL2_BUS;
622 *bp = BP_PLL_BUS_DIV_SELECT;
623 *bm = BM_PLL_BUS_DIV_SELECT;
624 } else if (clk == &pll3_usb_otg) {
625 reg = PLL3_USB_OTG;
626 *bp = BP_PLL_USB_DIV_SELECT;
627 *bm = BM_PLL_USB_DIV_SELECT;
628 } else if (clk == &pll7_usb_host) {
629 reg = PLL7_USB_HOST;
630 *bp = BP_PLL_USB_DIV_SELECT;
631 *bm = BM_PLL_USB_DIV_SELECT;
632 } else {
633 BUG();
634 }
635
636 return reg;
637}
638
639static unsigned long pll_get_rate(struct clk *clk)
640{
641 void __iomem *reg;
642 u32 div, bp, bm;
643
644 reg = pll_get_div_reg_bit(clk, &bp, &bm);
645 div = (readl_relaxed(reg) & bm) >> bp;
646
647 return (div == 1) ? clk_get_rate(clk->parent) * 22 :
648 clk_get_rate(clk->parent) * 20;
649}
650
651static int pll_set_rate(struct clk *clk, unsigned long rate)
652{
653 void __iomem *reg;
654 u32 val, div, bp, bm;
655
656 if (rate == FREQ_528M)
657 div = 1;
658 else if (rate == FREQ_480M)
659 div = 0;
660 else
661 return -EINVAL;
662
663 reg = pll_get_div_reg_bit(clk, &bp, &bm);
664 val = readl_relaxed(reg);
665 val &= ~bm;
666 val |= div << bp;
667 writel_relaxed(val, reg);
668
669 return 0;
670}
671
672#define pll2_bus_get_rate pll_get_rate
673#define pll2_bus_set_rate pll_set_rate
674#define pll3_usb_otg_get_rate pll_get_rate
675#define pll3_usb_otg_set_rate pll_set_rate
676#define pll7_usb_host_get_rate pll_get_rate
677#define pll7_usb_host_set_rate pll_set_rate
678#define pll4_audio_get_rate pll_av_get_rate
679#define pll4_audio_set_rate pll_av_set_rate
680#define pll5_video_get_rate pll_av_get_rate
681#define pll5_video_set_rate pll_av_set_rate
682#define pll6_mlb_get_rate NULL
683#define pll6_mlb_set_rate NULL
684
685#define DEF_PLL(name) \
686 static struct clk name = { \
687 .enable = pll_enable, \
688 .disable = pll_disable, \
689 .get_rate = name##_get_rate, \
690 .set_rate = name##_set_rate, \
691 .parent = &osc_clk, \
692 }
693
694DEF_PLL(pll1_sys);
695DEF_PLL(pll2_bus);
696DEF_PLL(pll3_usb_otg);
697DEF_PLL(pll4_audio);
698DEF_PLL(pll5_video);
699DEF_PLL(pll6_mlb);
700DEF_PLL(pll7_usb_host);
701DEF_PLL(pll8_enet);
702
703static unsigned long pfd_get_rate(struct clk *clk)
704{
705 u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
706 u32 frac, bp_frac;
707
708 if (apbh_dma_clk.usecount == 0)
709 apbh_dma_clk.enable(&apbh_dma_clk);
710
711 bp_frac = clk->enable_shift - 7;
712 frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK;
713 do_div(tmp, frac);
714
715 return tmp;
716}
717
718static int pfd_set_rate(struct clk *clk, unsigned long rate)
719{
720 u32 val, frac, bp_frac;
721 u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
722
723 if (apbh_dma_clk.usecount == 0)
724 apbh_dma_clk.enable(&apbh_dma_clk);
725
726 /*
727 * Round up the divider so that we don't set a rate
728 * higher than what is requested
729 */
730 tmp += rate / 2;
731 do_div(tmp, rate);
732 frac = tmp;
733 frac = (frac < 12) ? 12 : frac;
734 frac = (frac > 35) ? 35 : frac;
735
736 /*
737 * The frac field always starts from 7 bits lower
738 * position of enable bit
739 */
740 bp_frac = clk->enable_shift - 7;
741 val = readl_relaxed(clk->enable_reg);
742 val &= ~(PFD_FRAC_MASK << bp_frac);
743 val |= frac << bp_frac;
744 writel_relaxed(val, clk->enable_reg);
745
746 tmp = (u64) clk_get_rate(clk->parent) * 18;
747 do_div(tmp, frac);
748
749 if (apbh_dma_clk.usecount == 0)
750 apbh_dma_clk.disable(&apbh_dma_clk);
751
752 return 0;
753}
754
755static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
756{
757 u32 frac;
758 u64 tmp;
759
760 tmp = (u64) clk_get_rate(clk->parent) * 18;
761 tmp += rate / 2;
762 do_div(tmp, rate);
763 frac = tmp;
764 frac = (frac < 12) ? 12 : frac;
765 frac = (frac > 35) ? 35 : frac;
766 tmp = (u64) clk_get_rate(clk->parent) * 18;
767 do_div(tmp, frac);
768
769 return tmp;
770}
771
772static int pfd_enable(struct clk *clk)
773{
774 u32 val;
775
776 if (apbh_dma_clk.usecount == 0)
777 apbh_dma_clk.enable(&apbh_dma_clk);
778
779 val = readl_relaxed(clk->enable_reg);
780 val &= ~(1 << clk->enable_shift);
781 writel_relaxed(val, clk->enable_reg);
782
783 if (apbh_dma_clk.usecount == 0)
784 apbh_dma_clk.disable(&apbh_dma_clk);
785
786 return 0;
787}
788
789static void pfd_disable(struct clk *clk)
790{
791 u32 val;
792
793 if (apbh_dma_clk.usecount == 0)
794 apbh_dma_clk.enable(&apbh_dma_clk);
795
796 val = readl_relaxed(clk->enable_reg);
797 val |= 1 << clk->enable_shift;
798 writel_relaxed(val, clk->enable_reg);
799
800 if (apbh_dma_clk.usecount == 0)
801 apbh_dma_clk.disable(&apbh_dma_clk);
802}
803
804#define DEF_PFD(name, er, es, p) \
805 static struct clk name = { \
806 .enable_reg = er, \
807 .enable_shift = es, \
808 .enable = pfd_enable, \
809 .disable = pfd_disable, \
810 .get_rate = pfd_get_rate, \
811 .set_rate = pfd_set_rate, \
812 .round_rate = pfd_round_rate, \
813 .parent = p, \
814 }
815
816DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus);
817DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus);
818DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus);
819DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg);
820DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
821DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
822DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
823
824static unsigned long twd_clk_get_rate(struct clk *clk)
825{
826 return clk_get_rate(clk->parent) / 2;
827}
828
829static struct clk twd_clk = {
830 .parent = &arm_clk,
831 .get_rate = twd_clk_get_rate,
832};
833
834static unsigned long pll2_200m_get_rate(struct clk *clk)
835{
836 return clk_get_rate(clk->parent) / 2;
837}
838
839static struct clk pll2_200m = {
840 .parent = &pll2_pfd_400m,
841 .get_rate = pll2_200m_get_rate,
842};
843
844static unsigned long pll3_120m_get_rate(struct clk *clk)
845{
846 return clk_get_rate(clk->parent) / 4;
847}
848
849static struct clk pll3_120m = {
850 .parent = &pll3_usb_otg,
851 .get_rate = pll3_120m_get_rate,
852};
853
854static unsigned long pll3_80m_get_rate(struct clk *clk)
855{
856 return clk_get_rate(clk->parent) / 6;
857}
858
859static struct clk pll3_80m = {
860 .parent = &pll3_usb_otg,
861 .get_rate = pll3_80m_get_rate,
862};
863
864static unsigned long pll3_60m_get_rate(struct clk *clk)
865{
866 return clk_get_rate(clk->parent) / 8;
867}
868
869static struct clk pll3_60m = {
870 .parent = &pll3_usb_otg,
871 .get_rate = pll3_60m_get_rate,
872};
873
874static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent)
875{
876 u32 val = readl_relaxed(CCSR);
877
878 if (parent == &pll1_sys) {
879 val &= ~BM_CCSR_PLL1_SW_SEL;
880 val &= ~BM_CCSR_STEP_SEL;
881 } else if (parent == &osc_clk) {
882 val |= BM_CCSR_PLL1_SW_SEL;
883 val &= ~BM_CCSR_STEP_SEL;
884 } else if (parent == &pll2_pfd_400m) {
885 val |= BM_CCSR_PLL1_SW_SEL;
886 val |= BM_CCSR_STEP_SEL;
887 } else {
888 return -EINVAL;
889 }
890
891 writel_relaxed(val, CCSR);
892
893 return 0;
894}
895
896static struct clk pll1_sw_clk = {
897 .parent = &pll1_sys,
898 .set_parent = pll1_sw_clk_set_parent,
899};
900
901static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf)
902{
903 u32 min_pred, temp_pred, old_err, err;
904
905 if (div >= 512) {
906 *pred = 8;
907 *podf = 64;
908 } else if (div >= 8) {
909 min_pred = (div - 1) / 64 + 1;
910 old_err = 8;
911 for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) {
912 err = div % temp_pred;
913 if (err == 0) {
914 *pred = temp_pred;
915 break;
916 }
917 err = temp_pred - err;
918 if (err < old_err) {
919 old_err = err;
920 *pred = temp_pred;
921 }
922 }
923 *podf = (div + *pred - 1) / *pred;
924 } else if (div < 8) {
925 *pred = div;
926 *podf = 1;
927 }
928}
929
930static int _clk_enable(struct clk *clk)
931{
932 u32 reg;
933 reg = readl_relaxed(clk->enable_reg);
934 reg |= 0x3 << clk->enable_shift;
935 writel_relaxed(reg, clk->enable_reg);
936
937 return 0;
938}
939
940static void _clk_disable(struct clk *clk)
941{
942 u32 reg;
943 reg = readl_relaxed(clk->enable_reg);
944 reg &= ~(0x3 << clk->enable_shift);
945 writel_relaxed(reg, clk->enable_reg);
946}
947
948static int _clk_enable_1b(struct clk *clk)
949{
950 u32 reg;
951 reg = readl_relaxed(clk->enable_reg);
952 reg |= 0x1 << clk->enable_shift;
953 writel_relaxed(reg, clk->enable_reg);
954
955 return 0;
956}
957
958static void _clk_disable_1b(struct clk *clk)
959{
960 u32 reg;
961 reg = readl_relaxed(clk->enable_reg);
962 reg &= ~(0x1 << clk->enable_shift);
963 writel_relaxed(reg, clk->enable_reg);
964}
965
966struct divider {
967 struct clk *clk;
968 void __iomem *reg;
969 u32 bp_pred;
970 u32 bm_pred;
971 u32 bp_podf;
972 u32 bm_podf;
973};
974
975#define DEF_CLK_DIV1(d, c, r, b) \
976 static struct divider d = { \
977 .clk = c, \
978 .reg = r, \
979 .bp_podf = BP_##r##_##b##_PODF, \
980 .bm_podf = BM_##r##_##b##_PODF, \
981 }
982
983DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM);
984DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG);
985DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB);
986DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI);
987DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI);
988DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI);
989DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2);
990DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2);
991DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE);
992DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE);
993DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER);
994DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK);
995DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI);
996DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW);
997DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN);
998DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART);
999DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1);
1000DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2);
1001DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3);
1002DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4);
1003DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI);
1004DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX);
1005DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE);
1006DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE);
1007DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE);
1008DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE);
1009DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP);
1010DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP);
1011DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1);
1012
1013#define DEF_CLK_DIV2(d, c, r, b) \
1014 static struct divider d = { \
1015 .clk = c, \
1016 .reg = r, \
1017 .bp_pred = BP_##r##_##b##_PRED, \
1018 .bm_pred = BM_##r##_##b##_PRED, \
1019 .bp_podf = BP_##r##_##b##_PODF, \
1020 .bm_podf = BM_##r##_##b##_PODF, \
1021 }
1022
1023DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1);
1024DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3);
1025DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI);
1026DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2);
1027DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC);
1028DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF);
1029DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL);
1030
1031static struct divider *dividers[] = {
1032 &arm_div,
1033 &ipg_div,
1034 &ahb_div,
1035 &axi_div,
1036 &mmdc_ch0_axi_div,
1037 &mmdc_ch1_axi_div,
1038 &periph_clk2_div,
1039 &periph2_clk2_div,
1040 &gpu2d_core_div,
1041 &gpu3d_core_div,
1042 &gpu3d_shader_div,
1043 &ipg_perclk_div,
1044 &emi_div,
1045 &emi_slow_div,
1046 &can_div,
1047 &uart_div,
1048 &usdhc1_div,
1049 &usdhc2_div,
1050 &usdhc3_div,
1051 &usdhc4_div,
1052 &vpu_div,
1053 &hsi_tx_div,
1054 &ipu1_di0_pre_div,
1055 &ipu1_di1_pre_div,
1056 &ipu2_di0_pre_div,
1057 &ipu2_di1_pre_div,
1058 &ipu1_div,
1059 &ipu2_div,
1060 &ssi1_div,
1061 &ssi3_div,
1062 &esai_div,
1063 &ssi2_div,
1064 &enfc_div,
1065 &spdif_div,
1066 &asrc_serial_div,
1067 &cko1_div,
1068};
1069
1070static unsigned long ldb_di_clk_get_rate(struct clk *clk)
1071{
1072 u32 val = readl_relaxed(CSCMR2);
1073
1074 val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV :
1075 BM_CSCMR2_LDB_DI1_IPU_DIV;
1076 if (val)
1077 return clk_get_rate(clk->parent) / 7;
1078 else
1079 return clk_get_rate(clk->parent) * 2 / 7;
1080}
1081
1082static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate)
1083{
1084 unsigned long parent_rate = clk_get_rate(clk->parent);
1085 u32 val = readl_relaxed(CSCMR2);
1086
1087 if (rate * 7 <= parent_rate + parent_rate / 20)
1088 val |= BM_CSCMR2_LDB_DI0_IPU_DIV;
1089 else
1090 val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV;
1091
1092 writel_relaxed(val, CSCMR2);
1093
1094 return 0;
1095}
1096
1097static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate)
1098{
1099 unsigned long parent_rate = clk_get_rate(clk->parent);
1100
1101 if (rate * 7 <= parent_rate + parent_rate / 20)
1102 return parent_rate / 7;
1103 else
1104 return 2 * parent_rate / 7;
1105}
1106
1107static unsigned long _clk_get_rate(struct clk *clk)
1108{
1109 struct divider *d;
1110 u32 val, pred, podf;
1111 int i, num;
1112
1113 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1114 return ldb_di_clk_get_rate(clk);
1115
1116 num = ARRAY_SIZE(dividers);
1117 for (i = 0; i < num; i++)
1118 if (dividers[i]->clk == clk) {
1119 d = dividers[i];
1120 break;
1121 }
1122 if (i == num)
1123 return clk_get_rate(clk->parent);
1124
1125 val = readl_relaxed(d->reg);
1126 pred = ((val & d->bm_pred) >> d->bp_pred) + 1;
1127 podf = ((val & d->bm_podf) >> d->bp_podf) + 1;
1128
1129 return clk_get_rate(clk->parent) / (pred * podf);
1130}
1131
1132static int clk_busy_wait(struct clk *clk)
1133{
1134 int timeout = 0x100000;
1135 u32 bm;
1136
1137 if (clk == &axi_clk)
1138 bm = BM_CDHIPR_AXI_PODF_BUSY;
1139 else if (clk == &ahb_clk)
1140 bm = BM_CDHIPR_AHB_PODF_BUSY;
1141 else if (clk == &mmdc_ch0_axi_clk)
1142 bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY;
1143 else if (clk == &periph_clk)
1144 bm = BM_CDHIPR_PERIPH_SEL_BUSY;
1145 else if (clk == &arm_clk)
1146 bm = BM_CDHIPR_ARM_PODF_BUSY;
1147 else
1148 return -EINVAL;
1149
1150 while ((readl_relaxed(CDHIPR) & bm) && --timeout)
1151 cpu_relax();
1152
1153 if (unlikely(!timeout))
1154 return -EBUSY;
1155
1156 return 0;
1157}
1158
1159static int _clk_set_rate(struct clk *clk, unsigned long rate)
1160{
1161 unsigned long parent_rate = clk_get_rate(clk->parent);
1162 struct divider *d;
1163 u32 val, div, max_div, pred = 0, podf;
1164 int i, num;
1165
1166 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1167 return ldb_di_clk_set_rate(clk, rate);
1168
1169 num = ARRAY_SIZE(dividers);
1170 for (i = 0; i < num; i++)
1171 if (dividers[i]->clk == clk) {
1172 d = dividers[i];
1173 break;
1174 }
1175 if (i == num)
1176 return -EINVAL;
1177
1178 max_div = ((d->bm_pred >> d->bp_pred) + 1) *
1179 ((d->bm_podf >> d->bp_podf) + 1);
1180
1181 div = parent_rate / rate;
1182 if (div == 0)
1183 div++;
1184
1185 if ((parent_rate / div != rate) || div > max_div)
1186 return -EINVAL;
1187
1188 if (d->bm_pred) {
1189 calc_pred_podf_dividers(div, &pred, &podf);
1190 } else {
1191 pred = 1;
1192 podf = div;
1193 }
1194
1195 val = readl_relaxed(d->reg);
1196 val &= ~(d->bm_pred | d->bm_podf);
1197 val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf;
1198 writel_relaxed(val, d->reg);
1199
1200 if (clk == &axi_clk || clk == &ahb_clk ||
1201 clk == &mmdc_ch0_axi_clk || clk == &arm_clk)
1202 return clk_busy_wait(clk);
1203
1204 return 0;
1205}
1206
1207static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
1208{
1209 unsigned long parent_rate = clk_get_rate(clk->parent);
1210 u32 div = parent_rate / rate;
1211 u32 div_max, pred = 0, podf;
1212 struct divider *d;
1213 int i, num;
1214
1215 if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
1216 return ldb_di_clk_round_rate(clk, rate);
1217
1218 num = ARRAY_SIZE(dividers);
1219 for (i = 0; i < num; i++)
1220 if (dividers[i]->clk == clk) {
1221 d = dividers[i];
1222 break;
1223 }
1224 if (i == num)
1225 return -EINVAL;
1226
1227 if (div == 0 || parent_rate % rate)
1228 div++;
1229
1230 if (d->bm_pred) {
1231 calc_pred_podf_dividers(div, &pred, &podf);
1232 div = pred * podf;
1233 } else {
1234 div_max = (d->bm_podf >> d->bp_podf) + 1;
1235 if (div > div_max)
1236 div = div_max;
1237 }
1238
1239 return parent_rate / div;
1240}
1241
1242struct multiplexer {
1243 struct clk *clk;
1244 void __iomem *reg;
1245 u32 bp;
1246 u32 bm;
1247 int pnum;
1248 struct clk *parents[];
1249};
1250
1251static struct multiplexer axi_mux = {
1252 .clk = &axi_clk,
1253 .reg = CBCDR,
1254 .bp = BP_CBCDR_AXI_SEL,
1255 .bm = BM_CBCDR_AXI_SEL,
1256 .parents = {
1257 &periph_clk,
1258 &pll2_pfd_400m,
1259 &pll3_pfd_540m,
1260 NULL
1261 },
1262};
1263
1264static struct multiplexer periph_mux = {
1265 .clk = &periph_clk,
1266 .reg = CBCDR,
1267 .bp = BP_CBCDR_PERIPH_CLK_SEL,
1268 .bm = BM_CBCDR_PERIPH_CLK_SEL,
1269 .parents = {
1270 &periph_pre_clk,
1271 &periph_clk2_clk,
1272 NULL
1273 },
1274};
1275
1276static struct multiplexer periph_pre_mux = {
1277 .clk = &periph_pre_clk,
1278 .reg = CBCMR,
1279 .bp = BP_CBCMR_PRE_PERIPH_CLK_SEL,
1280 .bm = BM_CBCMR_PRE_PERIPH_CLK_SEL,
1281 .parents = {
1282 &pll2_bus,
1283 &pll2_pfd_400m,
1284 &pll2_pfd_352m,
1285 &pll2_200m,
1286 NULL
1287 },
1288};
1289
1290static struct multiplexer periph_clk2_mux = {
1291 .clk = &periph_clk2_clk,
1292 .reg = CBCMR,
1293 .bp = BP_CBCMR_PERIPH_CLK2_SEL,
1294 .bm = BM_CBCMR_PERIPH_CLK2_SEL,
1295 .parents = {
1296 &pll3_usb_otg,
1297 &osc_clk,
1298 NULL
1299 },
1300};
1301
1302static struct multiplexer periph2_mux = {
1303 .clk = &periph2_clk,
1304 .reg = CBCDR,
1305 .bp = BP_CBCDR_PERIPH2_CLK_SEL,
1306 .bm = BM_CBCDR_PERIPH2_CLK_SEL,
1307 .parents = {
1308 &periph2_pre_clk,
1309 &periph2_clk2_clk,
1310 NULL
1311 },
1312};
1313
1314static struct multiplexer periph2_pre_mux = {
1315 .clk = &periph2_pre_clk,
1316 .reg = CBCMR,
1317 .bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL,
1318 .bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL,
1319 .parents = {
1320 &pll2_bus,
1321 &pll2_pfd_400m,
1322 &pll2_pfd_352m,
1323 &pll2_200m,
1324 NULL
1325 },
1326};
1327
1328static struct multiplexer periph2_clk2_mux = {
1329 .clk = &periph2_clk2_clk,
1330 .reg = CBCMR,
1331 .bp = BP_CBCMR_PERIPH2_CLK2_SEL,
1332 .bm = BM_CBCMR_PERIPH2_CLK2_SEL,
1333 .parents = {
1334 &pll3_usb_otg,
1335 &osc_clk,
1336 NULL
1337 },
1338};
1339
1340static struct multiplexer gpu2d_axi_mux = {
1341 .clk = &gpu2d_axi_clk,
1342 .reg = CBCMR,
1343 .bp = BP_CBCMR_GPU2D_AXI_SEL,
1344 .bm = BM_CBCMR_GPU2D_AXI_SEL,
1345 .parents = {
1346 &axi_clk,
1347 &ahb_clk,
1348 NULL
1349 },
1350};
1351
1352static struct multiplexer gpu3d_axi_mux = {
1353 .clk = &gpu3d_axi_clk,
1354 .reg = CBCMR,
1355 .bp = BP_CBCMR_GPU3D_AXI_SEL,
1356 .bm = BM_CBCMR_GPU3D_AXI_SEL,
1357 .parents = {
1358 &axi_clk,
1359 &ahb_clk,
1360 NULL
1361 },
1362};
1363
1364static struct multiplexer gpu3d_core_mux = {
1365 .clk = &gpu3d_core_clk,
1366 .reg = CBCMR,
1367 .bp = BP_CBCMR_GPU3D_CORE_SEL,
1368 .bm = BM_CBCMR_GPU3D_CORE_SEL,
1369 .parents = {
1370 &mmdc_ch0_axi_clk,
1371 &pll3_usb_otg,
1372 &pll2_pfd_594m,
1373 &pll2_pfd_400m,
1374 NULL
1375 },
1376};
1377
1378static struct multiplexer gpu3d_shader_mux = {
1379 .clk = &gpu3d_shader_clk,
1380 .reg = CBCMR,
1381 .bp = BP_CBCMR_GPU3D_SHADER_SEL,
1382 .bm = BM_CBCMR_GPU3D_SHADER_SEL,
1383 .parents = {
1384 &mmdc_ch0_axi_clk,
1385 &pll3_usb_otg,
1386 &pll2_pfd_594m,
1387 &pll3_pfd_720m,
1388 NULL
1389 },
1390};
1391
1392static struct multiplexer pcie_axi_mux = {
1393 .clk = &pcie_clk,
1394 .reg = CBCMR,
1395 .bp = BP_CBCMR_PCIE_AXI_SEL,
1396 .bm = BM_CBCMR_PCIE_AXI_SEL,
1397 .parents = {
1398 &axi_clk,
1399 &ahb_clk,
1400 NULL
1401 },
1402};
1403
1404static struct multiplexer vdo_axi_mux = {
1405 .clk = &vdo_axi_clk,
1406 .reg = CBCMR,
1407 .bp = BP_CBCMR_VDO_AXI_SEL,
1408 .bm = BM_CBCMR_VDO_AXI_SEL,
1409 .parents = {
1410 &axi_clk,
1411 &ahb_clk,
1412 NULL
1413 },
1414};
1415
1416static struct multiplexer vpu_axi_mux = {
1417 .clk = &vpu_clk,
1418 .reg = CBCMR,
1419 .bp = BP_CBCMR_VPU_AXI_SEL,
1420 .bm = BM_CBCMR_VPU_AXI_SEL,
1421 .parents = {
1422 &axi_clk,
1423 &pll2_pfd_400m,
1424 &pll2_pfd_352m,
1425 NULL
1426 },
1427};
1428
1429static struct multiplexer gpu2d_core_mux = {
1430 .clk = &gpu2d_core_clk,
1431 .reg = CBCMR,
1432 .bp = BP_CBCMR_GPU2D_CORE_SEL,
1433 .bm = BM_CBCMR_GPU2D_CORE_SEL,
1434 .parents = {
1435 &axi_clk,
1436 &pll3_usb_otg,
1437 &pll2_pfd_352m,
1438 &pll2_pfd_400m,
1439 NULL
1440 },
1441};
1442
1443#define DEF_SSI_MUX(id) \
1444 static struct multiplexer ssi##id##_mux = { \
1445 .clk = &ssi##id##_clk, \
1446 .reg = CSCMR1, \
1447 .bp = BP_CSCMR1_SSI##id##_SEL, \
1448 .bm = BM_CSCMR1_SSI##id##_SEL, \
1449 .parents = { \
1450 &pll3_pfd_508m, \
1451 &pll3_pfd_454m, \
1452 &pll4_audio, \
1453 NULL \
1454 }, \
1455 }
1456
1457DEF_SSI_MUX(1);
1458DEF_SSI_MUX(2);
1459DEF_SSI_MUX(3);
1460
1461#define DEF_USDHC_MUX(id) \
1462 static struct multiplexer usdhc##id##_mux = { \
1463 .clk = &usdhc##id##_clk, \
1464 .reg = CSCMR1, \
1465 .bp = BP_CSCMR1_USDHC##id##_SEL, \
1466 .bm = BM_CSCMR1_USDHC##id##_SEL, \
1467 .parents = { \
1468 &pll2_pfd_400m, \
1469 &pll2_pfd_352m, \
1470 NULL \
1471 }, \
1472 }
1473
1474DEF_USDHC_MUX(1);
1475DEF_USDHC_MUX(2);
1476DEF_USDHC_MUX(3);
1477DEF_USDHC_MUX(4);
1478
1479static struct multiplexer emi_mux = {
1480 .clk = &emi_clk,
1481 .reg = CSCMR1,
1482 .bp = BP_CSCMR1_EMI_SEL,
1483 .bm = BM_CSCMR1_EMI_SEL,
1484 .parents = {
1485 &axi_clk,
1486 &pll3_usb_otg,
1487 &pll2_pfd_400m,
1488 &pll2_pfd_352m,
1489 NULL
1490 },
1491};
1492
1493static struct multiplexer emi_slow_mux = {
1494 .clk = &emi_slow_clk,
1495 .reg = CSCMR1,
1496 .bp = BP_CSCMR1_EMI_SLOW_SEL,
1497 .bm = BM_CSCMR1_EMI_SLOW_SEL,
1498 .parents = {
1499 &axi_clk,
1500 &pll3_usb_otg,
1501 &pll2_pfd_400m,
1502 &pll2_pfd_352m,
1503 NULL
1504 },
1505};
1506
1507static struct multiplexer esai_mux = {
1508 .clk = &esai_clk,
1509 .reg = CSCMR2,
1510 .bp = BP_CSCMR2_ESAI_SEL,
1511 .bm = BM_CSCMR2_ESAI_SEL,
1512 .parents = {
1513 &pll4_audio,
1514 &pll3_pfd_508m,
1515 &pll3_pfd_454m,
1516 &pll3_usb_otg,
1517 NULL
1518 },
1519};
1520
1521#define DEF_LDB_DI_MUX(id) \
1522 static struct multiplexer ldb_di##id##_mux = { \
1523 .clk = &ldb_di##id##_clk, \
1524 .reg = CS2CDR, \
1525 .bp = BP_CS2CDR_LDB_DI##id##_SEL, \
1526 .bm = BM_CS2CDR_LDB_DI##id##_SEL, \
1527 .parents = { \
1528 &pll5_video, \
1529 &pll2_pfd_352m, \
1530 &pll2_pfd_400m, \
1531 &pll3_pfd_540m, \
1532 &pll3_usb_otg, \
1533 NULL \
1534 }, \
1535 }
1536
1537DEF_LDB_DI_MUX(0);
1538DEF_LDB_DI_MUX(1);
1539
1540static struct multiplexer enfc_mux = {
1541 .clk = &enfc_clk,
1542 .reg = CS2CDR,
1543 .bp = BP_CS2CDR_ENFC_SEL,
1544 .bm = BM_CS2CDR_ENFC_SEL,
1545 .parents = {
1546 &pll2_pfd_352m,
1547 &pll2_bus,
1548 &pll3_usb_otg,
1549 &pll2_pfd_400m,
1550 NULL
1551 },
1552};
1553
1554static struct multiplexer spdif_mux = {
1555 .clk = &spdif_clk,
1556 .reg = CDCDR,
1557 .bp = BP_CDCDR_SPDIF_SEL,
1558 .bm = BM_CDCDR_SPDIF_SEL,
1559 .parents = {
1560 &pll4_audio,
1561 &pll3_pfd_508m,
1562 &pll3_pfd_454m,
1563 &pll3_usb_otg,
1564 NULL
1565 },
1566};
1567
1568static struct multiplexer asrc_serial_mux = {
1569 .clk = &asrc_serial_clk,
1570 .reg = CDCDR,
1571 .bp = BP_CDCDR_ASRC_SERIAL_SEL,
1572 .bm = BM_CDCDR_ASRC_SERIAL_SEL,
1573 .parents = {
1574 &pll4_audio,
1575 &pll3_pfd_508m,
1576 &pll3_pfd_454m,
1577 &pll3_usb_otg,
1578 NULL
1579 },
1580};
1581
1582static struct multiplexer hsi_tx_mux = {
1583 .clk = &hsi_tx_clk,
1584 .reg = CDCDR,
1585 .bp = BP_CDCDR_HSI_TX_SEL,
1586 .bm = BM_CDCDR_HSI_TX_SEL,
1587 .parents = {
1588 &pll3_120m,
1589 &pll2_pfd_400m,
1590 NULL
1591 },
1592};
1593
1594#define DEF_IPU_DI_PRE_MUX(r, i, d) \
1595 static struct multiplexer ipu##i##_di##d##_pre_mux = { \
1596 .clk = &ipu##i##_di##d##_pre_clk, \
1597 .reg = r, \
1598 .bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \
1599 .bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \
1600 .parents = { \
1601 &mmdc_ch0_axi_clk, \
1602 &pll3_usb_otg, \
1603 &pll5_video, \
1604 &pll2_pfd_352m, \
1605 &pll2_pfd_400m, \
1606 &pll3_pfd_540m, \
1607 NULL \
1608 }, \
1609 }
1610
1611DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0);
1612DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1);
1613DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0);
1614DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1);
1615
1616#define DEF_IPU_DI_MUX(r, i, d) \
1617 static struct multiplexer ipu##i##_di##d##_mux = { \
1618 .clk = &ipu##i##_di##d##_clk, \
1619 .reg = r, \
1620 .bp = BP_##r##_IPU##i##_DI##d##_SEL, \
1621 .bm = BM_##r##_IPU##i##_DI##d##_SEL, \
1622 .parents = { \
1623 &ipu##i##_di##d##_pre_clk, \
1624 &dummy_clk, \
1625 &dummy_clk, \
1626 &ldb_di0_clk, \
1627 &ldb_di1_clk, \
1628 NULL \
1629 }, \
1630 }
1631
1632DEF_IPU_DI_MUX(CHSCCDR, 1, 0);
1633DEF_IPU_DI_MUX(CHSCCDR, 1, 1);
1634DEF_IPU_DI_MUX(CSCDR2, 2, 0);
1635DEF_IPU_DI_MUX(CSCDR2, 2, 1);
1636
1637#define DEF_IPU_MUX(id) \
1638 static struct multiplexer ipu##id##_mux = { \
1639 .clk = &ipu##id##_clk, \
1640 .reg = CSCDR3, \
1641 .bp = BP_CSCDR3_IPU##id##_HSP_SEL, \
1642 .bm = BM_CSCDR3_IPU##id##_HSP_SEL, \
1643 .parents = { \
1644 &mmdc_ch0_axi_clk, \
1645 &pll2_pfd_400m, \
1646 &pll3_120m, \
1647 &pll3_pfd_540m, \
1648 NULL \
1649 }, \
1650 }
1651
1652DEF_IPU_MUX(1);
1653DEF_IPU_MUX(2);
1654
1655static struct multiplexer cko1_mux = {
1656 .clk = &cko1_clk,
1657 .reg = CCOSR,
1658 .bp = BP_CCOSR_CKO1_SEL,
1659 .bm = BM_CCOSR_CKO1_SEL,
1660 .parents = {
1661 &pll3_usb_otg,
1662 &pll2_bus,
1663 &pll1_sys,
1664 &pll5_video,
1665 &dummy_clk,
1666 &axi_clk,
1667 &enfc_clk,
1668 &ipu1_di0_clk,
1669 &ipu1_di1_clk,
1670 &ipu2_di0_clk,
1671 &ipu2_di1_clk,
1672 &ahb_clk,
1673 &ipg_clk,
1674 &ipg_perclk,
1675 &ckil_clk,
1676 &pll4_audio,
1677 NULL
1678 },
1679};
1680
1681static struct multiplexer *multiplexers[] = {
1682 &axi_mux,
1683 &periph_mux,
1684 &periph_pre_mux,
1685 &periph_clk2_mux,
1686 &periph2_mux,
1687 &periph2_pre_mux,
1688 &periph2_clk2_mux,
1689 &gpu2d_axi_mux,
1690 &gpu3d_axi_mux,
1691 &gpu3d_core_mux,
1692 &gpu3d_shader_mux,
1693 &pcie_axi_mux,
1694 &vdo_axi_mux,
1695 &vpu_axi_mux,
1696 &gpu2d_core_mux,
1697 &ssi1_mux,
1698 &ssi2_mux,
1699 &ssi3_mux,
1700 &usdhc1_mux,
1701 &usdhc2_mux,
1702 &usdhc3_mux,
1703 &usdhc4_mux,
1704 &emi_mux,
1705 &emi_slow_mux,
1706 &esai_mux,
1707 &ldb_di0_mux,
1708 &ldb_di1_mux,
1709 &enfc_mux,
1710 &spdif_mux,
1711 &asrc_serial_mux,
1712 &hsi_tx_mux,
1713 &ipu1_di0_pre_mux,
1714 &ipu1_di0_mux,
1715 &ipu1_di1_pre_mux,
1716 &ipu1_di1_mux,
1717 &ipu2_di0_pre_mux,
1718 &ipu2_di0_mux,
1719 &ipu2_di1_pre_mux,
1720 &ipu2_di1_mux,
1721 &ipu1_mux,
1722 &ipu2_mux,
1723 &cko1_mux,
1724};
1725
1726static int _clk_set_parent(struct clk *clk, struct clk *parent)
1727{
1728 struct multiplexer *m;
1729 int i, num;
1730 u32 val;
1731
1732 num = ARRAY_SIZE(multiplexers);
1733 for (i = 0; i < num; i++)
1734 if (multiplexers[i]->clk == clk) {
1735 m = multiplexers[i];
1736 break;
1737 }
1738 if (i == num)
1739 return -EINVAL;
1740
1741 i = 0;
1742 while (m->parents[i]) {
1743 if (parent == m->parents[i])
1744 break;
1745 i++;
1746 }
1747 if (!m->parents[i] || m->parents[i] == &dummy_clk)
1748 return -EINVAL;
1749
1750 val = readl_relaxed(m->reg);
1751 val &= ~m->bm;
1752 val |= i << m->bp;
1753 writel_relaxed(val, m->reg);
1754
1755 if (clk == &periph_clk)
1756 return clk_busy_wait(clk);
1757
1758 return 0;
1759}
1760
1761#define DEF_NG_CLK(name, p) \
1762 static struct clk name = { \
1763 .get_rate = _clk_get_rate, \
1764 .set_rate = _clk_set_rate, \
1765 .round_rate = _clk_round_rate, \
1766 .set_parent = _clk_set_parent, \
1767 .parent = p, \
1768 }
1769
1770DEF_NG_CLK(periph_clk2_clk, &osc_clk);
1771DEF_NG_CLK(periph_pre_clk, &pll2_bus);
1772DEF_NG_CLK(periph_clk, &periph_pre_clk);
1773DEF_NG_CLK(periph2_clk2_clk, &osc_clk);
1774DEF_NG_CLK(periph2_pre_clk, &pll2_bus);
1775DEF_NG_CLK(periph2_clk, &periph2_pre_clk);
1776DEF_NG_CLK(axi_clk, &periph_clk);
1777DEF_NG_CLK(emi_clk, &axi_clk);
1778DEF_NG_CLK(arm_clk, &pll1_sw_clk);
1779DEF_NG_CLK(ahb_clk, &periph_clk);
1780DEF_NG_CLK(ipg_clk, &ahb_clk);
1781DEF_NG_CLK(ipg_perclk, &ipg_clk);
1782DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m);
1783DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m);
1784DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m);
1785DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m);
1786DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg);
1787
1788#define DEF_CLK(name, er, es, p, s) \
1789 static struct clk name = { \
1790 .enable_reg = er, \
1791 .enable_shift = es, \
1792 .enable = _clk_enable, \
1793 .disable = _clk_disable, \
1794 .get_rate = _clk_get_rate, \
1795 .set_rate = _clk_set_rate, \
1796 .round_rate = _clk_round_rate, \
1797 .set_parent = _clk_set_parent, \
1798 .parent = p, \
1799 .secondary = s, \
1800 }
1801
1802#define DEF_CLK_1B(name, er, es, p, s) \
1803 static struct clk name = { \
1804 .enable_reg = er, \
1805 .enable_shift = es, \
1806 .enable = _clk_enable_1b, \
1807 .disable = _clk_disable_1b, \
1808 .get_rate = _clk_get_rate, \
1809 .set_rate = _clk_set_rate, \
1810 .round_rate = _clk_round_rate, \
1811 .set_parent = _clk_set_parent, \
1812 .parent = p, \
1813 .secondary = s, \
1814 }
1815
1816DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL);
1817DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL);
1818DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL);
1819DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL);
1820DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL);
1821DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk);
1822DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL);
1823DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk);
1824DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL);
1825DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL);
1826DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL);
1827DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL);
1828DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL);
1829DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL);
1830DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL);
1831DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL);
1832DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk);
1833DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk);
1834DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk);
1835DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk);
1836DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL);
1837DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk);
1838DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL);
1839DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL);
1840DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL);
1841DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL);
1842DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL);
1843DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL);
1844DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL);
1845DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL);
1846DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL);
1847DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL);
1848DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL);
1849DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL);
1850DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL);
1851DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL);
1852DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL);
1853DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL);
1854DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk);
1855DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL);
1856DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk);
1857DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL);
1858DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL);
1859DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL);
1860DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL);
1861DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL);
1862DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL);
1863DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk);
1864DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk);
1865DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk);
1866DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL);
1867DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL);
1868DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk);
1869DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL);
1870DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL);
1871DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL);
1872DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL);
1873DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk);
1874DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL);
1875DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL);
1876DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL);
1877DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL);
1878DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL);
1879DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL);
1880DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL);
1881DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL);
1882DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL);
1883
1884static int pcie_clk_enable(struct clk *clk)
1885{
1886 u32 val;
1887
1888 val = readl_relaxed(PLL8_ENET);
1889 val |= BM_PLL_ENET_EN_PCIE;
1890 writel_relaxed(val, PLL8_ENET);
1891
1892 return _clk_enable(clk);
1893}
1894
1895static void pcie_clk_disable(struct clk *clk)
1896{
1897 u32 val;
1898
1899 _clk_disable(clk);
1900
1901 val = readl_relaxed(PLL8_ENET);
1902 val &= BM_PLL_ENET_EN_PCIE;
1903 writel_relaxed(val, PLL8_ENET);
1904}
1905
1906static struct clk pcie_clk = {
1907 .enable_reg = CCGR4,
1908 .enable_shift = CG0,
1909 .enable = pcie_clk_enable,
1910 .disable = pcie_clk_disable,
1911 .set_parent = _clk_set_parent,
1912 .parent = &axi_clk,
1913 .secondary = &pll8_enet,
1914};
1915
1916static int sata_clk_enable(struct clk *clk)
1917{
1918 u32 val;
1919
1920 val = readl_relaxed(PLL8_ENET);
1921 val |= BM_PLL_ENET_EN_SATA;
1922 writel_relaxed(val, PLL8_ENET);
1923
1924 return _clk_enable(clk);
1925}
1926
1927static void sata_clk_disable(struct clk *clk)
1928{
1929 u32 val;
1930
1931 _clk_disable(clk);
1932
1933 val = readl_relaxed(PLL8_ENET);
1934 val &= BM_PLL_ENET_EN_SATA;
1935 writel_relaxed(val, PLL8_ENET);
1936}
1937
1938static struct clk sata_clk = {
1939 .enable_reg = CCGR5,
1940 .enable_shift = CG2,
1941 .enable = sata_clk_enable,
1942 .disable = sata_clk_disable,
1943 .parent = &ipg_clk,
1944 .secondary = &pll8_enet,
1945};
1946
1947#define _REGISTER_CLOCK(d, n, c) \
1948 { \
1949 .dev_id = d, \
1950 .con_id = n, \
1951 .clk = &c, \
1952 }
1953
1954static struct clk_lookup lookups[] = {
1955 _REGISTER_CLOCK("2020000.uart", NULL, uart_clk),
1956 _REGISTER_CLOCK("21e8000.uart", NULL, uart_clk),
1957 _REGISTER_CLOCK("21ec000.uart", NULL, uart_clk),
1958 _REGISTER_CLOCK("21f0000.uart", NULL, uart_clk),
1959 _REGISTER_CLOCK("21f4000.uart", NULL, uart_clk),
1960 _REGISTER_CLOCK("2188000.enet", NULL, enet_clk),
1961 _REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk),
1962 _REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk),
1963 _REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk),
1964 _REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk),
1965 _REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk),
1966 _REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk),
1967 _REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk),
1968 _REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk),
1969 _REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk),
1970 _REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk),
1971 _REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk),
1972 _REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk),
1973 _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
1974 _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
1975 _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
1976 _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
1977 _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
1978 _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
1979 _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
1980 _REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk),
1981 _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk),
1982 _REGISTER_CLOCK(NULL, "can2_clk", can2_clk),
1983 _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk),
1984 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
1985 _REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk),
1986 _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
1987 _REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk),
1988 _REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk),
1989 _REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk),
1990 _REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk),
1991 _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
1992 _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
1993 _REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
1994 _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk),
1995};
1996
1997int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
1998{
1999 u32 val = readl_relaxed(CLPCR);
2000
2001 val &= ~BM_CLPCR_LPM;
2002 switch (mode) {
2003 case WAIT_CLOCKED:
2004 break;
2005 case WAIT_UNCLOCKED:
2006 val |= 0x1 << BP_CLPCR_LPM;
2007 break;
2008 case STOP_POWER_ON:
2009 val |= 0x2 << BP_CLPCR_LPM;
2010 break;
2011 case WAIT_UNCLOCKED_POWER_OFF:
2012 val |= 0x1 << BP_CLPCR_LPM;
2013 val &= ~BM_CLPCR_VSTBY;
2014 val &= ~BM_CLPCR_SBYOS;
2015 break;
2016 case STOP_POWER_OFF:
2017 val |= 0x2 << BP_CLPCR_LPM;
2018 val |= 0x3 << BP_CLPCR_STBY_COUNT;
2019 val |= BM_CLPCR_VSTBY;
2020 val |= BM_CLPCR_SBYOS;
2021 break;
2022 default:
2023 return -EINVAL;
2024 }
2025 writel_relaxed(val, CLPCR);
2026
2027 return 0;
2028}
2029
2030static struct map_desc imx6q_clock_desc[] = {
2031 imx_map_entry(MX6Q, CCM, MT_DEVICE),
2032 imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
2033};
2034
2035void __init imx6q_clock_map_io(void)
2036{
2037 iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
2038}
2039
2040int __init mx6q_clocks_init(void)
2041{
2042 struct device_node *np;
2043 void __iomem *base;
2044 int i, irq;
2045
2046 /* retrieve the freqency of fixed clocks from device tree */
2047 for_each_compatible_node(np, NULL, "fixed-clock") {
2048 u32 rate;
2049 if (of_property_read_u32(np, "clock-frequency", &rate))
2050 continue;
2051
2052 if (of_device_is_compatible(np, "fsl,imx-ckil"))
2053 external_low_reference = rate;
2054 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
2055 external_high_reference = rate;
2056 else if (of_device_is_compatible(np, "fsl,imx-osc"))
2057 oscillator_reference = rate;
2058 }
2059
2060 for (i = 0; i < ARRAY_SIZE(lookups); i++)
2061 clkdev_add(&lookups[i]);
2062
2063 /* only keep necessary clocks on */
2064 writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0);
2065 writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2);
2066 writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3);
2067 writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4);
2068 writel_relaxed(0x3 << CG0, CCGR5);
2069 writel_relaxed(0, CCGR6);
2070 writel_relaxed(0, CCGR7);
2071
2072 clk_enable(&uart_clk);
2073 clk_enable(&mmdc_ch0_axi_clk);
2074
2075 clk_set_rate(&pll4_audio, FREQ_650M);
2076 clk_set_rate(&pll5_video, FREQ_650M);
2077 clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk);
2078 clk_set_parent(&ipu1_di0_pre_clk, &pll5_video);
2079 clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m);
2080 clk_set_rate(&gpu3d_shader_clk, FREQ_594M);
2081 clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk);
2082 clk_set_rate(&gpu3d_core_clk, FREQ_528M);
2083 clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
2084 clk_set_rate(&asrc_serial_clk, 1500000);
2085 clk_set_rate(&enfc_clk, 11000000);
2086
2087 /*
2088 * Before pinctrl API is available, we have to rely on the pad
2089 * configuration set up by bootloader. For usdhc example here,
2090 * u-boot sets up the pads for 49.5 MHz case, and we have to lower
2091 * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
2092 *
2093 * FIXME: This is should be removed after pinctrl API is available.
2094 * At that time, usdhc driver can call pinctrl API to change pad
2095 * configuration dynamically per different usdhc clock settings.
2096 */
2097 clk_set_rate(&usdhc1_clk, 49500000);
2098 clk_set_rate(&usdhc2_clk, 49500000);
2099 clk_set_rate(&usdhc3_clk, 49500000);
2100 clk_set_rate(&usdhc4_clk, 49500000);
2101
2102 clk_set_parent(&cko1_clk, &ahb_clk);
2103
2104 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
2105 base = of_iomap(np, 0);
2106 WARN_ON(!base);
2107 irq = irq_of_parse_and_map(np, 0);
2108 mxc_timer_init(&gpt_clk, base, irq);
2109
2110 return 0;
2111}
diff --git a/arch/arm/mach-imx/clock-mx51-mx53.c b/arch/arm/mach-imx/clock-mx51-mx53.c
deleted file mode 100644
index 08470504a08..00000000000
--- a/arch/arm/mach-imx/clock-mx51-mx53.c
+++ /dev/null
@@ -1,1675 +0,0 @@
1/*
2 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/mm.h>
14#include <linux/delay.h>
15#include <linux/clk.h>
16#include <linux/io.h>
17#include <linux/clkdev.h>
18#include <linux/of.h>
19
20#include <asm/div64.h>
21
22#include <mach/hardware.h>
23#include <mach/common.h>
24#include <mach/clock.h>
25
26#include "crm-regs-imx5.h"
27
28/* External clock values passed-in by the board code */
29static unsigned long external_high_reference, external_low_reference;
30static unsigned long oscillator_reference, ckih2_reference;
31
32static struct clk osc_clk;
33static struct clk pll1_main_clk;
34static struct clk pll1_sw_clk;
35static struct clk pll2_sw_clk;
36static struct clk pll3_sw_clk;
37static struct clk mx53_pll4_sw_clk;
38static struct clk lp_apm_clk;
39static struct clk periph_apm_clk;
40static struct clk ahb_clk;
41static struct clk ipg_clk;
42static struct clk usboh3_clk;
43static struct clk emi_fast_clk;
44static struct clk ipu_clk;
45static struct clk mipi_hsc1_clk;
46static struct clk esdhc1_clk;
47static struct clk esdhc2_clk;
48static struct clk esdhc3_mx53_clk;
49
50#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
51
52/* calculate best pre and post dividers to get the required divider */
53static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
54 u32 max_pre, u32 max_post)
55{
56 if (div >= max_pre * max_post) {
57 *pre = max_pre;
58 *post = max_post;
59 } else if (div >= max_pre) {
60 u32 min_pre, temp_pre, old_err, err;
61 min_pre = DIV_ROUND_UP(div, max_post);
62 old_err = max_pre;
63 for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
64 err = div % temp_pre;
65 if (err == 0) {
66 *pre = temp_pre;
67 break;
68 }
69 err = temp_pre - err;
70 if (err < old_err) {
71 old_err = err;
72 *pre = temp_pre;
73 }
74 }
75 *post = DIV_ROUND_UP(div, *pre);
76 } else {
77 *pre = div;
78 *post = 1;
79 }
80}
81
82static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
83{
84 u32 reg = __raw_readl(clk->enable_reg);
85
86 reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
87 reg |= mode << clk->enable_shift;
88
89 __raw_writel(reg, clk->enable_reg);
90}
91
92static int _clk_ccgr_enable(struct clk *clk)
93{
94 _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
95 return 0;
96}
97
98static void _clk_ccgr_disable(struct clk *clk)
99{
100 _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
101}
102
103static int _clk_ccgr_enable_inrun(struct clk *clk)
104{
105 _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
106 return 0;
107}
108
109static void _clk_ccgr_disable_inwait(struct clk *clk)
110{
111 _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
112}
113
114/*
115 * For the 4-to-1 muxed input clock
116 */
117static inline u32 _get_mux(struct clk *parent, struct clk *m0,
118 struct clk *m1, struct clk *m2, struct clk *m3)
119{
120 if (parent == m0)
121 return 0;
122 else if (parent == m1)
123 return 1;
124 else if (parent == m2)
125 return 2;
126 else if (parent == m3)
127 return 3;
128 else
129 BUG();
130
131 return -EINVAL;
132}
133
134static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
135{
136 if (pll == &pll1_main_clk)
137 return MX51_DPLL1_BASE;
138 else if (pll == &pll2_sw_clk)
139 return MX51_DPLL2_BASE;
140 else if (pll == &pll3_sw_clk)
141 return MX51_DPLL3_BASE;
142 else
143 BUG();
144
145 return NULL;
146}
147
148static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
149{
150 if (pll == &pll1_main_clk)
151 return MX53_DPLL1_BASE;
152 else if (pll == &pll2_sw_clk)
153 return MX53_DPLL2_BASE;
154 else if (pll == &pll3_sw_clk)
155 return MX53_DPLL3_BASE;
156 else if (pll == &mx53_pll4_sw_clk)
157 return MX53_DPLL4_BASE;
158 else
159 BUG();
160
161 return NULL;
162}
163
164static inline void __iomem *_get_pll_base(struct clk *pll)
165{
166 if (cpu_is_mx51())
167 return _mx51_get_pll_base(pll);
168 else
169 return _mx53_get_pll_base(pll);
170}
171
172static unsigned long clk_pll_get_rate(struct clk *clk)
173{
174 long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
175 unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
176 void __iomem *pllbase;
177 s64 temp;
178 unsigned long parent_rate;
179
180 parent_rate = clk_get_rate(clk->parent);
181
182 pllbase = _get_pll_base(clk);
183
184 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
185 pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
186 dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
187
188 if (pll_hfsm == 0) {
189 dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
190 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
191 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
192 } else {
193 dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
194 dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
195 dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
196 }
197 pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
198 mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
199 mfi = (mfi <= 5) ? 5 : mfi;
200 mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
201 mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
202 /* Sign extend to 32-bits */
203 if (mfn >= 0x04000000) {
204 mfn |= 0xFC000000;
205 mfn_abs = -mfn;
206 }
207
208 ref_clk = 2 * parent_rate;
209 if (dbl != 0)
210 ref_clk *= 2;
211
212 ref_clk /= (pdf + 1);
213 temp = (u64) ref_clk * mfn_abs;
214 do_div(temp, mfd + 1);
215 if (mfn < 0)
216 temp = -temp;
217 temp = (ref_clk * mfi) + temp;
218
219 return temp;
220}
221
222static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
223{
224 u32 reg;
225 void __iomem *pllbase;
226
227 long mfi, pdf, mfn, mfd = 999999;
228 s64 temp64;
229 unsigned long quad_parent_rate;
230 unsigned long pll_hfsm, dp_ctl;
231 unsigned long parent_rate;
232
233 parent_rate = clk_get_rate(clk->parent);
234
235 pllbase = _get_pll_base(clk);
236
237 quad_parent_rate = 4 * parent_rate;
238 pdf = mfi = -1;
239 while (++pdf < 16 && mfi < 5)
240 mfi = rate * (pdf+1) / quad_parent_rate;
241 if (mfi > 15)
242 return -EINVAL;
243 pdf--;
244
245 temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
246 do_div(temp64, quad_parent_rate/1000000);
247 mfn = (long)temp64;
248
249 dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
250 /* use dpdck0_2 */
251 __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
252 pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
253 if (pll_hfsm == 0) {
254 reg = mfi << 4 | pdf;
255 __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
256 __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
257 __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
258 } else {
259 reg = mfi << 4 | pdf;
260 __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
261 __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
262 __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
263 }
264
265 return 0;
266}
267
268static int _clk_pll_enable(struct clk *clk)
269{
270 u32 reg;
271 void __iomem *pllbase;
272 int i = 0;
273
274 pllbase = _get_pll_base(clk);
275 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
276 if (reg & MXC_PLL_DP_CTL_UPEN)
277 return 0;
278
279 reg |= MXC_PLL_DP_CTL_UPEN;
280 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
281
282 /* Wait for lock */
283 do {
284 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
285 if (reg & MXC_PLL_DP_CTL_LRF)
286 break;
287
288 udelay(1);
289 } while (++i < MAX_DPLL_WAIT_TRIES);
290
291 if (i == MAX_DPLL_WAIT_TRIES) {
292 pr_err("MX5: pll locking failed\n");
293 return -EINVAL;
294 }
295
296 return 0;
297}
298
299static void _clk_pll_disable(struct clk *clk)
300{
301 u32 reg;
302 void __iomem *pllbase;
303
304 pllbase = _get_pll_base(clk);
305 reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
306 __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
307}
308
309static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
310{
311 u32 reg, step;
312
313 reg = __raw_readl(MXC_CCM_CCSR);
314
315 /* When switching from pll_main_clk to a bypass clock, first select a
316 * multiplexed clock in 'step_sel', then shift the glitchless mux
317 * 'pll1_sw_clk_sel'.
318 *
319 * When switching back, do it in reverse order
320 */
321 if (parent == &pll1_main_clk) {
322 /* Switch to pll1_main_clk */
323 reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
324 __raw_writel(reg, MXC_CCM_CCSR);
325 /* step_clk mux switched to lp_apm, to save power. */
326 reg = __raw_readl(MXC_CCM_CCSR);
327 reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
328 reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
329 MXC_CCM_CCSR_STEP_SEL_OFFSET);
330 } else {
331 if (parent == &lp_apm_clk) {
332 step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
333 } else if (parent == &pll2_sw_clk) {
334 step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
335 } else if (parent == &pll3_sw_clk) {
336 step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
337 } else
338 return -EINVAL;
339
340 reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
341 reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
342
343 __raw_writel(reg, MXC_CCM_CCSR);
344 /* Switch to step_clk */
345 reg = __raw_readl(MXC_CCM_CCSR);
346 reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
347 }
348 __raw_writel(reg, MXC_CCM_CCSR);
349 return 0;
350}
351
352static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
353{
354 u32 reg, div;
355 unsigned long parent_rate;
356
357 parent_rate = clk_get_rate(clk->parent);
358
359 reg = __raw_readl(MXC_CCM_CCSR);
360
361 if (clk->parent == &pll2_sw_clk) {
362 div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
363 MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
364 } else if (clk->parent == &pll3_sw_clk) {
365 div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
366 MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
367 } else
368 div = 1;
369 return parent_rate / div;
370}
371
372static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
373{
374 u32 reg;
375
376 reg = __raw_readl(MXC_CCM_CCSR);
377
378 if (parent == &pll2_sw_clk)
379 reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
380 else
381 reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
382
383 __raw_writel(reg, MXC_CCM_CCSR);
384 return 0;
385}
386
387static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
388{
389 u32 reg;
390
391 if (parent == &osc_clk)
392 reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
393 else
394 return -EINVAL;
395
396 __raw_writel(reg, MXC_CCM_CCSR);
397
398 return 0;
399}
400
401static unsigned long clk_cpu_get_rate(struct clk *clk)
402{
403 u32 cacrr, div;
404 unsigned long parent_rate;
405
406 parent_rate = clk_get_rate(clk->parent);
407 cacrr = __raw_readl(MXC_CCM_CACRR);
408 div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
409
410 return parent_rate / div;
411}
412
413static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
414{
415 u32 reg, cpu_podf;
416 unsigned long parent_rate;
417
418 parent_rate = clk_get_rate(clk->parent);
419 cpu_podf = parent_rate / rate - 1;
420 /* use post divider to change freq */
421 reg = __raw_readl(MXC_CCM_CACRR);
422 reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
423 reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
424 __raw_writel(reg, MXC_CCM_CACRR);
425
426 return 0;
427}
428
429static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
430{
431 u32 reg, mux;
432 int i = 0;
433
434 mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
435
436 reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
437 reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
438 __raw_writel(reg, MXC_CCM_CBCMR);
439
440 /* Wait for lock */
441 do {
442 reg = __raw_readl(MXC_CCM_CDHIPR);
443 if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
444 break;
445
446 udelay(1);
447 } while (++i < MAX_DPLL_WAIT_TRIES);
448
449 if (i == MAX_DPLL_WAIT_TRIES) {
450 pr_err("MX5: Set parent for periph_apm clock failed\n");
451 return -EINVAL;
452 }
453
454 return 0;
455}
456
457static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
458{
459 u32 reg;
460
461 reg = __raw_readl(MXC_CCM_CBCDR);
462
463 if (parent == &pll2_sw_clk)
464 reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
465 else if (parent == &periph_apm_clk)
466 reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
467 else
468 return -EINVAL;
469
470 __raw_writel(reg, MXC_CCM_CBCDR);
471
472 return 0;
473}
474
475static struct clk main_bus_clk = {
476 .parent = &pll2_sw_clk,
477 .set_parent = _clk_main_bus_set_parent,
478};
479
480static unsigned long clk_ahb_get_rate(struct clk *clk)
481{
482 u32 reg, div;
483 unsigned long parent_rate;
484
485 parent_rate = clk_get_rate(clk->parent);
486
487 reg = __raw_readl(MXC_CCM_CBCDR);
488 div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
489 MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
490 return parent_rate / div;
491}
492
493
494static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
495{
496 u32 reg, div;
497 unsigned long parent_rate;
498 int i = 0;
499
500 parent_rate = clk_get_rate(clk->parent);
501
502 div = parent_rate / rate;
503 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
504 return -EINVAL;
505
506 reg = __raw_readl(MXC_CCM_CBCDR);
507 reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
508 reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
509 __raw_writel(reg, MXC_CCM_CBCDR);
510
511 /* Wait for lock */
512 do {
513 reg = __raw_readl(MXC_CCM_CDHIPR);
514 if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
515 break;
516
517 udelay(1);
518 } while (++i < MAX_DPLL_WAIT_TRIES);
519
520 if (i == MAX_DPLL_WAIT_TRIES) {
521 pr_err("MX5: clk_ahb_set_rate failed\n");
522 return -EINVAL;
523 }
524
525 return 0;
526}
527
528static unsigned long _clk_ahb_round_rate(struct clk *clk,
529 unsigned long rate)
530{
531 u32 div;
532 unsigned long parent_rate;
533
534 parent_rate = clk_get_rate(clk->parent);
535
536 div = parent_rate / rate;
537 if (div > 8)
538 div = 8;
539 else if (div == 0)
540 div++;
541 return parent_rate / div;
542}
543
544
545static int _clk_max_enable(struct clk *clk)
546{
547 u32 reg;
548
549 _clk_ccgr_enable(clk);
550
551 /* Handshake with MAX when LPM is entered. */
552 reg = __raw_readl(MXC_CCM_CLPCR);
553 if (cpu_is_mx51())
554 reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
555 else if (cpu_is_mx53())
556 reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
557 __raw_writel(reg, MXC_CCM_CLPCR);
558
559 return 0;
560}
561
562static void _clk_max_disable(struct clk *clk)
563{
564 u32 reg;
565
566 _clk_ccgr_disable_inwait(clk);
567
568 /* No Handshake with MAX when LPM is entered as its disabled. */
569 reg = __raw_readl(MXC_CCM_CLPCR);
570 if (cpu_is_mx51())
571 reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
572 else if (cpu_is_mx53())
573 reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
574 __raw_writel(reg, MXC_CCM_CLPCR);
575}
576
577static unsigned long clk_ipg_get_rate(struct clk *clk)
578{
579 u32 reg, div;
580 unsigned long parent_rate;
581
582 parent_rate = clk_get_rate(clk->parent);
583
584 reg = __raw_readl(MXC_CCM_CBCDR);
585 div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
586 MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
587
588 return parent_rate / div;
589}
590
591static unsigned long clk_ipg_per_get_rate(struct clk *clk)
592{
593 u32 reg, prediv1, prediv2, podf;
594 unsigned long parent_rate;
595
596 parent_rate = clk_get_rate(clk->parent);
597
598 if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
599 /* the main_bus_clk is the one before the DVFS engine */
600 reg = __raw_readl(MXC_CCM_CBCDR);
601 prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
602 MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
603 prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
604 MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
605 podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
606 MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
607 return parent_rate / (prediv1 * prediv2 * podf);
608 } else if (clk->parent == &ipg_clk)
609 return parent_rate;
610 else
611 BUG();
612}
613
614static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
615{
616 u32 reg;
617
618 reg = __raw_readl(MXC_CCM_CBCMR);
619
620 reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
621 reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
622
623 if (parent == &ipg_clk)
624 reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
625 else if (parent == &lp_apm_clk)
626 reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
627 else if (parent != &main_bus_clk)
628 return -EINVAL;
629
630 __raw_writel(reg, MXC_CCM_CBCMR);
631
632 return 0;
633}
634
635#define clk_nfc_set_parent NULL
636
637static unsigned long clk_nfc_get_rate(struct clk *clk)
638{
639 unsigned long rate;
640 u32 reg, div;
641
642 reg = __raw_readl(MXC_CCM_CBCDR);
643 div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
644 MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
645 rate = clk_get_rate(clk->parent) / div;
646 WARN_ON(rate == 0);
647 return rate;
648}
649
650static unsigned long clk_nfc_round_rate(struct clk *clk,
651 unsigned long rate)
652{
653 u32 div;
654 unsigned long parent_rate = clk_get_rate(clk->parent);
655
656 if (!rate)
657 return -EINVAL;
658
659 div = parent_rate / rate;
660
661 if (parent_rate % rate)
662 div++;
663
664 if (div > 8)
665 return -EINVAL;
666
667 return parent_rate / div;
668
669}
670
671static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
672{
673 u32 reg, div;
674
675 div = clk_get_rate(clk->parent) / rate;
676 if (div == 0)
677 div++;
678 if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
679 return -EINVAL;
680
681 reg = __raw_readl(MXC_CCM_CBCDR);
682 reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
683 reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
684 __raw_writel(reg, MXC_CCM_CBCDR);
685
686 while (__raw_readl(MXC_CCM_CDHIPR) &
687 MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
688 }
689
690 return 0;
691}
692
693static unsigned long get_high_reference_clock_rate(struct clk *clk)
694{
695 return external_high_reference;
696}
697
698static unsigned long get_low_reference_clock_rate(struct clk *clk)
699{
700 return external_low_reference;
701}
702
703static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
704{
705 return oscillator_reference;
706}
707
708static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
709{
710 return ckih2_reference;
711}
712
713static unsigned long clk_emi_slow_get_rate(struct clk *clk)
714{
715 u32 reg, div;
716
717 reg = __raw_readl(MXC_CCM_CBCDR);
718 div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
719 MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
720
721 return clk_get_rate(clk->parent) / div;
722}
723
724static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
725{
726 unsigned long rate;
727 u32 reg, div;
728
729 reg = __raw_readl(MXC_CCM_CBCDR);
730 div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
731 MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
732 rate = clk_get_rate(clk->parent) / div;
733
734 return rate;
735}
736
737/* External high frequency clock */
738static struct clk ckih_clk = {
739 .get_rate = get_high_reference_clock_rate,
740};
741
742static struct clk ckih2_clk = {
743 .get_rate = get_ckih2_reference_clock_rate,
744};
745
746static struct clk osc_clk = {
747 .get_rate = get_oscillator_reference_clock_rate,
748};
749
750/* External low frequency (32kHz) clock */
751static struct clk ckil_clk = {
752 .get_rate = get_low_reference_clock_rate,
753};
754
755static struct clk pll1_main_clk = {
756 .parent = &osc_clk,
757 .get_rate = clk_pll_get_rate,
758 .enable = _clk_pll_enable,
759 .disable = _clk_pll_disable,
760};
761
762/* Clock tree block diagram (WIP):
763 * CCM: Clock Controller Module
764 *
765 * PLL output -> |
766 * | CCM Switcher -> CCM_CLK_ROOT_GEN ->
767 * PLL bypass -> |
768 *
769 */
770
771/* PLL1 SW supplies to ARM core */
772static struct clk pll1_sw_clk = {
773 .parent = &pll1_main_clk,
774 .set_parent = _clk_pll1_sw_set_parent,
775 .get_rate = clk_pll1_sw_get_rate,
776};
777
778/* PLL2 SW supplies to AXI/AHB/IP buses */
779static struct clk pll2_sw_clk = {
780 .parent = &osc_clk,
781 .get_rate = clk_pll_get_rate,
782 .set_rate = _clk_pll_set_rate,
783 .set_parent = _clk_pll2_sw_set_parent,
784 .enable = _clk_pll_enable,
785 .disable = _clk_pll_disable,
786};
787
788/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
789static struct clk pll3_sw_clk = {
790 .parent = &osc_clk,
791 .set_rate = _clk_pll_set_rate,
792 .get_rate = clk_pll_get_rate,
793 .enable = _clk_pll_enable,
794 .disable = _clk_pll_disable,
795};
796
797/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
798static struct clk mx53_pll4_sw_clk = {
799 .parent = &osc_clk,
800 .set_rate = _clk_pll_set_rate,
801 .enable = _clk_pll_enable,
802 .disable = _clk_pll_disable,
803};
804
805/* Low-power Audio Playback Mode clock */
806static struct clk lp_apm_clk = {
807 .parent = &osc_clk,
808 .set_parent = _clk_lp_apm_set_parent,
809};
810
811static struct clk periph_apm_clk = {
812 .parent = &pll1_sw_clk,
813 .set_parent = _clk_periph_apm_set_parent,
814};
815
816static struct clk cpu_clk = {
817 .parent = &pll1_sw_clk,
818 .get_rate = clk_cpu_get_rate,
819 .set_rate = clk_cpu_set_rate,
820};
821
822static struct clk ahb_clk = {
823 .parent = &main_bus_clk,
824 .get_rate = clk_ahb_get_rate,
825 .set_rate = _clk_ahb_set_rate,
826 .round_rate = _clk_ahb_round_rate,
827};
828
829static struct clk iim_clk = {
830 .parent = &ipg_clk,
831 .enable_reg = MXC_CCM_CCGR0,
832 .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
833};
834
835/* Main IP interface clock for access to registers */
836static struct clk ipg_clk = {
837 .parent = &ahb_clk,
838 .get_rate = clk_ipg_get_rate,
839};
840
841static struct clk ipg_perclk = {
842 .parent = &lp_apm_clk,
843 .get_rate = clk_ipg_per_get_rate,
844 .set_parent = _clk_ipg_per_set_parent,
845};
846
847static struct clk ahb_max_clk = {
848 .parent = &ahb_clk,
849 .enable_reg = MXC_CCM_CCGR0,
850 .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
851 .enable = _clk_max_enable,
852 .disable = _clk_max_disable,
853};
854
855static struct clk aips_tz1_clk = {
856 .parent = &ahb_clk,
857 .secondary = &ahb_max_clk,
858 .enable_reg = MXC_CCM_CCGR0,
859 .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
860 .enable = _clk_ccgr_enable,
861 .disable = _clk_ccgr_disable_inwait,
862};
863
864static struct clk aips_tz2_clk = {
865 .parent = &ahb_clk,
866 .secondary = &ahb_max_clk,
867 .enable_reg = MXC_CCM_CCGR0,
868 .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
869 .enable = _clk_ccgr_enable,
870 .disable = _clk_ccgr_disable_inwait,
871};
872
873static struct clk gpc_dvfs_clk = {
874 .enable_reg = MXC_CCM_CCGR5,
875 .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
876 .enable = _clk_ccgr_enable,
877 .disable = _clk_ccgr_disable,
878};
879
880static struct clk gpt_32k_clk = {
881 .id = 0,
882 .parent = &ckil_clk,
883};
884
885static struct clk dummy_clk = {
886 .id = 0,
887};
888
889static struct clk emi_slow_clk = {
890 .parent = &pll2_sw_clk,
891 .enable_reg = MXC_CCM_CCGR5,
892 .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
893 .enable = _clk_ccgr_enable,
894 .disable = _clk_ccgr_disable_inwait,
895 .get_rate = clk_emi_slow_get_rate,
896};
897
898static int clk_ipu_enable(struct clk *clk)
899{
900 u32 reg;
901
902 _clk_ccgr_enable(clk);
903
904 /* Enable handshake with IPU when certain clock rates are changed */
905 reg = __raw_readl(MXC_CCM_CCDR);
906 reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
907 __raw_writel(reg, MXC_CCM_CCDR);
908
909 /* Enable handshake with IPU when LPM is entered */
910 reg = __raw_readl(MXC_CCM_CLPCR);
911 reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
912 __raw_writel(reg, MXC_CCM_CLPCR);
913
914 return 0;
915}
916
917static void clk_ipu_disable(struct clk *clk)
918{
919 u32 reg;
920
921 _clk_ccgr_disable(clk);
922
923 /* Disable handshake with IPU whe dividers are changed */
924 reg = __raw_readl(MXC_CCM_CCDR);
925 reg |= MXC_CCM_CCDR_IPU_HS_MASK;
926 __raw_writel(reg, MXC_CCM_CCDR);
927
928 /* Disable handshake with IPU when LPM is entered */
929 reg = __raw_readl(MXC_CCM_CLPCR);
930 reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
931 __raw_writel(reg, MXC_CCM_CLPCR);
932}
933
934static struct clk ahbmux1_clk = {
935 .parent = &ahb_clk,
936 .secondary = &ahb_max_clk,
937 .enable_reg = MXC_CCM_CCGR0,
938 .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
939 .enable = _clk_ccgr_enable,
940 .disable = _clk_ccgr_disable_inwait,
941};
942
943static struct clk ipu_sec_clk = {
944 .parent = &emi_fast_clk,
945 .secondary = &ahbmux1_clk,
946};
947
948static struct clk ddr_hf_clk = {
949 .parent = &pll1_sw_clk,
950 .get_rate = _clk_ddr_hf_get_rate,
951};
952
953static struct clk ddr_clk = {
954 .parent = &ddr_hf_clk,
955};
956
957/* clock definitions for MIPI HSC unit which has been removed
958 * from documentation, but not from hardware
959 */
960static int _clk_hsc_enable(struct clk *clk)
961{
962 u32 reg;
963
964 _clk_ccgr_enable(clk);
965 /* Handshake with IPU when certain clock rates are changed. */
966 reg = __raw_readl(MXC_CCM_CCDR);
967 reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
968 __raw_writel(reg, MXC_CCM_CCDR);
969
970 reg = __raw_readl(MXC_CCM_CLPCR);
971 reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
972 __raw_writel(reg, MXC_CCM_CLPCR);
973
974 return 0;
975}
976
977static void _clk_hsc_disable(struct clk *clk)
978{
979 u32 reg;
980
981 _clk_ccgr_disable(clk);
982 /* No handshake with HSC as its not enabled. */
983 reg = __raw_readl(MXC_CCM_CCDR);
984 reg |= MXC_CCM_CCDR_HSC_HS_MASK;
985 __raw_writel(reg, MXC_CCM_CCDR);
986
987 reg = __raw_readl(MXC_CCM_CLPCR);
988 reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
989 __raw_writel(reg, MXC_CCM_CLPCR);
990}
991
992static struct clk mipi_hsp_clk = {
993 .parent = &ipu_clk,
994 .enable_reg = MXC_CCM_CCGR4,
995 .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
996 .enable = _clk_hsc_enable,
997 .disable = _clk_hsc_disable,
998 .secondary = &mipi_hsc1_clk,
999};
1000
1001#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
1002 static struct clk name = { \
1003 .id = i, \
1004 .enable_reg = er, \
1005 .enable_shift = es, \
1006 .get_rate = pfx##_get_rate, \
1007 .set_rate = pfx##_set_rate, \
1008 .round_rate = pfx##_round_rate, \
1009 .set_parent = pfx##_set_parent, \
1010 .enable = _clk_ccgr_enable, \
1011 .disable = _clk_ccgr_disable, \
1012 .parent = p, \
1013 .secondary = s, \
1014 }
1015
1016#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
1017 static struct clk name = { \
1018 .id = i, \
1019 .enable_reg = er, \
1020 .enable_shift = es, \
1021 .get_rate = pfx##_get_rate, \
1022 .set_rate = pfx##_set_rate, \
1023 .set_parent = pfx##_set_parent, \
1024 .enable = _clk_max_enable, \
1025 .disable = _clk_max_disable, \
1026 .parent = p, \
1027 .secondary = s, \
1028 }
1029
1030#define CLK_GET_RATE(name, nr, bitsname) \
1031static unsigned long clk_##name##_get_rate(struct clk *clk) \
1032{ \
1033 u32 reg, pred, podf; \
1034 \
1035 reg = __raw_readl(MXC_CCM_CSCDR##nr); \
1036 pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \
1037 >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
1038 podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \
1039 >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
1040 \
1041 return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \
1042 (pred + 1) * (podf + 1)); \
1043}
1044
1045#define CLK_SET_PARENT(name, nr, bitsname) \
1046static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
1047{ \
1048 u32 reg, mux; \
1049 \
1050 mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \
1051 &pll3_sw_clk, &lp_apm_clk); \
1052 reg = __raw_readl(MXC_CCM_CSCMR##nr) & \
1053 ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \
1054 reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \
1055 __raw_writel(reg, MXC_CCM_CSCMR##nr); \
1056 \
1057 return 0; \
1058}
1059
1060#define CLK_SET_RATE(name, nr, bitsname) \
1061static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \
1062{ \
1063 u32 reg, div, parent_rate; \
1064 u32 pre = 0, post = 0; \
1065 \
1066 parent_rate = clk_get_rate(clk->parent); \
1067 div = parent_rate / rate; \
1068 \
1069 if ((parent_rate / div) != rate) \
1070 return -EINVAL; \
1071 \
1072 __calc_pre_post_dividers(div, &pre, &post, \
1073 (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \
1074 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \
1075 (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \
1076 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
1077 \
1078 /* Set sdhc1 clock divider */ \
1079 reg = __raw_readl(MXC_CCM_CSCDR##nr) & \
1080 ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \
1081 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \
1082 reg |= (post - 1) << \
1083 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
1084 reg |= (pre - 1) << \
1085 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
1086 __raw_writel(reg, MXC_CCM_CSCDR##nr); \
1087 \
1088 return 0; \
1089}
1090
1091/* UART */
1092CLK_GET_RATE(uart, 1, UART)
1093CLK_SET_PARENT(uart, 1, UART)
1094
1095static struct clk uart_root_clk = {
1096 .parent = &pll2_sw_clk,
1097 .get_rate = clk_uart_get_rate,
1098 .set_parent = clk_uart_set_parent,
1099};
1100
1101/* USBOH3 */
1102CLK_GET_RATE(usboh3, 1, USBOH3)
1103CLK_SET_PARENT(usboh3, 1, USBOH3)
1104
1105static struct clk usboh3_clk = {
1106 .parent = &pll2_sw_clk,
1107 .get_rate = clk_usboh3_get_rate,
1108 .set_parent = clk_usboh3_set_parent,
1109 .enable = _clk_ccgr_enable,
1110 .disable = _clk_ccgr_disable,
1111 .enable_reg = MXC_CCM_CCGR2,
1112 .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
1113};
1114
1115static struct clk usb_ahb_clk = {
1116 .parent = &ipg_clk,
1117 .enable = _clk_ccgr_enable,
1118 .disable = _clk_ccgr_disable,
1119 .enable_reg = MXC_CCM_CCGR2,
1120 .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
1121};
1122
1123static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
1124{
1125 u32 reg;
1126
1127 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
1128
1129 if (parent == &pll3_sw_clk)
1130 reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
1131
1132 __raw_writel(reg, MXC_CCM_CSCMR1);
1133
1134 return 0;
1135}
1136
1137static struct clk usb_phy1_clk = {
1138 .parent = &pll3_sw_clk,
1139 .set_parent = clk_usb_phy1_set_parent,
1140 .enable = _clk_ccgr_enable,
1141 .enable_reg = MXC_CCM_CCGR2,
1142 .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
1143 .disable = _clk_ccgr_disable,
1144};
1145
1146/* eCSPI */
1147CLK_GET_RATE(ecspi, 2, CSPI)
1148CLK_SET_PARENT(ecspi, 1, CSPI)
1149
1150static struct clk ecspi_main_clk = {
1151 .parent = &pll3_sw_clk,
1152 .get_rate = clk_ecspi_get_rate,
1153 .set_parent = clk_ecspi_set_parent,
1154};
1155
1156/* eSDHC */
1157CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
1158CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
1159CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
1160
1161/* mx51 specific */
1162CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
1163CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
1164CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
1165
1166static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
1167{
1168 u32 reg;
1169
1170 reg = __raw_readl(MXC_CCM_CSCMR1);
1171 if (parent == &esdhc1_clk)
1172 reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
1173 else if (parent == &esdhc2_clk)
1174 reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
1175 else
1176 return -EINVAL;
1177 __raw_writel(reg, MXC_CCM_CSCMR1);
1178
1179 return 0;
1180}
1181
1182static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
1183{
1184 u32 reg;
1185
1186 reg = __raw_readl(MXC_CCM_CSCMR1);
1187 if (parent == &esdhc1_clk)
1188 reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1189 else if (parent == &esdhc2_clk)
1190 reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1191 else
1192 return -EINVAL;
1193 __raw_writel(reg, MXC_CCM_CSCMR1);
1194
1195 return 0;
1196}
1197
1198/* mx53 specific */
1199static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent)
1200{
1201 u32 reg;
1202
1203 reg = __raw_readl(MXC_CCM_CSCMR1);
1204 if (parent == &esdhc1_clk)
1205 reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
1206 else if (parent == &esdhc3_mx53_clk)
1207 reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
1208 else
1209 return -EINVAL;
1210 __raw_writel(reg, MXC_CCM_CSCMR1);
1211
1212 return 0;
1213}
1214
1215CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
1216CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
1217CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
1218
1219static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent)
1220{
1221 u32 reg;
1222
1223 reg = __raw_readl(MXC_CCM_CSCMR1);
1224 if (parent == &esdhc1_clk)
1225 reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1226 else if (parent == &esdhc3_mx53_clk)
1227 reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
1228 else
1229 return -EINVAL;
1230 __raw_writel(reg, MXC_CCM_CSCMR1);
1231
1232 return 0;
1233}
1234
1235#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
1236 static struct clk name = { \
1237 .id = i, \
1238 .enable_reg = er, \
1239 .enable_shift = es, \
1240 .get_rate = gr, \
1241 .set_rate = sr, \
1242 .enable = e, \
1243 .disable = d, \
1244 .parent = p, \
1245 .secondary = s, \
1246 }
1247
1248#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
1249 DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
1250
1251/* Shared peripheral bus arbiter */
1252DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
1253 NULL, NULL, &ipg_clk, NULL);
1254
1255/* UART */
1256DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
1257 NULL, NULL, &ipg_clk, &aips_tz1_clk);
1258DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
1259 NULL, NULL, &ipg_clk, &aips_tz1_clk);
1260DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
1261 NULL, NULL, &ipg_clk, &spba_clk);
1262DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET,
1263 NULL, NULL, &ipg_clk, &spba_clk);
1264DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET,
1265 NULL, NULL, &ipg_clk, &spba_clk);
1266DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
1267 NULL, NULL, &uart_root_clk, &uart1_ipg_clk);
1268DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
1269 NULL, NULL, &uart_root_clk, &uart2_ipg_clk);
1270DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
1271 NULL, NULL, &uart_root_clk, &uart3_ipg_clk);
1272DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET,
1273 NULL, NULL, &uart_root_clk, &uart4_ipg_clk);
1274DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET,
1275 NULL, NULL, &uart_root_clk, &uart5_ipg_clk);
1276
1277/* GPT */
1278DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
1279 NULL, NULL, &ipg_clk, NULL);
1280DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
1281 NULL, NULL, &ipg_clk, &gpt_ipg_clk);
1282
1283DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
1284 NULL, NULL, &ipg_perclk, NULL);
1285DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
1286 NULL, NULL, &ipg_perclk, NULL);
1287
1288/* I2C */
1289DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
1290 NULL, NULL, &ipg_perclk, NULL);
1291DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
1292 NULL, NULL, &ipg_perclk, NULL);
1293DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
1294 NULL, NULL, &ipg_clk, NULL);
1295DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
1296 NULL, NULL, &ipg_perclk, NULL);
1297
1298/* FEC */
1299DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
1300 NULL, NULL, &ipg_clk, NULL);
1301
1302/* NFC */
1303DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
1304 clk_nfc, &emi_slow_clk, NULL);
1305
1306/* SSI */
1307DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
1308 NULL, NULL, &ipg_clk, NULL);
1309DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
1310 NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
1311DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
1312 NULL, NULL, &ipg_clk, NULL);
1313DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
1314 NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
1315DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
1316 NULL, NULL, &ipg_clk, NULL);
1317DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
1318 NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
1319
1320/* eCSPI */
1321DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
1322 NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
1323 &ipg_clk, &spba_clk);
1324DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
1325 NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
1326DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
1327 NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
1328 &ipg_clk, &aips_tz2_clk);
1329DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
1330 NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
1331
1332/* CSPI */
1333DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
1334 NULL, NULL, &ipg_clk, &aips_tz2_clk);
1335DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
1336 NULL, NULL, &ipg_clk, &cspi_ipg_clk);
1337
1338/* SDMA */
1339DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
1340 NULL, NULL, &ahb_clk, NULL);
1341
1342/* eSDHC */
1343DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
1344 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1345DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
1346 clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
1347DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
1348 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1349DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
1350 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1351DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
1352 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1353
1354/* mx51 specific */
1355DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
1356 clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
1357
1358static struct clk esdhc3_clk = {
1359 .id = 2,
1360 .parent = &esdhc1_clk,
1361 .set_parent = clk_esdhc3_set_parent,
1362 .enable_reg = MXC_CCM_CCGR3,
1363 .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
1364 .enable = _clk_max_enable,
1365 .disable = _clk_max_disable,
1366 .secondary = &esdhc3_ipg_clk,
1367};
1368static struct clk esdhc4_clk = {
1369 .id = 3,
1370 .parent = &esdhc1_clk,
1371 .set_parent = clk_esdhc4_set_parent,
1372 .enable_reg = MXC_CCM_CCGR3,
1373 .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
1374 .enable = _clk_max_enable,
1375 .disable = _clk_max_disable,
1376 .secondary = &esdhc4_ipg_clk,
1377};
1378
1379/* mx53 specific */
1380static struct clk esdhc2_mx53_clk = {
1381 .id = 2,
1382 .parent = &esdhc1_clk,
1383 .set_parent = clk_esdhc2_mx53_set_parent,
1384 .enable_reg = MXC_CCM_CCGR3,
1385 .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
1386 .enable = _clk_max_enable,
1387 .disable = _clk_max_disable,
1388 .secondary = &esdhc3_ipg_clk,
1389};
1390
1391DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET,
1392 clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk);
1393
1394static struct clk esdhc4_mx53_clk = {
1395 .id = 3,
1396 .parent = &esdhc1_clk,
1397 .set_parent = clk_esdhc4_mx53_set_parent,
1398 .enable_reg = MXC_CCM_CCGR3,
1399 .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
1400 .enable = _clk_max_enable,
1401 .disable = _clk_max_disable,
1402 .secondary = &esdhc4_ipg_clk,
1403};
1404
1405static struct clk sata_clk = {
1406 .parent = &ipg_clk,
1407 .enable = _clk_max_enable,
1408 .enable_reg = MXC_CCM_CCGR4,
1409 .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
1410 .disable = _clk_max_disable,
1411};
1412
1413static struct clk ahci_phy_clk = {
1414 .parent = &usb_phy1_clk,
1415};
1416
1417static struct clk ahci_dma_clk = {
1418 .parent = &ahb_clk,
1419};
1420
1421DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
1422DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
1423DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
1424
1425/* IPU */
1426DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
1427 NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
1428
1429DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
1430 NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
1431 &ddr_clk, NULL);
1432
1433DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
1434 NULL, NULL, &pll3_sw_clk, NULL);
1435DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
1436 NULL, NULL, &pll3_sw_clk, NULL);
1437
1438/* PATA */
1439DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG0_OFFSET,
1440 NULL, NULL, &ipg_clk, &spba_clk);
1441
1442#define _REGISTER_CLOCK(d, n, c) \
1443 { \
1444 .dev_id = d, \
1445 .con_id = n, \
1446 .clk = &c, \
1447 },
1448
1449static struct clk_lookup mx51_lookups[] = {
1450 /* i.mx51 has the i.mx21 type uart */
1451 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
1452 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
1453 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
1454 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1455 /* i.mx51 has the i.mx27 type fec */
1456 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
1457 _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
1458 _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
1459 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1460 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1461 _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
1462 _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
1463 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
1464 _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
1465 _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
1466 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
1467 _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
1468 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
1469 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
1470 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
1471 _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
1472 _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
1473 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
1474 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
1475 _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
1476 /* i.mx51 has the i.mx35 type sdma */
1477 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
1478 _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1479 _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
1480 _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
1481 _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
1482 _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
1483 /* i.mx51 has the i.mx35 type cspi */
1484 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
1485 _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk)
1486 _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk)
1487 _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk)
1488 _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk)
1489 _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
1490 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1491 _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
1492 _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
1493 _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
1494 _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
1495 _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
1496 _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
1497 _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
1498 _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
1499};
1500
1501static struct clk_lookup mx53_lookups[] = {
1502 /* i.mx53 has the i.mx21 type uart */
1503 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
1504 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
1505 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
1506 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
1507 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
1508 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1509 /* i.mx53 has the i.mx25 type fec */
1510 _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
1511 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1512 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1513 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1514 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk)
1515 /* i.mx53 has the i.mx51 type ecspi */
1516 _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
1517 _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
1518 /* i.mx53 has the i.mx25 type cspi */
1519 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
1520 _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk)
1521 _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk)
1522 _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk)
1523 _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk)
1524 _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
1525 _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
1526 /* i.mx53 has the i.mx35 type sdma */
1527 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
1528 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
1529 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
1530 _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
1531 _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
1532 _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
1533 _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk)
1534 _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk)
1535 _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk)
1536};
1537
1538static void clk_tree_init(void)
1539{
1540 u32 reg;
1541
1542 ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
1543
1544 /*
1545 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
1546 * 8MHz, its derived from lp_apm.
1547 *
1548 * FIXME: Verify if true for all boards
1549 */
1550 reg = __raw_readl(MXC_CCM_CBCDR);
1551 reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
1552 reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
1553 reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
1554 reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
1555 __raw_writel(reg, MXC_CCM_CBCDR);
1556}
1557
1558int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
1559 unsigned long ckih1, unsigned long ckih2)
1560{
1561 int i;
1562
1563 external_low_reference = ckil;
1564 external_high_reference = ckih1;
1565 ckih2_reference = ckih2;
1566 oscillator_reference = osc;
1567
1568 for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
1569 clkdev_add(&mx51_lookups[i]);
1570
1571 clk_tree_init();
1572
1573 clk_enable(&cpu_clk);
1574 clk_enable(&main_bus_clk);
1575
1576 clk_enable(&iim_clk);
1577 imx_print_silicon_rev("i.MX51", mx51_revision());
1578 clk_disable(&iim_clk);
1579
1580 /* move usb_phy_clk to 24MHz */
1581 clk_set_parent(&usb_phy1_clk, &osc_clk);
1582
1583 /* set the usboh3_clk parent to pll2_sw_clk */
1584 clk_set_parent(&usboh3_clk, &pll2_sw_clk);
1585
1586 /* Set SDHC parents to be PLL2 */
1587 clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
1588 clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
1589
1590 /* set SDHC root clock as 166.25MHZ*/
1591 clk_set_rate(&esdhc1_clk, 166250000);
1592 clk_set_rate(&esdhc2_clk, 166250000);
1593
1594 /* System timer */
1595 mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
1596 MX51_INT_GPT);
1597 return 0;
1598}
1599
1600int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
1601 unsigned long ckih1, unsigned long ckih2)
1602{
1603 int i;
1604
1605 external_low_reference = ckil;
1606 external_high_reference = ckih1;
1607 ckih2_reference = ckih2;
1608 oscillator_reference = osc;
1609
1610 for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
1611 clkdev_add(&mx53_lookups[i]);
1612
1613 clk_tree_init();
1614
1615 clk_set_parent(&uart_root_clk, &pll3_sw_clk);
1616 clk_enable(&cpu_clk);
1617 clk_enable(&main_bus_clk);
1618
1619 clk_enable(&iim_clk);
1620 imx_print_silicon_rev("i.MX53", mx53_revision());
1621 clk_disable(&iim_clk);
1622
1623 /* Set SDHC parents to be PLL2 */
1624 clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
1625 clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk);
1626
1627 /* set SDHC root clock as 200MHZ*/
1628 clk_set_rate(&esdhc1_clk, 200000000);
1629 clk_set_rate(&esdhc3_mx53_clk, 200000000);
1630
1631 /* System timer */
1632 mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
1633 MX53_INT_GPT);
1634 return 0;
1635}
1636
1637#ifdef CONFIG_OF
1638static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
1639 unsigned long *ckih1, unsigned long *ckih2)
1640{
1641 struct device_node *np;
1642
1643 /* retrieve the freqency of fixed clocks from device tree */
1644 for_each_compatible_node(np, NULL, "fixed-clock") {
1645 u32 rate;
1646 if (of_property_read_u32(np, "clock-frequency", &rate))
1647 continue;
1648
1649 if (of_device_is_compatible(np, "fsl,imx-ckil"))
1650 *ckil = rate;
1651 else if (of_device_is_compatible(np, "fsl,imx-osc"))
1652 *osc = rate;
1653 else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
1654 *ckih1 = rate;
1655 else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
1656 *ckih2 = rate;
1657 }
1658}
1659
1660int __init mx51_clocks_init_dt(void)
1661{
1662 unsigned long ckil, osc, ckih1, ckih2;
1663
1664 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
1665 return mx51_clocks_init(ckil, osc, ckih1, ckih2);
1666}
1667
1668int __init mx53_clocks_init_dt(void)
1669{
1670 unsigned long ckil, osc, ckih1, ckih2;
1671
1672 clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
1673 return mx53_clocks_init(ckil, osc, ckih1, ckih2);
1674}
1675#endif
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
index aa15c517d06..8eb15a2fcaf 100644
--- a/arch/arm/mach-imx/cpu-imx5.c
+++ b/arch/arm/mach-imx/cpu-imx5.c
@@ -62,11 +62,8 @@ EXPORT_SYMBOL(mx51_revision);
62 * Dependent on link order - so the assumption is that vfp_init is called 62 * Dependent on link order - so the assumption is that vfp_init is called
63 * before us. 63 * before us.
64 */ 64 */
65static int __init mx51_neon_fixup(void) 65int __init mx51_neon_fixup(void)
66{ 66{
67 if (!cpu_is_mx51())
68 return 0;
69
70 if (mx51_revision() < IMX_CHIP_REVISION_3_0 && 67 if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
71 (elf_hwcap & HWCAP_NEON)) { 68 (elf_hwcap & HWCAP_NEON)) {
72 elf_hwcap &= ~HWCAP_NEON; 69 elf_hwcap &= ~HWCAP_NEON;
@@ -75,7 +72,6 @@ static int __init mx51_neon_fixup(void)
75 return 0; 72 return 0;
76} 73}
77 74
78late_initcall(mx51_neon_fixup);
79#endif 75#endif
80 76
81static int get_mx53_srev(void) 77static int get_mx53_srev(void)
diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
index 53141273df4..a1dfde53e33 100644
--- a/arch/arm/mach-imx/crmregs-imx3.h
+++ b/arch/arm/mach-imx/crmregs-imx3.h
@@ -24,48 +24,47 @@
24#define CKIH_CLK_FREQ_27MHZ 27000000 24#define CKIH_CLK_FREQ_27MHZ 27000000
25#define CKIL_CLK_FREQ 32768 25#define CKIL_CLK_FREQ 32768
26 26
27#define MXC_CCM_BASE (cpu_is_mx31() ? \ 27extern void __iomem *mx3_ccm_base;
28MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR))
29 28
30/* Register addresses */ 29/* Register addresses */
31#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00) 30#define MXC_CCM_CCMR 0x00
32#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04) 31#define MXC_CCM_PDR0 0x04
33#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08) 32#define MXC_CCM_PDR1 0x08
34#define MX35_CCM_PDR2 (MXC_CCM_BASE + 0x0C) 33#define MX35_CCM_PDR2 0x0C
35#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C) 34#define MXC_CCM_RCSR 0x0C
36#define MX35_CCM_PDR3 (MXC_CCM_BASE + 0x10) 35#define MX35_CCM_PDR3 0x10
37#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10) 36#define MXC_CCM_MPCTL 0x10
38#define MX35_CCM_PDR4 (MXC_CCM_BASE + 0x14) 37#define MX35_CCM_PDR4 0x14
39#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14) 38#define MXC_CCM_UPCTL 0x14
40#define MX35_CCM_RCSR (MXC_CCM_BASE + 0x18) 39#define MX35_CCM_RCSR 0x18
41#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18) 40#define MXC_CCM_SRPCTL 0x18
42#define MX35_CCM_MPCTL (MXC_CCM_BASE + 0x1C) 41#define MX35_CCM_MPCTL 0x1C
43#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C) 42#define MXC_CCM_COSR 0x1C
44#define MX35_CCM_PPCTL (MXC_CCM_BASE + 0x20) 43#define MX35_CCM_PPCTL 0x20
45#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20) 44#define MXC_CCM_CGR0 0x20
46#define MX35_CCM_ACMR (MXC_CCM_BASE + 0x24) 45#define MX35_CCM_ACMR 0x24
47#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24) 46#define MXC_CCM_CGR1 0x24
48#define MX35_CCM_COSR (MXC_CCM_BASE + 0x28) 47#define MX35_CCM_COSR 0x28
49#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28) 48#define MXC_CCM_CGR2 0x28
50#define MX35_CCM_CGR0 (MXC_CCM_BASE + 0x2C) 49#define MX35_CCM_CGR0 0x2C
51#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C) 50#define MXC_CCM_WIMR 0x2C
52#define MX35_CCM_CGR1 (MXC_CCM_BASE + 0x30) 51#define MX35_CCM_CGR1 0x30
53#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30) 52#define MXC_CCM_LDC 0x30
54#define MX35_CCM_CGR2 (MXC_CCM_BASE + 0x34) 53#define MX35_CCM_CGR2 0x34
55#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34) 54#define MXC_CCM_DCVR0 0x34
56#define MX35_CCM_CGR3 (MXC_CCM_BASE + 0x38) 55#define MX35_CCM_CGR3 0x38
57#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38) 56#define MXC_CCM_DCVR1 0x38
58#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C) 57#define MXC_CCM_DCVR2 0x3C
59#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40) 58#define MXC_CCM_DCVR3 0x40
60#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44) 59#define MXC_CCM_LTR0 0x44
61#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48) 60#define MXC_CCM_LTR1 0x48
62#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C) 61#define MXC_CCM_LTR2 0x4C
63#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50) 62#define MXC_CCM_LTR3 0x50
64#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54) 63#define MXC_CCM_LTBR0 0x54
65#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58) 64#define MXC_CCM_LTBR1 0x58
66#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C) 65#define MXC_CCM_PMCR0 0x5C
67#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60) 66#define MXC_CCM_PMCR1 0x60
68#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64) 67#define MXC_CCM_PDR2 0x64
69 68
70/* Register bit definitions */ 69/* Register bit definitions */
71#define MXC_CCM_CCMR_WBEN (1 << 27) 70#define MXC_CCM_CCMR_WBEN (1 << 27)
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index 5f577fbda2c..18e78dba429 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -118,6 +118,7 @@ DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
118 .handle_irq = imx51_handle_irq, 118 .handle_irq = imx51_handle_irq,
119 .timer = &imx51_timer, 119 .timer = &imx51_timer,
120 .init_machine = imx51_dt_init, 120 .init_machine = imx51_dt_init,
121 .init_late = imx51_init_late,
121 .dt_compat = imx51_dt_board_compat, 122 .dt_compat = imx51_dt_board_compat,
122 .restart = mxc_restart, 123 .restart = mxc_restart,
123MACHINE_END 124MACHINE_END
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 574eca4b89a..eb04b6248e4 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -10,6 +10,9 @@
10 * http://www.gnu.org/copyleft/gpl.html 10 * http://www.gnu.org/copyleft/gpl.html
11 */ 11 */
12 12
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/err.h>
13#include <linux/io.h> 16#include <linux/io.h>
14#include <linux/irq.h> 17#include <linux/irq.h>
15#include <linux/irqdomain.h> 18#include <linux/irqdomain.h>
@@ -81,6 +84,19 @@ static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
81 { /* sentinel */ } 84 { /* sentinel */ }
82}; 85};
83 86
87static void __init imx53_qsb_init(void)
88{
89 struct clk *clk;
90
91 clk = clk_get_sys(NULL, "ssi_ext1");
92 if (IS_ERR(clk)) {
93 pr_err("failed to get clk ssi_ext1\n");
94 return;
95 }
96
97 clk_register_clkdev(clk, NULL, "0-000a");
98}
99
84static void __init imx53_dt_init(void) 100static void __init imx53_dt_init(void)
85{ 101{
86 struct device_node *node; 102 struct device_node *node;
@@ -99,6 +115,9 @@ static void __init imx53_dt_init(void)
99 of_node_put(node); 115 of_node_put(node);
100 } 116 }
101 117
118 if (of_machine_is_compatible("fsl,imx53-qsb"))
119 imx53_qsb_init();
120
102 of_platform_populate(NULL, of_default_bus_match_table, 121 of_platform_populate(NULL, of_default_bus_match_table,
103 imx53_auxdata_lookup, NULL); 122 imx53_auxdata_lookup, NULL);
104} 123}
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
index 0213f8dcee8..c40a34c0048 100644
--- a/arch/arm/mach-imx/lluart.c
+++ b/arch/arm/mach-imx/lluart.c
@@ -17,6 +17,12 @@
17#include <mach/hardware.h> 17#include <mach/hardware.h>
18 18
19static struct map_desc imx_lluart_desc = { 19static struct map_desc imx_lluart_desc = {
20#ifdef CONFIG_DEBUG_IMX6Q_UART2
21 .virtual = MX6Q_IO_P2V(MX6Q_UART2_BASE_ADDR),
22 .pfn = __phys_to_pfn(MX6Q_UART2_BASE_ADDR),
23 .length = MX6Q_UART2_SIZE,
24 .type = MT_DEVICE,
25#endif
20#ifdef CONFIG_DEBUG_IMX6Q_UART4 26#ifdef CONFIG_DEBUG_IMX6Q_UART4
21 .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR), 27 .virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
22 .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR), 28 .pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c
index ce341a6874f..ac50f1671e3 100644
--- a/arch/arm/mach-imx/mach-cpuimx51sd.c
+++ b/arch/arm/mach-imx/mach-cpuimx51sd.c
@@ -369,5 +369,6 @@ MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
369 .handle_irq = imx51_handle_irq, 369 .handle_irq = imx51_handle_irq,
370 .timer = &mxc_timer, 370 .timer = &mxc_timer,
371 .init_machine = eukrea_cpuimx51sd_init, 371 .init_machine = eukrea_cpuimx51sd_init,
372 .init_late = imx51_init_late,
372 .restart = mxc_restart, 373 .restart = mxc_restart,
373MACHINE_END 374MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 3df360a52c1..b47e98b7d53 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -10,6 +10,8 @@
10 * http://www.gnu.org/copyleft/gpl.html 10 * http://www.gnu.org/copyleft/gpl.html
11 */ 11 */
12 12
13#include <linux/clk.h>
14#include <linux/clkdev.h>
13#include <linux/delay.h> 15#include <linux/delay.h>
14#include <linux/init.h> 16#include <linux/init.h>
15#include <linux/io.h> 17#include <linux/io.h>
@@ -64,18 +66,53 @@ soft:
64/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ 66/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
65static int ksz9021rn_phy_fixup(struct phy_device *phydev) 67static int ksz9021rn_phy_fixup(struct phy_device *phydev)
66{ 68{
67 /* min rx data delay */ 69 if (IS_ENABLED(CONFIG_PHYLIB)) {
68 phy_write(phydev, 0x0b, 0x8105); 70 /* min rx data delay */
69 phy_write(phydev, 0x0c, 0x0000); 71 phy_write(phydev, 0x0b, 0x8105);
72 phy_write(phydev, 0x0c, 0x0000);
70 73
71 /* max rx/tx clock delay, min rx/tx control delay */ 74 /* max rx/tx clock delay, min rx/tx control delay */
72 phy_write(phydev, 0x0b, 0x8104); 75 phy_write(phydev, 0x0b, 0x8104);
73 phy_write(phydev, 0x0c, 0xf0f0); 76 phy_write(phydev, 0x0c, 0xf0f0);
74 phy_write(phydev, 0x0b, 0x104); 77 phy_write(phydev, 0x0b, 0x104);
78 }
75 79
76 return 0; 80 return 0;
77} 81}
78 82
83static void __init imx6q_sabrelite_cko1_setup(void)
84{
85 struct clk *cko1_sel, *ahb, *cko1;
86 unsigned long rate;
87
88 cko1_sel = clk_get_sys(NULL, "cko1_sel");
89 ahb = clk_get_sys(NULL, "ahb");
90 cko1 = clk_get_sys(NULL, "cko1");
91 if (IS_ERR(cko1_sel) || IS_ERR(ahb) || IS_ERR(cko1)) {
92 pr_err("cko1 setup failed!\n");
93 goto put_clk;
94 }
95 clk_set_parent(cko1_sel, ahb);
96 rate = clk_round_rate(cko1, 16000000);
97 clk_set_rate(cko1, rate);
98 clk_register_clkdev(cko1, NULL, "0-000a");
99put_clk:
100 if (!IS_ERR(cko1_sel))
101 clk_put(cko1_sel);
102 if (!IS_ERR(ahb))
103 clk_put(ahb);
104 if (!IS_ERR(cko1))
105 clk_put(cko1);
106}
107
108static void __init imx6q_sabrelite_init(void)
109{
110 if (IS_ENABLED(CONFIG_PHYLIB))
111 phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
112 ksz9021rn_phy_fixup);
113 imx6q_sabrelite_cko1_setup();
114}
115
79static void __init imx6q_init_machine(void) 116static void __init imx6q_init_machine(void)
80{ 117{
81 /* 118 /*
@@ -85,8 +122,7 @@ static void __init imx6q_init_machine(void)
85 pinctrl_provide_dummies(); 122 pinctrl_provide_dummies();
86 123
87 if (of_machine_is_compatible("fsl,imx6q-sabrelite")) 124 if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
88 phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, 125 imx6q_sabrelite_init();
89 ksz9021rn_phy_fixup);
90 126
91 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 127 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
92 128
@@ -139,6 +175,7 @@ static struct sys_timer imx6q_timer = {
139static const char *imx6q_dt_compat[] __initdata = { 175static const char *imx6q_dt_compat[] __initdata = {
140 "fsl,imx6q-arm2", 176 "fsl,imx6q-arm2",
141 "fsl,imx6q-sabrelite", 177 "fsl,imx6q-sabrelite",
178 "fsl,imx6q-sabresd",
142 "fsl,imx6q", 179 "fsl,imx6q",
143 NULL, 180 NULL,
144}; 181};
diff --git a/arch/arm/mach-imx/mach-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c
index 83eab4176ca..3c5b163923f 100644
--- a/arch/arm/mach-imx/mach-mx51_3ds.c
+++ b/arch/arm/mach-imx/mach-mx51_3ds.c
@@ -175,5 +175,6 @@ MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
175 .handle_irq = imx51_handle_irq, 175 .handle_irq = imx51_handle_irq,
176 .timer = &mx51_3ds_timer, 176 .timer = &mx51_3ds_timer,
177 .init_machine = mx51_3ds_init, 177 .init_machine = mx51_3ds_init,
178 .init_late = imx51_init_late,
178 .restart = mxc_restart, 179 .restart = mxc_restart,
179MACHINE_END 180MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c
index e4b822e9f71..dde397014d4 100644
--- a/arch/arm/mach-imx/mach-mx51_babbage.c
+++ b/arch/arm/mach-imx/mach-mx51_babbage.c
@@ -163,6 +163,12 @@ static iomux_v3_cfg_t mx51babbage_pads[] = {
163 MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, 163 MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
164 MX51_PAD_CSPI1_SS0__GPIO4_24, 164 MX51_PAD_CSPI1_SS0__GPIO4_24,
165 MX51_PAD_CSPI1_SS1__GPIO4_25, 165 MX51_PAD_CSPI1_SS1__GPIO4_25,
166
167 /* Audio */
168 MX51_PAD_AUD3_BB_TXD__AUD3_TXD,
169 MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
170 MX51_PAD_AUD3_BB_CK__AUD3_TXC,
171 MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
166}; 172};
167 173
168/* Serial ports */ 174/* Serial ports */
@@ -426,5 +432,6 @@ MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
426 .handle_irq = imx51_handle_irq, 432 .handle_irq = imx51_handle_irq,
427 .timer = &mx51_babbage_timer, 433 .timer = &mx51_babbage_timer,
428 .init_machine = mx51_babbage_init, 434 .init_machine = mx51_babbage_init,
435 .init_late = imx51_init_late,
429 .restart = mxc_restart, 436 .restart = mxc_restart,
430MACHINE_END 437MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_efikamx.c b/arch/arm/mach-imx/mach-mx51_efikamx.c
index 86e96ef11f9..8d09c0126ca 100644
--- a/arch/arm/mach-imx/mach-mx51_efikamx.c
+++ b/arch/arm/mach-imx/mach-mx51_efikamx.c
@@ -207,29 +207,32 @@ static void mx51_efikamx_power_off(void)
207 207
208static int __init mx51_efikamx_power_init(void) 208static int __init mx51_efikamx_power_init(void)
209{ 209{
210 if (machine_is_mx51_efikamx()) { 210 pwgt1 = regulator_get(NULL, "pwgt1");
211 pwgt1 = regulator_get(NULL, "pwgt1"); 211 pwgt2 = regulator_get(NULL, "pwgt2");
212 pwgt2 = regulator_get(NULL, "pwgt2"); 212 if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
213 if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { 213 regulator_enable(pwgt1);
214 regulator_enable(pwgt1); 214 regulator_enable(pwgt2);
215 regulator_enable(pwgt2); 215 }
216 } 216 gpio_request(EFIKAMX_POWEROFF, "poweroff");
217 gpio_request(EFIKAMX_POWEROFF, "poweroff"); 217 pm_power_off = mx51_efikamx_power_off;
218 pm_power_off = mx51_efikamx_power_off; 218
219 219 /* enable coincell charger. maybe need a small power driver ? */
220 /* enable coincell charger. maybe need a small power driver ? */ 220 coincell = regulator_get(NULL, "coincell");
221 coincell = regulator_get(NULL, "coincell"); 221 if (!IS_ERR(coincell)) {
222 if (!IS_ERR(coincell)) { 222 regulator_set_voltage(coincell, 3000000, 3000000);
223 regulator_set_voltage(coincell, 3000000, 3000000); 223 regulator_enable(coincell);
224 regulator_enable(coincell);
225 }
226
227 regulator_has_full_constraints();
228 } 224 }
229 225
226 regulator_has_full_constraints();
227
230 return 0; 228 return 0;
231} 229}
232late_initcall(mx51_efikamx_power_init); 230
231static void __init mx51_efikamx_init_late(void)
232{
233 imx51_init_late();
234 mx51_efikamx_power_init();
235}
233 236
234static void __init mx51_efikamx_init(void) 237static void __init mx51_efikamx_init(void)
235{ 238{
@@ -292,5 +295,6 @@ MACHINE_START(MX51_EFIKAMX, "Genesi Efika MX (Smarttop)")
292 .handle_irq = imx51_handle_irq, 295 .handle_irq = imx51_handle_irq,
293 .timer = &mx51_efikamx_timer, 296 .timer = &mx51_efikamx_timer,
294 .init_machine = mx51_efikamx_init, 297 .init_machine = mx51_efikamx_init,
298 .init_late = mx51_efikamx_init_late,
295 .restart = mx51_efikamx_restart, 299 .restart = mx51_efikamx_restart,
296MACHINE_END 300MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_efikasb.c b/arch/arm/mach-imx/mach-mx51_efikasb.c
index 88f837a6cc7..fdbd181b97e 100644
--- a/arch/arm/mach-imx/mach-mx51_efikasb.c
+++ b/arch/arm/mach-imx/mach-mx51_efikasb.c
@@ -211,22 +211,25 @@ static void mx51_efikasb_power_off(void)
211 211
212static int __init mx51_efikasb_power_init(void) 212static int __init mx51_efikasb_power_init(void)
213{ 213{
214 if (machine_is_mx51_efikasb()) { 214 pwgt1 = regulator_get(NULL, "pwgt1");
215 pwgt1 = regulator_get(NULL, "pwgt1"); 215 pwgt2 = regulator_get(NULL, "pwgt2");
216 pwgt2 = regulator_get(NULL, "pwgt2"); 216 if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
217 if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { 217 regulator_enable(pwgt1);
218 regulator_enable(pwgt1); 218 regulator_enable(pwgt2);
219 regulator_enable(pwgt2);
220 }
221 gpio_request(EFIKASB_POWEROFF, "poweroff");
222 pm_power_off = mx51_efikasb_power_off;
223
224 regulator_has_full_constraints();
225 } 219 }
220 gpio_request(EFIKASB_POWEROFF, "poweroff");
221 pm_power_off = mx51_efikasb_power_off;
222
223 regulator_has_full_constraints();
226 224
227 return 0; 225 return 0;
228} 226}
229late_initcall(mx51_efikasb_power_init); 227
228static void __init mx51_efikasb_init_late(void)
229{
230 imx51_init_late();
231 mx51_efikasb_power_init();
232}
230 233
231/* 01 R1.3 board 234/* 01 R1.3 board
232 10 R2.0 board */ 235 10 R2.0 board */
@@ -287,6 +290,7 @@ MACHINE_START(MX51_EFIKASB, "Genesi Efika MX (Smartbook)")
287 .init_irq = mx51_init_irq, 290 .init_irq = mx51_init_irq,
288 .handle_irq = imx51_handle_irq, 291 .handle_irq = imx51_handle_irq,
289 .init_machine = efikasb_board_init, 292 .init_machine = efikasb_board_init,
293 .init_late = mx51_efikasb_init_late,
290 .timer = &mx51_efikasb_timer, 294 .timer = &mx51_efikasb_timer,
291 .restart = mxc_restart, 295 .restart = mxc_restart,
292MACHINE_END 296MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index 10c9795934a..0a40004154f 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -694,6 +694,11 @@ static void __init pcm037_reserve(void)
694 MX3_CAMERA_BUF_SIZE); 694 MX3_CAMERA_BUF_SIZE);
695} 695}
696 696
697static void __init pcm037_init_late(void)
698{
699 pcm037_eet_init_devices();
700}
701
697MACHINE_START(PCM037, "Phytec Phycore pcm037") 702MACHINE_START(PCM037, "Phytec Phycore pcm037")
698 /* Maintainer: Pengutronix */ 703 /* Maintainer: Pengutronix */
699 .atag_offset = 0x100, 704 .atag_offset = 0x100,
@@ -704,5 +709,6 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
704 .handle_irq = imx31_handle_irq, 709 .handle_irq = imx31_handle_irq,
705 .timer = &pcm037_timer, 710 .timer = &pcm037_timer,
706 .init_machine = pcm037_init, 711 .init_machine = pcm037_init,
712 .init_late = pcm037_init_late,
707 .restart = mxc_restart, 713 .restart = mxc_restart,
708MACHINE_END 714MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c
index 1b7606bef8f..11ffa81ad17 100644
--- a/arch/arm/mach-imx/mach-pcm037_eet.c
+++ b/arch/arm/mach-imx/mach-pcm037_eet.c
@@ -160,9 +160,9 @@ static const struct gpio_keys_platform_data
160 .rep = 0, /* No auto-repeat */ 160 .rep = 0, /* No auto-repeat */
161}; 161};
162 162
163static int __init eet_init_devices(void) 163int __init pcm037_eet_init_devices(void)
164{ 164{
165 if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) 165 if (pcm037_variant() != PCM037_EET)
166 return 0; 166 return 0;
167 167
168 mxc_iomux_setup_multiple_pins(pcm037_eet_pins, 168 mxc_iomux_setup_multiple_pins(pcm037_eet_pins,
@@ -176,4 +176,3 @@ static int __init eet_init_devices(void)
176 176
177 return 0; 177 return 0;
178} 178}
179late_initcall(eet_init_devices);
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 9128d15b1eb..967ed5b35a4 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -32,6 +32,10 @@
32#include <mach/iomux-v3.h> 32#include <mach/iomux-v3.h>
33#include <mach/irqs.h> 33#include <mach/irqs.h>
34 34
35#include "crmregs-imx3.h"
36
37void __iomem *mx3_ccm_base;
38
35static void imx3_idle(void) 39static void imx3_idle(void)
36{ 40{
37 unsigned long reg = 0; 41 unsigned long reg = 0;
@@ -138,6 +142,7 @@ void __init imx31_init_early(void)
138 mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); 142 mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
139 arch_ioremap_caller = imx3_ioremap_caller; 143 arch_ioremap_caller = imx3_ioremap_caller;
140 arm_pm_idle = imx3_idle; 144 arm_pm_idle = imx3_idle;
145 mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
141} 146}
142 147
143void __init mx31_init_irq(void) 148void __init mx31_init_irq(void)
@@ -211,6 +216,7 @@ void __init imx35_init_early(void)
211 mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); 216 mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
212 arm_pm_idle = imx3_idle; 217 arm_pm_idle = imx3_idle;
213 arch_ioremap_caller = imx3_ioremap_caller; 218 arch_ioremap_caller = imx3_ioremap_caller;
219 mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
214} 220}
215 221
216void __init mx35_init_irq(void) 222void __init mx35_init_irq(void)
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index ba91e6b31cf..feeee17da96 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -33,6 +33,7 @@ static void imx5_idle(void)
33 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); 33 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
34 if (IS_ERR(gpc_dvfs_clk)) 34 if (IS_ERR(gpc_dvfs_clk))
35 return; 35 return;
36 clk_prepare(gpc_dvfs_clk);
36 } 37 }
37 clk_enable(gpc_dvfs_clk); 38 clk_enable(gpc_dvfs_clk);
38 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); 39 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
@@ -236,3 +237,8 @@ void __init imx53_soc_init(void)
236 platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res, 237 platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
237 ARRAY_SIZE(imx53_audmux_res)); 238 ARRAY_SIZE(imx53_audmux_res));
238} 239}
240
241void __init imx51_init_late(void)
242{
243 mx51_neon_fixup();
244}
diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h
index d6929721a5f..7d167690e17 100644
--- a/arch/arm/mach-imx/pcm037.h
+++ b/arch/arm/mach-imx/pcm037.h
@@ -8,4 +8,10 @@ enum pcm037_board_variant {
8 8
9extern enum pcm037_board_variant pcm037_variant(void); 9extern enum pcm037_board_variant pcm037_variant(void);
10 10
11#ifdef CONFIG_MACH_PCM037_EET
12int pcm037_eet_init_devices(void);
13#else
14static inline int pcm037_eet_init_devices(void) { return 0; }
15#endif
16
11#endif 17#endif
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
index b3752439632..822103bdb70 100644
--- a/arch/arm/mach-imx/pm-imx3.c
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -21,14 +21,14 @@
21 */ 21 */
22void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) 22void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
23{ 23{
24 int reg = __raw_readl(MXC_CCM_CCMR); 24 int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR);
25 reg &= ~MXC_CCM_CCMR_LPM_MASK; 25 reg &= ~MXC_CCM_CCMR_LPM_MASK;
26 26
27 switch (mode) { 27 switch (mode) {
28 case MX3_WAIT: 28 case MX3_WAIT:
29 if (cpu_is_mx35()) 29 if (cpu_is_mx35())
30 reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; 30 reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
31 __raw_writel(reg, MXC_CCM_CCMR); 31 __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
32 break; 32 break;
33 default: 33 default:
34 pr_err("Unknown cpu power mode: %d\n", mode); 34 pr_err("Unknown cpu power mode: %d\n", mode);
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c
index 985453994dd..55e357ab292 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -27,7 +27,6 @@
27#include <linux/mtd/physmap.h> 27#include <linux/mtd/physmap.h>
28#include <linux/spi/flash.h> 28#include <linux/spi/flash.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/spi/orion_spi.h>
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <asm/mach/arch.h> 31#include <asm/mach/arch.h>
33#include <asm/mach/map.h> 32#include <asm/mach/map.h>
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 10d1969b9e3..edc3f8a9d45 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -43,6 +43,9 @@ static void __init kirkwood_dt_init(void)
43 kirkwood_l2_init(); 43 kirkwood_l2_init();
44#endif 44#endif
45 45
46 /* Setup root of clk tree */
47 kirkwood_clk_init();
48
46 /* internal devices that every board has */ 49 /* internal devices that every board has */
47 kirkwood_wdt_init(); 50 kirkwood_wdt_init();
48 kirkwood_xor0_init(); 51 kirkwood_xor0_init();
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 3ad037385a5..25fb3fd418e 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -15,7 +15,8 @@
15#include <linux/ata_platform.h> 15#include <linux/ata_platform.h>
16#include <linux/mtd/nand.h> 16#include <linux/mtd/nand.h>
17#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
18#include <linux/of.h> 18#include <linux/clk-provider.h>
19#include <linux/spinlock.h>
19#include <net/dsa.h> 20#include <net/dsa.h>
20#include <asm/page.h> 21#include <asm/page.h>
21#include <asm/timex.h> 22#include <asm/timex.h>
@@ -32,6 +33,7 @@
32#include <plat/common.h> 33#include <plat/common.h>
33#include <plat/time.h> 34#include <plat/time.h>
34#include <plat/addr-map.h> 35#include <plat/addr-map.h>
36#include <plat/mv_xor.h>
35#include "common.h" 37#include "common.h"
36 38
37/***************************************************************************** 39/*****************************************************************************
@@ -61,20 +63,188 @@ void __init kirkwood_map_io(void)
61 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); 63 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
62} 64}
63 65
64/* 66/*****************************************************************************
65 * Default clock control bits. Any bit _not_ set in this variable 67 * CLK tree
66 * will be cleared from the hardware after platform devices have been 68 ****************************************************************************/
67 * registered. Some reserved bits must be set to 1. 69
68 */ 70static void disable_sata0(void)
69unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; 71{
72 /* Disable PLL and IVREF */
73 writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
74 /* Disable PHY */
75 writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
76}
77
78static void disable_sata1(void)
79{
80 /* Disable PLL and IVREF */
81 writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
82 /* Disable PHY */
83 writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
84}
85
86static void disable_pcie0(void)
87{
88 writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
89 while (1)
90 if (readl(PCIE_STATUS) & 0x1)
91 break;
92 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
93}
94
95static void disable_pcie1(void)
96{
97 u32 dev, rev;
98
99 kirkwood_pcie_id(&dev, &rev);
100
101 if (dev == MV88F6282_DEV_ID) {
102 writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
103 while (1)
104 if (readl(PCIE1_STATUS) & 0x1)
105 break;
106 writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
107 }
108}
109
110/* An extended version of the gated clk. This calls fn() before
111 * disabling the clock. We use this to turn off PHYs etc. */
112struct clk_gate_fn {
113 struct clk_gate gate;
114 void (*fn)(void);
115};
116
117#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate)
118#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
119
120static void clk_gate_fn_disable(struct clk_hw *hw)
121{
122 struct clk_gate *gate = to_clk_gate(hw);
123 struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
124
125 if (gate_fn->fn)
126 gate_fn->fn();
127
128 clk_gate_ops.disable(hw);
129}
130
131static struct clk_ops clk_gate_fn_ops;
132
133static struct clk __init *clk_register_gate_fn(struct device *dev,
134 const char *name,
135 const char *parent_name, unsigned long flags,
136 void __iomem *reg, u8 bit_idx,
137 u8 clk_gate_flags, spinlock_t *lock,
138 void (*fn)(void))
139{
140 struct clk_gate_fn *gate_fn;
141 struct clk *clk;
142 struct clk_init_data init;
143
144 gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL);
145 if (!gate_fn) {
146 pr_err("%s: could not allocate gated clk\n", __func__);
147 return ERR_PTR(-ENOMEM);
148 }
149
150 init.name = name;
151 init.ops = &clk_gate_fn_ops;
152 init.flags = flags;
153 init.parent_names = (parent_name ? &parent_name : NULL);
154 init.num_parents = (parent_name ? 1 : 0);
155
156 /* struct clk_gate assignments */
157 gate_fn->gate.reg = reg;
158 gate_fn->gate.bit_idx = bit_idx;
159 gate_fn->gate.flags = clk_gate_flags;
160 gate_fn->gate.lock = lock;
161 gate_fn->gate.hw.init = &init;
162
163 /* ops is the gate ops, but with our disable function */
164 if (clk_gate_fn_ops.disable != clk_gate_fn_disable) {
165 clk_gate_fn_ops = clk_gate_ops;
166 clk_gate_fn_ops.disable = clk_gate_fn_disable;
167 }
70 168
169 clk = clk_register(dev, &gate_fn->gate.hw);
170
171 if (IS_ERR(clk))
172 kfree(gate_fn);
173
174 return clk;
175}
176
177static DEFINE_SPINLOCK(gating_lock);
178static struct clk *tclk;
179
180static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
181{
182 return clk_register_gate(NULL, name, "tclk", 0,
183 (void __iomem *)CLOCK_GATING_CTRL,
184 bit_idx, 0, &gating_lock);
185}
186
187static struct clk __init *kirkwood_register_gate_fn(const char *name,
188 u8 bit_idx,
189 void (*fn)(void))
190{
191 return clk_register_gate_fn(NULL, name, "tclk", 0,
192 (void __iomem *)CLOCK_GATING_CTRL,
193 bit_idx, 0, &gating_lock, fn);
194}
195
196void __init kirkwood_clk_init(void)
197{
198 struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio;
199 struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio;
200
201 tclk = clk_register_fixed_rate(NULL, "tclk", NULL,
202 CLK_IS_ROOT, kirkwood_tclk);
203
204 runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT);
205 ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
206 ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
207 sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0,
208 disable_sata0);
209 sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1,
210 disable_sata1);
211 usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0);
212 sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO);
213 crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
214 xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0);
215 xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1);
216 pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0,
217 disable_pcie0);
218 pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1,
219 disable_pcie1);
220 audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO);
221 kirkwood_register_gate("tdm", CGC_BIT_TDM);
222 kirkwood_register_gate("tsu", CGC_BIT_TSU);
223
224 /* clkdev entries, mapping clks to devices */
225 orion_clkdev_add(NULL, "orion_spi.0", runit);
226 orion_clkdev_add(NULL, "orion_spi.1", runit);
227 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0);
228 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1);
229 orion_clkdev_add(NULL, "orion_wdt", tclk);
230 orion_clkdev_add("0", "sata_mv.0", sata0);
231 orion_clkdev_add("1", "sata_mv.0", sata1);
232 orion_clkdev_add(NULL, "orion-ehci.0", usb0);
233 orion_clkdev_add(NULL, "orion_nand", runit);
234 orion_clkdev_add(NULL, "mvsdio", sdio);
235 orion_clkdev_add(NULL, "mv_crypto", crypto);
236 orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0);
237 orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1);
238 orion_clkdev_add("0", "pcie", pex0);
239 orion_clkdev_add("1", "pcie", pex1);
240 orion_clkdev_add(NULL, "kirkwood-i2s", audio);
241}
71 242
72/***************************************************************************** 243/*****************************************************************************
73 * EHCI0 244 * EHCI0
74 ****************************************************************************/ 245 ****************************************************************************/
75void __init kirkwood_ehci_init(void) 246void __init kirkwood_ehci_init(void)
76{ 247{
77 kirkwood_clk_ctrl |= CGC_USB0;
78 orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); 248 orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
79} 249}
80 250
@@ -84,11 +254,9 @@ void __init kirkwood_ehci_init(void)
84 ****************************************************************************/ 254 ****************************************************************************/
85void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) 255void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
86{ 256{
87 kirkwood_clk_ctrl |= CGC_GE0;
88
89 orion_ge00_init(eth_data, 257 orion_ge00_init(eth_data,
90 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, 258 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
91 IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); 259 IRQ_KIRKWOOD_GE00_ERR);
92} 260}
93 261
94 262
@@ -97,12 +265,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
97 ****************************************************************************/ 265 ****************************************************************************/
98void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) 266void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
99{ 267{
100
101 kirkwood_clk_ctrl |= CGC_GE1;
102
103 orion_ge01_init(eth_data, 268 orion_ge01_init(eth_data,
104 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, 269 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
105 IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); 270 IRQ_KIRKWOOD_GE01_ERR);
106} 271}
107 272
108 273
@@ -144,7 +309,6 @@ static struct platform_device kirkwood_nand_flash = {
144void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, 309void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
145 int chip_delay) 310 int chip_delay)
146{ 311{
147 kirkwood_clk_ctrl |= CGC_RUNIT;
148 kirkwood_nand_data.parts = parts; 312 kirkwood_nand_data.parts = parts;
149 kirkwood_nand_data.nr_parts = nr_parts; 313 kirkwood_nand_data.nr_parts = nr_parts;
150 kirkwood_nand_data.chip_delay = chip_delay; 314 kirkwood_nand_data.chip_delay = chip_delay;
@@ -154,7 +318,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
154void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, 318void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
155 int (*dev_ready)(struct mtd_info *)) 319 int (*dev_ready)(struct mtd_info *))
156{ 320{
157 kirkwood_clk_ctrl |= CGC_RUNIT;
158 kirkwood_nand_data.parts = parts; 321 kirkwood_nand_data.parts = parts;
159 kirkwood_nand_data.nr_parts = nr_parts; 322 kirkwood_nand_data.nr_parts = nr_parts;
160 kirkwood_nand_data.dev_ready = dev_ready; 323 kirkwood_nand_data.dev_ready = dev_ready;
@@ -175,10 +338,6 @@ static void __init kirkwood_rtc_init(void)
175 ****************************************************************************/ 338 ****************************************************************************/
176void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) 339void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
177{ 340{
178 kirkwood_clk_ctrl |= CGC_SATA0;
179 if (sata_data->n_ports > 1)
180 kirkwood_clk_ctrl |= CGC_SATA1;
181
182 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); 341 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
183} 342}
184 343
@@ -221,7 +380,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
221 mvsdio_data->clock = 100000000; 380 mvsdio_data->clock = 100000000;
222 else 381 else
223 mvsdio_data->clock = 200000000; 382 mvsdio_data->clock = 200000000;
224 kirkwood_clk_ctrl |= CGC_SDIO;
225 kirkwood_sdio.dev.platform_data = mvsdio_data; 383 kirkwood_sdio.dev.platform_data = mvsdio_data;
226 platform_device_register(&kirkwood_sdio); 384 platform_device_register(&kirkwood_sdio);
227} 385}
@@ -232,8 +390,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
232 ****************************************************************************/ 390 ****************************************************************************/
233void __init kirkwood_spi_init() 391void __init kirkwood_spi_init()
234{ 392{
235 kirkwood_clk_ctrl |= CGC_RUNIT; 393 orion_spi_init(SPI_PHYS_BASE);
236 orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
237} 394}
238 395
239 396
@@ -253,7 +410,7 @@ void __init kirkwood_i2c_init(void)
253void __init kirkwood_uart0_init(void) 410void __init kirkwood_uart0_init(void)
254{ 411{
255 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, 412 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
256 IRQ_KIRKWOOD_UART_0, kirkwood_tclk); 413 IRQ_KIRKWOOD_UART_0, tclk);
257} 414}
258 415
259 416
@@ -263,7 +420,7 @@ void __init kirkwood_uart0_init(void)
263void __init kirkwood_uart1_init(void) 420void __init kirkwood_uart1_init(void)
264{ 421{
265 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, 422 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
266 IRQ_KIRKWOOD_UART_1, kirkwood_tclk); 423 IRQ_KIRKWOOD_UART_1, tclk);
267} 424}
268 425
269/***************************************************************************** 426/*****************************************************************************
@@ -271,7 +428,6 @@ void __init kirkwood_uart1_init(void)
271 ****************************************************************************/ 428 ****************************************************************************/
272void __init kirkwood_crypto_init(void) 429void __init kirkwood_crypto_init(void)
273{ 430{
274 kirkwood_clk_ctrl |= CGC_CRYPTO;
275 orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, 431 orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
276 KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); 432 KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
277} 433}
@@ -282,8 +438,6 @@ void __init kirkwood_crypto_init(void)
282 ****************************************************************************/ 438 ****************************************************************************/
283void __init kirkwood_xor0_init(void) 439void __init kirkwood_xor0_init(void)
284{ 440{
285 kirkwood_clk_ctrl |= CGC_XOR0;
286
287 orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, 441 orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
288 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); 442 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
289} 443}
@@ -294,8 +448,6 @@ void __init kirkwood_xor0_init(void)
294 ****************************************************************************/ 448 ****************************************************************************/
295void __init kirkwood_xor1_init(void) 449void __init kirkwood_xor1_init(void)
296{ 450{
297 kirkwood_clk_ctrl |= CGC_XOR1;
298
299 orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, 451 orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
300 IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); 452 IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
301} 453}
@@ -306,7 +458,7 @@ void __init kirkwood_xor1_init(void)
306 ****************************************************************************/ 458 ****************************************************************************/
307void __init kirkwood_wdt_init(void) 459void __init kirkwood_wdt_init(void)
308{ 460{
309 orion_wdt_init(kirkwood_tclk); 461 orion_wdt_init();
310} 462}
311 463
312 464
@@ -382,7 +534,6 @@ static struct platform_device kirkwood_pcm_device = {
382 534
383void __init kirkwood_audio_init(void) 535void __init kirkwood_audio_init(void)
384{ 536{
385 kirkwood_clk_ctrl |= CGC_AUDIO;
386 platform_device_register(&kirkwood_i2s_device); 537 platform_device_register(&kirkwood_i2s_device);
387 platform_device_register(&kirkwood_pcm_device); 538 platform_device_register(&kirkwood_pcm_device);
388} 539}
@@ -466,6 +617,9 @@ void __init kirkwood_init(void)
466 kirkwood_l2_init(); 617 kirkwood_l2_init();
467#endif 618#endif
468 619
620 /* Setup root of clk tree */
621 kirkwood_clk_init();
622
469 /* internal devices that every board has */ 623 /* internal devices that every board has */
470 kirkwood_rtc_init(); 624 kirkwood_rtc_init();
471 kirkwood_wdt_init(); 625 kirkwood_wdt_init();
@@ -478,72 +632,6 @@ void __init kirkwood_init(void)
478#endif 632#endif
479} 633}
480 634
481static int __init kirkwood_clock_gate(void)
482{
483 unsigned int curr = readl(CLOCK_GATING_CTRL);
484 u32 dev, rev;
485
486#ifdef CONFIG_OF
487 struct device_node *np;
488#endif
489 kirkwood_pcie_id(&dev, &rev);
490 printk(KERN_DEBUG "Gating clock of unused units\n");
491 printk(KERN_DEBUG "before: 0x%08x\n", curr);
492
493 /* Make sure those units are accessible */
494 writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
495
496#ifdef CONFIG_OF
497 np = of_find_compatible_node(NULL, NULL, "mrvl,orion-nand");
498 if (np && of_device_is_available(np)) {
499 kirkwood_clk_ctrl |= CGC_RUNIT;
500 of_node_put(np);
501 }
502#endif
503
504 /* For SATA: first shutdown the phy */
505 if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
506 /* Disable PLL and IVREF */
507 writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
508 /* Disable PHY */
509 writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
510 }
511 if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
512 /* Disable PLL and IVREF */
513 writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
514 /* Disable PHY */
515 writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
516 }
517
518 /* For PCIe: first shutdown the phy */
519 if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
520 writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
521 while (1)
522 if (readl(PCIE_STATUS) & 0x1)
523 break;
524 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
525 }
526
527 /* For PCIe 1: first shutdown the phy */
528 if (dev == MV88F6282_DEV_ID) {
529 if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
530 writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
531 while (1)
532 if (readl(PCIE1_STATUS) & 0x1)
533 break;
534 writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
535 }
536 } else /* keep this bit set for devices that don't have PCIe1 */
537 kirkwood_clk_ctrl |= CGC_PEX1;
538
539 /* Now gate clock the required units */
540 writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
541 printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
542
543 return 0;
544}
545late_initcall(kirkwood_clock_gate);
546
547void kirkwood_restart(char mode, const char *cmd) 635void kirkwood_restart(char mode, const char *cmd)
548{ 636{
549 /* 637 /*
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index a34c41a5172..9248fa2c165 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -50,6 +50,7 @@ void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
50void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); 50void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *));
51void kirkwood_audio_init(void); 51void kirkwood_audio_init(void);
52void kirkwood_restart(char, const char *); 52void kirkwood_restart(char, const char *);
53void kirkwood_clk_init(void);
53 54
54/* board init functions for boards not fully converted to fdt */ 55/* board init functions for boards not fully converted to fdt */
55#ifdef CONFIG_MACH_DREAMPLUG_DT 56#ifdef CONFIG_MACH_DREAMPLUG_DT
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 957bd7997d7..3eee37a3b50 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -43,6 +43,22 @@
43#define L2_WRITETHROUGH 0x00000010 43#define L2_WRITETHROUGH 0x00000010
44 44
45#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c) 45#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c)
46#define CGC_BIT_GE0 (0)
47#define CGC_BIT_PEX0 (2)
48#define CGC_BIT_USB0 (3)
49#define CGC_BIT_SDIO (4)
50#define CGC_BIT_TSU (5)
51#define CGC_BIT_DUNIT (6)
52#define CGC_BIT_RUNIT (7)
53#define CGC_BIT_XOR0 (8)
54#define CGC_BIT_AUDIO (9)
55#define CGC_BIT_SATA0 (14)
56#define CGC_BIT_SATA1 (15)
57#define CGC_BIT_XOR1 (16)
58#define CGC_BIT_CRYPTO (17)
59#define CGC_BIT_PEX1 (18)
60#define CGC_BIT_GE1 (19)
61#define CGC_BIT_TDM (20)
46#define CGC_GE0 (1 << 0) 62#define CGC_GE0 (1 << 0)
47#define CGC_PEX0 (1 << 2) 63#define CGC_PEX0 (1 << 2)
48#define CGC_USB0 (1 << 3) 64#define CGC_USB0 (1 << 3)
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 85f6169c248..6d8364a9781 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -23,7 +23,6 @@
23#include <linux/gpio_keys.h> 23#include <linux/gpio_keys.h>
24#include <linux/spi/flash.h> 24#include <linux/spi/flash.h>
25#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
26#include <linux/spi/orion_spi.h>
27#include <net/dsa.h> 26#include <net/dsa.h>
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <asm/mach/arch.h> 28#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index de373176ee6..6e8b2efa3c3 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/clk.h>
14#include <video/vga.h> 15#include <video/vga.h>
15#include <asm/irq.h> 16#include <asm/irq.h>
16#include <asm/mach/pci.h> 17#include <asm/mach/pci.h>
@@ -19,6 +20,23 @@
19#include <plat/addr-map.h> 20#include <plat/addr-map.h>
20#include "common.h" 21#include "common.h"
21 22
23static void kirkwood_enable_pcie_clk(const char *port)
24{
25 struct clk *clk;
26
27 clk = clk_get_sys("pcie", port);
28 if (IS_ERR(clk)) {
29 printk(KERN_ERR "PCIE clock %s missing\n", port);
30 return;
31 }
32 clk_prepare_enable(clk);
33 clk_put(clk);
34}
35
36/* This function is called very early in the boot when probing the
37 hardware to determine what we actually are, and what rate tclk is
38 ticking at. Hence calling kirkwood_enable_pcie_clk() is not
39 possible since the clk tree has not been created yet. */
22void kirkwood_enable_pcie(void) 40void kirkwood_enable_pcie(void)
23{ 41{
24 u32 curr = readl(CLOCK_GATING_CTRL); 42 u32 curr = readl(CLOCK_GATING_CTRL);
@@ -26,7 +44,7 @@ void kirkwood_enable_pcie(void)
26 writel(curr | CGC_PEX0, CLOCK_GATING_CTRL); 44 writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
27} 45}
28 46
29void __init kirkwood_pcie_id(u32 *dev, u32 *rev) 47void kirkwood_pcie_id(u32 *dev, u32 *rev)
30{ 48{
31 kirkwood_enable_pcie(); 49 kirkwood_enable_pcie();
32 *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE); 50 *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
@@ -159,7 +177,6 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
159 177
160static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) 178static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
161{ 179{
162 extern unsigned int kirkwood_clk_ctrl;
163 struct pcie_port *pp; 180 struct pcie_port *pp;
164 int index; 181 int index;
165 182
@@ -178,11 +195,11 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
178 195
179 switch (index) { 196 switch (index) {
180 case 0: 197 case 0:
181 kirkwood_clk_ctrl |= CGC_PEX0; 198 kirkwood_enable_pcie_clk("0");
182 pcie0_ioresources_init(pp); 199 pcie0_ioresources_init(pp);
183 break; 200 break;
184 case 1: 201 case 1:
185 kirkwood_clk_ctrl |= CGC_PEX1; 202 kirkwood_enable_pcie_clk("1");
186 pcie1_ioresources_init(pp); 203 pcie1_ioresources_init(pp);
187 break; 204 break;
188 default: 205 default:
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index fd2c9c8b683..f742a66a704 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -16,7 +16,6 @@
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/spi/flash.h> 17#include <linux/spi/flash.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/spi/orion_spi.h>
20#include <asm/mach-types.h> 19#include <asm/mach-types.h>
21#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
22#include <mach/kirkwood.h> 21#include <mach/kirkwood.h>
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index f9d2a11b7f9..bad738e4404 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -16,7 +16,6 @@
16#include <linux/mtd/physmap.h> 16#include <linux/mtd/physmap.h>
17#include <linux/spi/flash.h> 17#include <linux/spi/flash.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/spi/orion_spi.h>
20#include <linux/i2c.h> 19#include <linux/i2c.h>
21#include <linux/mv643xx_eth.h> 20#include <linux/mv643xx_eth.h>
22#include <linux/ata_platform.h> 21#include <linux/ata_platform.h>
diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c
index 24294b2bc46..8943ede29b4 100644
--- a/arch/arm/mach-kirkwood/tsx1x-common.c
+++ b/arch/arm/mach-kirkwood/tsx1x-common.c
@@ -4,7 +4,6 @@
4#include <linux/mtd/physmap.h> 4#include <linux/mtd/physmap.h>
5#include <linux/spi/flash.h> 5#include <linux/spi/flash.h>
6#include <linux/spi/spi.h> 6#include <linux/spi/spi.h>
7#include <linux/spi/orion_spi.h>
8#include <linux/serial_reg.h> 7#include <linux/serial_reg.h>
9#include <mach/kirkwood.h> 8#include <mach/kirkwood.h>
10#include "common.h" 9#include "common.h"
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index 26aac363a06..4fa3e99d9a6 100644
--- a/arch/arm/mach-msm/board-halibut.c
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -94,6 +94,11 @@ static void __init halibut_map_io(void)
94 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); 94 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
95} 95}
96 96
97static void __init halibut_init_late(void)
98{
99 smd_debugfs_init();
100}
101
97MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") 102MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
98 .atag_offset = 0x100, 103 .atag_offset = 0x100,
99 .fixup = halibut_fixup, 104 .fixup = halibut_fixup,
@@ -101,5 +106,6 @@ MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
101 .init_early = halibut_init_early, 106 .init_early = halibut_init_early,
102 .init_irq = halibut_init_irq, 107 .init_irq = halibut_init_irq,
103 .init_machine = halibut_init, 108 .init_machine = halibut_init,
109 .init_late = halibut_init_late,
104 .timer = &msm_timer, 110 .timer = &msm_timer,
105MACHINE_END 111MACHINE_END
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
index 5a4882fc6f7..cf1f89a5dc6 100644
--- a/arch/arm/mach-msm/board-mahimahi.c
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -71,6 +71,11 @@ static void __init mahimahi_map_io(void)
71 msm_clock_init(); 71 msm_clock_init();
72} 72}
73 73
74static void __init mahimahi_init_late(void)
75{
76 smd_debugfs_init();
77}
78
74extern struct sys_timer msm_timer; 79extern struct sys_timer msm_timer;
75 80
76MACHINE_START(MAHIMAHI, "mahimahi") 81MACHINE_START(MAHIMAHI, "mahimahi")
@@ -79,5 +84,6 @@ MACHINE_START(MAHIMAHI, "mahimahi")
79 .map_io = mahimahi_map_io, 84 .map_io = mahimahi_map_io,
80 .init_irq = msm_init_irq, 85 .init_irq = msm_init_irq,
81 .init_machine = mahimahi_init, 86 .init_machine = mahimahi_init,
87 .init_late = mahimahi_init_late,
82 .timer = &msm_timer, 88 .timer = &msm_timer,
83MACHINE_END 89MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 6d84ee740df..451ab1d43c9 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -128,11 +128,17 @@ static void __init msm7x2x_map_io(void)
128#endif 128#endif
129} 129}
130 130
131static void __init msm7x2x_init_late(void)
132{
133 smd_debugfs_init();
134}
135
131MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") 136MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
132 .atag_offset = 0x100, 137 .atag_offset = 0x100,
133 .map_io = msm7x2x_map_io, 138 .map_io = msm7x2x_map_io,
134 .init_irq = msm7x2x_init_irq, 139 .init_irq = msm7x2x_init_irq,
135 .init_machine = msm7x2x_init, 140 .init_machine = msm7x2x_init,
141 .init_late = msm7x2x_init_late,
136 .timer = &msm_timer, 142 .timer = &msm_timer,
137MACHINE_END 143MACHINE_END
138 144
@@ -141,6 +147,7 @@ MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
141 .map_io = msm7x2x_map_io, 147 .map_io = msm7x2x_map_io,
142 .init_irq = msm7x2x_init_irq, 148 .init_irq = msm7x2x_init_irq,
143 .init_machine = msm7x2x_init, 149 .init_machine = msm7x2x_init,
150 .init_late = msm7x2x_init_late,
144 .timer = &msm_timer, 151 .timer = &msm_timer,
145MACHINE_END 152MACHINE_END
146 153
@@ -149,6 +156,7 @@ MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
149 .map_io = msm7x2x_map_io, 156 .map_io = msm7x2x_map_io,
150 .init_irq = msm7x2x_init_irq, 157 .init_irq = msm7x2x_init_irq,
151 .init_machine = msm7x2x_init, 158 .init_machine = msm7x2x_init,
159 .init_late = msm7x2x_init_late,
152 .timer = &msm_timer, 160 .timer = &msm_timer,
153MACHINE_END 161MACHINE_END
154 162
@@ -157,5 +165,6 @@ MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
157 .map_io = msm7x2x_map_io, 165 .map_io = msm7x2x_map_io,
158 .init_irq = msm7x2x_init_irq, 166 .init_irq = msm7x2x_init_irq,
159 .init_machine = msm7x2x_init, 167 .init_machine = msm7x2x_init,
168 .init_late = msm7x2x_init_late,
160 .timer = &msm_timer, 169 .timer = &msm_timer,
161MACHINE_END 170MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 75b3cfcada6..a5001378135 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -119,6 +119,11 @@ static void __init msm7x30_map_io(void)
119 msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30); 119 msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
120} 120}
121 121
122static void __init msm7x30_init_late(void)
123{
124 smd_debugfs_init();
125}
126
122MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") 127MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
123 .atag_offset = 0x100, 128 .atag_offset = 0x100,
124 .fixup = msm7x30_fixup, 129 .fixup = msm7x30_fixup,
@@ -126,6 +131,7 @@ MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
126 .map_io = msm7x30_map_io, 131 .map_io = msm7x30_map_io,
127 .init_irq = msm7x30_init_irq, 132 .init_irq = msm7x30_init_irq,
128 .init_machine = msm7x30_init, 133 .init_machine = msm7x30_init,
134 .init_late = msm7x30_init_late,
129 .timer = &msm_timer, 135 .timer = &msm_timer,
130MACHINE_END 136MACHINE_END
131 137
@@ -136,6 +142,7 @@ MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
136 .map_io = msm7x30_map_io, 142 .map_io = msm7x30_map_io,
137 .init_irq = msm7x30_init_irq, 143 .init_irq = msm7x30_init_irq,
138 .init_machine = msm7x30_init, 144 .init_machine = msm7x30_init,
145 .init_late = msm7x30_init_late,
139 .timer = &msm_timer, 146 .timer = &msm_timer,
140MACHINE_END 147MACHINE_END
141 148
@@ -146,5 +153,6 @@ MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
146 .map_io = msm7x30_map_io, 153 .map_io = msm7x30_map_io,
147 .init_irq = msm7x30_init_irq, 154 .init_irq = msm7x30_init_irq,
148 .init_machine = msm7x30_init, 155 .init_machine = msm7x30_init,
156 .init_late = msm7x30_init_late,
149 .timer = &msm_timer, 157 .timer = &msm_timer,
150MACHINE_END 158MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index ed359812853..65f4a1daa2e 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -93,6 +93,11 @@ static void __init msm8960_rumi3_init(void)
93 platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices)); 93 platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
94} 94}
95 95
96static void __init msm8960_init_late(void)
97{
98 smd_debugfs_init();
99}
100
96MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR") 101MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
97 .fixup = msm8960_fixup, 102 .fixup = msm8960_fixup,
98 .reserve = msm8960_reserve, 103 .reserve = msm8960_reserve,
@@ -101,6 +106,7 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
101 .timer = &msm_timer, 106 .timer = &msm_timer,
102 .handle_irq = gic_handle_irq, 107 .handle_irq = gic_handle_irq,
103 .init_machine = msm8960_sim_init, 108 .init_machine = msm8960_sim_init,
109 .init_late = msm8960_init_late,
104MACHINE_END 110MACHINE_END
105 111
106MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3") 112MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
@@ -111,5 +117,6 @@ MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
111 .timer = &msm_timer, 117 .timer = &msm_timer,
112 .handle_irq = gic_handle_irq, 118 .handle_irq = gic_handle_irq,
113 .init_machine = msm8960_rumi3_init, 119 .init_machine = msm8960_rumi3_init,
120 .init_late = msm8960_init_late,
114MACHINE_END 121MACHINE_END
115 122
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index fb3496a52ef..e37a724cd1e 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -81,6 +81,11 @@ static void __init msm8x60_init(void)
81{ 81{
82} 82}
83 83
84static void __init msm8x60_init_late(void)
85{
86 smd_debugfs_init();
87}
88
84#ifdef CONFIG_OF 89#ifdef CONFIG_OF
85static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = { 90static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = {
86 {} 91 {}
@@ -111,6 +116,7 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
111 .init_irq = msm8x60_init_irq, 116 .init_irq = msm8x60_init_irq,
112 .handle_irq = gic_handle_irq, 117 .handle_irq = gic_handle_irq,
113 .init_machine = msm8x60_init, 118 .init_machine = msm8x60_init,
119 .init_late = msm8x60_init_late,
114 .timer = &msm_timer, 120 .timer = &msm_timer,
115MACHINE_END 121MACHINE_END
116 122
@@ -121,6 +127,7 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
121 .init_irq = msm8x60_init_irq, 127 .init_irq = msm8x60_init_irq,
122 .handle_irq = gic_handle_irq, 128 .handle_irq = gic_handle_irq,
123 .init_machine = msm8x60_init, 129 .init_machine = msm8x60_init,
130 .init_late = msm8x60_init_late,
124 .timer = &msm_timer, 131 .timer = &msm_timer,
125MACHINE_END 132MACHINE_END
126 133
@@ -131,6 +138,7 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
131 .init_irq = msm8x60_init_irq, 138 .init_irq = msm8x60_init_irq,
132 .handle_irq = gic_handle_irq, 139 .handle_irq = gic_handle_irq,
133 .init_machine = msm8x60_init, 140 .init_machine = msm8x60_init,
141 .init_late = msm8x60_init_late,
134 .timer = &msm_timer, 142 .timer = &msm_timer,
135MACHINE_END 143MACHINE_END
136 144
@@ -141,6 +149,7 @@ MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
141 .init_irq = msm8x60_init_irq, 149 .init_irq = msm8x60_init_irq,
142 .handle_irq = gic_handle_irq, 150 .handle_irq = gic_handle_irq,
143 .init_machine = msm8x60_init, 151 .init_machine = msm8x60_init,
152 .init_late = msm8x60_init_late,
144 .timer = &msm_timer, 153 .timer = &msm_timer,
145MACHINE_END 154MACHINE_END
146 155
@@ -150,6 +159,7 @@ DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
150 .map_io = msm8x60_map_io, 159 .map_io = msm8x60_map_io,
151 .init_irq = msm8x60_init_irq, 160 .init_irq = msm8x60_init_irq,
152 .init_machine = msm8x60_dt_init, 161 .init_machine = msm8x60_dt_init,
162 .init_late = msm8x60_init_late,
153 .timer = &msm_timer, 163 .timer = &msm_timer,
154 .dt_compat = msm8x60_fluid_match, 164 .dt_compat = msm8x60_fluid_match,
155MACHINE_END 165MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index fbaa4ed95a3..c8fe0edb976 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -190,11 +190,17 @@ static void __init qsd8x50_init(void)
190 qsd8x50_init_mmc(); 190 qsd8x50_init_mmc();
191} 191}
192 192
193static void __init qsd8x50_init_late(void)
194{
195 smd_debugfs_init();
196}
197
193MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") 198MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
194 .atag_offset = 0x100, 199 .atag_offset = 0x100,
195 .map_io = qsd8x50_map_io, 200 .map_io = qsd8x50_map_io,
196 .init_irq = qsd8x50_init_irq, 201 .init_irq = qsd8x50_init_irq,
197 .init_machine = qsd8x50_init, 202 .init_machine = qsd8x50_init,
203 .init_late = qsd8x50_init_late,
198 .timer = &msm_timer, 204 .timer = &msm_timer,
199MACHINE_END 205MACHINE_END
200 206
@@ -203,5 +209,6 @@ MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
203 .map_io = qsd8x50_map_io, 209 .map_io = qsd8x50_map_io,
204 .init_irq = qsd8x50_init_irq, 210 .init_irq = qsd8x50_init_irq,
205 .init_machine = qsd8x50_init, 211 .init_machine = qsd8x50_init,
212 .init_late = qsd8x50_init_late,
206 .timer = &msm_timer, 213 .timer = &msm_timer,
207MACHINE_END 214MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
index 4a8ea0d40b6..2e569ab10ee 100644
--- a/arch/arm/mach-msm/board-sapphire.c
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -101,6 +101,11 @@ static void __init sapphire_map_io(void)
101 msm_clock_init(); 101 msm_clock_init();
102} 102}
103 103
104static void __init sapphire_init_late(void)
105{
106 smd_debugfs_init();
107}
108
104MACHINE_START(SAPPHIRE, "sapphire") 109MACHINE_START(SAPPHIRE, "sapphire")
105/* Maintainer: Brian Swetland <swetland@google.com> */ 110/* Maintainer: Brian Swetland <swetland@google.com> */
106 .atag_offset = 0x100, 111 .atag_offset = 0x100,
@@ -108,5 +113,6 @@ MACHINE_START(SAPPHIRE, "sapphire")
108 .map_io = sapphire_map_io, 113 .map_io = sapphire_map_io,
109 .init_irq = sapphire_init_irq, 114 .init_irq = sapphire_init_irq,
110 .init_machine = sapphire_init, 115 .init_machine = sapphire_init,
116 .init_late = sapphire_init_late,
111 .timer = &msm_timer, 117 .timer = &msm_timer,
112MACHINE_END 118MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index d4060a37e23..bbe13f12fa0 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -98,6 +98,11 @@ static void __init trout_map_io(void)
98 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); 98 msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
99} 99}
100 100
101static void __init trout_init_late(void)
102{
103 smd_debugfs_init();
104}
105
101MACHINE_START(TROUT, "HTC Dream") 106MACHINE_START(TROUT, "HTC Dream")
102 .atag_offset = 0x100, 107 .atag_offset = 0x100,
103 .fixup = trout_fixup, 108 .fixup = trout_fixup,
@@ -105,5 +110,6 @@ MACHINE_START(TROUT, "HTC Dream")
105 .init_early = trout_init_early, 110 .init_early = trout_init_early,
106 .init_irq = trout_init_irq, 111 .init_irq = trout_init_irq,
107 .init_machine = trout_init, 112 .init_machine = trout_init,
113 .init_late = trout_init_late,
108 .timer = &msm_timer, 114 .timer = &msm_timer,
109MACHINE_END 115MACHINE_END
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 2ce8f1f2fc4..435f8edfafd 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -47,4 +47,10 @@ int __init msm_add_sdcc(unsigned int controller,
47 struct msm_mmc_platform_data *plat, 47 struct msm_mmc_platform_data *plat,
48 unsigned int stat_irq, unsigned long stat_irq_flags); 48 unsigned int stat_irq, unsigned long stat_irq_flags);
49 49
50#if defined(CONFIG_MSM_SMD) && defined(CONFIG_DEBUG_FS)
51int smd_debugfs_init(void);
52#else
53static inline int smd_debugfs_init(void) { return 0; }
54#endif
55
50#endif 56#endif
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index c56df9e932a..8056b3e5590 100644
--- a/arch/arm/mach-msm/smd_debug.c
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -216,7 +216,7 @@ static void debug_create(const char *name, umode_t mode,
216 debugfs_create_file(name, mode, dent, fill, &debug_ops); 216 debugfs_create_file(name, mode, dent, fill, &debug_ops);
217} 217}
218 218
219static int smd_debugfs_init(void) 219int __init smd_debugfs_init(void)
220{ 220{
221 struct dentry *dent; 221 struct dentry *dent;
222 222
@@ -234,7 +234,6 @@ static int smd_debugfs_init(void)
234 return 0; 234 return 0;
235} 235}
236 236
237late_initcall(smd_debugfs_init);
238#endif 237#endif
239 238
240 239
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index a5dcf766a3f..b4c53b846c9 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -13,6 +13,7 @@
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/ata_platform.h> 15#include <linux/ata_platform.h>
16#include <linux/clk-provider.h>
16#include <linux/ethtool.h> 17#include <linux/ethtool.h>
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
18#include <asm/mach/time.h> 19#include <asm/mach/time.h>
@@ -103,24 +104,24 @@ static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
103 104
104static int get_tclk(void) 105static int get_tclk(void)
105{ 106{
106 int tclk; 107 int tclk_freq;
107 108
108 /* 109 /*
109 * TCLK tick rate is configured by DEV_A[2:0] strap pins. 110 * TCLK tick rate is configured by DEV_A[2:0] strap pins.
110 */ 111 */
111 switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) { 112 switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
112 case 1: 113 case 1:
113 tclk = 166666667; 114 tclk_freq = 166666667;
114 break; 115 break;
115 case 3: 116 case 3:
116 tclk = 200000000; 117 tclk_freq = 200000000;
117 break; 118 break;
118 default: 119 default:
119 panic("unknown TCLK PLL setting: %.8x\n", 120 panic("unknown TCLK PLL setting: %.8x\n",
120 readl(SAMPLE_AT_RESET_HIGH)); 121 readl(SAMPLE_AT_RESET_HIGH));
121 } 122 }
122 123
123 return tclk; 124 return tclk_freq;
124} 125}
125 126
126 127
@@ -166,6 +167,19 @@ void __init mv78xx0_map_io(void)
166 167
167 168
168/***************************************************************************** 169/*****************************************************************************
170 * CLK tree
171 ****************************************************************************/
172static struct clk *tclk;
173
174static void __init clk_init(void)
175{
176 tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
177 get_tclk());
178
179 orion_clkdev_init(tclk);
180}
181
182/*****************************************************************************
169 * EHCI 183 * EHCI
170 ****************************************************************************/ 184 ****************************************************************************/
171void __init mv78xx0_ehci0_init(void) 185void __init mv78xx0_ehci0_init(void)
@@ -199,7 +213,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
199{ 213{
200 orion_ge00_init(eth_data, 214 orion_ge00_init(eth_data,
201 GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, 215 GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
202 IRQ_MV78XX0_GE_ERR, get_tclk()); 216 IRQ_MV78XX0_GE_ERR);
203} 217}
204 218
205 219
@@ -210,7 +224,7 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
210{ 224{
211 orion_ge01_init(eth_data, 225 orion_ge01_init(eth_data,
212 GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, 226 GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
213 NO_IRQ, get_tclk()); 227 NO_IRQ);
214} 228}
215 229
216 230
@@ -234,7 +248,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
234 248
235 orion_ge10_init(eth_data, 249 orion_ge10_init(eth_data,
236 GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM, 250 GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
237 NO_IRQ, get_tclk()); 251 NO_IRQ);
238} 252}
239 253
240 254
@@ -258,7 +272,7 @@ void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
258 272
259 orion_ge11_init(eth_data, 273 orion_ge11_init(eth_data,
260 GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM, 274 GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
261 NO_IRQ, get_tclk()); 275 NO_IRQ);
262} 276}
263 277
264/***************************************************************************** 278/*****************************************************************************
@@ -285,7 +299,7 @@ void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
285void __init mv78xx0_uart0_init(void) 299void __init mv78xx0_uart0_init(void)
286{ 300{
287 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, 301 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
288 IRQ_MV78XX0_UART_0, get_tclk()); 302 IRQ_MV78XX0_UART_0, tclk);
289} 303}
290 304
291 305
@@ -295,7 +309,7 @@ void __init mv78xx0_uart0_init(void)
295void __init mv78xx0_uart1_init(void) 309void __init mv78xx0_uart1_init(void)
296{ 310{
297 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, 311 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
298 IRQ_MV78XX0_UART_1, get_tclk()); 312 IRQ_MV78XX0_UART_1, tclk);
299} 313}
300 314
301 315
@@ -305,7 +319,7 @@ void __init mv78xx0_uart1_init(void)
305void __init mv78xx0_uart2_init(void) 319void __init mv78xx0_uart2_init(void)
306{ 320{
307 orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE, 321 orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
308 IRQ_MV78XX0_UART_2, get_tclk()); 322 IRQ_MV78XX0_UART_2, tclk);
309} 323}
310 324
311/***************************************************************************** 325/*****************************************************************************
@@ -314,7 +328,7 @@ void __init mv78xx0_uart2_init(void)
314void __init mv78xx0_uart3_init(void) 328void __init mv78xx0_uart3_init(void)
315{ 329{
316 orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE, 330 orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
317 IRQ_MV78XX0_UART_3, get_tclk()); 331 IRQ_MV78XX0_UART_3, tclk);
318} 332}
319 333
320/***************************************************************************** 334/*****************************************************************************
@@ -378,25 +392,26 @@ void __init mv78xx0_init(void)
378 int hclk; 392 int hclk;
379 int pclk; 393 int pclk;
380 int l2clk; 394 int l2clk;
381 int tclk;
382 395
383 core_index = mv78xx0_core_index(); 396 core_index = mv78xx0_core_index();
384 hclk = get_hclk(); 397 hclk = get_hclk();
385 get_pclk_l2clk(hclk, core_index, &pclk, &l2clk); 398 get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
386 tclk = get_tclk();
387 399
388 printk(KERN_INFO "%s ", mv78xx0_id()); 400 printk(KERN_INFO "%s ", mv78xx0_id());
389 printk("core #%d, ", core_index); 401 printk("core #%d, ", core_index);
390 printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000); 402 printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
391 printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000); 403 printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
392 printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); 404 printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
393 printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000); 405 printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
394 406
395 mv78xx0_setup_cpu_mbus(); 407 mv78xx0_setup_cpu_mbus();
396 408
397#ifdef CONFIG_CACHE_FEROCEON_L2 409#ifdef CONFIG_CACHE_FEROCEON_L2
398 feroceon_l2_init(is_l2_writethrough()); 410 feroceon_l2_init(is_l2_writethrough());
399#endif 411#endif
412
413 /* Setup root of clk tree */
414 clk_init();
400} 415}
401 416
402void mv78xx0_restart(char mode, const char *cmd) 417void mv78xx0_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 07d5383d68e..91cf0625819 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -7,18 +7,28 @@ config MXS_OCOTP
7 7
8config SOC_IMX23 8config SOC_IMX23
9 bool 9 bool
10 select ARM_AMBA
10 select CPU_ARM926T 11 select CPU_ARM926T
11 select HAVE_PWM 12 select HAVE_PWM
12 select PINCTRL_IMX23 13 select PINCTRL_IMX23
13 14
14config SOC_IMX28 15config SOC_IMX28
15 bool 16 bool
17 select ARM_AMBA
16 select CPU_ARM926T 18 select CPU_ARM926T
17 select HAVE_PWM 19 select HAVE_PWM
18 select PINCTRL_IMX28 20 select PINCTRL_IMX28
19 21
20comment "MXS platforms:" 22comment "MXS platforms:"
21 23
24config MACH_MXS_DT
25 bool "Support MXS platforms from device tree"
26 select SOC_IMX23
27 select SOC_IMX28
28 help
29 Include support for Freescale MXS platforms(i.MX23 and i.MX28)
30 using the device tree for discovery
31
22config MACH_STMP378X_DEVB 32config MACH_STMP378X_DEVB
23 bool "Support STMP378x_devb Platform" 33 bool "Support STMP378x_devb Platform"
24 select SOC_IMX23 34 select SOC_IMX23
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 908bf9a567f..e41590ccb43 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,12 +1,10 @@
1# Common support 1# Common support
2obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o mm.o 2obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o
3 3
4obj-$(CONFIG_MXS_OCOTP) += ocotp.o 4obj-$(CONFIG_MXS_OCOTP) += ocotp.o
5obj-$(CONFIG_PM) += pm.o 5obj-$(CONFIG_PM) += pm.o
6 6
7obj-$(CONFIG_SOC_IMX23) += clock-mx23.o 7obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
8obj-$(CONFIG_SOC_IMX28) += clock-mx28.o
9
10obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o 8obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
11obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o 9obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
12obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o 10obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
deleted file mode 100644
index e3ac52c3401..00000000000
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ /dev/null
@@ -1,536 +0,0 @@
1/*
2 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
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 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/jiffies.h>
24#include <linux/clkdev.h>
25
26#include <asm/clkdev.h>
27#include <asm/div64.h>
28
29#include <mach/mx23.h>
30#include <mach/common.h>
31#include <mach/clock.h>
32
33#include "regs-clkctrl-mx23.h"
34
35#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
36#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
37
38#define PARENT_RATE_SHIFT 8
39
40static int _raw_clk_enable(struct clk *clk)
41{
42 u32 reg;
43
44 if (clk->enable_reg) {
45 reg = __raw_readl(clk->enable_reg);
46 reg &= ~(1 << clk->enable_shift);
47 __raw_writel(reg, clk->enable_reg);
48 }
49
50 return 0;
51}
52
53static void _raw_clk_disable(struct clk *clk)
54{
55 u32 reg;
56
57 if (clk->enable_reg) {
58 reg = __raw_readl(clk->enable_reg);
59 reg |= 1 << clk->enable_shift;
60 __raw_writel(reg, clk->enable_reg);
61 }
62}
63
64/*
65 * ref_xtal_clk
66 */
67static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
68{
69 return 24000000;
70}
71
72static struct clk ref_xtal_clk = {
73 .get_rate = ref_xtal_clk_get_rate,
74};
75
76/*
77 * pll_clk
78 */
79static unsigned long pll_clk_get_rate(struct clk *clk)
80{
81 return 480000000;
82}
83
84static int pll_clk_enable(struct clk *clk)
85{
86 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
87 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
88 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
89
90 /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
91 * and is incorrect (excessive). Per definition of the PLLCTRL0
92 * POWER field, waiting at least 10us.
93 */
94 udelay(10);
95
96 return 0;
97}
98
99static void pll_clk_disable(struct clk *clk)
100{
101 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
102 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
103 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
104}
105
106static struct clk pll_clk = {
107 .get_rate = pll_clk_get_rate,
108 .enable = pll_clk_enable,
109 .disable = pll_clk_disable,
110 .parent = &ref_xtal_clk,
111};
112
113/*
114 * ref_clk
115 */
116#define _CLK_GET_RATE_REF(name, sr, ss) \
117static unsigned long name##_get_rate(struct clk *clk) \
118{ \
119 unsigned long parent_rate; \
120 u32 reg, div; \
121 \
122 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
123 div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
124 parent_rate = clk_get_rate(clk->parent); \
125 \
126 return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
127 div, PARENT_RATE_SHIFT); \
128}
129
130_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
131_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
132_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
133_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
134
135#define _DEFINE_CLOCK_REF(name, er, es) \
136 static struct clk name = { \
137 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
138 .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
139 .get_rate = name##_get_rate, \
140 .enable = _raw_clk_enable, \
141 .disable = _raw_clk_disable, \
142 .parent = &pll_clk, \
143 }
144
145_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
146_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
147_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
148_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
149
150/*
151 * General clocks
152 *
153 * clk_get_rate
154 */
155static unsigned long rtc_clk_get_rate(struct clk *clk)
156{
157 /* ref_xtal_clk is implemented as the only parent */
158 return clk_get_rate(clk->parent) / 768;
159}
160
161static unsigned long clk32k_clk_get_rate(struct clk *clk)
162{
163 return clk->parent->get_rate(clk->parent) / 750;
164}
165
166#define _CLK_GET_RATE(name, rs) \
167static unsigned long name##_get_rate(struct clk *clk) \
168{ \
169 u32 reg, div; \
170 \
171 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
172 \
173 if (clk->parent == &ref_xtal_clk) \
174 div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
175 BP_CLKCTRL_##rs##_DIV_XTAL; \
176 else \
177 div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
178 BP_CLKCTRL_##rs##_DIV_##rs; \
179 \
180 if (!div) \
181 return -EINVAL; \
182 \
183 return clk_get_rate(clk->parent) / div; \
184}
185
186_CLK_GET_RATE(cpu_clk, CPU)
187_CLK_GET_RATE(emi_clk, EMI)
188
189#define _CLK_GET_RATE1(name, rs) \
190static unsigned long name##_get_rate(struct clk *clk) \
191{ \
192 u32 reg, div; \
193 \
194 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
195 div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
196 \
197 if (!div) \
198 return -EINVAL; \
199 \
200 return clk_get_rate(clk->parent) / div; \
201}
202
203_CLK_GET_RATE1(hbus_clk, HBUS)
204_CLK_GET_RATE1(xbus_clk, XBUS)
205_CLK_GET_RATE1(ssp_clk, SSP)
206_CLK_GET_RATE1(gpmi_clk, GPMI)
207_CLK_GET_RATE1(lcdif_clk, PIX)
208
209#define _CLK_GET_RATE_STUB(name) \
210static unsigned long name##_get_rate(struct clk *clk) \
211{ \
212 return clk_get_rate(clk->parent); \
213}
214
215_CLK_GET_RATE_STUB(uart_clk)
216_CLK_GET_RATE_STUB(audio_clk)
217_CLK_GET_RATE_STUB(pwm_clk)
218
219/*
220 * clk_set_rate
221 */
222static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
223{
224 u32 reg, bm_busy, div_max, d, f, div, frac;
225 unsigned long diff, parent_rate, calc_rate;
226
227 parent_rate = clk_get_rate(clk->parent);
228
229 if (clk->parent == &ref_xtal_clk) {
230 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
231 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
232 div = DIV_ROUND_UP(parent_rate, rate);
233 if (div == 0 || div > div_max)
234 return -EINVAL;
235 } else {
236 div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
237 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
238 rate >>= PARENT_RATE_SHIFT;
239 parent_rate >>= PARENT_RATE_SHIFT;
240 diff = parent_rate;
241 div = frac = 1;
242 for (d = 1; d <= div_max; d++) {
243 f = parent_rate * 18 / d / rate;
244 if ((parent_rate * 18 / d) % rate)
245 f++;
246 if (f < 18 || f > 35)
247 continue;
248
249 calc_rate = parent_rate * 18 / f / d;
250 if (calc_rate > rate)
251 continue;
252
253 if (rate - calc_rate < diff) {
254 frac = f;
255 div = d;
256 diff = rate - calc_rate;
257 }
258
259 if (diff == 0)
260 break;
261 }
262
263 if (diff == parent_rate)
264 return -EINVAL;
265
266 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
267 reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
268 reg |= frac;
269 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
270 }
271
272 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
273 reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
274 reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
275 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
276
277 mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
278
279 return 0;
280}
281
282#define _CLK_SET_RATE(name, dr) \
283static int name##_set_rate(struct clk *clk, unsigned long rate) \
284{ \
285 u32 reg, div_max, div; \
286 unsigned long parent_rate; \
287 \
288 parent_rate = clk_get_rate(clk->parent); \
289 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
290 \
291 div = DIV_ROUND_UP(parent_rate, rate); \
292 if (div == 0 || div > div_max) \
293 return -EINVAL; \
294 \
295 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
296 reg &= ~BM_CLKCTRL_##dr##_DIV; \
297 reg |= div << BP_CLKCTRL_##dr##_DIV; \
298 if (reg & (1 << clk->enable_shift)) { \
299 pr_err("%s: clock is gated\n", __func__); \
300 return -EINVAL; \
301 } \
302 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
303 \
304 mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
305 return 0; \
306}
307
308_CLK_SET_RATE(xbus_clk, XBUS)
309_CLK_SET_RATE(ssp_clk, SSP)
310_CLK_SET_RATE(gpmi_clk, GPMI)
311_CLK_SET_RATE(lcdif_clk, PIX)
312
313#define _CLK_SET_RATE_STUB(name) \
314static int name##_set_rate(struct clk *clk, unsigned long rate) \
315{ \
316 return -EINVAL; \
317}
318
319_CLK_SET_RATE_STUB(emi_clk)
320_CLK_SET_RATE_STUB(uart_clk)
321_CLK_SET_RATE_STUB(audio_clk)
322_CLK_SET_RATE_STUB(pwm_clk)
323_CLK_SET_RATE_STUB(clk32k_clk)
324
325/*
326 * clk_set_parent
327 */
328#define _CLK_SET_PARENT(name, bit) \
329static int name##_set_parent(struct clk *clk, struct clk *parent) \
330{ \
331 if (parent != clk->parent) { \
332 __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
333 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
334 clk->parent = parent; \
335 } \
336 \
337 return 0; \
338}
339
340_CLK_SET_PARENT(cpu_clk, CPU)
341_CLK_SET_PARENT(emi_clk, EMI)
342_CLK_SET_PARENT(ssp_clk, SSP)
343_CLK_SET_PARENT(gpmi_clk, GPMI)
344_CLK_SET_PARENT(lcdif_clk, PIX)
345
346#define _CLK_SET_PARENT_STUB(name) \
347static int name##_set_parent(struct clk *clk, struct clk *parent) \
348{ \
349 if (parent != clk->parent) \
350 return -EINVAL; \
351 else \
352 return 0; \
353}
354
355_CLK_SET_PARENT_STUB(uart_clk)
356_CLK_SET_PARENT_STUB(audio_clk)
357_CLK_SET_PARENT_STUB(pwm_clk)
358_CLK_SET_PARENT_STUB(clk32k_clk)
359
360/*
361 * clk definition
362 */
363static struct clk cpu_clk = {
364 .get_rate = cpu_clk_get_rate,
365 .set_rate = cpu_clk_set_rate,
366 .set_parent = cpu_clk_set_parent,
367 .parent = &ref_cpu_clk,
368};
369
370static struct clk hbus_clk = {
371 .get_rate = hbus_clk_get_rate,
372 .parent = &cpu_clk,
373};
374
375static struct clk xbus_clk = {
376 .get_rate = xbus_clk_get_rate,
377 .set_rate = xbus_clk_set_rate,
378 .parent = &ref_xtal_clk,
379};
380
381static struct clk rtc_clk = {
382 .get_rate = rtc_clk_get_rate,
383 .parent = &ref_xtal_clk,
384};
385
386/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
387static struct clk usb_clk = {
388 .enable_reg = DIGCTRL_BASE_ADDR,
389 .enable_shift = 2,
390 .enable = _raw_clk_enable,
391 .disable = _raw_clk_disable,
392 .parent = &pll_clk,
393};
394
395#define _DEFINE_CLOCK(name, er, es, p) \
396 static struct clk name = { \
397 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
398 .enable_shift = BP_CLKCTRL_##er##_##es, \
399 .get_rate = name##_get_rate, \
400 .set_rate = name##_set_rate, \
401 .set_parent = name##_set_parent, \
402 .enable = _raw_clk_enable, \
403 .disable = _raw_clk_disable, \
404 .parent = p, \
405 }
406
407_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
408_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
409_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
410_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
411_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
412_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
413_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
414_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
415
416#define _REGISTER_CLOCK(d, n, c) \
417 { \
418 .dev_id = d, \
419 .con_id = n, \
420 .clk = &c, \
421 },
422
423static struct clk_lookup lookups[] = {
424 /* for amba bus driver */
425 _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
426 /* for amba-pl011 driver */
427 _REGISTER_CLOCK("duart", NULL, uart_clk)
428 _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
429 _REGISTER_CLOCK("rtc", NULL, rtc_clk)
430 _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
431 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
432 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
433 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
434 _REGISTER_CLOCK(NULL, "usb", usb_clk)
435 _REGISTER_CLOCK(NULL, "audio", audio_clk)
436 _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
437 _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
438 _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
439 _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
440 _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
441 _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
442 _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
443};
444
445static int clk_misc_init(void)
446{
447 u32 reg;
448 int ret;
449
450 /* Fix up parent per register setting */
451 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
452 cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
453 &ref_xtal_clk : &ref_cpu_clk;
454 emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
455 &ref_xtal_clk : &ref_emi_clk;
456 ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
457 &ref_xtal_clk : &ref_io_clk;
458 gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
459 &ref_xtal_clk : &ref_io_clk;
460 lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
461 &ref_xtal_clk : &ref_pix_clk;
462
463 /* Use int div over frac when both are available */
464 __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
465 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
466 __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
467 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
468 __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
469 CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
470
471 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
472 reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
473 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
474
475 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
476 reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
477 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
478
479 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
480 reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
481 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
482
483 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
484 reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
485 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
486
487 /*
488 * Set safe hbus clock divider. A divider of 3 ensure that
489 * the Vddd voltage required for the cpu clock is sufficiently
490 * high for the hbus clock.
491 */
492 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
493 reg &= BM_CLKCTRL_HBUS_DIV;
494 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
495 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
496
497 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
498
499 /* Gate off cpu clock in WFI for power saving */
500 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
501 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
502
503 /*
504 * 480 MHz seems too high to be ssp clock source directly,
505 * so set frac to get a 288 MHz ref_io.
506 */
507 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
508 reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
509 reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
510 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
511
512 return ret;
513}
514
515int __init mx23_clocks_init(void)
516{
517 clk_misc_init();
518
519 /*
520 * source ssp clock from ref_io than ref_xtal,
521 * as ref_xtal only provides 24 MHz as maximum.
522 */
523 clk_set_parent(&ssp_clk, &ref_io_clk);
524
525 clk_prepare_enable(&cpu_clk);
526 clk_prepare_enable(&hbus_clk);
527 clk_prepare_enable(&xbus_clk);
528 clk_prepare_enable(&emi_clk);
529 clk_prepare_enable(&uart_clk);
530
531 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
532
533 mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
534
535 return 0;
536}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
deleted file mode 100644
index cea29c99e21..00000000000
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ /dev/null
@@ -1,803 +0,0 @@
1/*
2 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
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 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/jiffies.h>
24#include <linux/clkdev.h>
25#include <linux/spinlock.h>
26
27#include <asm/clkdev.h>
28#include <asm/div64.h>
29
30#include <mach/mx28.h>
31#include <mach/common.h>
32#include <mach/clock.h>
33#include <mach/digctl.h>
34
35#include "regs-clkctrl-mx28.h"
36
37#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
38#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
39
40#define PARENT_RATE_SHIFT 8
41
42static struct clk pll2_clk;
43static struct clk cpu_clk;
44static struct clk emi_clk;
45static struct clk saif0_clk;
46static struct clk saif1_clk;
47static struct clk clk32k_clk;
48static DEFINE_SPINLOCK(clkmux_lock);
49
50/*
51 * HW_SAIF_CLKMUX_SEL:
52 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
53 * clock pins selected for SAIF1 input clocks.
54 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
55 * SAIF0 clock inputs selected for SAIF1 input clocks.
56 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
57 * clocks.
58 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
59 * clocks.
60 */
61int mxs_saif_clkmux_select(unsigned int clkmux)
62{
63 if (clkmux > 0x3)
64 return -EINVAL;
65
66 spin_lock(&clkmux_lock);
67 __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
68 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
69 __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
70 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
71 spin_unlock(&clkmux_lock);
72
73 return 0;
74}
75
76static int _raw_clk_enable(struct clk *clk)
77{
78 u32 reg;
79
80 if (clk->enable_reg) {
81 reg = __raw_readl(clk->enable_reg);
82 reg &= ~(1 << clk->enable_shift);
83 __raw_writel(reg, clk->enable_reg);
84 }
85
86 return 0;
87}
88
89static void _raw_clk_disable(struct clk *clk)
90{
91 u32 reg;
92
93 if (clk->enable_reg) {
94 reg = __raw_readl(clk->enable_reg);
95 reg |= 1 << clk->enable_shift;
96 __raw_writel(reg, clk->enable_reg);
97 }
98}
99
100/*
101 * ref_xtal_clk
102 */
103static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
104{
105 return 24000000;
106}
107
108static struct clk ref_xtal_clk = {
109 .get_rate = ref_xtal_clk_get_rate,
110};
111
112/*
113 * pll_clk
114 */
115static unsigned long pll0_clk_get_rate(struct clk *clk)
116{
117 return 480000000;
118}
119
120static unsigned long pll1_clk_get_rate(struct clk *clk)
121{
122 return 480000000;
123}
124
125static unsigned long pll2_clk_get_rate(struct clk *clk)
126{
127 return 50000000;
128}
129
130#define _CLK_ENABLE_PLL(name, r, g) \
131static int name##_enable(struct clk *clk) \
132{ \
133 __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
134 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
135 udelay(10); \
136 \
137 if (clk == &pll2_clk) \
138 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
139 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
140 else \
141 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
142 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
143 \
144 return 0; \
145}
146
147_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
148_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
149_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
150
151#define _CLK_DISABLE_PLL(name, r, g) \
152static void name##_disable(struct clk *clk) \
153{ \
154 __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
155 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
156 \
157 if (clk == &pll2_clk) \
158 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
159 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
160 else \
161 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
162 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
163 \
164}
165
166_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
167_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
168_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
169
170#define _DEFINE_CLOCK_PLL(name) \
171 static struct clk name = { \
172 .get_rate = name##_get_rate, \
173 .enable = name##_enable, \
174 .disable = name##_disable, \
175 .parent = &ref_xtal_clk, \
176 }
177
178_DEFINE_CLOCK_PLL(pll0_clk);
179_DEFINE_CLOCK_PLL(pll1_clk);
180_DEFINE_CLOCK_PLL(pll2_clk);
181
182/*
183 * ref_clk
184 */
185#define _CLK_GET_RATE_REF(name, sr, ss) \
186static unsigned long name##_get_rate(struct clk *clk) \
187{ \
188 unsigned long parent_rate; \
189 u32 reg, div; \
190 \
191 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
192 div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
193 parent_rate = clk_get_rate(clk->parent); \
194 \
195 return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
196 div, PARENT_RATE_SHIFT); \
197}
198
199_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
200_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
201_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
202_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
203_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
204_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
205
206#define _DEFINE_CLOCK_REF(name, er, es) \
207 static struct clk name = { \
208 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
209 .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
210 .get_rate = name##_get_rate, \
211 .enable = _raw_clk_enable, \
212 .disable = _raw_clk_disable, \
213 .parent = &pll0_clk, \
214 }
215
216_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
217_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
218_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
219_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
220_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
221_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
222
223/*
224 * General clocks
225 *
226 * clk_get_rate
227 */
228static unsigned long lradc_clk_get_rate(struct clk *clk)
229{
230 return clk_get_rate(clk->parent) / 16;
231}
232
233static unsigned long rtc_clk_get_rate(struct clk *clk)
234{
235 /* ref_xtal_clk is implemented as the only parent */
236 return clk_get_rate(clk->parent) / 768;
237}
238
239static unsigned long clk32k_clk_get_rate(struct clk *clk)
240{
241 return clk->parent->get_rate(clk->parent) / 750;
242}
243
244static unsigned long spdif_clk_get_rate(struct clk *clk)
245{
246 return clk_get_rate(clk->parent) / 4;
247}
248
249#define _CLK_GET_RATE(name, rs) \
250static unsigned long name##_get_rate(struct clk *clk) \
251{ \
252 u32 reg, div; \
253 \
254 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
255 \
256 if (clk->parent == &ref_xtal_clk) \
257 div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
258 BP_CLKCTRL_##rs##_DIV_XTAL; \
259 else \
260 div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
261 BP_CLKCTRL_##rs##_DIV_##rs; \
262 \
263 if (!div) \
264 return -EINVAL; \
265 \
266 return clk_get_rate(clk->parent) / div; \
267}
268
269_CLK_GET_RATE(cpu_clk, CPU)
270_CLK_GET_RATE(emi_clk, EMI)
271
272#define _CLK_GET_RATE1(name, rs) \
273static unsigned long name##_get_rate(struct clk *clk) \
274{ \
275 u32 reg, div; \
276 \
277 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
278 div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
279 \
280 if (!div) \
281 return -EINVAL; \
282 \
283 if (clk == &saif0_clk || clk == &saif1_clk) \
284 return clk_get_rate(clk->parent) >> 16 * div; \
285 else \
286 return clk_get_rate(clk->parent) / div; \
287}
288
289_CLK_GET_RATE1(hbus_clk, HBUS)
290_CLK_GET_RATE1(xbus_clk, XBUS)
291_CLK_GET_RATE1(ssp0_clk, SSP0)
292_CLK_GET_RATE1(ssp1_clk, SSP1)
293_CLK_GET_RATE1(ssp2_clk, SSP2)
294_CLK_GET_RATE1(ssp3_clk, SSP3)
295_CLK_GET_RATE1(gpmi_clk, GPMI)
296_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
297_CLK_GET_RATE1(saif0_clk, SAIF0)
298_CLK_GET_RATE1(saif1_clk, SAIF1)
299
300#define _CLK_GET_RATE_STUB(name) \
301static unsigned long name##_get_rate(struct clk *clk) \
302{ \
303 return clk_get_rate(clk->parent); \
304}
305
306_CLK_GET_RATE_STUB(uart_clk)
307_CLK_GET_RATE_STUB(pwm_clk)
308_CLK_GET_RATE_STUB(can0_clk)
309_CLK_GET_RATE_STUB(can1_clk)
310_CLK_GET_RATE_STUB(fec_clk)
311
312/*
313 * clk_set_rate
314 */
315/* fool compiler */
316#define BM_CLKCTRL_CPU_DIV 0
317#define BP_CLKCTRL_CPU_DIV 0
318#define BM_CLKCTRL_CPU_BUSY 0
319
320#define _CLK_SET_RATE(name, dr, fr, fs) \
321static int name##_set_rate(struct clk *clk, unsigned long rate) \
322{ \
323 u32 reg, bm_busy, div_max, d, f, div, frac; \
324 unsigned long diff, parent_rate, calc_rate; \
325 \
326 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
327 bm_busy = BM_CLKCTRL_##dr##_BUSY; \
328 \
329 if (clk->parent == &ref_xtal_clk) { \
330 parent_rate = clk_get_rate(clk->parent); \
331 div = DIV_ROUND_UP(parent_rate, rate); \
332 if (clk == &cpu_clk) { \
333 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
334 BP_CLKCTRL_CPU_DIV_XTAL; \
335 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
336 } \
337 if (div == 0 || div > div_max) \
338 return -EINVAL; \
339 } else { \
340 /* \
341 * hack alert: this block modifies clk->parent, too, \
342 * so the base to use it the grand parent. \
343 */ \
344 parent_rate = clk_get_rate(clk->parent->parent); \
345 rate >>= PARENT_RATE_SHIFT; \
346 parent_rate >>= PARENT_RATE_SHIFT; \
347 diff = parent_rate; \
348 div = frac = 1; \
349 if (clk == &cpu_clk) { \
350 div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
351 BP_CLKCTRL_CPU_DIV_CPU; \
352 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
353 } \
354 for (d = 1; d <= div_max; d++) { \
355 f = parent_rate * 18 / d / rate; \
356 if ((parent_rate * 18 / d) % rate) \
357 f++; \
358 if (f < 18 || f > 35) \
359 continue; \
360 \
361 calc_rate = parent_rate * 18 / f / d; \
362 if (calc_rate > rate) \
363 continue; \
364 \
365 if (rate - calc_rate < diff) { \
366 frac = f; \
367 div = d; \
368 diff = rate - calc_rate; \
369 } \
370 \
371 if (diff == 0) \
372 break; \
373 } \
374 \
375 if (diff == parent_rate) \
376 return -EINVAL; \
377 \
378 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
379 reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
380 reg |= frac << BP_CLKCTRL_##fr##_##fs##FRAC; \
381 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
382 } \
383 \
384 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
385 if (clk == &cpu_clk) { \
386 reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
387 reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
388 } else { \
389 reg &= ~BM_CLKCTRL_##dr##_DIV; \
390 reg |= div << BP_CLKCTRL_##dr##_DIV; \
391 if (reg & (1 << clk->enable_shift)) { \
392 pr_err("%s: clock is gated\n", __func__); \
393 return -EINVAL; \
394 } \
395 } \
396 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
397 \
398 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
399}
400
401_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
402_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
403_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
404_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
405_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
406_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
407_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
408
409#define _CLK_SET_RATE1(name, dr) \
410static int name##_set_rate(struct clk *clk, unsigned long rate) \
411{ \
412 u32 reg, div_max, div; \
413 unsigned long parent_rate; \
414 \
415 parent_rate = clk_get_rate(clk->parent); \
416 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
417 \
418 div = DIV_ROUND_UP(parent_rate, rate); \
419 if (div == 0 || div > div_max) \
420 return -EINVAL; \
421 \
422 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
423 reg &= ~BM_CLKCTRL_##dr##_DIV; \
424 reg |= div << BP_CLKCTRL_##dr##_DIV; \
425 if (reg & (1 << clk->enable_shift)) { \
426 pr_err("%s: clock is gated\n", __func__); \
427 return -EINVAL; \
428 } \
429 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
430 \
431 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
432}
433
434_CLK_SET_RATE1(xbus_clk, XBUS)
435
436/* saif clock uses 16 bits frac div */
437#define _CLK_SET_RATE_SAIF(name, rs) \
438static int name##_set_rate(struct clk *clk, unsigned long rate) \
439{ \
440 u16 div; \
441 u32 reg; \
442 u64 lrate; \
443 unsigned long parent_rate; \
444 \
445 parent_rate = clk_get_rate(clk->parent); \
446 if (rate > parent_rate) \
447 return -EINVAL; \
448 \
449 lrate = (u64)rate << 16; \
450 do_div(lrate, parent_rate); \
451 div = (u16)lrate; \
452 \
453 if (!div) \
454 return -EINVAL; \
455 \
456 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
457 reg &= ~BM_CLKCTRL_##rs##_DIV; \
458 reg |= div << BP_CLKCTRL_##rs##_DIV; \
459 if (reg & (1 << clk->enable_shift)) { \
460 pr_err("%s: clock is gated\n", __func__); \
461 return -EINVAL; \
462 } \
463 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
464 \
465 return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
466}
467
468_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
469_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
470
471#define _CLK_SET_RATE_STUB(name) \
472static int name##_set_rate(struct clk *clk, unsigned long rate) \
473{ \
474 return -EINVAL; \
475}
476
477_CLK_SET_RATE_STUB(emi_clk)
478_CLK_SET_RATE_STUB(uart_clk)
479_CLK_SET_RATE_STUB(pwm_clk)
480_CLK_SET_RATE_STUB(spdif_clk)
481_CLK_SET_RATE_STUB(clk32k_clk)
482_CLK_SET_RATE_STUB(can0_clk)
483_CLK_SET_RATE_STUB(can1_clk)
484_CLK_SET_RATE_STUB(fec_clk)
485
486/*
487 * clk_set_parent
488 */
489#define _CLK_SET_PARENT(name, bit) \
490static int name##_set_parent(struct clk *clk, struct clk *parent) \
491{ \
492 if (parent != clk->parent) { \
493 __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
494 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
495 clk->parent = parent; \
496 } \
497 \
498 return 0; \
499}
500
501_CLK_SET_PARENT(cpu_clk, CPU)
502_CLK_SET_PARENT(emi_clk, EMI)
503_CLK_SET_PARENT(ssp0_clk, SSP0)
504_CLK_SET_PARENT(ssp1_clk, SSP1)
505_CLK_SET_PARENT(ssp2_clk, SSP2)
506_CLK_SET_PARENT(ssp3_clk, SSP3)
507_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
508_CLK_SET_PARENT(gpmi_clk, GPMI)
509_CLK_SET_PARENT(saif0_clk, SAIF0)
510_CLK_SET_PARENT(saif1_clk, SAIF1)
511
512#define _CLK_SET_PARENT_STUB(name) \
513static int name##_set_parent(struct clk *clk, struct clk *parent) \
514{ \
515 if (parent != clk->parent) \
516 return -EINVAL; \
517 else \
518 return 0; \
519}
520
521_CLK_SET_PARENT_STUB(pwm_clk)
522_CLK_SET_PARENT_STUB(uart_clk)
523_CLK_SET_PARENT_STUB(clk32k_clk)
524_CLK_SET_PARENT_STUB(spdif_clk)
525_CLK_SET_PARENT_STUB(fec_clk)
526_CLK_SET_PARENT_STUB(can0_clk)
527_CLK_SET_PARENT_STUB(can1_clk)
528
529/*
530 * clk definition
531 */
532static struct clk cpu_clk = {
533 .get_rate = cpu_clk_get_rate,
534 .set_rate = cpu_clk_set_rate,
535 .set_parent = cpu_clk_set_parent,
536 .parent = &ref_cpu_clk,
537};
538
539static struct clk hbus_clk = {
540 .get_rate = hbus_clk_get_rate,
541 .parent = &cpu_clk,
542};
543
544static struct clk xbus_clk = {
545 .get_rate = xbus_clk_get_rate,
546 .set_rate = xbus_clk_set_rate,
547 .parent = &ref_xtal_clk,
548};
549
550static struct clk lradc_clk = {
551 .get_rate = lradc_clk_get_rate,
552 .parent = &clk32k_clk,
553};
554
555static struct clk rtc_clk = {
556 .get_rate = rtc_clk_get_rate,
557 .parent = &ref_xtal_clk,
558};
559
560/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
561static struct clk usb0_clk = {
562 .enable_reg = DIGCTRL_BASE_ADDR,
563 .enable_shift = 2,
564 .enable = _raw_clk_enable,
565 .disable = _raw_clk_disable,
566 .parent = &pll0_clk,
567};
568
569static struct clk usb1_clk = {
570 .enable_reg = DIGCTRL_BASE_ADDR,
571 .enable_shift = 16,
572 .enable = _raw_clk_enable,
573 .disable = _raw_clk_disable,
574 .parent = &pll1_clk,
575};
576
577#define _DEFINE_CLOCK(name, er, es, p) \
578 static struct clk name = { \
579 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
580 .enable_shift = BP_CLKCTRL_##er##_##es, \
581 .get_rate = name##_get_rate, \
582 .set_rate = name##_set_rate, \
583 .set_parent = name##_set_parent, \
584 .enable = _raw_clk_enable, \
585 .disable = _raw_clk_disable, \
586 .parent = p, \
587 }
588
589_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
590_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
591_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
592_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
593_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
594_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
595_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
596_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
597_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
598_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
599_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
600_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
601_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
602_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
603_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
604_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
605
606#define _REGISTER_CLOCK(d, n, c) \
607 { \
608 .dev_id = d, \
609 .con_id = n, \
610 .clk = &c, \
611 },
612
613static struct clk_lookup lookups[] = {
614 /* for amba bus driver */
615 _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
616 /* for amba-pl011 driver */
617 _REGISTER_CLOCK("duart", NULL, uart_clk)
618 _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
619 _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
620 _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
621 _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
622 _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
623 _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
624 _REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
625 _REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
626 _REGISTER_CLOCK("rtc", NULL, rtc_clk)
627 _REGISTER_CLOCK("pll2", NULL, pll2_clk)
628 _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
629 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
630 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
631 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
632 _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
633 _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
634 _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
635 _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
636 _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
637 _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
638 _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
639 _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
640 _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
641 _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
642 _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
643 _REGISTER_CLOCK("mxs-pwm.5", NULL, pwm_clk)
644 _REGISTER_CLOCK("mxs-pwm.6", NULL, pwm_clk)
645 _REGISTER_CLOCK("mxs-pwm.7", NULL, pwm_clk)
646 _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
647 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
648 _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
649 _REGISTER_CLOCK("mxs-saif.0", NULL, saif0_clk)
650 _REGISTER_CLOCK("mxs-saif.1", NULL, saif1_clk)
651};
652
653static int clk_misc_init(void)
654{
655 u32 reg;
656 int ret;
657
658 /* Fix up parent per register setting */
659 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
660 cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
661 &ref_xtal_clk : &ref_cpu_clk;
662 emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
663 &ref_xtal_clk : &ref_emi_clk;
664 ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
665 &ref_xtal_clk : &ref_io0_clk;
666 ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
667 &ref_xtal_clk : &ref_io0_clk;
668 ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
669 &ref_xtal_clk : &ref_io1_clk;
670 ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
671 &ref_xtal_clk : &ref_io1_clk;
672 lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
673 &ref_xtal_clk : &ref_pix_clk;
674 gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
675 &ref_xtal_clk : &ref_gpmi_clk;
676 saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
677 &ref_xtal_clk : &pll0_clk;
678 saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
679 &ref_xtal_clk : &pll0_clk;
680
681 /* Use int div over frac when both are available */
682 __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
683 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
684 __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
685 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
686 __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
687 CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
688
689 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
690 reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
691 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
692
693 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
694 reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
695 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
696
697 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
698 reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
699 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
700
701 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
702 reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
703 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
704
705 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
706 reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
707 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
708
709 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
710 reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
711 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
712
713 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
714 reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
715 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
716
717 /* SAIF has to use frac div for functional operation */
718 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
719 reg |= BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
720 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
721
722 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
723 reg |= BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
724 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
725
726 /*
727 * Set safe hbus clock divider. A divider of 3 ensure that
728 * the Vddd voltage required for the cpu clock is sufficiently
729 * high for the hbus clock.
730 */
731 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
732 reg &= BM_CLKCTRL_HBUS_DIV;
733 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
734 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
735
736 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
737
738 /* Gate off cpu clock in WFI for power saving */
739 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
740 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
741
742 /*
743 * Extra fec clock setting
744 * The DENX M28 uses an external clock source
745 * and the clock output must not be enabled
746 */
747 if (!machine_is_m28evk()) {
748 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
749 reg &= ~BM_CLKCTRL_ENET_SLEEP;
750 reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
751 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
752 }
753
754 /*
755 * 480 MHz seems too high to be ssp clock source directly,
756 * so set frac0 to get a 288 MHz ref_io0.
757 */
758 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
759 reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
760 reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
761 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
762
763 return ret;
764}
765
766int __init mx28_clocks_init(void)
767{
768 clk_misc_init();
769
770 /*
771 * source ssp clock from ref_io0 than ref_xtal,
772 * as ref_xtal only provides 24 MHz as maximum.
773 */
774 clk_set_parent(&ssp0_clk, &ref_io0_clk);
775 clk_set_parent(&ssp1_clk, &ref_io0_clk);
776 clk_set_parent(&ssp2_clk, &ref_io1_clk);
777 clk_set_parent(&ssp3_clk, &ref_io1_clk);
778
779 clk_prepare_enable(&cpu_clk);
780 clk_prepare_enable(&hbus_clk);
781 clk_prepare_enable(&xbus_clk);
782 clk_prepare_enable(&emi_clk);
783 clk_prepare_enable(&uart_clk);
784
785 clk_set_parent(&lcdif_clk, &ref_pix_clk);
786 clk_set_parent(&saif0_clk, &pll0_clk);
787 clk_set_parent(&saif1_clk, &pll0_clk);
788
789 /*
790 * Set an initial clock rate for the saif internal logic to work
791 * properly. This is important when working in EXTMASTER mode that
792 * uses the other saif's BITCLK&LRCLK but it still needs a basic
793 * clock which should be fast enough for the internal logic.
794 */
795 clk_set_rate(&saif0_clk, 24000000);
796 clk_set_rate(&saif1_clk, 24000000);
797
798 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
799
800 mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
801
802 return 0;
803}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
deleted file mode 100644
index 97a6f4acc6c..00000000000
--- a/arch/arm/mach-mxs/clock.c
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * Based on arch/arm/plat-omap/clock.c
3 *
4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
7 * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25/* #define DEBUG */
26
27#include <linux/clk.h>
28#include <linux/err.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/io.h>
32#include <linux/kernel.h>
33#include <linux/list.h>
34#include <linux/module.h>
35#include <linux/mutex.h>
36#include <linux/platform_device.h>
37#include <linux/proc_fs.h>
38#include <linux/semaphore.h>
39#include <linux/string.h>
40
41#include <mach/clock.h>
42
43static LIST_HEAD(clocks);
44static DEFINE_MUTEX(clocks_mutex);
45
46/*-------------------------------------------------------------------------
47 * Standard clock functions defined in include/linux/clk.h
48 *-------------------------------------------------------------------------*/
49
50static void __clk_disable(struct clk *clk)
51{
52 if (clk == NULL || IS_ERR(clk))
53 return;
54 WARN_ON(!clk->usecount);
55
56 if (!(--clk->usecount)) {
57 if (clk->disable)
58 clk->disable(clk);
59 __clk_disable(clk->parent);
60 }
61}
62
63static int __clk_enable(struct clk *clk)
64{
65 if (clk == NULL || IS_ERR(clk))
66 return -EINVAL;
67
68 if (clk->usecount++ == 0) {
69 __clk_enable(clk->parent);
70
71 if (clk->enable)
72 clk->enable(clk);
73 }
74 return 0;
75}
76
77/*
78 * The clk_enable/clk_disable could be called by drivers in atomic context,
79 * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
80 * can hold a mutex, as the pair will only be called in non-atomic context.
81 * Before migrating to common clk framework, we can have __clk_enable and
82 * __clk_disable called in clk_prepare/clk_unprepare with mutex held and
83 * leave clk_enable/clk_disable as the dummy functions.
84 */
85int clk_prepare(struct clk *clk)
86{
87 int ret = 0;
88
89 if (clk == NULL || IS_ERR(clk))
90 return -EINVAL;
91
92 mutex_lock(&clocks_mutex);
93 ret = __clk_enable(clk);
94 mutex_unlock(&clocks_mutex);
95
96 return ret;
97}
98EXPORT_SYMBOL(clk_prepare);
99
100void clk_unprepare(struct clk *clk)
101{
102 if (clk == NULL || IS_ERR(clk))
103 return;
104
105 mutex_lock(&clocks_mutex);
106 __clk_disable(clk);
107 mutex_unlock(&clocks_mutex);
108}
109EXPORT_SYMBOL(clk_unprepare);
110
111int clk_enable(struct clk *clk)
112{
113 return 0;
114}
115EXPORT_SYMBOL(clk_enable);
116
117void clk_disable(struct clk *clk)
118{
119 /* nothing to do */
120}
121EXPORT_SYMBOL(clk_disable);
122
123/* Retrieve the *current* clock rate. If the clock itself
124 * does not provide a special calculation routine, ask
125 * its parent and so on, until one is able to return
126 * a valid clock rate
127 */
128unsigned long clk_get_rate(struct clk *clk)
129{
130 if (clk == NULL || IS_ERR(clk))
131 return 0UL;
132
133 if (clk->get_rate)
134 return clk->get_rate(clk);
135
136 return clk_get_rate(clk->parent);
137}
138EXPORT_SYMBOL(clk_get_rate);
139
140/* Round the requested clock rate to the nearest supported
141 * rate that is less than or equal to the requested rate.
142 * This is dependent on the clock's current parent.
143 */
144long clk_round_rate(struct clk *clk, unsigned long rate)
145{
146 if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
147 return 0;
148
149 return clk->round_rate(clk, rate);
150}
151EXPORT_SYMBOL(clk_round_rate);
152
153/* Set the clock to the requested clock rate. The rate must
154 * match a supported rate exactly based on what clk_round_rate returns
155 */
156int clk_set_rate(struct clk *clk, unsigned long rate)
157{
158 int ret = -EINVAL;
159
160 if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
161 return ret;
162
163 mutex_lock(&clocks_mutex);
164 ret = clk->set_rate(clk, rate);
165 mutex_unlock(&clocks_mutex);
166
167 return ret;
168}
169EXPORT_SYMBOL(clk_set_rate);
170
171/* Set the clock's parent to another clock source */
172int clk_set_parent(struct clk *clk, struct clk *parent)
173{
174 int ret = -EINVAL;
175 struct clk *old;
176
177 if (clk == NULL || IS_ERR(clk) || parent == NULL ||
178 IS_ERR(parent) || clk->set_parent == NULL)
179 return ret;
180
181 if (clk->usecount)
182 clk_prepare_enable(parent);
183
184 mutex_lock(&clocks_mutex);
185 ret = clk->set_parent(clk, parent);
186 if (ret == 0) {
187 old = clk->parent;
188 clk->parent = parent;
189 } else {
190 old = parent;
191 }
192 mutex_unlock(&clocks_mutex);
193
194 if (clk->usecount)
195 clk_disable(old);
196
197 return ret;
198}
199EXPORT_SYMBOL(clk_set_parent);
200
201/* Retrieve the clock's parent clock source */
202struct clk *clk_get_parent(struct clk *clk)
203{
204 struct clk *ret = NULL;
205
206 if (clk == NULL || IS_ERR(clk))
207 return ret;
208
209 return clk->parent;
210}
211EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index b8913df4cfa..19659de1c4e 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -1,6 +1,5 @@
1config MXS_HAVE_AMBA_DUART 1config MXS_HAVE_AMBA_DUART
2 bool 2 bool
3 select ARM_AMBA
4 3
5config MXS_HAVE_PLATFORM_AUART 4config MXS_HAVE_PLATFORM_AUART
6 bool 5 bool
diff --git a/arch/arm/mach-mxs/devices/platform-dma.c b/arch/arm/mach-mxs/devices/platform-dma.c
index 6a0202b1016..46824501de0 100644
--- a/arch/arm/mach-mxs/devices/platform-dma.c
+++ b/arch/arm/mach-mxs/devices/platform-dma.c
@@ -14,7 +14,7 @@
14#include <mach/mx28.h> 14#include <mach/mx28.h>
15#include <mach/devices-common.h> 15#include <mach/devices-common.h>
16 16
17static struct platform_device *__init mxs_add_dma(const char *devid, 17struct platform_device *__init mxs_add_dma(const char *devid,
18 resource_size_t base) 18 resource_size_t base)
19{ 19{
20 struct resource res[] = { 20 struct resource res[] = {
@@ -29,22 +29,3 @@ static struct platform_device *__init mxs_add_dma(const char *devid,
29 res, ARRAY_SIZE(res), NULL, 0, 29 res, ARRAY_SIZE(res), NULL, 0,
30 DMA_BIT_MASK(32)); 30 DMA_BIT_MASK(32));
31} 31}
32
33static int __init mxs_add_mxs_dma(void)
34{
35 char *apbh = "mxs-dma-apbh";
36 char *apbx = "mxs-dma-apbx";
37
38 if (cpu_is_mx23()) {
39 mxs_add_dma(apbh, MX23_APBH_DMA_BASE_ADDR);
40 mxs_add_dma(apbx, MX23_APBX_DMA_BASE_ADDR);
41 }
42
43 if (cpu_is_mx28()) {
44 mxs_add_dma(apbh, MX28_APBH_DMA_BASE_ADDR);
45 mxs_add_dma(apbx, MX28_APBX_DMA_BASE_ADDR);
46 }
47
48 return 0;
49}
50arch_initcall(mxs_add_mxs_dma);
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
index ed0885e414e..cd99f19ec63 100644
--- a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
+++ b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
@@ -14,7 +14,7 @@
14#include <mach/devices-common.h> 14#include <mach/devices-common.h>
15 15
16struct platform_device *__init mxs_add_gpio( 16struct platform_device *__init mxs_add_gpio(
17 int id, resource_size_t iobase, int irq) 17 char *name, int id, resource_size_t iobase, int irq)
18{ 18{
19 struct resource res[] = { 19 struct resource res[] = {
20 { 20 {
@@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio(
29 }; 29 };
30 30
31 return platform_device_register_resndata(&mxs_apbh_bus, 31 return platform_device_register_resndata(&mxs_apbh_bus,
32 "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0); 32 name, id, res, ARRAY_SIZE(res), NULL, 0);
33} 33}
34
35static int __init mxs_add_mxs_gpio(void)
36{
37 if (cpu_is_mx23()) {
38 mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
39 mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
40 mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
41 }
42
43 if (cpu_is_mx28()) {
44 mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
45 mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
46 mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
47 mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
48 mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
49 }
50
51 return 0;
52}
53postcore_initcall(mxs_add_mxs_gpio);
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
index bef9d923f54..b33c9d05c55 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -17,8 +17,9 @@
17#include <mach/mx28.h> 17#include <mach/mx28.h>
18#include <mach/devices-common.h> 18#include <mach/devices-common.h>
19 19
20#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \ 20#define mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid) \
21 { \ 21 { \
22 .devid = _devid, \
22 .id = _id, \ 23 .id = _id, \
23 .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \ 24 .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
24 .dma = soc ## _DMA_SSP ## hwid, \ 25 .dma = soc ## _DMA_SSP ## hwid, \
@@ -26,23 +27,23 @@
26 .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \ 27 .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
27 } 28 }
28 29
29#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \ 30#define mxs_mxs_mmc_data_entry(soc, _devid, _id, hwid) \
30 [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid) 31 [_id] = mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid)
31 32
32 33
33#ifdef CONFIG_SOC_IMX23 34#ifdef CONFIG_SOC_IMX23
34const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = { 35const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
35 mxs_mxs_mmc_data_entry(MX23, 0, 1), 36 mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 0, 1),
36 mxs_mxs_mmc_data_entry(MX23, 1, 2), 37 mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 1, 2),
37}; 38};
38#endif 39#endif
39 40
40#ifdef CONFIG_SOC_IMX28 41#ifdef CONFIG_SOC_IMX28
41const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { 42const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
42 mxs_mxs_mmc_data_entry(MX28, 0, 0), 43 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 0, 0),
43 mxs_mxs_mmc_data_entry(MX28, 1, 1), 44 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 1, 1),
44 mxs_mxs_mmc_data_entry(MX28, 2, 2), 45 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 2, 2),
45 mxs_mxs_mmc_data_entry(MX28, 3, 3), 46 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 3, 3),
46}; 47};
47#endif 48#endif
48 49
@@ -70,6 +71,6 @@ struct platform_device *__init mxs_add_mxs_mmc(
70 }, 71 },
71 }; 72 };
72 73
73 return mxs_add_platform_device("mxs-mmc", data->id, 74 return mxs_add_platform_device(data->devid, data->id,
74 res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); 75 res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
75} 76}
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
deleted file mode 100644
index 592c9ab5d76..00000000000
--- a/arch/arm/mach-mxs/include/mach/clock.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#ifndef __MACH_MXS_CLOCK_H__
21#define __MACH_MXS_CLOCK_H__
22
23#ifndef __ASSEMBLY__
24#include <linux/list.h>
25
26struct module;
27
28struct clk {
29 int id;
30 /* Source clock this clk depends on */
31 struct clk *parent;
32 /* Reference count of clock enable/disable */
33 __s8 usecount;
34 /* Register bit position for clock's enable/disable control. */
35 u8 enable_shift;
36 /* Register address for clock's enable/disable control. */
37 void __iomem *enable_reg;
38 u32 flags;
39 /* get the current clock rate (always a fresh value) */
40 unsigned long (*get_rate) (struct clk *);
41 /* Function ptr to set the clock to a new rate. The rate must match a
42 supported rate returned from round_rate. Leave blank if clock is not
43 programmable */
44 int (*set_rate) (struct clk *, unsigned long);
45 /* Function ptr to round the requested clock rate to the nearest
46 supported rate that is less than or equal to the requested rate. */
47 unsigned long (*round_rate) (struct clk *, unsigned long);
48 /* Function ptr to enable the clock. Leave blank if clock can not
49 be gated. */
50 int (*enable) (struct clk *);
51 /* Function ptr to disable the clock. Leave blank if clock can not
52 be gated. */
53 void (*disable) (struct clk *);
54 /* Function ptr to set the parent clock of the clock. */
55 int (*set_parent) (struct clk *, struct clk *);
56};
57
58int clk_register(struct clk *clk);
59void clk_unregister(struct clk *clk);
60
61#endif /* __ASSEMBLY__ */
62#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 8d88399b73e..de6c7ba4254 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -11,28 +11,27 @@
11#ifndef __MACH_MXS_COMMON_H__ 11#ifndef __MACH_MXS_COMMON_H__
12#define __MACH_MXS_COMMON_H__ 12#define __MACH_MXS_COMMON_H__
13 13
14struct clk;
15
16extern const u32 *mxs_get_ocotp(void); 14extern const u32 *mxs_get_ocotp(void);
17extern int mxs_reset_block(void __iomem *); 15extern int mxs_reset_block(void __iomem *);
18extern void mxs_timer_init(struct clk *, int); 16extern void mxs_timer_init(int);
19extern void mxs_restart(char, const char *); 17extern void mxs_restart(char, const char *);
20extern int mxs_saif_clkmux_select(unsigned int clkmux); 18extern int mxs_saif_clkmux_select(unsigned int clkmux);
21 19
22extern void mx23_soc_init(void); 20extern void mx23_soc_init(void);
23extern int mx23_register_gpios(void);
24extern int mx23_clocks_init(void); 21extern int mx23_clocks_init(void);
25extern void mx23_map_io(void); 22extern void mx23_map_io(void);
26extern void mx23_init_irq(void); 23extern void mx23_init_irq(void);
27 24
28extern void mx28_soc_init(void); 25extern void mx28_soc_init(void);
29extern int mx28_register_gpios(void);
30extern int mx28_clocks_init(void); 26extern int mx28_clocks_init(void);
31extern void mx28_map_io(void); 27extern void mx28_map_io(void);
32extern void mx28_init_irq(void); 28extern void mx28_init_irq(void);
33 29
34extern void icoll_init_irq(void); 30extern void icoll_init_irq(void);
35 31
36extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask); 32extern struct platform_device *mxs_add_dma(const char *devid,
33 resource_size_t base);
34extern struct platform_device *mxs_add_gpio(char *name, int id,
35 resource_size_t iobase, int irq);
37 36
38#endif /* __MACH_MXS_COMMON_H__ */ 37#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 21e45a70d34..e8b1d958240 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -82,8 +82,9 @@ struct platform_device * __init mxs_add_mxs_i2c(
82 const struct mxs_mxs_i2c_data *data); 82 const struct mxs_mxs_i2c_data *data);
83 83
84/* mmc */ 84/* mmc */
85#include <mach/mmc.h> 85#include <linux/mmc/mxs-mmc.h>
86struct mxs_mxs_mmc_data { 86struct mxs_mxs_mmc_data {
87 const char *devid;
87 int id; 88 int id;
88 resource_size_t iobase; 89 resource_size_t iobase;
89 resource_size_t dma; 90 resource_size_t dma;
diff --git a/arch/arm/mach-mxs/include/mach/mmc.h b/arch/arm/mach-mxs/include/mach/mmc.h
deleted file mode 100644
index 211547a0556..00000000000
--- a/arch/arm/mach-mxs/include/mach/mmc.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
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
9#ifndef __MACH_MXS_MMC_H__
10#define __MACH_MXS_MMC_H__
11
12struct mxs_mmc_platform_data {
13 int wp_gpio; /* write protect pin */
14 unsigned int flags;
15#define SLOTF_4_BIT_CAPABLE (1 << 0)
16#define SLOTF_8_BIT_CAPABLE (1 << 1)
17};
18#endif /* __MACH_MXS_MMC_H__ */
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index da4610ebe9e..dafd48e86c8 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -226,7 +226,7 @@ static void __init mx28evk_fec_reset(void)
226 struct clk *clk; 226 struct clk *clk;
227 227
228 /* Enable fec phy clock */ 228 /* Enable fec phy clock */
229 clk = clk_get_sys("pll2", NULL); 229 clk = clk_get_sys("enet_out", NULL);
230 if (!IS_ERR(clk)) 230 if (!IS_ERR(clk))
231 clk_prepare_enable(clk); 231 clk_prepare_enable(clk);
232 232
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
new file mode 100644
index 00000000000..8cac94b3302
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -0,0 +1,121 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/init.h>
18#include <linux/irqdomain.h>
19#include <linux/of_irq.h>
20#include <linux/of_platform.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/time.h>
23#include <mach/common.h>
24
25static int __init mxs_icoll_add_irq_domain(struct device_node *np,
26 struct device_node *interrupt_parent)
27{
28 irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
29
30 return 0;
31}
32
33static int __init mxs_gpio_add_irq_domain(struct device_node *np,
34 struct device_node *interrupt_parent)
35{
36 static int gpio_irq_base = MXS_GPIO_IRQ_START;
37
38 irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
39 gpio_irq_base += 32;
40
41 return 0;
42}
43
44static const struct of_device_id mxs_irq_match[] __initconst = {
45 { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
46 { .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
47 { /* sentinel */ }
48};
49
50static void __init mxs_dt_init_irq(void)
51{
52 icoll_init_irq();
53 of_irq_init(mxs_irq_match);
54}
55
56static void __init imx23_timer_init(void)
57{
58 mx23_clocks_init();
59}
60
61static struct sys_timer imx23_timer = {
62 .init = imx23_timer_init,
63};
64
65static void __init imx28_timer_init(void)
66{
67 mx28_clocks_init();
68}
69
70static struct sys_timer imx28_timer = {
71 .init = imx28_timer_init,
72};
73
74static void __init imx28_evk_init(void)
75{
76 struct clk *clk;
77
78 /* Enable fec phy clock */
79 clk = clk_get_sys("enet_out", NULL);
80 if (!IS_ERR(clk))
81 clk_prepare_enable(clk);
82}
83
84static void __init mxs_machine_init(void)
85{
86 if (of_machine_is_compatible("fsl,imx28-evk"))
87 imx28_evk_init();
88
89 of_platform_populate(NULL, of_default_bus_match_table,
90 NULL, NULL);
91}
92
93static const char *imx23_dt_compat[] __initdata = {
94 "fsl,imx23-evk",
95 "fsl,imx23",
96 NULL,
97};
98
99static const char *imx28_dt_compat[] __initdata = {
100 "fsl,imx28-evk",
101 "fsl,imx28",
102 NULL,
103};
104
105DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
106 .map_io = mx23_map_io,
107 .init_irq = mxs_dt_init_irq,
108 .timer = &imx23_timer,
109 .init_machine = mxs_machine_init,
110 .dt_compat = imx23_dt_compat,
111 .restart = mxs_restart,
112MACHINE_END
113
114DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
115 .map_io = mx28_map_io,
116 .init_irq = mxs_dt_init_irq,
117 .timer = &imx28_timer,
118 .init_machine = mxs_machine_init,
119 .dt_compat = imx28_dt_compat,
120 .restart = mxs_restart,
121MACHINE_END
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c
index 67a384edcf5..dccb67a9e7c 100644
--- a/arch/arm/mach-mxs/mm.c
+++ b/arch/arm/mach-mxs/mm.c
@@ -66,9 +66,25 @@ void __init mx28_init_irq(void)
66void __init mx23_soc_init(void) 66void __init mx23_soc_init(void)
67{ 67{
68 pinctrl_provide_dummies(); 68 pinctrl_provide_dummies();
69
70 mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
71 mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
72
73 mxs_add_gpio("imx23-gpio", 0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
74 mxs_add_gpio("imx23-gpio", 1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
75 mxs_add_gpio("imx23-gpio", 2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
69} 76}
70 77
71void __init mx28_soc_init(void) 78void __init mx28_soc_init(void)
72{ 79{
73 pinctrl_provide_dummies(); 80 pinctrl_provide_dummies();
81
82 mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
83 mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
84
85 mxs_add_gpio("imx28-gpio", 0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
86 mxs_add_gpio("imx28-gpio", 1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
87 mxs_add_gpio("imx28-gpio", 2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
88 mxs_add_gpio("imx28-gpio", 3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
89 mxs_add_gpio("imx28-gpio", 4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
74} 90}
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
deleted file mode 100644
index 0ea5c9d0e2b..00000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx23.h
+++ /dev/null
@@ -1,331 +0,0 @@
1/*
2 * Freescale CLKCTRL Register Definitions
3 *
4 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
5 * Copyright 2008-2010 Freescale Semiconductor, Inc.
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This file is created by xml file. Don't Edit it.
22 *
23 * Xml Revision: 1.48
24 * Template revision: 26195
25 */
26
27#ifndef __REGS_CLKCTRL_MX23_H__
28#define __REGS_CLKCTRL_MX23_H__
29
30
31#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
32#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
33#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
34#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
35
36#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
37#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
38#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
39 (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
40#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
41#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
42#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
43#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
44#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
45#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
46#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
47 (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
48#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
49#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
50#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
51#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
52#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
53#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
54#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
55 (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
56#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
57#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
58#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
59#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
60#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
61#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
62
63#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
64
65#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
66#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
67#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
68#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
69#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
70 (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
71
72#define HW_CLKCTRL_CPU (0x00000020)
73#define HW_CLKCTRL_CPU_SET (0x00000024)
74#define HW_CLKCTRL_CPU_CLR (0x00000028)
75#define HW_CLKCTRL_CPU_TOG (0x0000002c)
76
77#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
78#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
79#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
80#define BP_CLKCTRL_CPU_DIV_XTAL 16
81#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
82#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
83 (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
84#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
85#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
86#define BP_CLKCTRL_CPU_DIV_CPU 0
87#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
88#define BF_CLKCTRL_CPU_DIV_CPU(v) \
89 (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
90
91#define HW_CLKCTRL_HBUS (0x00000030)
92#define HW_CLKCTRL_HBUS_SET (0x00000034)
93#define HW_CLKCTRL_HBUS_CLR (0x00000038)
94#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
95
96#define BM_CLKCTRL_HBUS_BUSY 0x20000000
97#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
98#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
99#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
100#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
101#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
102#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
103#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
104#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
105#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
106#define BP_CLKCTRL_HBUS_SLOW_DIV 16
107#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
108#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
109 (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
110#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
111#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
112#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
113#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
114#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
115#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
116#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
117#define BP_CLKCTRL_HBUS_DIV 0
118#define BM_CLKCTRL_HBUS_DIV 0x0000001F
119#define BF_CLKCTRL_HBUS_DIV(v) \
120 (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
121
122#define HW_CLKCTRL_XBUS (0x00000040)
123
124#define BM_CLKCTRL_XBUS_BUSY 0x80000000
125#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
126#define BP_CLKCTRL_XBUS_DIV 0
127#define BM_CLKCTRL_XBUS_DIV 0x000003FF
128#define BF_CLKCTRL_XBUS_DIV(v) \
129 (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
130
131#define HW_CLKCTRL_XTAL (0x00000050)
132#define HW_CLKCTRL_XTAL_SET (0x00000054)
133#define HW_CLKCTRL_XTAL_CLR (0x00000058)
134#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
135
136#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
137#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
138#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
139#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
140#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
141#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
142#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
143#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
144#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
145#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
146#define BP_CLKCTRL_XTAL_DIV_UART 0
147#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
148#define BF_CLKCTRL_XTAL_DIV_UART(v) \
149 (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
150
151#define HW_CLKCTRL_PIX (0x00000060)
152
153#define BP_CLKCTRL_PIX_CLKGATE 31
154#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
155#define BM_CLKCTRL_PIX_BUSY 0x20000000
156#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
157#define BP_CLKCTRL_PIX_DIV 0
158#define BM_CLKCTRL_PIX_DIV 0x00000FFF
159#define BF_CLKCTRL_PIX_DIV(v) \
160 (((v) << 0) & BM_CLKCTRL_PIX_DIV)
161
162#define HW_CLKCTRL_SSP (0x00000070)
163
164#define BP_CLKCTRL_SSP_CLKGATE 31
165#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
166#define BM_CLKCTRL_SSP_BUSY 0x20000000
167#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
168#define BP_CLKCTRL_SSP_DIV 0
169#define BM_CLKCTRL_SSP_DIV 0x000001FF
170#define BF_CLKCTRL_SSP_DIV(v) \
171 (((v) << 0) & BM_CLKCTRL_SSP_DIV)
172
173#define HW_CLKCTRL_GPMI (0x00000080)
174
175#define BP_CLKCTRL_GPMI_CLKGATE 31
176#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
177#define BM_CLKCTRL_GPMI_BUSY 0x20000000
178#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
179#define BP_CLKCTRL_GPMI_DIV 0
180#define BM_CLKCTRL_GPMI_DIV 0x000003FF
181#define BF_CLKCTRL_GPMI_DIV(v) \
182 (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
183
184#define HW_CLKCTRL_SPDIF (0x00000090)
185
186#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
187
188#define HW_CLKCTRL_EMI (0x000000a0)
189
190#define BP_CLKCTRL_EMI_CLKGATE 31
191#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
192#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
193#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
194#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
195#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
196#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
197#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
198#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
199#define BP_CLKCTRL_EMI_DIV_XTAL 8
200#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
201#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
202 (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
203#define BP_CLKCTRL_EMI_DIV_EMI 0
204#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
205#define BF_CLKCTRL_EMI_DIV_EMI(v) \
206 (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
207
208#define HW_CLKCTRL_IR (0x000000b0)
209
210#define BM_CLKCTRL_IR_CLKGATE 0x80000000
211#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
212#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
213#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
214#define BP_CLKCTRL_IR_IROV_DIV 16
215#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
216#define BF_CLKCTRL_IR_IROV_DIV(v) \
217 (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
218#define BP_CLKCTRL_IR_IR_DIV 0
219#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
220#define BF_CLKCTRL_IR_IR_DIV(v) \
221 (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
222
223#define HW_CLKCTRL_SAIF (0x000000c0)
224
225#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
226#define BM_CLKCTRL_SAIF_BUSY 0x20000000
227#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
228#define BP_CLKCTRL_SAIF_DIV 0
229#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
230#define BF_CLKCTRL_SAIF_DIV(v) \
231 (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
232
233#define HW_CLKCTRL_TV (0x000000d0)
234
235#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
236#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
237
238#define HW_CLKCTRL_ETM (0x000000e0)
239
240#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
241#define BM_CLKCTRL_ETM_BUSY 0x20000000
242#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
243#define BP_CLKCTRL_ETM_DIV 0
244#define BM_CLKCTRL_ETM_DIV 0x0000003F
245#define BF_CLKCTRL_ETM_DIV(v) \
246 (((v) << 0) & BM_CLKCTRL_ETM_DIV)
247
248#define HW_CLKCTRL_FRAC (0x000000f0)
249#define HW_CLKCTRL_FRAC_SET (0x000000f4)
250#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
251#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
252
253#define BP_CLKCTRL_FRAC_CLKGATEIO 31
254#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
255#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
256#define BP_CLKCTRL_FRAC_IOFRAC 24
257#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
258#define BF_CLKCTRL_FRAC_IOFRAC(v) \
259 (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
260#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
261#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
262#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
263#define BP_CLKCTRL_FRAC_PIXFRAC 16
264#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
265#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
266 (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
267#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
268#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
269#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
270#define BP_CLKCTRL_FRAC_EMIFRAC 8
271#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
272#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
273 (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
274#define BP_CLKCTRL_FRAC_CLKGATECPU 7
275#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
276#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
277#define BP_CLKCTRL_FRAC_CPUFRAC 0
278#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
279#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
280 (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
281
282#define HW_CLKCTRL_FRAC1 (0x00000100)
283#define HW_CLKCTRL_FRAC1_SET (0x00000104)
284#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
285#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
286
287#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
288#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
289
290#define HW_CLKCTRL_CLKSEQ (0x00000110)
291#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
292#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
293#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
294
295#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
296#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
297#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
298#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
299#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
300#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
301#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
302#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
303
304#define HW_CLKCTRL_RESET (0x00000120)
305
306#define BM_CLKCTRL_RESET_CHIP 0x00000002
307#define BM_CLKCTRL_RESET_DIG 0x00000001
308
309#define HW_CLKCTRL_STATUS (0x00000130)
310
311#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
312#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
313#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
314 (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
315
316#define HW_CLKCTRL_VERSION (0x00000140)
317
318#define BP_CLKCTRL_VERSION_MAJOR 24
319#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
320#define BF_CLKCTRL_VERSION_MAJOR(v) \
321 (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
322#define BP_CLKCTRL_VERSION_MINOR 16
323#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
324#define BF_CLKCTRL_VERSION_MINOR(v) \
325 (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
326#define BP_CLKCTRL_VERSION_STEP 0
327#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
328#define BF_CLKCTRL_VERSION_STEP(v) \
329 (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
330
331#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
deleted file mode 100644
index 7d1b061d794..00000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx28.h
+++ /dev/null
@@ -1,486 +0,0 @@
1/*
2 * Freescale CLKCTRL Register Definitions
3 *
4 * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
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 * This file is created by xml file. Don't Edit it.
21 *
22 * Xml Revision: 1.48
23 * Template revision: 26195
24 */
25
26#ifndef __REGS_CLKCTRL_MX28_H__
27#define __REGS_CLKCTRL_MX28_H__
28
29#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
30#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
31#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
32#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
33
34#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
35#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
36#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
37 (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
38#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
39#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
40#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
41#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
42#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
43#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
44#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
45 (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
46#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
47#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
48#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
49#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
50#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
51#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
52#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
53 (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
54#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
55#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
56#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
57#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
58#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
59#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
60
61#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
62
63#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
64#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
65#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
66#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
67#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
68 (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
69
70#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
71#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
72#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
73#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
74
75#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
76#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
77#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
78#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
79 (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
80#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
81#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
82#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
83#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
84#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
85#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
86#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
87 (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
88#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
89#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
90#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
91#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
92#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
93#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
94#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
95 (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
96#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
97#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
98#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
99#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
100#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
101#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
102
103#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
104
105#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
106#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
107#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
108#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
109#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
110 (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
111
112#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
113#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
114#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
115#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
116
117#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
118#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
119#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
120#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
121 (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
122#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
123#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
124#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
125#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
126 (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
127#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
128
129#define HW_CLKCTRL_CPU (0x00000050)
130#define HW_CLKCTRL_CPU_SET (0x00000054)
131#define HW_CLKCTRL_CPU_CLR (0x00000058)
132#define HW_CLKCTRL_CPU_TOG (0x0000005c)
133
134#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
135#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
136#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
137#define BP_CLKCTRL_CPU_DIV_XTAL 16
138#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
139#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
140 (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
141#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
142#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
143#define BP_CLKCTRL_CPU_DIV_CPU 0
144#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
145#define BF_CLKCTRL_CPU_DIV_CPU(v) \
146 (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
147
148#define HW_CLKCTRL_HBUS (0x00000060)
149#define HW_CLKCTRL_HBUS_SET (0x00000064)
150#define HW_CLKCTRL_HBUS_CLR (0x00000068)
151#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
152
153#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
154#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
155#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
156#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
157#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
158#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
159#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
160#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
161#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
162#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
163#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
164#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
165#define BP_CLKCTRL_HBUS_SLOW_DIV 16
166#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
167#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
168 (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
169#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
170#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
171#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
172#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
173#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
174#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
175#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
176#define BP_CLKCTRL_HBUS_DIV 0
177#define BM_CLKCTRL_HBUS_DIV 0x0000001F
178#define BF_CLKCTRL_HBUS_DIV(v) \
179 (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
180
181#define HW_CLKCTRL_XBUS (0x00000070)
182
183#define BM_CLKCTRL_XBUS_BUSY 0x80000000
184#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
185#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
186#define BP_CLKCTRL_XBUS_DIV 0
187#define BM_CLKCTRL_XBUS_DIV 0x000003FF
188#define BF_CLKCTRL_XBUS_DIV(v) \
189 (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
190
191#define HW_CLKCTRL_XTAL (0x00000080)
192#define HW_CLKCTRL_XTAL_SET (0x00000084)
193#define HW_CLKCTRL_XTAL_CLR (0x00000088)
194#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
195
196#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
197#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
198#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
199#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
200#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
201#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
202#define BP_CLKCTRL_XTAL_DIV_UART 0
203#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
204#define BF_CLKCTRL_XTAL_DIV_UART(v) \
205 (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
206
207#define HW_CLKCTRL_SSP0 (0x00000090)
208
209#define BP_CLKCTRL_SSP0_CLKGATE 31
210#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
211#define BM_CLKCTRL_SSP0_BUSY 0x20000000
212#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
213#define BP_CLKCTRL_SSP0_DIV 0
214#define BM_CLKCTRL_SSP0_DIV 0x000001FF
215#define BF_CLKCTRL_SSP0_DIV(v) \
216 (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
217
218#define HW_CLKCTRL_SSP1 (0x000000a0)
219
220#define BP_CLKCTRL_SSP1_CLKGATE 31
221#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
222#define BM_CLKCTRL_SSP1_BUSY 0x20000000
223#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
224#define BP_CLKCTRL_SSP1_DIV 0
225#define BM_CLKCTRL_SSP1_DIV 0x000001FF
226#define BF_CLKCTRL_SSP1_DIV(v) \
227 (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
228
229#define HW_CLKCTRL_SSP2 (0x000000b0)
230
231#define BP_CLKCTRL_SSP2_CLKGATE 31
232#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
233#define BM_CLKCTRL_SSP2_BUSY 0x20000000
234#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
235#define BP_CLKCTRL_SSP2_DIV 0
236#define BM_CLKCTRL_SSP2_DIV 0x000001FF
237#define BF_CLKCTRL_SSP2_DIV(v) \
238 (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
239
240#define HW_CLKCTRL_SSP3 (0x000000c0)
241
242#define BP_CLKCTRL_SSP3_CLKGATE 31
243#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
244#define BM_CLKCTRL_SSP3_BUSY 0x20000000
245#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
246#define BP_CLKCTRL_SSP3_DIV 0
247#define BM_CLKCTRL_SSP3_DIV 0x000001FF
248#define BF_CLKCTRL_SSP3_DIV(v) \
249 (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
250
251#define HW_CLKCTRL_GPMI (0x000000d0)
252
253#define BP_CLKCTRL_GPMI_CLKGATE 31
254#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
255#define BM_CLKCTRL_GPMI_BUSY 0x20000000
256#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
257#define BP_CLKCTRL_GPMI_DIV 0
258#define BM_CLKCTRL_GPMI_DIV 0x000003FF
259#define BF_CLKCTRL_GPMI_DIV(v) \
260 (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
261
262#define HW_CLKCTRL_SPDIF (0x000000e0)
263
264#define BP_CLKCTRL_SPDIF_CLKGATE 31
265#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
266
267#define HW_CLKCTRL_EMI (0x000000f0)
268
269#define BP_CLKCTRL_EMI_CLKGATE 31
270#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
271#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
272#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
273#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
274#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
275#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
276#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
277#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
278#define BP_CLKCTRL_EMI_DIV_XTAL 8
279#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
280#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
281 (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
282#define BP_CLKCTRL_EMI_DIV_EMI 0
283#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
284#define BF_CLKCTRL_EMI_DIV_EMI(v) \
285 (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
286
287#define HW_CLKCTRL_SAIF0 (0x00000100)
288
289#define BP_CLKCTRL_SAIF0_CLKGATE 31
290#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
291#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
292#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
293#define BP_CLKCTRL_SAIF0_DIV 0
294#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
295#define BF_CLKCTRL_SAIF0_DIV(v) \
296 (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
297
298#define HW_CLKCTRL_SAIF1 (0x00000110)
299
300#define BP_CLKCTRL_SAIF1_CLKGATE 31
301#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
302#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
303#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
304#define BP_CLKCTRL_SAIF1_DIV 0
305#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
306#define BF_CLKCTRL_SAIF1_DIV(v) \
307 (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
308
309#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
310
311#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
312#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
313#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
314#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
315#define BP_CLKCTRL_DIS_LCDIF_DIV 0
316#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
317#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
318 (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
319
320#define HW_CLKCTRL_ETM (0x00000130)
321
322#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
323#define BM_CLKCTRL_ETM_BUSY 0x20000000
324#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
325#define BP_CLKCTRL_ETM_DIV 0
326#define BM_CLKCTRL_ETM_DIV 0x0000007F
327#define BF_CLKCTRL_ETM_DIV(v) \
328 (((v) << 0) & BM_CLKCTRL_ETM_DIV)
329
330#define HW_CLKCTRL_ENET (0x00000140)
331
332#define BM_CLKCTRL_ENET_SLEEP 0x80000000
333#define BP_CLKCTRL_ENET_DISABLE 30
334#define BM_CLKCTRL_ENET_DISABLE 0x40000000
335#define BM_CLKCTRL_ENET_STATUS 0x20000000
336#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
337#define BP_CLKCTRL_ENET_DIV_TIME 21
338#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
339#define BF_CLKCTRL_ENET_DIV_TIME(v) \
340 (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
341#define BM_CLKCTRL_ENET_BUSY 0x08000000
342#define BP_CLKCTRL_ENET_DIV 21
343#define BM_CLKCTRL_ENET_DIV 0x07E00000
344#define BF_CLKCTRL_ENET_DIV(v) \
345 (((v) << 21) & BM_CLKCTRL_ENET_DIV)
346#define BP_CLKCTRL_ENET_TIME_SEL 19
347#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
348#define BF_CLKCTRL_ENET_TIME_SEL(v) \
349 (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
350#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
351#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
352#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
353#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
354#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
355#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
356#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
357
358#define HW_CLKCTRL_HSADC (0x00000150)
359
360#define BM_CLKCTRL_HSADC_RESETB 0x40000000
361#define BP_CLKCTRL_HSADC_FREQDIV 28
362#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
363#define BF_CLKCTRL_HSADC_FREQDIV(v) \
364 (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
365
366#define HW_CLKCTRL_FLEXCAN (0x00000160)
367
368#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
369#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
370#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
371#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
372#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
373#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
374
375#define HW_CLKCTRL_FRAC0 (0x000001b0)
376#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
377#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
378#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
379
380#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
381#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
382#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
383#define BP_CLKCTRL_FRAC0_IO0FRAC 24
384#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
385#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
386 (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
387#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
388#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
389#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
390#define BP_CLKCTRL_FRAC0_IO1FRAC 16
391#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
392#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
393 (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
394#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
395#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
396#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
397#define BP_CLKCTRL_FRAC0_EMIFRAC 8
398#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
399#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
400 (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
401#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
402#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
403#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
404#define BP_CLKCTRL_FRAC0_CPUFRAC 0
405#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
406#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
407 (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
408
409#define HW_CLKCTRL_FRAC1 (0x000001c0)
410#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
411#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
412#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
413
414#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
415#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
416#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
417#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
418#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
419#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
420 (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
421#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
422#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
423#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
424#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
425#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
426#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
427 (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
428#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
429#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
430#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
431#define BP_CLKCTRL_FRAC1_PIXFRAC 0
432#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
433#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
434 (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
435
436#define HW_CLKCTRL_CLKSEQ (0x000001d0)
437#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
438#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
439#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
440
441#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
442#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
443#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
444#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
445#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
446#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
447#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
448#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
449#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
450#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
451#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
452#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
453#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
454
455#define HW_CLKCTRL_RESET (0x000001e0)
456
457#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
458#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
459#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
460#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
461#define BM_CLKCTRL_RESET_CHIP 0x00000002
462#define BM_CLKCTRL_RESET_DIG 0x00000001
463
464#define HW_CLKCTRL_STATUS (0x000001f0)
465
466#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
467#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
468#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
469 (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
470
471#define HW_CLKCTRL_VERSION (0x00000200)
472
473#define BP_CLKCTRL_VERSION_MAJOR 24
474#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
475#define BF_CLKCTRL_VERSION_MAJOR(v) \
476 (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
477#define BP_CLKCTRL_VERSION_MINOR 16
478#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
479#define BF_CLKCTRL_VERSION_MINOR(v) \
480 (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
481#define BP_CLKCTRL_VERSION_STEP 0
482#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
483#define BF_CLKCTRL_VERSION_STEP(v) \
484 (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
485
486#endif /* __REGS_CLKCTRL_MX28_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 80ac1fca8a0..30042e23bfa 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,8 +37,6 @@
37#define MXS_MODULE_CLKGATE (1 << 30) 37#define MXS_MODULE_CLKGATE (1 << 30)
38#define MXS_MODULE_SFTRST (1 << 31) 38#define MXS_MODULE_SFTRST (1 << 31)
39 39
40#define CLKCTRL_TIMEOUT 10 /* 10 ms */
41
42static void __iomem *mxs_clkctrl_reset_addr; 40static void __iomem *mxs_clkctrl_reset_addr;
43 41
44/* 42/*
@@ -139,17 +137,3 @@ error:
139 return -ETIMEDOUT; 137 return -ETIMEDOUT;
140} 138}
141EXPORT_SYMBOL(mxs_reset_block); 139EXPORT_SYMBOL(mxs_reset_block);
142
143int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
144{
145 unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
146 while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
147 + reg_offset) & mask) {
148 if (time_after(jiffies, timeout)) {
149 pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
150 return -ETIMEDOUT;
151 }
152 }
153
154 return 0;
155}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index 564a63279f1..02d36de9c4e 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -20,6 +20,7 @@
20 * MA 02110-1301, USA. 20 * MA 02110-1301, USA.
21 */ 21 */
22 22
23#include <linux/err.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/irq.h> 25#include <linux/irq.h>
25#include <linux/clockchips.h> 26#include <linux/clockchips.h>
@@ -243,8 +244,16 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
243 return 0; 244 return 0;
244} 245}
245 246
246void __init mxs_timer_init(struct clk *timer_clk, int irq) 247void __init mxs_timer_init(int irq)
247{ 248{
249 struct clk *timer_clk;
250
251 timer_clk = clk_get_sys("timrot", NULL);
252 if (IS_ERR(timer_clk)) {
253 pr_err("%s: failed to get clk\n", __func__);
254 return;
255 }
256
248 clk_prepare_enable(timer_clk); 257 clk_prepare_enable(timer_clk);
249 258
250 /* 259 /*
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index c1b681ef4cb..f2f8a584701 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -595,7 +595,12 @@ gpio_free:
595 gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); 595 gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
596 return err; 596 return err;
597} 597}
598late_initcall(late_init); 598
599static void __init ams_delta_init_late(void)
600{
601 omap1_init_late();
602 late_init();
603}
599 604
600static void __init ams_delta_map_io(void) 605static void __init ams_delta_map_io(void)
601{ 606{
@@ -611,6 +616,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
611 .reserve = omap_reserve, 616 .reserve = omap_reserve,
612 .init_irq = omap1_init_irq, 617 .init_irq = omap1_init_irq,
613 .init_machine = ams_delta_init, 618 .init_machine = ams_delta_init,
619 .init_late = ams_delta_init_late,
614 .timer = &omap1_timer, 620 .timer = &omap1_timer,
615 .restart = omap1_restart, 621 .restart = omap1_restart,
616MACHINE_END 622MACHINE_END
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 4a4afb37102..c7364fdbda0 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -369,6 +369,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
369 .reserve = omap_reserve, 369 .reserve = omap_reserve,
370 .init_irq = omap1_init_irq, 370 .init_irq = omap1_init_irq,
371 .init_machine = omap_fsample_init, 371 .init_machine = omap_fsample_init,
372 .init_late = omap1_init_late,
372 .timer = &omap1_timer, 373 .timer = &omap1_timer,
373 .restart = omap1_restart, 374 .restart = omap1_restart,
374MACHINE_END 375MACHINE_END
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 9a5fe581bc1..e75e2d55a2d 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -88,6 +88,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
88 .reserve = omap_reserve, 88 .reserve = omap_reserve,
89 .init_irq = omap1_init_irq, 89 .init_irq = omap1_init_irq,
90 .init_machine = omap_generic_init, 90 .init_machine = omap_generic_init,
91 .init_late = omap1_init_late,
91 .timer = &omap1_timer, 92 .timer = &omap1_timer,
92 .restart = omap1_restart, 93 .restart = omap1_restart,
93MACHINE_END 94MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 057ec13f064..7e503686f7a 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -431,6 +431,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
431 .reserve = omap_reserve, 431 .reserve = omap_reserve,
432 .init_irq = omap1_init_irq, 432 .init_irq = omap1_init_irq,
433 .init_machine = h2_init, 433 .init_machine = h2_init,
434 .init_late = omap1_init_late,
434 .timer = &omap1_timer, 435 .timer = &omap1_timer,
435 .restart = omap1_restart, 436 .restart = omap1_restart,
436MACHINE_END 437MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index f6ddf875965..9fb03f189d9 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -425,6 +425,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
425 .reserve = omap_reserve, 425 .reserve = omap_reserve,
426 .init_irq = omap1_init_irq, 426 .init_irq = omap1_init_irq,
427 .init_machine = h3_init, 427 .init_machine = h3_init,
428 .init_late = omap1_init_late,
428 .timer = &omap1_timer, 429 .timer = &omap1_timer,
429 .restart = omap1_restart, 430 .restart = omap1_restart,
430MACHINE_END 431MACHINE_END
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 60c06ee2385..118a9d4a4c5 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -605,6 +605,7 @@ MACHINE_START(HERALD, "HTC Herald")
605 .reserve = omap_reserve, 605 .reserve = omap_reserve,
606 .init_irq = omap1_init_irq, 606 .init_irq = omap1_init_irq,
607 .init_machine = htcherald_init, 607 .init_machine = htcherald_init,
608 .init_late = omap1_init_late,
608 .timer = &omap1_timer, 609 .timer = &omap1_timer,
609 .restart = omap1_restart, 610 .restart = omap1_restart,
610MACHINE_END 611MACHINE_END
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 67d7fd57a69..7970223a559 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -457,6 +457,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
457 .reserve = omap_reserve, 457 .reserve = omap_reserve,
458 .init_irq = omap1_init_irq, 458 .init_irq = omap1_init_irq,
459 .init_machine = innovator_init, 459 .init_machine = innovator_init,
460 .init_late = omap1_init_late,
460 .timer = &omap1_timer, 461 .timer = &omap1_timer,
461 .restart = omap1_restart, 462 .restart = omap1_restart,
462MACHINE_END 463MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index d21dcc2fbc5..7212ae97f44 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -255,6 +255,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
255 .reserve = omap_reserve, 255 .reserve = omap_reserve,
256 .init_irq = omap1_init_irq, 256 .init_irq = omap1_init_irq,
257 .init_machine = omap_nokia770_init, 257 .init_machine = omap_nokia770_init,
258 .init_late = omap1_init_late,
258 .timer = &omap1_timer, 259 .timer = &omap1_timer,
259 .restart = omap1_restart, 260 .restart = omap1_restart,
260MACHINE_END 261MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index a5f85dda3f6..da8d872d3d1 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -574,6 +574,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
574 .reserve = omap_reserve, 574 .reserve = omap_reserve,
575 .init_irq = omap1_init_irq, 575 .init_irq = omap1_init_irq,
576 .init_machine = osk_init, 576 .init_machine = osk_init,
577 .init_late = omap1_init_late,
577 .timer = &omap1_timer, 578 .timer = &omap1_timer,
578 .restart = omap1_restart, 579 .restart = omap1_restart,
579MACHINE_END 580MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index a60e6c22f81..949b62a7369 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -267,6 +267,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
267 .reserve = omap_reserve, 267 .reserve = omap_reserve,
268 .init_irq = omap1_init_irq, 268 .init_irq = omap1_init_irq,
269 .init_machine = omap_palmte_init, 269 .init_machine = omap_palmte_init,
270 .init_late = omap1_init_late,
270 .timer = &omap1_timer, 271 .timer = &omap1_timer,
271 .restart = omap1_restart, 272 .restart = omap1_restart,
272MACHINE_END 273MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 8d854878547..7f1e1cf2bf4 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -313,6 +313,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
313 .reserve = omap_reserve, 313 .reserve = omap_reserve,
314 .init_irq = omap1_init_irq, 314 .init_irq = omap1_init_irq,
315 .init_machine = omap_palmtt_init, 315 .init_machine = omap_palmtt_init,
316 .init_late = omap1_init_late,
316 .timer = &omap1_timer, 317 .timer = &omap1_timer,
317 .restart = omap1_restart, 318 .restart = omap1_restart,
318MACHINE_END 319MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 61ed4f0247c..3c71c6bace2 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -330,6 +330,7 @@ MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
330 .reserve = omap_reserve, 330 .reserve = omap_reserve,
331 .init_irq = omap1_init_irq, 331 .init_irq = omap1_init_irq,
332 .init_machine = omap_palmz71_init, 332 .init_machine = omap_palmz71_init,
333 .init_late = omap1_init_late,
333 .timer = &omap1_timer, 334 .timer = &omap1_timer,
334 .restart = omap1_restart, 335 .restart = omap1_restart,
335MACHINE_END 336MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index a2c88890e76..f2cb24387c2 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -331,6 +331,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
331 .reserve = omap_reserve, 331 .reserve = omap_reserve,
332 .init_irq = omap1_init_irq, 332 .init_irq = omap1_init_irq,
333 .init_machine = omap_perseus2_init, 333 .init_machine = omap_perseus2_init,
334 .init_late = omap1_init_late,
334 .timer = &omap1_timer, 335 .timer = &omap1_timer,
335 .restart = omap1_restart, 336 .restart = omap1_restart,
336MACHINE_END 337MACHINE_END
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index f34cb74a9f4..3b7b82b1368 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -407,6 +407,7 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
407 .reserve = omap_reserve, 407 .reserve = omap_reserve,
408 .init_irq = omap1_init_irq, 408 .init_irq = omap1_init_irq,
409 .init_machine = omap_sx1_init, 409 .init_machine = omap_sx1_init,
410 .init_late = omap1_init_late,
410 .timer = &omap1_timer, 411 .timer = &omap1_timer,
411 .restart = omap1_restart, 412 .restart = omap1_restart,
412MACHINE_END 413MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 37232d04233..afd67f0ec49 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -294,6 +294,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
294 .reserve = omap_reserve, 294 .reserve = omap_reserve,
295 .init_irq = omap1_init_irq, 295 .init_irq = omap1_init_irq,
296 .init_machine = voiceblue_init, 296 .init_machine = voiceblue_init,
297 .init_late = omap1_init_late,
297 .timer = &omap1_timer, 298 .timer = &omap1_timer,
298 .restart = voiceblue_restart, 299 .restart = voiceblue_restart,
299MACHINE_END 300MACHINE_END
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index bb7779b5779..c2552b24f9f 100644
--- a/arch/arm/mach-omap1/common.h
+++ b/arch/arm/mach-omap1/common.h
@@ -53,8 +53,18 @@ static inline void omap16xx_map_io(void)
53} 53}
54#endif 54#endif
55 55
56#ifdef CONFIG_OMAP_SERIAL_WAKE
57int omap_serial_wakeup_init(void);
58#else
59static inline int omap_serial_wakeup_init(void)
60{
61 return 0;
62}
63#endif
64
56void omap1_init_early(void); 65void omap1_init_early(void);
57void omap1_init_irq(void); 66void omap1_init_irq(void);
67void omap1_init_late(void);
58void omap1_restart(char, const char *); 68void omap1_restart(char, const char *);
59 69
60extern void __init omap_check_revision(void); 70extern void __init omap_check_revision(void);
@@ -63,7 +73,14 @@ extern void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
63 unsigned int ctrl); 73 unsigned int ctrl);
64 74
65extern struct sys_timer omap1_timer; 75extern struct sys_timer omap1_timer;
66extern bool omap_32k_timer_init(void); 76#ifdef CONFIG_OMAP_32K_TIMER
77extern int omap_32k_timer_init(void);
78#else
79static inline int __init omap_32k_timer_init(void)
80{
81 return -ENODEV;
82}
83#endif
67 84
68extern u32 omap_irq_flags; 85extern u32 omap_irq_flags;
69 86
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index dcd8ddbec2b..fa1fa4deb6a 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
22#include <plat/tc.h> 22#include <plat/tc.h>
23#include <plat/board.h> 23#include <plat/board.h>
24#include <plat/mux.h> 24#include <plat/mux.h>
25#include <plat/dma.h>
25#include <plat/mmc.h> 26#include <plat/mmc.h>
26#include <plat/omap7xx.h> 27#include <plat/omap7xx.h>
27 28
@@ -31,6 +32,22 @@
31#include "common.h" 32#include "common.h"
32#include "clock.h" 33#include "clock.h"
33 34
35#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
36
37static struct platform_device omap_pcm = {
38 .name = "omap-pcm-audio",
39 .id = -1,
40};
41
42static void omap_init_audio(void)
43{
44 platform_device_register(&omap_pcm);
45}
46
47#else
48static inline void omap_init_audio(void) {}
49#endif
50
34/*-------------------------------------------------------------------------*/ 51/*-------------------------------------------------------------------------*/
35 52
36#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE) 53#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
@@ -128,6 +145,56 @@ static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
128 } 145 }
129} 146}
130 147
148#define OMAP_MMC_NR_RES 4
149
150/*
151 * Register MMC devices.
152 */
153static int __init omap_mmc_add(const char *name, int id, unsigned long base,
154 unsigned long size, unsigned int irq,
155 unsigned rx_req, unsigned tx_req,
156 struct omap_mmc_platform_data *data)
157{
158 struct platform_device *pdev;
159 struct resource res[OMAP_MMC_NR_RES];
160 int ret;
161
162 pdev = platform_device_alloc(name, id);
163 if (!pdev)
164 return -ENOMEM;
165
166 memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
167 res[0].start = base;
168 res[0].end = base + size - 1;
169 res[0].flags = IORESOURCE_MEM;
170 res[1].start = res[1].end = irq;
171 res[1].flags = IORESOURCE_IRQ;
172 res[2].start = rx_req;
173 res[2].name = "rx";
174 res[2].flags = IORESOURCE_DMA;
175 res[3].start = tx_req;
176 res[3].name = "tx";
177 res[3].flags = IORESOURCE_DMA;
178
179 ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
180 if (ret == 0)
181 ret = platform_device_add_data(pdev, data, sizeof(*data));
182 if (ret)
183 goto fail;
184
185 ret = platform_device_add(pdev);
186 if (ret)
187 goto fail;
188
189 /* return device handle to board setup code */
190 data->dev = &pdev->dev;
191 return 0;
192
193fail:
194 platform_device_put(pdev);
195 return ret;
196}
197
131void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, 198void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
132 int nr_controllers) 199 int nr_controllers)
133{ 200{
@@ -135,6 +202,7 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
135 202
136 for (i = 0; i < nr_controllers; i++) { 203 for (i = 0; i < nr_controllers; i++) {
137 unsigned long base, size; 204 unsigned long base, size;
205 unsigned rx_req, tx_req;
138 unsigned int irq = 0; 206 unsigned int irq = 0;
139 207
140 if (!mmc_data[i]) 208 if (!mmc_data[i])
@@ -146,19 +214,24 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
146 case 0: 214 case 0:
147 base = OMAP1_MMC1_BASE; 215 base = OMAP1_MMC1_BASE;
148 irq = INT_MMC; 216 irq = INT_MMC;
217 rx_req = OMAP_DMA_MMC_RX;
218 tx_req = OMAP_DMA_MMC_TX;
149 break; 219 break;
150 case 1: 220 case 1:
151 if (!cpu_is_omap16xx()) 221 if (!cpu_is_omap16xx())
152 return; 222 return;
153 base = OMAP1_MMC2_BASE; 223 base = OMAP1_MMC2_BASE;
154 irq = INT_1610_MMC2; 224 irq = INT_1610_MMC2;
225 rx_req = OMAP_DMA_MMC2_RX;
226 tx_req = OMAP_DMA_MMC2_TX;
155 break; 227 break;
156 default: 228 default:
157 continue; 229 continue;
158 } 230 }
159 size = OMAP1_MMC_SIZE; 231 size = OMAP1_MMC_SIZE;
160 232
161 omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]); 233 omap_mmc_add("mmci-omap", i, base, size, irq,
234 rx_req, tx_req, mmc_data[i]);
162 }; 235 };
163} 236}
164 237
@@ -242,23 +315,48 @@ void __init omap1_camera_init(void *info)
242 315
243static inline void omap_init_sti(void) {} 316static inline void omap_init_sti(void) {}
244 317
245#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE) 318/* Numbering for the SPI-capable controllers when used for SPI:
319 * spi = 1
320 * uwire = 2
321 * mmc1..2 = 3..4
322 * mcbsp1..3 = 5..7
323 */
246 324
247static struct platform_device omap_pcm = { 325#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
248 .name = "omap-pcm-audio", 326
249 .id = -1, 327#define OMAP_UWIRE_BASE 0xfffb3000
328
329static struct resource uwire_resources[] = {
330 {
331 .start = OMAP_UWIRE_BASE,
332 .end = OMAP_UWIRE_BASE + 0x20,
333 .flags = IORESOURCE_MEM,
334 },
250}; 335};
251 336
252static void omap_init_audio(void) 337static struct platform_device omap_uwire_device = {
338 .name = "omap_uwire",
339 .id = -1,
340 .num_resources = ARRAY_SIZE(uwire_resources),
341 .resource = uwire_resources,
342};
343
344static void omap_init_uwire(void)
253{ 345{
254 platform_device_register(&omap_pcm); 346 /* FIXME define and use a boot tag; not all boards will be hooking
255} 347 * up devices to the microwire controller, and multi-board configs
348 * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
349 */
256 350
351 /* board-specific code must configure chipselects (only a few
352 * are normally used) and SCLK/SDI/SDO (each has two choices).
353 */
354 (void) platform_device_register(&omap_uwire_device);
355}
257#else 356#else
258static inline void omap_init_audio(void) {} 357static inline void omap_init_uwire(void) {}
259#endif 358#endif
260 359
261/*-------------------------------------------------------------------------*/
262 360
263/* 361/*
264 * This gets called after board-specific INIT_MACHINE, and initializes most 362 * This gets called after board-specific INIT_MACHINE, and initializes most
@@ -292,11 +390,12 @@ static int __init omap1_init_devices(void)
292 * in alphabetical order so they're easier to sort through. 390 * in alphabetical order so they're easier to sort through.
293 */ 391 */
294 392
393 omap_init_audio();
295 omap_init_mbox(); 394 omap_init_mbox();
296 omap_init_rtc(); 395 omap_init_rtc();
297 omap_init_spi100k(); 396 omap_init_spi100k();
298 omap_init_sti(); 397 omap_init_sti();
299 omap_init_audio(); 398 omap_init_uwire();
300 399
301 return 0; 400 return 0;
302} 401}
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 71ce017bf5d..6c95a59f0f1 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -137,6 +137,11 @@ void __init omap1_init_early(void)
137 omap_init_consistent_dma_size(); 137 omap_init_consistent_dma_size();
138} 138}
139 139
140void __init omap1_init_late(void)
141{
142 omap_serial_wakeup_init();
143}
144
140/* 145/*
141 * NOTE: Please use ioremap + __raw_read/write where possible instead of these 146 * NOTE: Please use ioremap + __raw_read/write where possible instead of these
142 */ 147 */
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 93ae8f29727..6809c9e56c9 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -237,7 +237,7 @@ static void __init omap_serial_set_port_wakeup(int gpio_nr)
237 enable_irq_wake(gpio_to_irq(gpio_nr)); 237 enable_irq_wake(gpio_to_irq(gpio_nr));
238} 238}
239 239
240static int __init omap_serial_wakeup_init(void) 240int __init omap_serial_wakeup_init(void)
241{ 241{
242 if (!cpu_is_omap16xx()) 242 if (!cpu_is_omap16xx())
243 return 0; 243 return 0;
@@ -251,7 +251,6 @@ static int __init omap_serial_wakeup_init(void)
251 251
252 return 0; 252 return 0;
253} 253}
254late_initcall(omap_serial_wakeup_init);
255 254
256#endif /* CONFIG_OMAP_SERIAL_WAKE */ 255#endif /* CONFIG_OMAP_SERIAL_WAKE */
257 256
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 4d8dd9a1b04..4062480bfec 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -232,20 +232,6 @@ static inline void omap_mpu_timer_init(void)
232} 232}
233#endif /* CONFIG_OMAP_MPU_TIMER */ 233#endif /* CONFIG_OMAP_MPU_TIMER */
234 234
235static inline int omap_32k_timer_usable(void)
236{
237 int res = false;
238
239 if (cpu_is_omap730() || cpu_is_omap15xx())
240 return res;
241
242#ifdef CONFIG_OMAP_32K_TIMER
243 res = omap_32k_timer_init();
244#endif
245
246 return res;
247}
248
249/* 235/*
250 * --------------------------------------------------------------------------- 236 * ---------------------------------------------------------------------------
251 * Timer initialization 237 * Timer initialization
@@ -253,7 +239,7 @@ static inline int omap_32k_timer_usable(void)
253 */ 239 */
254static void __init omap1_timer_init(void) 240static void __init omap1_timer_init(void)
255{ 241{
256 if (!omap_32k_timer_usable()) 242 if (omap_32k_timer_init() != 0)
257 omap_mpu_timer_init(); 243 omap_mpu_timer_init();
258} 244}
259 245
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 325b9a0aa4a..eae49c3980c 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -71,6 +71,7 @@
71 71
72/* 16xx specific defines */ 72/* 16xx specific defines */
73#define OMAP1_32K_TIMER_BASE 0xfffb9000 73#define OMAP1_32K_TIMER_BASE 0xfffb9000
74#define OMAP1_32KSYNC_TIMER_BASE 0xfffbc400
74#define OMAP1_32K_TIMER_CR 0x08 75#define OMAP1_32K_TIMER_CR 0x08
75#define OMAP1_32K_TIMER_TVR 0x00 76#define OMAP1_32K_TIMER_TVR 0x00
76#define OMAP1_32K_TIMER_TCR 0x04 77#define OMAP1_32K_TIMER_TCR 0x04
@@ -182,10 +183,29 @@ static __init void omap_init_32k_timer(void)
182 * Timer initialization 183 * Timer initialization
183 * --------------------------------------------------------------------------- 184 * ---------------------------------------------------------------------------
184 */ 185 */
185bool __init omap_32k_timer_init(void) 186int __init omap_32k_timer_init(void)
186{ 187{
187 omap_init_clocksource_32k(); 188 int ret = -ENODEV;
188 omap_init_32k_timer();
189 189
190 return true; 190 if (cpu_is_omap16xx()) {
191 void __iomem *base;
192 struct clk *sync32k_ick;
193
194 base = ioremap(OMAP1_32KSYNC_TIMER_BASE, SZ_1K);
195 if (!base) {
196 pr_err("32k_counter: failed to map base addr\n");
197 return -ENODEV;
198 }
199
200 sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
201 if (!IS_ERR(sync32k_ick))
202 clk_enable(sync32k_ick);
203
204 ret = omap_init_clocksource_32k(base);
205 }
206
207 if (!ret)
208 omap_init_32k_timer();
209
210 return ret;
191} 211}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 964ee67a3b7..4cf5142f22c 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -78,12 +78,12 @@ config SOC_OMAP3430
78 default y 78 default y
79 select ARCH_OMAP_OTG 79 select ARCH_OMAP_OTG
80 80
81config SOC_OMAPTI81XX 81config SOC_TI81XX
82 bool "TI81XX support" 82 bool "TI81XX support"
83 depends on ARCH_OMAP3 83 depends on ARCH_OMAP3
84 default y 84 default y
85 85
86config SOC_OMAPAM33XX 86config SOC_AM33XX
87 bool "AM33XX support" 87 bool "AM33XX support"
88 depends on ARCH_OMAP3 88 depends on ARCH_OMAP3
89 default y 89 default y
@@ -320,12 +320,12 @@ config MACH_OMAP_3630SDP
320 320
321config MACH_TI8168EVM 321config MACH_TI8168EVM
322 bool "TI8168 Evaluation Module" 322 bool "TI8168 Evaluation Module"
323 depends on SOC_OMAPTI81XX 323 depends on SOC_TI81XX
324 default y 324 default y
325 325
326config MACH_TI8148EVM 326config MACH_TI8148EVM
327 bool "TI8148 Evaluation Module" 327 bool "TI8148 Evaluation Module"
328 depends on SOC_OMAPTI81XX 328 depends on SOC_TI81XX
329 default y 329 default y
330 330
331config MACH_OMAP_4430SDP 331config MACH_OMAP_4430SDP
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 385c083d24b..fa742f3c262 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -24,10 +24,11 @@ endif
24obj-$(CONFIG_TWL4030_CORE) += omap_twl.o 24obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
25 25
26# SMP support ONLY available for OMAP4 26# SMP support ONLY available for OMAP4
27
27obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 28obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
28obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o 29obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
29obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ 30obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o
30 sleep44xx.o 31obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o
31 32
32plus_sec := $(call as-instr,.arch_extension sec,+sec) 33plus_sec := $(call as-instr,.arch_extension sec,+sec)
33AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) 34AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -64,10 +65,10 @@ endif
64ifeq ($(CONFIG_PM),y) 65ifeq ($(CONFIG_PM),y)
65obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o 66obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
66obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o 67obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
67obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ 68obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
68 cpuidle34xx.o 69obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
69obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \ 70obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
70 cpuidle44xx.o 71obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
71obj-$(CONFIG_PM_DEBUG) += pm-debug.o 72obj-$(CONFIG_PM_DEBUG) += pm-debug.o
72obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o 73obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
73obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 74obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@ -84,90 +85,86 @@ endif
84# PRCM 85# PRCM
85obj-y += prm_common.o 86obj-y += prm_common.o
86obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o 87obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
87obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ 88obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
88 vc3xxx_data.o vp3xxx_data.o 89obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
89# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and 90obj-$(CONFIG_ARCH_OMAP4) += prcm.o cminst44xx.o cm44xx.o
90# will be removed once the OMAP4 part of the codebase is converted to 91obj-$(CONFIG_ARCH_OMAP4) += prcm_mpu44xx.o prminst44xx.o
91# use OMAP4-specific PRCM functions. 92obj-$(CONFIG_ARCH_OMAP4) += vc44xx_data.o vp44xx_data.o prm44xx.o
92obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
93 cm44xx.o prcm_mpu44xx.o \
94 prminst44xx.o vc44xx_data.o \
95 vp44xx_data.o prm44xx.o
96 93
97# OMAP voltage domains 94# OMAP voltage domains
98voltagedomain-common := voltage.o vc.o vp.o 95voltagedomain-common := voltage.o vc.o vp.o
99obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) \ 96obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
100 voltagedomains2xxx_data.o 97obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
101obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \ 98obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
102 voltagedomains3xxx_data.o 99obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
103obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \ 100obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
104 voltagedomains44xx_data.o 101obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
105 102
106# OMAP powerdomain framework 103# OMAP powerdomain framework
107powerdomain-common += powerdomain.o powerdomain-common.o 104powerdomain-common += powerdomain.o powerdomain-common.o
108obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \ 105obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
109 powerdomain2xxx_3xxx.o \ 106obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
110 powerdomains2xxx_data.o \ 107obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o
111 powerdomains2xxx_3xxx_data.o 108obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
112obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \ 109obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
113 powerdomain2xxx_3xxx.o \ 110obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o
114 powerdomains3xxx_data.o \ 111obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
115 powerdomains2xxx_3xxx_data.o 112obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
116obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \ 113obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
117 powerdomain44xx.o \ 114obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o
118 powerdomains44xx_data.o 115obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
119 116
120# PRCM clockdomain control 117# PRCM clockdomain control
121clockdomain-common += clockdomain.o \ 118clockdomain-common += clockdomain.o
122 clockdomains_common_data.o 119clockdomain-common += clockdomains_common_data.o
123obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) \ 120obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
124 clockdomain2xxx_3xxx.o \ 121obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o
125 clockdomains2xxx_3xxx_data.o 122obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
126obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o 123obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
127obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o 124obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
128obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) \ 125obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
129 clockdomain2xxx_3xxx.o \ 126obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o
130 clockdomains2xxx_3xxx_data.o \ 127obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
131 clockdomains3xxx_data.o 128obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
132obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) \ 129obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
133 clockdomain44xx.o \ 130obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o
134 clockdomains44xx_data.o 131obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
135 132
136# Clock framework 133# Clock framework
137obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \ 134obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
138 clkt2xxx_sys.o \ 135obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o
139 clkt2xxx_dpllcore.o \ 136obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
140 clkt2xxx_virt_prcm_set.o \ 137obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
141 clkt2xxx_apll.o clkt2xxx_osc.o \ 138obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
142 clkt2xxx_dpll.o clkt_iclk.o 139obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
143obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o 140obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
144obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o 141obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
145obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \ 142obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
146 clock34xx.o clkt34xx_dpll3m2.o \ 143obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
147 clock3517.o clock36xx.o \ 144obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
148 dpll3xxx.o clock3xxx_data.o \ 145obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
149 clkt_iclk.o 146obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
150obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \ 147obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
151 dpll3xxx.o dpll44xx.o 148obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
152 149
153# OMAP2 clock rate set data (old "OPP" data) 150# OMAP2 clock rate set data (old "OPP" data)
154obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o 151obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
155obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o 152obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
156 153
157# hwmod data 154# hwmod data
158obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o \ 155obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
159 omap_hwmod_2xxx_3xxx_ipblock_data.o \ 156obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
160 omap_hwmod_2xxx_interconnect_data.o \ 157obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
161 omap_hwmod_2xxx_3xxx_interconnect_data.o \ 158obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_interconnect_data.o
162 omap_hwmod_2420_data.o 159obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o
163obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o \ 160obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o
164 omap_hwmod_2xxx_3xxx_ipblock_data.o \ 161obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_ipblock_data.o
165 omap_hwmod_2xxx_interconnect_data.o \ 162obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_interconnect_data.o
166 omap_hwmod_2xxx_3xxx_interconnect_data.o \ 163obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_interconnect_data.o
167 omap_hwmod_2430_data.o 164obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o
168obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o \ 165obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o
169 omap_hwmod_2xxx_3xxx_interconnect_data.o \ 166obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o
170 omap_hwmod_3xxx_data.o 167obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
171obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o 168obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
172 169
173# EMU peripherals 170# EMU peripherals
@@ -208,23 +205,19 @@ obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
208obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o 205obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
209obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o 206obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
210obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o 207obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
211obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \ 208obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o sdram-nokia.o
212 sdram-nokia.o 209obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
213obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ 210obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
214 sdram-nokia.o \ 211obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
215 board-rx51-peripherals.o \ 212obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o board-zoom-peripherals.o
216 board-rx51-video.o 213obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-display.o
217obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \ 214obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-debugboard.o
218 board-zoom-peripherals.o \ 215obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o board-zoom-peripherals.o
219 board-zoom-display.o \ 216obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-display.o
220 board-zoom-debugboard.o 217obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-debugboard.o
221obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \ 218obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o
222 board-zoom-peripherals.o \ 219obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-peripherals.o
223 board-zoom-display.o \ 220obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-display.o
224 board-zoom-debugboard.o
225obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
226 board-zoom-peripherals.o \
227 board-zoom-display.o
228obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o 221obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
229obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o 222obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
230obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o 223obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index e658f835d0d..99ca6bad5c3 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -303,6 +303,7 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
303 .init_irq = omap2_init_irq, 303 .init_irq = omap2_init_irq,
304 .handle_irq = omap2_intc_handle_irq, 304 .handle_irq = omap2_intc_handle_irq,
305 .init_machine = omap_2430sdp_init, 305 .init_machine = omap_2430sdp_init,
306 .init_late = omap2430_init_late,
306 .timer = &omap2_timer, 307 .timer = &omap2_timer,
307 .restart = omap_prcm_restart, 308 .restart = omap_prcm_restart,
308MACHINE_END 309MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 37abb0d49b5..a98c688058a 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -605,6 +605,7 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
605 .init_irq = omap3_init_irq, 605 .init_irq = omap3_init_irq,
606 .handle_irq = omap3_intc_handle_irq, 606 .handle_irq = omap3_intc_handle_irq,
607 .init_machine = omap_3430sdp_init, 607 .init_machine = omap_3430sdp_init,
608 .init_late = omap3430_init_late,
608 .timer = &omap3_timer, 609 .timer = &omap3_timer,
609 .restart = omap_prcm_restart, 610 .restart = omap_prcm_restart,
610MACHINE_END 611MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 6ef350d1ae4..2dc9ba523c7 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -217,6 +217,7 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
217 .init_irq = omap3_init_irq, 217 .init_irq = omap3_init_irq,
218 .handle_irq = omap3_intc_handle_irq, 218 .handle_irq = omap3_intc_handle_irq,
219 .init_machine = omap_sdp_init, 219 .init_machine = omap_sdp_init,
220 .init_late = omap3630_init_late,
220 .timer = &omap3_timer, 221 .timer = &omap3_timer,
221 .restart = omap_prcm_restart, 222 .restart = omap_prcm_restart,
222MACHINE_END 223MACHINE_END
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 94af6cde2e3..8e17284a803 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -912,6 +912,7 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
912 .init_irq = gic_init_irq, 912 .init_irq = gic_init_irq,
913 .handle_irq = gic_handle_irq, 913 .handle_irq = gic_handle_irq,
914 .init_machine = omap_4430sdp_init, 914 .init_machine = omap_4430sdp_init,
915 .init_late = omap4430_init_late,
915 .timer = &omap4_timer, 916 .timer = &omap4_timer,
916 .restart = omap_prcm_restart, 917 .restart = omap_prcm_restart,
917MACHINE_END 918MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index 3b8a53c1f2a..92432c28673 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -102,6 +102,7 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
102 .init_irq = omap3_init_irq, 102 .init_irq = omap3_init_irq,
103 .handle_irq = omap3_intc_handle_irq, 103 .handle_irq = omap3_intc_handle_irq,
104 .init_machine = am3517_crane_init, 104 .init_machine = am3517_crane_init,
105 .init_late = am35xx_init_late,
105 .timer = &omap3_timer, 106 .timer = &omap3_timer,
106 .restart = omap_prcm_restart, 107 .restart = omap_prcm_restart,
107MACHINE_END 108MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 99790eb646e..18f601096ce 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -385,6 +385,7 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
385 .init_irq = omap3_init_irq, 385 .init_irq = omap3_init_irq,
386 .handle_irq = omap3_intc_handle_irq, 386 .handle_irq = omap3_intc_handle_irq,
387 .init_machine = am3517_evm_init, 387 .init_machine = am3517_evm_init,
388 .init_late = am35xx_init_late,
388 .timer = &omap3_timer, 389 .timer = &omap3_timer,
389 .restart = omap_prcm_restart, 390 .restart = omap_prcm_restart,
390MACHINE_END 391MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 768ece2e9c3..502c31e123b 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -356,6 +356,7 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
356 .init_irq = omap2_init_irq, 356 .init_irq = omap2_init_irq,
357 .handle_irq = omap2_intc_handle_irq, 357 .handle_irq = omap2_intc_handle_irq,
358 .init_machine = omap_apollon_init, 358 .init_machine = omap_apollon_init,
359 .init_late = omap2420_init_late,
359 .timer = &omap2_timer, 360 .timer = &omap2_timer,
360 .restart = omap_prcm_restart, 361 .restart = omap_prcm_restart,
361MACHINE_END 362MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index c03df142ea6..ded100c80a9 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -669,6 +669,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
669 .init_irq = omap3_init_irq, 669 .init_irq = omap3_init_irq,
670 .handle_irq = omap3_intc_handle_irq, 670 .handle_irq = omap3_intc_handle_irq,
671 .init_machine = cm_t35_init, 671 .init_machine = cm_t35_init,
672 .init_late = omap35xx_init_late,
672 .timer = &omap3_timer, 673 .timer = &omap3_timer,
673 .restart = omap_prcm_restart, 674 .restart = omap_prcm_restart,
674MACHINE_END 675MACHINE_END
@@ -681,6 +682,7 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730")
681 .init_irq = omap3_init_irq, 682 .init_irq = omap3_init_irq,
682 .handle_irq = omap3_intc_handle_irq, 683 .handle_irq = omap3_intc_handle_irq,
683 .init_machine = cm_t3730_init, 684 .init_machine = cm_t3730_init,
685 .init_late = omap3630_init_late,
684 .timer = &omap3_timer, 686 .timer = &omap3_timer,
685 .restart = omap_prcm_restart, 687 .restart = omap_prcm_restart,
686MACHINE_END 688MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 9e66e167e4f..a33ad4641d9 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -303,6 +303,7 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517")
303 .init_irq = omap3_init_irq, 303 .init_irq = omap3_init_irq,
304 .handle_irq = omap3_intc_handle_irq, 304 .handle_irq = omap3_intc_handle_irq,
305 .init_machine = cm_t3517_init, 305 .init_machine = cm_t3517_init,
306 .init_late = am35xx_init_late,
306 .timer = &omap3_timer, 307 .timer = &omap3_timer,
307 .restart = omap_prcm_restart, 308 .restart = omap_prcm_restart,
308MACHINE_END 309MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index b063f0d2faa..6567c1cd557 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -644,6 +644,7 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
644 .init_irq = omap3_init_irq, 644 .init_irq = omap3_init_irq,
645 .handle_irq = omap3_intc_handle_irq, 645 .handle_irq = omap3_intc_handle_irq,
646 .init_machine = devkit8000_init, 646 .init_machine = devkit8000_init,
647 .init_late = omap35xx_init_late,
647 .timer = &omap3_secure_timer, 648 .timer = &omap3_secure_timer,
648 .restart = omap_prcm_restart, 649 .restart = omap_prcm_restart,
649MACHINE_END 650MACHINE_END
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 7302ba7ff1b..20293465786 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -125,6 +125,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
125 .init_irq = omap_init_irq, 125 .init_irq = omap_init_irq,
126 .handle_irq = gic_handle_irq, 126 .handle_irq = gic_handle_irq,
127 .init_machine = omap_generic_init, 127 .init_machine = omap_generic_init,
128 .init_late = omap4430_init_late,
128 .timer = &omap4_timer, 129 .timer = &omap4_timer,
129 .dt_compat = omap4_boards_compat, 130 .dt_compat = omap4_boards_compat,
130 .restart = omap_prcm_restart, 131 .restart = omap_prcm_restart,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0bbbabe28fc..876becf8205 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -398,6 +398,7 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
398 .init_irq = omap2_init_irq, 398 .init_irq = omap2_init_irq,
399 .handle_irq = omap2_intc_handle_irq, 399 .handle_irq = omap2_intc_handle_irq,
400 .init_machine = omap_h4_init, 400 .init_machine = omap_h4_init,
401 .init_late = omap2420_init_late,
401 .timer = &omap2_timer, 402 .timer = &omap2_timer,
402 .restart = omap_prcm_restart, 403 .restart = omap_prcm_restart,
403MACHINE_END 404MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 7a274098f67..74915295482 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -650,6 +650,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
650 .init_irq = omap3_init_irq, 650 .init_irq = omap3_init_irq,
651 .handle_irq = omap3_intc_handle_irq, 651 .handle_irq = omap3_intc_handle_irq,
652 .init_machine = igep_init, 652 .init_machine = igep_init,
653 .init_late = omap35xx_init_late,
653 .timer = &omap3_timer, 654 .timer = &omap3_timer,
654 .restart = omap_prcm_restart, 655 .restart = omap_prcm_restart,
655MACHINE_END 656MACHINE_END
@@ -662,6 +663,7 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
662 .init_irq = omap3_init_irq, 663 .init_irq = omap3_init_irq,
663 .handle_irq = omap3_intc_handle_irq, 664 .handle_irq = omap3_intc_handle_irq,
664 .init_machine = igep_init, 665 .init_machine = igep_init,
666 .init_late = omap35xx_init_late,
665 .timer = &omap3_timer, 667 .timer = &omap3_timer,
666 .restart = omap_prcm_restart, 668 .restart = omap_prcm_restart,
667MACHINE_END 669MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 1b6049567ab..ef9e8297749 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -442,6 +442,7 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
442 .init_irq = omap3_init_irq, 442 .init_irq = omap3_init_irq,
443 .handle_irq = omap3_intc_handle_irq, 443 .handle_irq = omap3_intc_handle_irq,
444 .init_machine = omap_ldp_init, 444 .init_machine = omap_ldp_init,
445 .init_late = omap3430_init_late,
445 .timer = &omap3_timer, 446 .timer = &omap3_timer,
446 .restart = omap_prcm_restart, 447 .restart = omap_prcm_restart,
447MACHINE_END 448MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 518091c5f77..8ca14e88a31 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -694,6 +694,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800")
694 .init_irq = omap2_init_irq, 694 .init_irq = omap2_init_irq,
695 .handle_irq = omap2_intc_handle_irq, 695 .handle_irq = omap2_intc_handle_irq,
696 .init_machine = n8x0_init_machine, 696 .init_machine = n8x0_init_machine,
697 .init_late = omap2420_init_late,
697 .timer = &omap2_timer, 698 .timer = &omap2_timer,
698 .restart = omap_prcm_restart, 699 .restart = omap_prcm_restart,
699MACHINE_END 700MACHINE_END
@@ -706,6 +707,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
706 .init_irq = omap2_init_irq, 707 .init_irq = omap2_init_irq,
707 .handle_irq = omap2_intc_handle_irq, 708 .handle_irq = omap2_intc_handle_irq,
708 .init_machine = n8x0_init_machine, 709 .init_machine = n8x0_init_machine,
710 .init_late = omap2420_init_late,
709 .timer = &omap2_timer, 711 .timer = &omap2_timer,
710 .restart = omap_prcm_restart, 712 .restart = omap_prcm_restart,
711MACHINE_END 713MACHINE_END
@@ -718,6 +720,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
718 .init_irq = omap2_init_irq, 720 .init_irq = omap2_init_irq,
719 .handle_irq = omap2_intc_handle_irq, 721 .handle_irq = omap2_intc_handle_irq,
720 .init_machine = n8x0_init_machine, 722 .init_machine = n8x0_init_machine,
723 .init_late = omap2420_init_late,
721 .timer = &omap2_timer, 724 .timer = &omap2_timer,
722 .restart = omap_prcm_restart, 725 .restart = omap_prcm_restart,
723MACHINE_END 726MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2a7b9a9da1d..79c6909eeb7 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -543,6 +543,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
543 .init_irq = omap3_init_irq, 543 .init_irq = omap3_init_irq,
544 .handle_irq = omap3_intc_handle_irq, 544 .handle_irq = omap3_intc_handle_irq,
545 .init_machine = omap3_beagle_init, 545 .init_machine = omap3_beagle_init,
546 .init_late = omap3_init_late,
546 .timer = &omap3_secure_timer, 547 .timer = &omap3_secure_timer,
547 .restart = omap_prcm_restart, 548 .restart = omap_prcm_restart,
548MACHINE_END 549MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index ace3c675e9c..639bd07ea38 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -671,6 +671,7 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
671 .init_irq = omap3_init_irq, 671 .init_irq = omap3_init_irq,
672 .handle_irq = omap3_intc_handle_irq, 672 .handle_irq = omap3_intc_handle_irq,
673 .init_machine = omap3_evm_init, 673 .init_machine = omap3_evm_init,
674 .init_late = omap35xx_init_late,
674 .timer = &omap3_timer, 675 .timer = &omap3_timer,
675 .restart = omap_prcm_restart, 676 .restart = omap_prcm_restart,
676MACHINE_END 677MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index c008bf8e1c3..932e1778aff 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -242,6 +242,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
242 .init_irq = omap3_init_irq, 242 .init_irq = omap3_init_irq,
243 .handle_irq = omap3_intc_handle_irq, 243 .handle_irq = omap3_intc_handle_irq,
244 .init_machine = omap3logic_init, 244 .init_machine = omap3logic_init,
245 .init_late = omap35xx_init_late,
245 .timer = &omap3_timer, 246 .timer = &omap3_timer,
246 .restart = omap_prcm_restart, 247 .restart = omap_prcm_restart,
247MACHINE_END 248MACHINE_END
@@ -254,6 +255,7 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
254 .init_irq = omap3_init_irq, 255 .init_irq = omap3_init_irq,
255 .handle_irq = omap3_intc_handle_irq, 256 .handle_irq = omap3_intc_handle_irq,
256 .init_machine = omap3logic_init, 257 .init_machine = omap3logic_init,
258 .init_late = omap35xx_init_late,
257 .timer = &omap3_timer, 259 .timer = &omap3_timer,
258 .restart = omap_prcm_restart, 260 .restart = omap_prcm_restart,
259MACHINE_END 261MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 33d995d0f07..57aebee44fd 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -622,6 +622,7 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
622 .init_irq = omap3_init_irq, 622 .init_irq = omap3_init_irq,
623 .handle_irq = omap3_intc_handle_irq, 623 .handle_irq = omap3_intc_handle_irq,
624 .init_machine = omap3pandora_init, 624 .init_machine = omap3pandora_init,
625 .init_late = omap35xx_init_late,
625 .timer = &omap3_timer, 626 .timer = &omap3_timer,
626 .restart = omap_prcm_restart, 627 .restart = omap_prcm_restart,
627MACHINE_END 628MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 4396bae9167..b318f5602e3 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -436,6 +436,7 @@ MACHINE_START(SBC3530, "OMAP3 STALKER")
436 .init_irq = omap3_init_irq, 436 .init_irq = omap3_init_irq,
437 .handle_irq = omap3_intc_handle_irq, 437 .handle_irq = omap3_intc_handle_irq,
438 .init_machine = omap3_stalker_init, 438 .init_machine = omap3_stalker_init,
439 .init_late = omap35xx_init_late,
439 .timer = &omap3_secure_timer, 440 .timer = &omap3_secure_timer,
440 .restart = omap_prcm_restart, 441 .restart = omap_prcm_restart,
441MACHINE_END 442MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index ae2251fa4a6..485d14d6a8c 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -387,6 +387,7 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
387 .init_irq = omap3_init_irq, 387 .init_irq = omap3_init_irq,
388 .handle_irq = omap3_intc_handle_irq, 388 .handle_irq = omap3_intc_handle_irq,
389 .init_machine = omap3_touchbook_init, 389 .init_machine = omap3_touchbook_init,
390 .init_late = omap3430_init_late,
390 .timer = &omap3_secure_timer, 391 .timer = &omap3_secure_timer,
391 .restart = omap_prcm_restart, 392 .restart = omap_prcm_restart,
392MACHINE_END 393MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 68b8fc9ff01..982fb2622ab 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -521,6 +521,7 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
521 .init_irq = gic_init_irq, 521 .init_irq = gic_init_irq,
522 .handle_irq = gic_handle_irq, 522 .handle_irq = gic_handle_irq,
523 .init_machine = omap4_panda_init, 523 .init_machine = omap4_panda_init,
524 .init_late = omap4430_init_late,
524 .timer = &omap4_timer, 525 .timer = &omap4_timer,
525 .restart = omap_prcm_restart, 526 .restart = omap_prcm_restart,
526MACHINE_END 527MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 5527c1979a1..8fa2fc3a4c3 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -554,6 +554,7 @@ MACHINE_START(OVERO, "Gumstix Overo")
554 .init_irq = omap3_init_irq, 554 .init_irq = omap3_init_irq,
555 .handle_irq = omap3_intc_handle_irq, 555 .handle_irq = omap3_intc_handle_irq,
556 .init_machine = overo_init, 556 .init_machine = overo_init,
557 .init_late = omap35xx_init_late,
557 .timer = &omap3_timer, 558 .timer = &omap3_timer,
558 .restart = omap_prcm_restart, 559 .restart = omap_prcm_restart,
559MACHINE_END 560MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index ae53d71f0ce..0ad1bb3bdb9 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -151,6 +151,7 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
151 .init_irq = omap3_init_irq, 151 .init_irq = omap3_init_irq,
152 .handle_irq = omap3_intc_handle_irq, 152 .handle_irq = omap3_intc_handle_irq,
153 .init_machine = rm680_init, 153 .init_machine = rm680_init,
154 .init_late = omap3630_init_late,
154 .timer = &omap3_timer, 155 .timer = &omap3_timer,
155 .restart = omap_prcm_restart, 156 .restart = omap_prcm_restart,
156MACHINE_END 157MACHINE_END
@@ -163,6 +164,7 @@ MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
163 .init_irq = omap3_init_irq, 164 .init_irq = omap3_init_irq,
164 .handle_irq = omap3_intc_handle_irq, 165 .handle_irq = omap3_intc_handle_irq,
165 .init_machine = rm680_init, 166 .init_machine = rm680_init,
167 .init_late = omap3630_init_late,
166 .timer = &omap3_timer, 168 .timer = &omap3_timer,
167 .restart = omap_prcm_restart, 169 .restart = omap_prcm_restart,
168MACHINE_END 170MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 2da92a6ba40..345dd931f76 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -127,6 +127,7 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
127 .init_irq = omap3_init_irq, 127 .init_irq = omap3_init_irq,
128 .handle_irq = omap3_intc_handle_irq, 128 .handle_irq = omap3_intc_handle_irq,
129 .init_machine = rx51_init, 129 .init_machine = rx51_init,
130 .init_late = omap3430_init_late,
130 .timer = &omap3_timer, 131 .timer = &omap3_timer,
131 .restart = omap_prcm_restart, 132 .restart = omap_prcm_restart,
132MACHINE_END 133MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index ab9a7a9e9d6..d4c8392cadb 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -52,6 +52,7 @@ MACHINE_START(TI8168EVM, "ti8168evm")
52 .init_irq = ti81xx_init_irq, 52 .init_irq = ti81xx_init_irq,
53 .timer = &omap3_timer, 53 .timer = &omap3_timer,
54 .init_machine = ti81xx_evm_init, 54 .init_machine = ti81xx_evm_init,
55 .init_late = ti81xx_init_late,
55 .restart = omap_prcm_restart, 56 .restart = omap_prcm_restart,
56MACHINE_END 57MACHINE_END
57 58
@@ -63,5 +64,6 @@ MACHINE_START(TI8148EVM, "ti8148evm")
63 .init_irq = ti81xx_init_irq, 64 .init_irq = ti81xx_init_irq,
64 .timer = &omap3_timer, 65 .timer = &omap3_timer,
65 .init_machine = ti81xx_evm_init, 66 .init_machine = ti81xx_evm_init,
67 .init_late = ti81xx_init_late,
66 .restart = omap_prcm_restart, 68 .restart = omap_prcm_restart,
67MACHINE_END 69MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 5c20bcc57f2..4e7e56142e6 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -137,6 +137,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
137 .init_irq = omap3_init_irq, 137 .init_irq = omap3_init_irq,
138 .handle_irq = omap3_intc_handle_irq, 138 .handle_irq = omap3_intc_handle_irq,
139 .init_machine = omap_zoom_init, 139 .init_machine = omap_zoom_init,
140 .init_late = omap3430_init_late,
140 .timer = &omap3_timer, 141 .timer = &omap3_timer,
141 .restart = omap_prcm_restart, 142 .restart = omap_prcm_restart,
142MACHINE_END 143MACHINE_END
@@ -149,6 +150,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
149 .init_irq = omap3_init_irq, 150 .init_irq = omap3_init_irq,
150 .handle_irq = omap3_intc_handle_irq, 151 .handle_irq = omap3_intc_handle_irq,
151 .init_machine = omap_zoom_init, 152 .init_machine = omap_zoom_init,
153 .init_late = omap3630_init_late,
152 .timer = &omap3_timer, 154 .timer = &omap3_timer,
153 .restart = omap_prcm_restart, 155 .restart = omap_prcm_restart,
154MACHINE_END 156MACHINE_END
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index d6c9e618031..be9dfd1abe6 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -55,7 +55,7 @@ static inline void omap34xx_map_common_io(void)
55} 55}
56#endif 56#endif
57 57
58#ifdef CONFIG_SOC_OMAPTI81XX 58#ifdef CONFIG_SOC_TI81XX
59extern void omapti81xx_map_common_io(void); 59extern void omapti81xx_map_common_io(void);
60#else 60#else
61static inline void omapti81xx_map_common_io(void) 61static inline void omapti81xx_map_common_io(void)
@@ -63,7 +63,7 @@ static inline void omapti81xx_map_common_io(void)
63} 63}
64#endif 64#endif
65 65
66#ifdef CONFIG_SOC_OMAPAM33XX 66#ifdef CONFIG_SOC_AM33XX
67extern void omapam33xx_map_common_io(void); 67extern void omapam33xx_map_common_io(void);
68#else 68#else
69static inline void omapam33xx_map_common_io(void) 69static inline void omapam33xx_map_common_io(void)
@@ -79,6 +79,42 @@ static inline void omap44xx_map_common_io(void)
79} 79}
80#endif 80#endif
81 81
82#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
83int omap2_pm_init(void);
84#else
85static inline int omap2_pm_init(void)
86{
87 return 0;
88}
89#endif
90
91#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
92int omap3_pm_init(void);
93#else
94static inline int omap3_pm_init(void)
95{
96 return 0;
97}
98#endif
99
100#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
101int omap4_pm_init(void);
102#else
103static inline int omap4_pm_init(void)
104{
105 return 0;
106}
107#endif
108
109#ifdef CONFIG_OMAP_MUX
110int omap_mux_late_init(void);
111#else
112static inline int omap_mux_late_init(void)
113{
114 return 0;
115}
116#endif
117
82extern void omap2_init_common_infrastructure(void); 118extern void omap2_init_common_infrastructure(void);
83 119
84extern struct sys_timer omap2_timer; 120extern struct sys_timer omap2_timer;
@@ -95,6 +131,17 @@ void omap3_init_early(void); /* Do not use this one */
95void am35xx_init_early(void); 131void am35xx_init_early(void);
96void ti81xx_init_early(void); 132void ti81xx_init_early(void);
97void omap4430_init_early(void); 133void omap4430_init_early(void);
134void omap3_init_late(void); /* Do not use this one */
135void omap4430_init_late(void);
136void omap2420_init_late(void);
137void omap2430_init_late(void);
138void omap3430_init_late(void);
139void omap35xx_init_late(void);
140void omap3630_init_late(void);
141void am35xx_init_late(void);
142void ti81xx_init_late(void);
143void omap4430_init_late(void);
144int omap2_common_pm_late_init(void);
98void omap_prcm_restart(char, const char *); 145void omap_prcm_restart(char, const char *);
99 146
100/* 147/*
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index ae62ece04ef..7b4b9327e54 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -645,7 +645,11 @@ static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
645 645
646void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) 646void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
647{ 647{
648 char *name = "mmci-omap"; 648 struct platform_device *pdev;
649 struct omap_hwmod *oh;
650 int id = 0;
651 char *oh_name = "msdi1";
652 char *dev_name = "mmci-omap";
649 653
650 if (!mmc_data[0]) { 654 if (!mmc_data[0]) {
651 pr_err("%s fails: Incomplete platform data\n", __func__); 655 pr_err("%s fails: Incomplete platform data\n", __func__);
@@ -653,8 +657,17 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
653 } 657 }
654 658
655 omap242x_mmc_mux(mmc_data[0]); 659 omap242x_mmc_mux(mmc_data[0]);
656 omap_mmc_add(name, 0, OMAP2_MMC1_BASE, OMAP2420_MMC_SIZE, 660
657 INT_24XX_MMC_IRQ, mmc_data[0]); 661 oh = omap_hwmod_lookup(oh_name);
662 if (!oh) {
663 pr_err("Could not look up %s\n", oh_name);
664 return;
665 }
666 pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
667 sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
668 if (IS_ERR(pdev))
669 WARN(1, "Can'd build omap_device for %s:%s.\n",
670 dev_name, oh->name);
658} 671}
659 672
660#endif 673#endif
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index b19d8496c16..ff75abe60af 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -227,10 +227,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
227 227
228 dma_stride = OMAP2_DMA_STRIDE; 228 dma_stride = OMAP2_DMA_STRIDE;
229 dma_common_ch_start = CSDP; 229 dma_common_ch_start = CSDP;
230 if (cpu_is_omap3630() || cpu_is_omap44xx())
231 dma_common_ch_end = CCDN;
232 else
233 dma_common_ch_end = CCFN;
234 230
235 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL); 231 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
236 if (!p) { 232 if (!p) {
@@ -277,6 +273,13 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
277 dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__); 273 dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
278 return -ENOMEM; 274 return -ENOMEM;
279 } 275 }
276
277 /* Check the capabilities register for descriptor loading feature */
278 if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS)
279 dma_common_ch_end = CCDN;
280 else
281 dma_common_ch_end = CCFN;
282
280 return 0; 283 return 0;
281} 284}
282 285
diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c
index 3376388b317..845309f146f 100644
--- a/arch/arm/mach-omap2/dsp.c
+++ b/arch/arm/mach-omap2/dsp.c
@@ -28,8 +28,6 @@
28 28
29#include <plat/dsp.h> 29#include <plat/dsp.h>
30 30
31extern phys_addr_t omap_dsp_get_mempool_base(void);
32
33static struct platform_device *omap_dsp_pdev; 31static struct platform_device *omap_dsp_pdev;
34 32
35static struct omap_dsp_platform_data omap_dsp_pdata __initdata = { 33static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
@@ -47,6 +45,31 @@ static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
47 .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits, 45 .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits,
48}; 46};
49 47
48static phys_addr_t omap_dsp_phys_mempool_base;
49
50void __init omap_dsp_reserve_sdram_memblock(void)
51{
52 phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
53 phys_addr_t paddr;
54
55 if (!size)
56 return;
57
58 paddr = arm_memblock_steal(size, SZ_1M);
59 if (!paddr) {
60 pr_err("%s: failed to reserve %llx bytes\n",
61 __func__, (unsigned long long)size);
62 return;
63 }
64
65 omap_dsp_phys_mempool_base = paddr;
66}
67
68static phys_addr_t omap_dsp_get_mempool_base(void)
69{
70 return omap_dsp_phys_mempool_base;
71}
72
50static int __init omap_dsp_init(void) 73static int __init omap_dsp_init(void)
51{ 74{
52 struct platform_device *pdev; 75 struct platform_device *pdev;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 580e684e882..46b09dae770 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -50,6 +50,19 @@
50#define GPMC_ECC_SIZE_CONFIG 0x1fc 50#define GPMC_ECC_SIZE_CONFIG 0x1fc
51#define GPMC_ECC1_RESULT 0x200 51#define GPMC_ECC1_RESULT 0x200
52 52
53/* GPMC ECC control settings */
54#define GPMC_ECC_CTRL_ECCCLEAR 0x100
55#define GPMC_ECC_CTRL_ECCDISABLE 0x000
56#define GPMC_ECC_CTRL_ECCREG1 0x001
57#define GPMC_ECC_CTRL_ECCREG2 0x002
58#define GPMC_ECC_CTRL_ECCREG3 0x003
59#define GPMC_ECC_CTRL_ECCREG4 0x004
60#define GPMC_ECC_CTRL_ECCREG5 0x005
61#define GPMC_ECC_CTRL_ECCREG6 0x006
62#define GPMC_ECC_CTRL_ECCREG7 0x007
63#define GPMC_ECC_CTRL_ECCREG8 0x008
64#define GPMC_ECC_CTRL_ECCREG9 0x009
65
53#define GPMC_CS0_OFFSET 0x60 66#define GPMC_CS0_OFFSET 0x60
54#define GPMC_CS_SIZE 0x30 67#define GPMC_CS_SIZE 0x30
55 68
@@ -860,8 +873,9 @@ int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
860 gpmc_ecc_used = cs; 873 gpmc_ecc_used = cs;
861 874
862 /* clear ecc and enable bits */ 875 /* clear ecc and enable bits */
863 val = ((0x00000001<<8) | 0x00000001); 876 gpmc_write_reg(GPMC_ECC_CONTROL,
864 gpmc_write_reg(GPMC_ECC_CONTROL, val); 877 GPMC_ECC_CTRL_ECCCLEAR |
878 GPMC_ECC_CTRL_ECCREG1);
865 879
866 /* program ecc and result sizes */ 880 /* program ecc and result sizes */
867 val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F)); 881 val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F));
@@ -869,13 +883,15 @@ int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
869 883
870 switch (mode) { 884 switch (mode) {
871 case GPMC_ECC_READ: 885 case GPMC_ECC_READ:
872 gpmc_write_reg(GPMC_ECC_CONTROL, 0x101); 886 case GPMC_ECC_WRITE:
887 gpmc_write_reg(GPMC_ECC_CONTROL,
888 GPMC_ECC_CTRL_ECCCLEAR |
889 GPMC_ECC_CTRL_ECCREG1);
873 break; 890 break;
874 case GPMC_ECC_READSYN: 891 case GPMC_ECC_READSYN:
875 gpmc_write_reg(GPMC_ECC_CONTROL, 0x100); 892 gpmc_write_reg(GPMC_ECC_CONTROL,
876 break; 893 GPMC_ECC_CTRL_ECCCLEAR |
877 case GPMC_ECC_WRITE: 894 GPMC_ECC_CTRL_ECCDISABLE);
878 gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
879 break; 895 break;
880 default: 896 default:
881 printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode); 897 printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b0268eaffe1..be697d4e084 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -355,7 +355,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
355 * 355 *
356 * temporary HACK: ocr_mask instead of fixed supply 356 * temporary HACK: ocr_mask instead of fixed supply
357 */ 357 */
358 if (cpu_is_omap3505() || cpu_is_omap3517()) 358 if (soc_is_am35xx())
359 mmc->slots[0].ocr_mask = MMC_VDD_165_195 | 359 mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
360 MMC_VDD_26_27 | 360 MMC_VDD_26_27 |
361 MMC_VDD_27_28 | 361 MMC_VDD_27_28 |
@@ -365,7 +365,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
365 else 365 else
366 mmc->slots[0].ocr_mask = c->ocr_mask; 366 mmc->slots[0].ocr_mask = c->ocr_mask;
367 367
368 if (!cpu_is_omap3517() && !cpu_is_omap3505()) 368 if (!soc_is_am35xx())
369 mmc->slots[0].features |= HSMMC_HAS_PBIAS; 369 mmc->slots[0].features |= HSMMC_HAS_PBIAS;
370 370
371 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) 371 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
@@ -388,7 +388,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
388 } 388 }
389 } 389 }
390 390
391 if (cpu_is_omap3517() || cpu_is_omap3505()) 391 if (soc_is_am35xx())
392 mmc->slots[0].set_power = nop_mmc_set_power; 392 mmc->slots[0].set_power = nop_mmc_set_power;
393 393
394 /* OMAP3630 HSMMC1 supports only 4-bit */ 394 /* OMAP3630 HSMMC1 supports only 4-bit */
@@ -400,7 +400,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
400 } 400 }
401 break; 401 break;
402 case 2: 402 case 2:
403 if (cpu_is_omap3517() || cpu_is_omap3505()) 403 if (soc_is_am35xx())
404 mmc->slots[0].set_power = am35x_hsmmc2_set_power; 404 mmc->slots[0].set_power = am35x_hsmmc2_set_power;
405 405
406 if (c->ext_clock) 406 if (c->ext_clock)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index f1398171d8a..0389b3264ab 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -185,8 +185,7 @@ static void __init omap3_cpuinfo(void)
185 */ 185 */
186 if (cpu_is_omap3630()) { 186 if (cpu_is_omap3630()) {
187 cpu_name = "OMAP3630"; 187 cpu_name = "OMAP3630";
188 } else if (cpu_is_omap3517()) { 188 } else if (soc_is_am35xx()) {
189 /* AM35xx devices */
190 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; 189 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
191 } else if (cpu_is_ti816x()) { 190 } else if (cpu_is_ti816x()) {
192 cpu_name = "TI816X"; 191 cpu_name = "TI816X";
@@ -352,13 +351,13 @@ void __init omap3xxx_check_revision(void)
352 */ 351 */
353 switch (rev) { 352 switch (rev) {
354 case 0: 353 case 0:
355 omap_revision = OMAP3517_REV_ES1_0; 354 omap_revision = AM35XX_REV_ES1_0;
356 cpu_rev = "1.0"; 355 cpu_rev = "1.0";
357 break; 356 break;
358 case 1: 357 case 1:
359 /* FALLTHROUGH */ 358 /* FALLTHROUGH */
360 default: 359 default:
361 omap_revision = OMAP3517_REV_ES1_1; 360 omap_revision = AM35XX_REV_ES1_1;
362 cpu_rev = "1.1"; 361 cpu_rev = "1.1";
363 } 362 }
364 break; 363 break;
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
index d79321b0f2a..548de90b58c 100644
--- a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
+++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
@@ -16,18 +16,10 @@
16#define OMAP_WKG_ENB_B_0 0x14 16#define OMAP_WKG_ENB_B_0 0x14
17#define OMAP_WKG_ENB_C_0 0x18 17#define OMAP_WKG_ENB_C_0 0x18
18#define OMAP_WKG_ENB_D_0 0x1c 18#define OMAP_WKG_ENB_D_0 0x1c
19#define OMAP_WKG_ENB_SECURE_A_0 0x20
20#define OMAP_WKG_ENB_SECURE_B_0 0x24
21#define OMAP_WKG_ENB_SECURE_C_0 0x28
22#define OMAP_WKG_ENB_SECURE_D_0 0x2c
23#define OMAP_WKG_ENB_A_1 0x410 19#define OMAP_WKG_ENB_A_1 0x410
24#define OMAP_WKG_ENB_B_1 0x414 20#define OMAP_WKG_ENB_B_1 0x414
25#define OMAP_WKG_ENB_C_1 0x418 21#define OMAP_WKG_ENB_C_1 0x418
26#define OMAP_WKG_ENB_D_1 0x41c 22#define OMAP_WKG_ENB_D_1 0x41c
27#define OMAP_WKG_ENB_SECURE_A_1 0x420
28#define OMAP_WKG_ENB_SECURE_B_1 0x424
29#define OMAP_WKG_ENB_SECURE_C_1 0x428
30#define OMAP_WKG_ENB_SECURE_D_1 0x42c
31#define OMAP_AUX_CORE_BOOT_0 0x800 23#define OMAP_AUX_CORE_BOOT_0 0x800
32#define OMAP_AUX_CORE_BOOT_1 0x804 24#define OMAP_AUX_CORE_BOOT_1 0x804
33#define OMAP_PTMSYNCREQ_MASK 0xc00 25#define OMAP_PTMSYNCREQ_MASK 0xc00
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 4b9491aa36f..8d014ba04ab 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -173,7 +173,7 @@ static struct map_desc omap34xx_io_desc[] __initdata = {
173}; 173};
174#endif 174#endif
175 175
176#ifdef CONFIG_SOC_OMAPTI81XX 176#ifdef CONFIG_SOC_TI81XX
177static struct map_desc omapti81xx_io_desc[] __initdata = { 177static struct map_desc omapti81xx_io_desc[] __initdata = {
178 { 178 {
179 .virtual = L4_34XX_VIRT, 179 .virtual = L4_34XX_VIRT,
@@ -184,7 +184,7 @@ static struct map_desc omapti81xx_io_desc[] __initdata = {
184}; 184};
185#endif 185#endif
186 186
187#ifdef CONFIG_SOC_OMAPAM33XX 187#ifdef CONFIG_SOC_AM33XX
188static struct map_desc omapam33xx_io_desc[] __initdata = { 188static struct map_desc omapam33xx_io_desc[] __initdata = {
189 { 189 {
190 .virtual = L4_34XX_VIRT, 190 .virtual = L4_34XX_VIRT,
@@ -216,41 +216,11 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
216 .type = MT_DEVICE, 216 .type = MT_DEVICE,
217 }, 217 },
218 { 218 {
219 .virtual = OMAP44XX_GPMC_VIRT,
220 .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
221 .length = OMAP44XX_GPMC_SIZE,
222 .type = MT_DEVICE,
223 },
224 {
225 .virtual = OMAP44XX_EMIF1_VIRT,
226 .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
227 .length = OMAP44XX_EMIF1_SIZE,
228 .type = MT_DEVICE,
229 },
230 {
231 .virtual = OMAP44XX_EMIF2_VIRT,
232 .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
233 .length = OMAP44XX_EMIF2_SIZE,
234 .type = MT_DEVICE,
235 },
236 {
237 .virtual = OMAP44XX_DMM_VIRT,
238 .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS),
239 .length = OMAP44XX_DMM_SIZE,
240 .type = MT_DEVICE,
241 },
242 {
243 .virtual = L4_PER_44XX_VIRT, 219 .virtual = L4_PER_44XX_VIRT,
244 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS), 220 .pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
245 .length = L4_PER_44XX_SIZE, 221 .length = L4_PER_44XX_SIZE,
246 .type = MT_DEVICE, 222 .type = MT_DEVICE,
247 }, 223 },
248 {
249 .virtual = L4_EMU_44XX_VIRT,
250 .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS),
251 .length = L4_EMU_44XX_SIZE,
252 .type = MT_DEVICE,
253 },
254#ifdef CONFIG_OMAP4_ERRATA_I688 224#ifdef CONFIG_OMAP4_ERRATA_I688
255 { 225 {
256 .virtual = OMAP4_SRAM_VA, 226 .virtual = OMAP4_SRAM_VA,
@@ -286,14 +256,14 @@ void __init omap34xx_map_common_io(void)
286} 256}
287#endif 257#endif
288 258
289#ifdef CONFIG_SOC_OMAPTI81XX 259#ifdef CONFIG_SOC_TI81XX
290void __init omapti81xx_map_common_io(void) 260void __init omapti81xx_map_common_io(void)
291{ 261{
292 iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); 262 iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
293} 263}
294#endif 264#endif
295 265
296#ifdef CONFIG_SOC_OMAPAM33XX 266#ifdef CONFIG_SOC_AM33XX
297void __init omapam33xx_map_common_io(void) 267void __init omapam33xx_map_common_io(void)
298{ 268{
299 iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); 269 iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
@@ -380,6 +350,13 @@ void __init omap2420_init_early(void)
380 omap_hwmod_init_postsetup(); 350 omap_hwmod_init_postsetup();
381 omap2420_clk_init(); 351 omap2420_clk_init();
382} 352}
353
354void __init omap2420_init_late(void)
355{
356 omap_mux_late_init();
357 omap2_common_pm_late_init();
358 omap2_pm_init();
359}
383#endif 360#endif
384 361
385#ifdef CONFIG_SOC_OMAP2430 362#ifdef CONFIG_SOC_OMAP2430
@@ -395,6 +372,13 @@ void __init omap2430_init_early(void)
395 omap_hwmod_init_postsetup(); 372 omap_hwmod_init_postsetup();
396 omap2430_clk_init(); 373 omap2430_clk_init();
397} 374}
375
376void __init omap2430_init_late(void)
377{
378 omap_mux_late_init();
379 omap2_common_pm_late_init();
380 omap2_pm_init();
381}
398#endif 382#endif
399 383
400/* 384/*
@@ -449,6 +433,48 @@ void __init ti81xx_init_early(void)
449 omap_hwmod_init_postsetup(); 433 omap_hwmod_init_postsetup();
450 omap3xxx_clk_init(); 434 omap3xxx_clk_init();
451} 435}
436
437void __init omap3_init_late(void)
438{
439 omap_mux_late_init();
440 omap2_common_pm_late_init();
441 omap3_pm_init();
442}
443
444void __init omap3430_init_late(void)
445{
446 omap_mux_late_init();
447 omap2_common_pm_late_init();
448 omap3_pm_init();
449}
450
451void __init omap35xx_init_late(void)
452{
453 omap_mux_late_init();
454 omap2_common_pm_late_init();
455 omap3_pm_init();
456}
457
458void __init omap3630_init_late(void)
459{
460 omap_mux_late_init();
461 omap2_common_pm_late_init();
462 omap3_pm_init();
463}
464
465void __init am35xx_init_late(void)
466{
467 omap_mux_late_init();
468 omap2_common_pm_late_init();
469 omap3_pm_init();
470}
471
472void __init ti81xx_init_late(void)
473{
474 omap_mux_late_init();
475 omap2_common_pm_late_init();
476 omap3_pm_init();
477}
452#endif 478#endif
453 479
454#ifdef CONFIG_ARCH_OMAP4 480#ifdef CONFIG_ARCH_OMAP4
@@ -465,6 +491,13 @@ void __init omap4430_init_early(void)
465 omap_hwmod_init_postsetup(); 491 omap_hwmod_init_postsetup();
466 omap4xxx_clk_init(); 492 omap4xxx_clk_init();
467} 493}
494
495void __init omap4430_init_late(void)
496{
497 omap_mux_late_init();
498 omap2_common_pm_late_init();
499 omap4_pm_init();
500}
468#endif 501#endif
469 502
470void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, 503void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h
index 0812b154f5b..80b88921fab 100644
--- a/arch/arm/mach-omap2/iomap.h
+++ b/arch/arm/mach-omap2/iomap.h
@@ -37,9 +37,6 @@
37#define OMAP4_L3_PER_IO_OFFSET 0xb1100000 37#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
38#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET) 38#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
39 39
40#define OMAP4_GPMC_IO_OFFSET 0xa9000000
41#define OMAP4_GPMC_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
42
43#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */ 40#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */
44#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_IO_OFFSET) 41#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
45 42
@@ -170,28 +167,3 @@
170#define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET) 167#define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
171#define L4_ABE_44XX_SIZE SZ_1M 168#define L4_ABE_44XX_SIZE SZ_1M
172 169
173#define L4_EMU_44XX_PHYS L4_EMU_44XX_BASE
174 /* 0x54000000 --> 0xfe800000 */
175#define L4_EMU_44XX_VIRT (L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
176#define L4_EMU_44XX_SIZE SZ_8M
177
178#define OMAP44XX_GPMC_PHYS OMAP44XX_GPMC_BASE
179 /* 0x50000000 --> 0xf9000000 */
180#define OMAP44XX_GPMC_VIRT (OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
181#define OMAP44XX_GPMC_SIZE SZ_1M
182
183
184#define OMAP44XX_EMIF1_PHYS OMAP44XX_EMIF1_BASE
185 /* 0x4c000000 --> 0xfd100000 */
186#define OMAP44XX_EMIF1_VIRT (OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
187#define OMAP44XX_EMIF1_SIZE SZ_1M
188
189#define OMAP44XX_EMIF2_PHYS OMAP44XX_EMIF2_BASE
190 /* 0x4d000000 --> 0xfd200000 */
191#define OMAP44XX_EMIF2_SIZE SZ_1M
192#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE)
193
194#define OMAP44XX_DMM_PHYS OMAP44XX_DMM_BASE
195 /* 0x4e000000 --> 0xfd300000 */
196#define OMAP44XX_DMM_SIZE SZ_1M
197#define OMAP44XX_DMM_VIRT (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE)
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 1ecf54565fe..fdc4303be56 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -231,7 +231,7 @@ static inline void omap_intc_handle_irq(void __iomem *base_addr, struct pt_regs
231 goto out; 231 goto out;
232 232
233 irqnr = readl_relaxed(base_addr + 0xd8); 233 irqnr = readl_relaxed(base_addr + 0xd8);
234#ifdef CONFIG_SOC_OMAPTI81XX 234#ifdef CONFIG_SOC_TI81XX
235 if (irqnr) 235 if (irqnr)
236 goto out; 236 goto out;
237 irqnr = readl_relaxed(base_addr + 0xf8); 237 irqnr = readl_relaxed(base_addr + 0xf8);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 3268ee24ead..80e55c5c999 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -788,7 +788,7 @@ static void __init omap_mux_free_names(struct omap_mux *m)
788} 788}
789 789
790/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */ 790/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
791static int __init omap_mux_late_init(void) 791int __init omap_mux_late_init(void)
792{ 792{
793 struct omap_mux_partition *partition; 793 struct omap_mux_partition *partition;
794 int ret; 794 int ret;
@@ -823,7 +823,6 @@ static int __init omap_mux_late_init(void)
823 823
824 return 0; 824 return 0;
825} 825}
826late_initcall(omap_mux_late_init);
827 826
828static void __init omap_mux_package_fixup(struct omap_mux *p, 827static void __init omap_mux_package_fixup(struct omap_mux *p,
829 struct omap_mux *superset) 828 struct omap_mux *superset)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index fd48797fa95..b26d3c9bca1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3306,7 +3306,7 @@ int __init omap3xxx_hwmod_init(void)
3306 rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 || 3306 rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 ||
3307 rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { 3307 rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
3308 h = omap34xx_hwmod_ocp_ifs; 3308 h = omap34xx_hwmod_ocp_ifs;
3309 } else if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) { 3309 } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
3310 h = am35xx_hwmod_ocp_ifs; 3310 h = am35xx_hwmod_ocp_ifs;
3311 } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || 3311 } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
3312 rev == OMAP3630_REV_ES1_2) { 3312 rev == OMAP3630_REV_ES1_2) {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d0c1c969599..9cb5cede0f5 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -295,7 +295,7 @@ static int __init omap2_common_pm_init(void)
295} 295}
296postcore_initcall(omap2_common_pm_init); 296postcore_initcall(omap2_common_pm_init);
297 297
298static int __init omap2_common_pm_late_init(void) 298int __init omap2_common_pm_late_init(void)
299{ 299{
300 /* 300 /*
301 * In the case of DT, the PMIC and SR initialization will be done using 301 * In the case of DT, the PMIC and SR initialization will be done using
@@ -322,4 +322,3 @@ static int __init omap2_common_pm_late_init(void)
322 322
323 return 0; 323 return 0;
324} 324}
325late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index facfffca9ea..2edeffc923a 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -298,13 +298,10 @@ static void __init prcm_setup_regs(void)
298 WKUP_MOD, PM_WKEN); 298 WKUP_MOD, PM_WKEN);
299} 299}
300 300
301static int __init omap2_pm_init(void) 301int __init omap2_pm_init(void)
302{ 302{
303 u32 l; 303 u32 l;
304 304
305 if (!cpu_is_omap24xx())
306 return -ENODEV;
307
308 printk(KERN_INFO "Power Management for OMAP2 initializing\n"); 305 printk(KERN_INFO "Power Management for OMAP2 initializing\n");
309 l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET); 306 l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
310 printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); 307 printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
@@ -370,17 +367,13 @@ static int __init omap2_pm_init(void)
370 * These routines need to be in SRAM as that's the only 367 * These routines need to be in SRAM as that's the only
371 * memory the MPU can see when it wakes up. 368 * memory the MPU can see when it wakes up.
372 */ 369 */
373 if (cpu_is_omap24xx()) { 370 omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
374 omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, 371 omap24xx_idle_loop_suspend_sz);
375 omap24xx_idle_loop_suspend_sz);
376 372
377 omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, 373 omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
378 omap24xx_cpu_suspend_sz); 374 omap24xx_cpu_suspend_sz);
379 }
380 375
381 arm_pm_idle = omap2_pm_idle; 376 arm_pm_idle = omap2_pm_idle;
382 377
383 return 0; 378 return 0;
384} 379}
385
386late_initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8b43aefba0e..a34023d0ca7 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -697,15 +697,12 @@ static void __init pm_errata_configure(void)
697 } 697 }
698} 698}
699 699
700static int __init omap3_pm_init(void) 700int __init omap3_pm_init(void)
701{ 701{
702 struct power_state *pwrst, *tmp; 702 struct power_state *pwrst, *tmp;
703 struct clockdomain *neon_clkdm, *mpu_clkdm; 703 struct clockdomain *neon_clkdm, *mpu_clkdm;
704 int ret; 704 int ret;
705 705
706 if (!cpu_is_omap34xx())
707 return -ENODEV;
708
709 if (!omap3_has_io_chain_ctrl()) 706 if (!omap3_has_io_chain_ctrl())
710 pr_warning("PM: no software I/O chain control; some wakeups may be lost\n"); 707 pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
711 708
@@ -804,5 +801,3 @@ err2:
804err1: 801err1:
805 return ret; 802 return ret;
806} 803}
807
808late_initcall(omap3_pm_init);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 88562535242..ea24174f570 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -141,15 +141,12 @@ static void omap_default_idle(void)
141 * Initializes all powerdomain and clockdomain target states 141 * Initializes all powerdomain and clockdomain target states
142 * and all PRCM settings. 142 * and all PRCM settings.
143 */ 143 */
144static int __init omap4_pm_init(void) 144int __init omap4_pm_init(void)
145{ 145{
146 int ret; 146 int ret;
147 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup; 147 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
148 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; 148 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
149 149
150 if (!cpu_is_omap44xx())
151 return -ENODEV;
152
153 if (omap_rev() == OMAP4430_REV_ES1_0) { 150 if (omap_rev() == OMAP4430_REV_ES1_0) {
154 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); 151 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
155 return -ENODEV; 152 return -ENODEV;
@@ -217,4 +214,3 @@ static int __init omap4_pm_init(void)
217err2: 214err2:
218 return ret; 215 return ret;
219} 216}
220late_initcall(omap4_pm_init);
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index b7ea468eea3..fb0a0a6869d 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -311,7 +311,7 @@ void __init omap3xxx_powerdomains_init(void)
311 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0) 311 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
312 pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); 312 pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
313 else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 || 313 else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
314 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 || 314 rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1 ||
315 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2) 315 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
316 pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); 316 pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
317 else 317 else
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 1b7835865c8..840929bd9da 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -90,7 +90,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
90} 90}
91 91
92static struct irqaction omap2_gp_timer_irq = { 92static struct irqaction omap2_gp_timer_irq = {
93 .name = "gp timer", 93 .name = "gp_timer",
94 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 94 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
95 .handler = omap2_gp_timer_interrupt, 95 .handler = omap2_gp_timer_interrupt,
96}; 96};
@@ -132,7 +132,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
132} 132}
133 133
134static struct clock_event_device clockevent_gpt = { 134static struct clock_event_device clockevent_gpt = {
135 .name = "gp timer", 135 .name = "gp_timer",
136 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 136 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
137 .shift = 32, 137 .shift = 32,
138 .set_next_event = omap2_gp_timer_set_next_event, 138 .set_next_event = omap2_gp_timer_set_next_event,
@@ -236,22 +236,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
236} 236}
237 237
238/* Clocksource code */ 238/* Clocksource code */
239
240#ifdef CONFIG_OMAP_32K_TIMER
241/*
242 * When 32k-timer is enabled, don't use GPTimer for clocksource
243 * instead, just leave default clocksource which uses the 32k
244 * sync counter. See clocksource setup in plat-omap/counter_32k.c
245 */
246
247static void __init omap2_gp_clocksource_init(int unused, const char *dummy)
248{
249 omap_init_clocksource_32k();
250}
251
252#else
253
254static struct omap_dm_timer clksrc; 239static struct omap_dm_timer clksrc;
240static bool use_gptimer_clksrc;
255 241
256/* 242/*
257 * clocksource 243 * clocksource
@@ -262,7 +248,7 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs)
262} 248}
263 249
264static struct clocksource clocksource_gpt = { 250static struct clocksource clocksource_gpt = {
265 .name = "gp timer", 251 .name = "gp_timer",
266 .rating = 300, 252 .rating = 300,
267 .read = clocksource_read_cycles, 253 .read = clocksource_read_cycles,
268 .mask = CLOCKSOURCE_MASK(32), 254 .mask = CLOCKSOURCE_MASK(32),
@@ -278,7 +264,46 @@ static u32 notrace dmtimer_read_sched_clock(void)
278} 264}
279 265
280/* Setup free-running counter for clocksource */ 266/* Setup free-running counter for clocksource */
281static void __init omap2_gp_clocksource_init(int gptimer_id, 267static int __init omap2_sync32k_clocksource_init(void)
268{
269 int ret;
270 struct omap_hwmod *oh;
271 void __iomem *vbase;
272 const char *oh_name = "counter_32k";
273
274 /*
275 * First check hwmod data is available for sync32k counter
276 */
277 oh = omap_hwmod_lookup(oh_name);
278 if (!oh || oh->slaves_cnt == 0)
279 return -ENODEV;
280
281 omap_hwmod_setup_one(oh_name);
282
283 vbase = omap_hwmod_get_mpu_rt_va(oh);
284 if (!vbase) {
285 pr_warn("%s: failed to get counter_32k resource\n", __func__);
286 return -ENXIO;
287 }
288
289 ret = omap_hwmod_enable(oh);
290 if (ret) {
291 pr_warn("%s: failed to enable counter_32k module (%d)\n",
292 __func__, ret);
293 return ret;
294 }
295
296 ret = omap_init_clocksource_32k(vbase);
297 if (ret) {
298 pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
299 __func__, ret);
300 omap_hwmod_idle(oh);
301 }
302
303 return ret;
304}
305
306static void __init omap2_gptimer_clocksource_init(int gptimer_id,
282 const char *fck_source) 307 const char *fck_source)
283{ 308{
284 int res; 309 int res;
@@ -286,9 +311,6 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
286 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source); 311 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source);
287 BUG_ON(res); 312 BUG_ON(res);
288 313
289 pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
290 gptimer_id, clksrc.rate);
291
292 __omap_dm_timer_load_start(&clksrc, 314 __omap_dm_timer_load_start(&clksrc,
293 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); 315 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
294 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); 316 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
@@ -296,15 +318,36 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
296 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) 318 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
297 pr_err("Could not register clocksource %s\n", 319 pr_err("Could not register clocksource %s\n",
298 clocksource_gpt.name); 320 clocksource_gpt.name);
321 else
322 pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
323 gptimer_id, clksrc.rate);
324}
325
326static void __init omap2_clocksource_init(int gptimer_id,
327 const char *fck_source)
328{
329 /*
330 * First give preference to kernel parameter configuration
331 * by user (clocksource="gp_timer").
332 *
333 * In case of missing kernel parameter for clocksource,
334 * first check for availability for 32k-sync timer, in case
335 * of failure in finding 32k_counter module or registering
336 * it as clocksource, execution will fallback to gp-timer.
337 */
338 if (use_gptimer_clksrc == true)
339 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
340 else if (omap2_sync32k_clocksource_init())
341 /* Fall back to gp-timer code */
342 omap2_gptimer_clocksource_init(gptimer_id, fck_source);
299} 343}
300#endif
301 344
302#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \ 345#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
303 clksrc_nr, clksrc_src) \ 346 clksrc_nr, clksrc_src) \
304static void __init omap##name##_timer_init(void) \ 347static void __init omap##name##_timer_init(void) \
305{ \ 348{ \
306 omap2_gp_clockevent_init((clkev_nr), clkev_src); \ 349 omap2_gp_clockevent_init((clkev_nr), clkev_src); \
307 omap2_gp_clocksource_init((clksrc_nr), clksrc_src); \ 350 omap2_clocksource_init((clksrc_nr), clksrc_src); \
308} 351}
309 352
310#define OMAP_SYS_TIMER(name) \ 353#define OMAP_SYS_TIMER(name) \
@@ -335,7 +378,7 @@ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
335static void __init omap4_timer_init(void) 378static void __init omap4_timer_init(void)
336{ 379{
337 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); 380 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
338 omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE); 381 omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
339#ifdef CONFIG_LOCAL_TIMERS 382#ifdef CONFIG_LOCAL_TIMERS
340 /* Local timers are not supprted on OMAP4430 ES1.0 */ 383 /* Local timers are not supprted on OMAP4430 ES1.0 */
341 if (omap_rev() != OMAP4430_REV_ES1_0) { 384 if (omap_rev() != OMAP4430_REV_ES1_0) {
@@ -503,3 +546,28 @@ static int __init omap2_dm_timer_init(void)
503 return 0; 546 return 0;
504} 547}
505arch_initcall(omap2_dm_timer_init); 548arch_initcall(omap2_dm_timer_init);
549
550/**
551 * omap2_override_clocksource - clocksource override with user configuration
552 *
553 * Allows user to override default clocksource, using kernel parameter
554 * clocksource="gp_timer" (For all OMAP2PLUS architectures)
555 *
556 * Note that, here we are using same standard kernel parameter "clocksource=",
557 * and not introducing any OMAP specific interface.
558 */
559static int __init omap2_override_clocksource(char *str)
560{
561 if (!str)
562 return 0;
563 /*
564 * For OMAP architecture, we only have two options
565 * - sync_32k (default)
566 * - gp_timer (sys_clk based)
567 */
568 if (!strcmp(str, "gp_timer"))
569 use_gptimer_clksrc = true;
570
571 return 0;
572}
573early_param("clocksource", omap2_override_clocksource);
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 8d5ed775dd5..b19d1b43c12 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -90,7 +90,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
90 musb_plat.mode = board_data->mode; 90 musb_plat.mode = board_data->mode;
91 musb_plat.extvbus = board_data->extvbus; 91 musb_plat.extvbus = board_data->extvbus;
92 92
93 if (cpu_is_omap3517() || cpu_is_omap3505()) { 93 if (soc_is_am35xx()) {
94 oh_name = "am35x_otg_hs"; 94 oh_name = "am35x_otg_hs";
95 name = "musb-am35x"; 95 name = "musb-am35x";
96 } else if (cpu_is_ti81xx()) { 96 } else if (cpu_is_ti81xx()) {
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index 57db2038b23..d0103c80d04 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -118,7 +118,7 @@ void __init omap3xxx_voltagedomains_init(void)
118 } 118 }
119#endif 119#endif
120 120
121 if (cpu_is_omap3517() || cpu_is_omap3505()) 121 if (soc_is_am35xx())
122 voltdms = voltagedomains_am35xx; 122 voltdms = voltagedomains_am35xx;
123 else 123 else
124 voltdms = voltagedomains_omap3; 124 voltdms = voltagedomains_omap3;
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index e2e9db492d0..9148b229d0d 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -18,6 +18,7 @@
18#include <linux/mv643xx_i2c.h> 18#include <linux/mv643xx_i2c.h>
19#include <linux/ata_platform.h> 19#include <linux/ata_platform.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/clk-provider.h>
21#include <net/dsa.h> 22#include <net/dsa.h>
22#include <asm/page.h> 23#include <asm/page.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
@@ -70,6 +71,19 @@ void __init orion5x_map_io(void)
70 71
71 72
72/***************************************************************************** 73/*****************************************************************************
74 * CLK tree
75 ****************************************************************************/
76static struct clk *tclk;
77
78static void __init clk_init(void)
79{
80 tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
81 orion5x_tclk);
82
83 orion_clkdev_init(tclk);
84}
85
86/*****************************************************************************
73 * EHCI0 87 * EHCI0
74 ****************************************************************************/ 88 ****************************************************************************/
75void __init orion5x_ehci0_init(void) 89void __init orion5x_ehci0_init(void)
@@ -95,7 +109,7 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
95{ 109{
96 orion_ge00_init(eth_data, 110 orion_ge00_init(eth_data,
97 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, 111 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
98 IRQ_ORION5X_ETH_ERR, orion5x_tclk); 112 IRQ_ORION5X_ETH_ERR);
99} 113}
100 114
101 115
@@ -132,7 +146,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
132 ****************************************************************************/ 146 ****************************************************************************/
133void __init orion5x_spi_init() 147void __init orion5x_spi_init()
134{ 148{
135 orion_spi_init(SPI_PHYS_BASE, orion5x_tclk); 149 orion_spi_init(SPI_PHYS_BASE);
136} 150}
137 151
138 152
@@ -142,7 +156,7 @@ void __init orion5x_spi_init()
142void __init orion5x_uart0_init(void) 156void __init orion5x_uart0_init(void)
143{ 157{
144 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, 158 orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
145 IRQ_ORION5X_UART0, orion5x_tclk); 159 IRQ_ORION5X_UART0, tclk);
146} 160}
147 161
148/***************************************************************************** 162/*****************************************************************************
@@ -151,7 +165,7 @@ void __init orion5x_uart0_init(void)
151void __init orion5x_uart1_init(void) 165void __init orion5x_uart1_init(void)
152{ 166{
153 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, 167 orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
154 IRQ_ORION5X_UART1, orion5x_tclk); 168 IRQ_ORION5X_UART1, tclk);
155} 169}
156 170
157/***************************************************************************** 171/*****************************************************************************
@@ -179,7 +193,7 @@ static void __init orion5x_crypto_init(void)
179 ****************************************************************************/ 193 ****************************************************************************/
180void __init orion5x_wdt_init(void) 194void __init orion5x_wdt_init(void)
181{ 195{
182 orion_wdt_init(orion5x_tclk); 196 orion_wdt_init();
183} 197}
184 198
185 199
@@ -276,6 +290,9 @@ void __init orion5x_init(void)
276 */ 290 */
277 orion5x_setup_cpu_mbus_bridge(); 291 orion5x_setup_cpu_mbus_bridge();
278 292
293 /* Setup root of clk tree */
294 clk_init();
295
279 /* 296 /*
280 * Don't issue "Wait for Interrupt" instruction if we are 297 * Don't issue "Wait for Interrupt" instruction if we are
281 * running on D0 5281 silicon. 298 * running on D0 5281 silicon.
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
index e91bf0ba4e8..92df49c1b62 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -16,7 +16,6 @@
16#include <linux/mtd/physmap.h> 16#include <linux/mtd/physmap.h>
17#include <linux/mv643xx_eth.h> 17#include <linux/mv643xx_eth.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/spi/orion_spi.h>
20#include <linux/spi/flash.h> 19#include <linux/spi/flash.h>
21#include <linux/ethtool.h> 20#include <linux/ethtool.h>
22#include <net/dsa.h> 21#include <net/dsa.h>
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
index be4c9285850..a00d2f1254e 100644
--- a/arch/arm/mach-pnx4008/core.c
+++ b/arch/arm/mach-pnx4008/core.c
@@ -265,6 +265,17 @@ static void pnx4008_restart(char mode, const char *cmd)
265 soft_restart(0); 265 soft_restart(0);
266} 266}
267 267
268#ifdef CONFIG_PM
269extern int pnx4008_pm_init(void);
270#else
271static inline int pnx4008_pm_init(void) { return 0; }
272#endif
273
274void __init pnx4008_init_late(void)
275{
276 pnx4008_pm_init();
277}
278
268extern struct sys_timer pnx4008_timer; 279extern struct sys_timer pnx4008_timer;
269 280
270MACHINE_START(PNX4008, "Philips PNX4008") 281MACHINE_START(PNX4008, "Philips PNX4008")
@@ -273,6 +284,7 @@ MACHINE_START(PNX4008, "Philips PNX4008")
273 .map_io = pnx4008_map_io, 284 .map_io = pnx4008_map_io,
274 .init_irq = pnx4008_init_irq, 285 .init_irq = pnx4008_init_irq,
275 .init_machine = pnx4008_init, 286 .init_machine = pnx4008_init,
287 .init_late = pnx4008_init_late,
276 .timer = &pnx4008_timer, 288 .timer = &pnx4008_timer,
277 .restart = pnx4008_restart, 289 .restart = pnx4008_restart,
278MACHINE_END 290MACHINE_END
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index f3e60a049f9..26f8d06b142 100644
--- a/arch/arm/mach-pnx4008/pm.c
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -124,7 +124,7 @@ static const struct platform_suspend_ops pnx4008_pm_ops = {
124 .valid = pnx4008_pm_valid, 124 .valid = pnx4008_pm_valid,
125}; 125};
126 126
127static int __init pnx4008_pm_init(void) 127int __init pnx4008_pm_init(void)
128{ 128{
129 u32 sram_size_to_allocate; 129 u32 sram_size_to_allocate;
130 130
@@ -151,5 +151,3 @@ static int __init pnx4008_pm_init(void)
151 suspend_set_ops(&pnx4008_pm_ops); 151 suspend_set_ops(&pnx4008_pm_ops);
152 return 0; 152 return 0;
153} 153}
154
155late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index b28a930d4f8..60d826fc218 100644
--- a/arch/arm/mach-prima2/common.h
+++ b/arch/arm/mach-prima2/common.h
@@ -24,4 +24,10 @@ static inline void sirfsoc_map_lluart(void) {}
24extern void __init sirfsoc_map_lluart(void); 24extern void __init sirfsoc_map_lluart(void);
25#endif 25#endif
26 26
27#ifdef CONFIG_SUSPEND
28extern int sirfsoc_pm_init(void);
29#else
30static inline int sirfsoc_pm_init(void) { return 0; }
31#endif
32
27#endif 33#endif
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
index 26ebb57719d..fb5a7910af3 100644
--- a/arch/arm/mach-prima2/pm.c
+++ b/arch/arm/mach-prima2/pm.c
@@ -85,12 +85,11 @@ static const struct platform_suspend_ops sirfsoc_pm_ops = {
85 .valid = suspend_valid_only_mem, 85 .valid = suspend_valid_only_mem,
86}; 86};
87 87
88static int __init sirfsoc_pm_init(void) 88int __init sirfsoc_pm_init(void)
89{ 89{
90 suspend_set_ops(&sirfsoc_pm_ops); 90 suspend_set_ops(&sirfsoc_pm_ops);
91 return 0; 91 return 0;
92} 92}
93late_initcall(sirfsoc_pm_init);
94 93
95static const struct of_device_id pwrc_ids[] = { 94static const struct of_device_id pwrc_ids[] = {
96 { .compatible = "sirf,prima2-pwrc" }, 95 { .compatible = "sirf,prima2-pwrc" },
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
index 02b9c05ff99..8f0429d4b79 100644
--- a/arch/arm/mach-prima2/prima2.c
+++ b/arch/arm/mach-prima2/prima2.c
@@ -25,6 +25,11 @@ void __init sirfsoc_mach_init(void)
25 of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL); 25 of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL);
26} 26}
27 27
28void __init sirfsoc_init_late(void)
29{
30 sirfsoc_pm_init();
31}
32
28static const char *prima2cb_dt_match[] __initdata = { 33static const char *prima2cb_dt_match[] __initdata = {
29 "sirf,prima2-cb", 34 "sirf,prima2-cb",
30 NULL 35 NULL
@@ -39,6 +44,7 @@ MACHINE_START(PRIMA2_EVB, "prima2cb")
39 .timer = &sirfsoc_timer, 44 .timer = &sirfsoc_timer,
40 .dma_zone_size = SZ_256M, 45 .dma_zone_size = SZ_256M,
41 .init_machine = sirfsoc_mach_init, 46 .init_machine = sirfsoc_mach_init,
47 .init_late = sirfsoc_init_late,
42 .dt_compat = prima2cb_dt_match, 48 .dt_compat = prima2cb_dt_match,
43 .restart = sirfsoc_restart, 49 .restart = sirfsoc_restart,
44MACHINE_END 50MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index b34287ab5af..e24961109b7 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -518,6 +518,11 @@ config S3C2443_DMA
518 help 518 help
519 Internal config node for S3C2443 DMA support 519 Internal config node for S3C2443 DMA support
520 520
521config S3C2443_SETUP_SPI
522 bool
523 help
524 Common setup code for SPI GPIO configurations
525
521endif # CPU_S3C2443 || CPU_S3C2416 526endif # CPU_S3C2443 || CPU_S3C2416
522 527
523if CPU_S3C2443 528if CPU_S3C2443
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 3518fe812d5..0ab6ab15da4 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -14,6 +14,8 @@ obj- :=
14 14
15# core 15# core
16 16
17obj-y += common.o
18
17obj-$(CONFIG_CPU_S3C2410) += s3c2410.o 19obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
18obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o 20obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
19obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o 21obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
@@ -33,6 +35,10 @@ obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
33 35
34obj-$(CONFIG_CPU_S3C2443) += s3c2443.o irq-s3c2443.o clock-s3c2443.o 36obj-$(CONFIG_CPU_S3C2443) += s3c2443.o irq-s3c2443.o clock-s3c2443.o
35 37
38# PM
39
40obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
41
36# common code 42# common code
37 43
38obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o 44obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o
@@ -91,5 +97,6 @@ obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o
91# device setup 97# device setup
92 98
93obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 99obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
100obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi.o
94obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o 101obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o
95obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o 102obj-$(CONFIG_S3C24XX_SETUP_TS) += setup-ts.o
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
index dbc9ab4aaca..8702ecfaab3 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2416.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c
@@ -144,6 +144,7 @@ static struct clk_lookup s3c2416_clk_lookup[] = {
144 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk), 144 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
145 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk), 145 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
146 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk), 146 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
147 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &hsspi_mux.clk),
147}; 148};
148 149
149void __init s3c2416_init_clocks(int xtal) 150void __init s3c2416_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
index efb3ac35956..a4c5a520d99 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c
@@ -179,6 +179,11 @@ static struct clk *clks[] __initdata = {
179 &clk_hsmmc, 179 &clk_hsmmc,
180}; 180};
181 181
182static struct clk_lookup s3c2443_clk_lookup[] = {
183 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc),
184 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_hsspi.clk),
185};
186
182void __init s3c2443_init_clocks(int xtal) 187void __init s3c2443_init_clocks(int xtal)
183{ 188{
184 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON); 189 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
@@ -210,6 +215,7 @@ void __init s3c2443_init_clocks(int xtal)
210 215
211 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 216 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
212 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 217 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
218 clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
213 219
214 s3c_pwmclk_init(); 220 s3c_pwmclk_init();
215} 221}
diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c
index 460431589f3..aeeb2be283f 100644
--- a/arch/arm/mach-s3c24xx/common-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/common-s3c2443.c
@@ -424,11 +424,6 @@ static struct clk init_clocks_off[] = {
424 .enable = s3c2443_clkcon_enable_p, 424 .enable = s3c2443_clkcon_enable_p,
425 .ctrlbit = S3C2443_PCLKCON_IIS, 425 .ctrlbit = S3C2443_PCLKCON_IIS,
426 }, { 426 }, {
427 .name = "hsspi",
428 .parent = &clk_p,
429 .enable = s3c2443_clkcon_enable_p,
430 .ctrlbit = S3C2443_PCLKCON_HSSPI,
431 }, {
432 .name = "adc", 427 .name = "adc",
433 .parent = &clk_p, 428 .parent = &clk_p,
434 .enable = s3c2443_clkcon_enable_p, 429 .enable = s3c2443_clkcon_enable_p,
@@ -562,6 +557,14 @@ static struct clk hsmmc1_clk = {
562 .ctrlbit = S3C2443_HCLKCON_HSMMC, 557 .ctrlbit = S3C2443_HCLKCON_HSMMC,
563}; 558};
564 559
560static struct clk hsspi_clk = {
561 .name = "spi",
562 .devname = "s3c64xx-spi.0",
563 .parent = &clk_p,
564 .enable = s3c2443_clkcon_enable_p,
565 .ctrlbit = S3C2443_PCLKCON_HSSPI,
566};
567
565/* EPLLCON compatible enough to get on/off information */ 568/* EPLLCON compatible enough to get on/off information */
566 569
567void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll) 570void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
@@ -612,6 +615,7 @@ static struct clk *clks[] __initdata = {
612 &clk_usb_bus, 615 &clk_usb_bus,
613 &clk_armdiv, 616 &clk_armdiv,
614 &hsmmc1_clk, 617 &hsmmc1_clk,
618 &hsspi_clk,
615}; 619};
616 620
617static struct clksrc_clk *clksrcs[] __initdata = { 621static struct clksrc_clk *clksrcs[] __initdata = {
@@ -629,6 +633,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = {
629 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), 633 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
630 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), 634 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
631 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk), 635 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
636 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &hsspi_clk),
632}; 637};
633 638
634void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 639void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/mach-s3c24xx/common.c
index 290942d9add..56cdd34cce4 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -4,7 +4,7 @@
4 * http://www.simtec.co.uk/products/SWLINUX/ 4 * http://www.simtec.co.uk/products/SWLINUX/
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
7 * S3C24XX CPU Support 7 * Common code for S3C24XX machines
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@
41#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
42#include <asm/mach/map.h> 42#include <asm/mach/map.h>
43 43
44#include <mach/regs-clock.h>
44#include <mach/regs-gpio.h> 45#include <mach/regs-gpio.h>
45#include <plat/regs-serial.h> 46#include <plat/regs-serial.h>
46 47
@@ -52,6 +53,8 @@
52#include <plat/s3c2416.h> 53#include <plat/s3c2416.h>
53#include <plat/s3c244x.h> 54#include <plat/s3c244x.h>
54#include <plat/s3c2443.h> 55#include <plat/s3c2443.h>
56#include <plat/cpu-freq.h>
57#include <plat/pll.h>
55 58
56/* table of supported CPUs */ 59/* table of supported CPUs */
57 60
@@ -234,3 +237,67 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
234 237
235 s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids)); 238 s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
236} 239}
240
241/* Serial port registrations */
242
243static struct resource s3c2410_uart0_resource[] = {
244 [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K),
245 [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \
246 IRQ_S3CUART_ERR0 - IRQ_S3CUART_RX0 + 1, \
247 NULL, IORESOURCE_IRQ)
248};
249
250static struct resource s3c2410_uart1_resource[] = {
251 [0] = DEFINE_RES_MEM(S3C2410_PA_UART1, SZ_16K),
252 [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX1, \
253 IRQ_S3CUART_ERR1 - IRQ_S3CUART_RX1 + 1, \
254 NULL, IORESOURCE_IRQ)
255};
256
257static struct resource s3c2410_uart2_resource[] = {
258 [0] = DEFINE_RES_MEM(S3C2410_PA_UART2, SZ_16K),
259 [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX2, \
260 IRQ_S3CUART_ERR2 - IRQ_S3CUART_RX2 + 1, \
261 NULL, IORESOURCE_IRQ)
262};
263
264static struct resource s3c2410_uart3_resource[] = {
265 [0] = DEFINE_RES_MEM(S3C2443_PA_UART3, SZ_16K),
266 [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX3, \
267 IRQ_S3CUART_ERR3 - IRQ_S3CUART_RX3 + 1, \
268 NULL, IORESOURCE_IRQ)
269};
270
271struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
272 [0] = {
273 .resources = s3c2410_uart0_resource,
274 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
275 },
276 [1] = {
277 .resources = s3c2410_uart1_resource,
278 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
279 },
280 [2] = {
281 .resources = s3c2410_uart2_resource,
282 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
283 },
284 [3] = {
285 .resources = s3c2410_uart3_resource,
286 .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
287 },
288};
289
290/* initialise all the clocks */
291
292void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
293 unsigned long hclk,
294 unsigned long pclk)
295{
296 clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
297 clk_xtal.rate);
298
299 clk_mpll.rate = fclk;
300 clk_h.rate = hclk;
301 clk_p.rate = pclk;
302 clk_f.rate = fclk;
303}
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c
index e227c472a40..2d94228d286 100644
--- a/arch/arm/mach-s3c24xx/dma-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/dma-s3c2443.c
@@ -55,12 +55,20 @@ static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
55 .name = "sdi", 55 .name = "sdi",
56 .channels = MAP(S3C2443_DMAREQSEL_SDI), 56 .channels = MAP(S3C2443_DMAREQSEL_SDI),
57 }, 57 },
58 [DMACH_SPI0] = { 58 [DMACH_SPI0_RX] = {
59 .name = "spi0", 59 .name = "spi0-rx",
60 .channels = MAP(S3C2443_DMAREQSEL_SPI0RX),
61 },
62 [DMACH_SPI0_TX] = {
63 .name = "spi0-tx",
60 .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), 64 .channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
61 }, 65 },
62 [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */ 66 [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */
63 .name = "spi1", 67 .name = "spi1-rx",
68 .channels = MAP(S3C2443_DMAREQSEL_SPI1RX),
69 },
70 [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */
71 .name = "spi1-tx",
64 .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), 72 .channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
65 }, 73 },
66 [DMACH_UART0] = { 74 [DMACH_UART0] = {
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
index acbdfecd418..454831b6603 100644
--- a/arch/arm/mach-s3c24xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -47,6 +47,10 @@ enum dma_ch {
47 DMACH_UART2_SRC2, 47 DMACH_UART2_SRC2,
48 DMACH_UART3, /* s3c2443 has extra uart */ 48 DMACH_UART3, /* s3c2443 has extra uart */
49 DMACH_UART3_SRC2, 49 DMACH_UART3_SRC2,
50 DMACH_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */
51 DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */
52 DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */
53 DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */
50 DMACH_MAX, /* the end entry */ 54 DMACH_MAX, /* the end entry */
51}; 55};
52 56
diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
index 78ae807f128..8ba381f2dbe 100644
--- a/arch/arm/mach-s3c24xx/include/mach/map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -98,6 +98,8 @@
98 98
99/* SPI */ 99/* SPI */
100#define S3C2410_PA_SPI (0x59000000) 100#define S3C2410_PA_SPI (0x59000000)
101#define S3C2443_PA_SPI0 (0x52000000)
102#define S3C2443_PA_SPI1 S3C2410_PA_SPI
101 103
102/* SDI */ 104/* SDI */
103#define S3C2410_PA_SDI (0x5A000000) 105#define S3C2410_PA_SDI (0x5A000000)
@@ -162,4 +164,7 @@
162#define S3C_PA_WDT S3C2410_PA_WATCHDOG 164#define S3C_PA_WDT S3C2410_PA_WATCHDOG
163#define S3C_PA_NAND S3C24XX_PA_NAND 165#define S3C_PA_NAND S3C24XX_PA_NAND
164 166
167#define S3C_PA_SPI0 S3C2443_PA_SPI0
168#define S3C_PA_SPI1 S3C2443_PA_SPI1
169
165#endif /* __ASM_ARCH_MAP_H */ 170#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
index 0efb2e2848c..0efb2e2848c 100644
--- a/arch/arm/plat-s3c24xx/irq-pm.c
+++ b/arch/arm/mach-s3c24xx/irq-pm.c
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 60627e63a25..60627e63a25 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
diff --git a/arch/arm/mach-s3c24xx/setup-spi.c b/arch/arm/mach-s3c24xx/setup-spi.c
new file mode 100644
index 00000000000..5712c85f39b
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-spi.c
@@ -0,0 +1,39 @@
1/*
2 * HS-SPI device setup for S3C2443/S3C2416
3 *
4 * Copyright (C) 2011 Samsung Electronics Ltd.
5 * http://www.samsung.com/
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#include <linux/gpio.h>
13#include <linux/platform_device.h>
14
15#include <plat/gpio-cfg.h>
16#include <plat/s3c64xx-spi.h>
17
18#include <mach/hardware.h>
19#include <mach/regs-gpio.h>
20
21#ifdef CONFIG_S3C64XX_DEV_SPI0
22struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
23 .fifo_lvl_mask = 0x7f,
24 .rx_lvl_offset = 13,
25 .tx_st_done = 21,
26 .high_speed = 1,
27};
28
29int s3c64xx_spi0_cfg_gpio(struct platform_device *pdev)
30{
31 /* enable hsspi bit in misccr */
32 s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1);
33
34 s3c_gpio_cfgall_range(S3C2410_GPE(11), 3,
35 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
36
37 return 0;
38}
39#endif
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S
index c56612569b4..c56612569b4 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/mach-s3c24xx/sleep.S
diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c
index b313380342a..be746e33e86 100644
--- a/arch/arm/mach-s3c64xx/common.c
+++ b/arch/arm/mach-s3c64xx/common.c
@@ -384,3 +384,8 @@ void s3c64xx_restart(char mode, const char *cmd)
384 /* if all else fails, or mode was for soft, jump to 0 */ 384 /* if all else fails, or mode was for soft, jump to 0 */
385 soft_restart(0); 385 soft_restart(0);
386} 386}
387
388void __init s3c64xx_init_late(void)
389{
390 s3c64xx_pm_late_initcall();
391}
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
index 7a10be629ab..6cfc99bdfb3 100644
--- a/arch/arm/mach-s3c64xx/common.h
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -24,6 +24,7 @@ void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
24void s3c64xx_setup_clocks(void); 24void s3c64xx_setup_clocks(void);
25 25
26void s3c64xx_restart(char mode, const char *cmd); 26void s3c64xx_restart(char mode, const char *cmd);
27void s3c64xx_init_late(void);
27 28
28#ifdef CONFIG_CPU_S3C6400 29#ifdef CONFIG_CPU_S3C6400
29 30
@@ -51,4 +52,10 @@ extern void s3c6410_init_clocks(int xtal);
51#define s3c6410_init NULL 52#define s3c6410_init NULL
52#endif 53#endif
53 54
55#ifdef CONFIG_PM
56int __init s3c64xx_pm_late_initcall(void);
57#else
58static inline int s3c64xx_pm_late_initcall(void) { return 0; }
59#endif
60
54#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ 61#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index f252691fb20..314df0518af 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -230,6 +230,7 @@ MACHINE_START(ANW6410, "A&W6410")
230 .handle_irq = vic_handle_irq, 230 .handle_irq = vic_handle_irq,
231 .map_io = anw6410_map_io, 231 .map_io = anw6410_map_io,
232 .init_machine = anw6410_machine_init, 232 .init_machine = anw6410_machine_init,
233 .init_late = s3c64xx_init_late,
233 .timer = &s3c24xx_timer, 234 .timer = &s3c24xx_timer,
234 .restart = s3c64xx_restart, 235 .restart = s3c64xx_restart,
235MACHINE_END 236MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index aa1137fb47e..eda5e027b10 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -813,6 +813,7 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
813 .handle_irq = vic_handle_irq, 813 .handle_irq = vic_handle_irq,
814 .map_io = crag6410_map_io, 814 .map_io = crag6410_map_io,
815 .init_machine = crag6410_machine_init, 815 .init_machine = crag6410_machine_init,
816 .init_late = s3c64xx_init_late,
816 .timer = &s3c24xx_timer, 817 .timer = &s3c24xx_timer,
817 .restart = s3c64xx_restart, 818 .restart = s3c64xx_restart,
818MACHINE_END 819MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 521e07b8501..1bf6b9da20f 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -272,6 +272,7 @@ MACHINE_START(HMT, "Airgoo-HMT")
272 .handle_irq = vic_handle_irq, 272 .handle_irq = vic_handle_irq,
273 .map_io = hmt_map_io, 273 .map_io = hmt_map_io,
274 .init_machine = hmt_machine_init, 274 .init_machine = hmt_machine_init,
275 .init_late = s3c64xx_init_late,
275 .timer = &s3c24xx_timer, 276 .timer = &s3c24xx_timer,
276 .restart = s3c64xx_restart, 277 .restart = s3c64xx_restart,
277MACHINE_END 278MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index b2166d4a553..f8ea61ea3b3 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -339,6 +339,7 @@ MACHINE_START(MINI6410, "MINI6410")
339 .handle_irq = vic_handle_irq, 339 .handle_irq = vic_handle_irq,
340 .map_io = mini6410_map_io, 340 .map_io = mini6410_map_io,
341 .init_machine = mini6410_machine_init, 341 .init_machine = mini6410_machine_init,
342 .init_late = s3c64xx_init_late,
342 .timer = &s3c24xx_timer, 343 .timer = &s3c24xx_timer,
343 .restart = s3c64xx_restart, 344 .restart = s3c64xx_restart,
344MACHINE_END 345MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 0efa2ba783b..cad2e05eddf 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -104,6 +104,7 @@ MACHINE_START(NCP, "NCP")
104 .handle_irq = vic_handle_irq, 104 .handle_irq = vic_handle_irq,
105 .map_io = ncp_map_io, 105 .map_io = ncp_map_io,
106 .init_machine = ncp_machine_init, 106 .init_machine = ncp_machine_init,
107 .init_late = s3c64xx_init_late,
107 .timer = &s3c24xx_timer, 108 .timer = &s3c24xx_timer,
108 .restart = s3c64xx_restart, 109 .restart = s3c64xx_restart,
109MACHINE_END 110MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 5c08266cea2..b92d8e17d50 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -320,6 +320,7 @@ MACHINE_START(REAL6410, "REAL6410")
320 .handle_irq = vic_handle_irq, 320 .handle_irq = vic_handle_irq,
321 .map_io = real6410_map_io, 321 .map_io = real6410_map_io,
322 .init_machine = real6410_machine_init, 322 .init_machine = real6410_machine_init,
323 .init_late = s3c64xx_init_late,
323 .timer = &s3c24xx_timer, 324 .timer = &s3c24xx_timer,
324 .restart = s3c64xx_restart, 325 .restart = s3c64xx_restart,
325MACHINE_END 326MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index 3f42431d4dd..c5021d0335c 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -152,6 +152,7 @@ MACHINE_START(SMARTQ5, "SmartQ 5")
152 .handle_irq = vic_handle_irq, 152 .handle_irq = vic_handle_irq,
153 .map_io = smartq_map_io, 153 .map_io = smartq_map_io,
154 .init_machine = smartq5_machine_init, 154 .init_machine = smartq5_machine_init,
155 .init_late = s3c64xx_init_late,
155 .timer = &s3c24xx_timer, 156 .timer = &s3c24xx_timer,
156 .restart = s3c64xx_restart, 157 .restart = s3c64xx_restart,
157MACHINE_END 158MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index e5c09b6db96..aa9072a4cbe 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -168,6 +168,7 @@ MACHINE_START(SMARTQ7, "SmartQ 7")
168 .handle_irq = vic_handle_irq, 168 .handle_irq = vic_handle_irq,
169 .map_io = smartq_map_io, 169 .map_io = smartq_map_io,
170 .init_machine = smartq7_machine_init, 170 .init_machine = smartq7_machine_init,
171 .init_late = s3c64xx_init_late,
171 .timer = &s3c24xx_timer, 172 .timer = &s3c24xx_timer,
172 .restart = s3c64xx_restart, 173 .restart = s3c64xx_restart,
173MACHINE_END 174MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index 5f096534f4c..b0f4525c66b 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6400.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -93,6 +93,7 @@ MACHINE_START(SMDK6400, "SMDK6400")
93 .handle_irq = vic_handle_irq, 93 .handle_irq = vic_handle_irq,
94 .map_io = smdk6400_map_io, 94 .map_io = smdk6400_map_io,
95 .init_machine = smdk6400_machine_init, 95 .init_machine = smdk6400_machine_init,
96 .init_late = s3c64xx_init_late,
96 .timer = &s3c24xx_timer, 97 .timer = &s3c24xx_timer,
97 .restart = s3c64xx_restart, 98 .restart = s3c64xx_restart,
98MACHINE_END 99MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 7da044f738a..d44319b0941 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -702,6 +702,7 @@ MACHINE_START(SMDK6410, "SMDK6410")
702 .handle_irq = vic_handle_irq, 702 .handle_irq = vic_handle_irq,
703 .map_io = smdk6410_map_io, 703 .map_io = smdk6410_map_io,
704 .init_machine = smdk6410_machine_init, 704 .init_machine = smdk6410_machine_init,
705 .init_late = s3c64xx_init_late,
705 .timer = &s3c24xx_timer, 706 .timer = &s3c24xx_timer,
706 .restart = s3c64xx_restart, 707 .restart = s3c64xx_restart,
707MACHINE_END 708MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 7d3e81b9dd0..7feb426fc20 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -365,10 +365,9 @@ static __init int s3c64xx_pm_initcall(void)
365} 365}
366arch_initcall(s3c64xx_pm_initcall); 366arch_initcall(s3c64xx_pm_initcall);
367 367
368static __init int s3c64xx_pm_late_initcall(void) 368int __init s3c64xx_pm_late_initcall(void)
369{ 369{
370 pm_genpd_poweroff_unused(); 370 pm_genpd_poweroff_unused();
371 371
372 return 0; 372 return 0;
373} 373}
374late_initcall(s3c64xx_pm_late_initcall);
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 375d3f779a8..d1dc7f1a239 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -538,6 +538,7 @@ MACHINE_START(ASSABET, "Intel-Assabet")
538 .init_irq = sa1100_init_irq, 538 .init_irq = sa1100_init_irq,
539 .timer = &sa1100_timer, 539 .timer = &sa1100_timer,
540 .init_machine = assabet_init, 540 .init_machine = assabet_init,
541 .init_late = sa11x0_init_late,
541#ifdef CONFIG_SA1111 542#ifdef CONFIG_SA1111
542 .dma_zone_size = SZ_1M, 543 .dma_zone_size = SZ_1M,
543#endif 544#endif
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index e0f0c030258..b30fb99b587 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -305,6 +305,7 @@ MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
305 .map_io = badge4_map_io, 305 .map_io = badge4_map_io,
306 .nr_irqs = SA1100_NR_IRQS, 306 .nr_irqs = SA1100_NR_IRQS,
307 .init_irq = sa1100_init_irq, 307 .init_irq = sa1100_init_irq,
308 .init_late = sa11x0_init_late,
308 .timer = &sa1100_timer, 309 .timer = &sa1100_timer,
309#ifdef CONFIG_SA1111 310#ifdef CONFIG_SA1111
310 .dma_zone_size = SZ_1M, 311 .dma_zone_size = SZ_1M,
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 4a61f60e050..09d7f4b4b35 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -134,5 +134,6 @@ MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
134 .init_irq = cerf_init_irq, 134 .init_irq = cerf_init_irq,
135 .timer = &sa1100_timer, 135 .timer = &sa1100_timer,
136 .init_machine = cerf_init, 136 .init_machine = cerf_init,
137 .init_late = sa11x0_init_late,
137 .restart = sa11x0_restart, 138 .restart = sa11x0_restart,
138MACHINE_END 139MACHINE_END
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index c7f418b0cde..ea5cff38745 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -401,5 +401,6 @@ MACHINE_START(COLLIE, "Sharp-Collie")
401 .init_irq = sa1100_init_irq, 401 .init_irq = sa1100_init_irq,
402 .timer = &sa1100_timer, 402 .timer = &sa1100_timer,
403 .init_machine = collie_init, 403 .init_machine = collie_init,
404 .init_late = sa11x0_init_late,
404 .restart = sa11x0_restart, 405 .restart = sa11x0_restart,
405MACHINE_END 406MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 16be4c56abe..9db3e98e8b8 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -359,6 +359,10 @@ static int __init sa1100_init(void)
359 359
360arch_initcall(sa1100_init); 360arch_initcall(sa1100_init);
361 361
362void __init sa11x0_init_late(void)
363{
364 sa11x0_pm_init();
365}
362 366
363/* 367/*
364 * Common I/O mapping: 368 * Common I/O mapping:
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 9eb3b3cd5a6..a5b7c13da3e 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -11,6 +11,7 @@ extern void __init sa1100_map_io(void);
11extern void __init sa1100_init_irq(void); 11extern void __init sa1100_init_irq(void);
12extern void __init sa1100_init_gpio(void); 12extern void __init sa1100_init_gpio(void);
13extern void sa11x0_restart(char, const char *); 13extern void sa11x0_restart(char, const char *);
14extern void sa11x0_init_late(void);
14 15
15#define SET_BANK(__nr,__start,__size) \ 16#define SET_BANK(__nr,__start,__size) \
16 mi->bank[__nr].start = (__start), \ 17 mi->bank[__nr].start = (__start), \
@@ -41,3 +42,9 @@ void sa11x0_register_mcp(struct mcp_plat_data *data);
41 42
42struct sa1100fb_mach_info; 43struct sa1100fb_mach_info;
43void sa11x0_register_lcd(struct sa1100fb_mach_info *inf); 44void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
45
46#ifdef CONFIG_PM
47int sa11x0_pm_init(void);
48#else
49static inline int sa11x0_pm_init(void) { return 0; }
50#endif
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index b2e8d0f418e..e1571eab08a 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -110,6 +110,7 @@ MACHINE_START(H3100, "Compaq iPAQ H3100")
110 .init_irq = sa1100_init_irq, 110 .init_irq = sa1100_init_irq,
111 .timer = &sa1100_timer, 111 .timer = &sa1100_timer,
112 .init_machine = h3100_mach_init, 112 .init_machine = h3100_mach_init,
113 .init_late = sa11x0_init_late,
113 .restart = sa11x0_restart, 114 .restart = sa11x0_restart,
114MACHINE_END 115MACHINE_END
115 116
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index cb6659f294f..ba7a2901ab8 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -160,6 +160,7 @@ MACHINE_START(H3600, "Compaq iPAQ H3600")
160 .init_irq = sa1100_init_irq, 160 .init_irq = sa1100_init_irq,
161 .timer = &sa1100_timer, 161 .timer = &sa1100_timer,
162 .init_machine = h3600_mach_init, 162 .init_machine = h3600_mach_init,
163 .init_late = sa11x0_init_late,
163 .restart = sa11x0_restart, 164 .restart = sa11x0_restart,
164MACHINE_END 165MACHINE_END
165 166
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 5535475bf58..7f86bd91182 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -199,5 +199,6 @@ MACHINE_START(HACKKIT, "HackKit Cpu Board")
199 .init_irq = sa1100_init_irq, 199 .init_irq = sa1100_init_irq,
200 .timer = &sa1100_timer, 200 .timer = &sa1100_timer,
201 .init_machine = hackkit_init, 201 .init_machine = hackkit_init,
202 .init_late = sa11x0_init_late,
202 .restart = sa11x0_restart, 203 .restart = sa11x0_restart,
203MACHINE_END 204MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index ca7a7e83472..e3084f47027 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -348,6 +348,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
348 .init_irq = sa1100_init_irq, 348 .init_irq = sa1100_init_irq,
349 .timer = &sa1100_timer, 349 .timer = &sa1100_timer,
350 .init_machine = jornada720_mach_init, 350 .init_machine = jornada720_mach_init,
351 .init_late = sa11x0_init_late,
351#ifdef CONFIG_SA1111 352#ifdef CONFIG_SA1111
352 .dma_zone_size = SZ_1M, 353 .dma_zone_size = SZ_1M,
353#endif 354#endif
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index eb6534e0b0d..b775a0abec0 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -147,6 +147,7 @@ MACHINE_START(LART, "LART")
147 .nr_irqs = SA1100_NR_IRQS, 147 .nr_irqs = SA1100_NR_IRQS,
148 .init_irq = sa1100_init_irq, 148 .init_irq = sa1100_init_irq,
149 .init_machine = lart_init, 149 .init_machine = lart_init,
150 .init_late = sa11x0_init_late,
150 .timer = &sa1100_timer, 151 .timer = &sa1100_timer,
151 .restart = sa11x0_restart, 152 .restart = sa11x0_restart,
152MACHINE_END 153MACHINE_END
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 8f6446b9f02..41f69d97066 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -112,5 +112,6 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine")
112 .init_irq = sa1100_init_irq, 112 .init_irq = sa1100_init_irq,
113 .timer = &sa1100_timer, 113 .timer = &sa1100_timer,
114 .init_machine = nanoengine_init, 114 .init_machine = nanoengine_init,
115 .init_late = sa11x0_init_late,
115 .restart = sa11x0_restart, 116 .restart = sa11x0_restart,
116MACHINE_END 117MACHINE_END
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 6c58f01b358..266db873a4e 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -89,6 +89,7 @@ void neponset_ncr_frob(unsigned int mask, unsigned int val)
89 WARN(1, "nep_base unset\n"); 89 WARN(1, "nep_base unset\n");
90 } 90 }
91} 91}
92EXPORT_SYMBOL(neponset_ncr_frob);
92 93
93static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) 94static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
94{ 95{
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 1602575a0d5..37fe0a0a536 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -135,5 +135,6 @@ MACHINE_START(PLEB, "PLEB")
135 .init_irq = sa1100_init_irq, 135 .init_irq = sa1100_init_irq,
136 .timer = &sa1100_timer, 136 .timer = &sa1100_timer,
137 .init_machine = pleb_init, 137 .init_machine = pleb_init,
138 .init_late = sa11x0_init_late,
138 .restart = sa11x0_restart, 139 .restart = sa11x0_restart,
139MACHINE_END 140MACHINE_END
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 2fa499ec6af..690cf0ce5c0 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -117,10 +117,8 @@ static const struct platform_suspend_ops sa11x0_pm_ops = {
117 .valid = suspend_valid_only_mem, 117 .valid = suspend_valid_only_mem,
118}; 118};
119 119
120static int __init sa11x0_pm_init(void) 120int __init sa11x0_pm_init(void)
121{ 121{
122 suspend_set_ops(&sa11x0_pm_ops); 122 suspend_set_ops(&sa11x0_pm_ops);
123 return 0; 123 return 0;
124} 124}
125
126late_initcall(sa11x0_pm_init);
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index ca8bf59b904..5d33fc3108e 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -104,5 +104,6 @@ MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
104 .init_irq = sa1100_init_irq, 104 .init_irq = sa1100_init_irq,
105 .timer = &sa1100_timer, 105 .timer = &sa1100_timer,
106 .init_machine = shannon_init, 106 .init_machine = shannon_init,
107 .init_late = sa11x0_init_late,
107 .restart = sa11x0_restart, 108 .restart = sa11x0_restart,
108MACHINE_END 109MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 3efae03cb3d..fbd53593be5 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -395,6 +395,7 @@ MACHINE_START(SIMPAD, "Simpad")
395 .map_io = simpad_map_io, 395 .map_io = simpad_map_io,
396 .nr_irqs = SA1100_NR_IRQS, 396 .nr_irqs = SA1100_NR_IRQS,
397 .init_irq = sa1100_init_irq, 397 .init_irq = sa1100_init_irq,
398 .init_late = sa11x0_init_late,
398 .timer = &sa1100_timer, 399 .timer = &sa1100_timer,
399 .restart = sa11x0_restart, 400 .restart = sa11x0_restart,
400MACHINE_END 401MACHINE_END
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e6b177bc941..8aa1962c22a 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common objects 5# Common objects
6obj-y := timer.o console.o clock.o 6obj-y := timer.o console.o clock.o common.o
7 7
8# CPU objects 8# CPU objects
9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o 9obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 0891ec6e27f..5a6f22f05e9 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -580,5 +580,6 @@ MACHINE_START(AG5EVM, "ag5evm")
580 .init_irq = sh73a0_init_irq, 580 .init_irq = sh73a0_init_irq,
581 .handle_irq = gic_handle_irq, 581 .handle_irq = gic_handle_irq,
582 .init_machine = ag5evm_init, 582 .init_machine = ag5evm_init,
583 .init_late = shmobile_init_late,
583 .timer = &shmobile_timer, 584 .timer = &shmobile_timer,
584MACHINE_END 585MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index b540b8eb20c..ace60246a5d 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1469,5 +1469,6 @@ MACHINE_START(AP4EVB, "ap4evb")
1469 .init_irq = sh7372_init_irq, 1469 .init_irq = sh7372_init_irq,
1470 .handle_irq = shmobile_handle_irq_intc, 1470 .handle_irq = shmobile_handle_irq_intc,
1471 .init_machine = ap4evb_init, 1471 .init_machine = ap4evb_init,
1472 .init_late = shmobile_init_late,
1472 .timer = &shmobile_timer, 1473 .timer = &shmobile_timer,
1473MACHINE_END 1474MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index 63ab7062bee..e9b32cfbf74 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -500,5 +500,6 @@ MACHINE_START(BONITO, "bonito")
500 .init_irq = r8a7740_init_irq, 500 .init_irq = r8a7740_init_irq,
501 .handle_irq = shmobile_handle_irq_intc, 501 .handle_irq = shmobile_handle_irq_intc,
502 .init_machine = bonito_init, 502 .init_machine = bonito_init,
503 .init_late = shmobile_init_late,
503 .timer = &shmobile_timer, 504 .timer = &shmobile_timer,
504MACHINE_END 505MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 39b6cf85ced..796fa00ad3c 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -338,5 +338,6 @@ MACHINE_START(G3EVM, "g3evm")
338 .init_irq = sh7367_init_irq, 338 .init_irq = sh7367_init_irq,
339 .handle_irq = shmobile_handle_irq_intc, 339 .handle_irq = shmobile_handle_irq_intc,
340 .init_machine = g3evm_init, 340 .init_machine = g3evm_init,
341 .init_late = shmobile_init_late,
341 .timer = &shmobile_timer, 342 .timer = &shmobile_timer,
342MACHINE_END 343MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 0e5a39c670b..f1257321999 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -381,5 +381,6 @@ MACHINE_START(G4EVM, "g4evm")
381 .init_irq = sh7377_init_irq, 381 .init_irq = sh7377_init_irq,
382 .handle_irq = shmobile_handle_irq_intc, 382 .handle_irq = shmobile_handle_irq_intc,
383 .init_machine = g4evm_init, 383 .init_machine = g4evm_init,
384 .init_late = shmobile_init_late,
384 .timer = &shmobile_timer, 385 .timer = &shmobile_timer,
385MACHINE_END 386MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 200dcd42a3a..f60f1b281cc 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -521,5 +521,6 @@ MACHINE_START(KOTA2, "kota2")
521 .init_irq = sh73a0_init_irq, 521 .init_irq = sh73a0_init_irq,
522 .handle_irq = gic_handle_irq, 522 .handle_irq = gic_handle_irq,
523 .init_machine = kota2_init, 523 .init_machine = kota2_init,
524 .init_late = shmobile_init_late,
524 .timer = &shmobile_timer, 525 .timer = &shmobile_timer,
525MACHINE_END 526MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 50c67b22d08..b577f7c4467 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -1638,5 +1638,6 @@ MACHINE_START(MACKEREL, "mackerel")
1638 .init_irq = sh7372_init_irq, 1638 .init_irq = sh7372_init_irq,
1639 .handle_irq = shmobile_handle_irq_intc, 1639 .handle_irq = shmobile_handle_irq_intc,
1640 .init_machine = mackerel_init, 1640 .init_machine = mackerel_init,
1641 .init_late = shmobile_init_late,
1641 .timer = &shmobile_timer, 1642 .timer = &shmobile_timer,
1642MACHINE_END 1643MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index ef0e13bf0b3..14de3787caf 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -98,5 +98,6 @@ MACHINE_START(MARZEN, "marzen")
98 .init_irq = r8a7779_init_irq, 98 .init_irq = r8a7779_init_irq,
99 .handle_irq = gic_handle_irq, 99 .handle_irq = gic_handle_irq,
100 .init_machine = marzen_init, 100 .init_machine = marzen_init,
101 .init_late = shmobile_init_late,
101 .timer = &shmobile_timer, 102 .timer = &shmobile_timer,
102MACHINE_END 103MACHINE_END
diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c
new file mode 100644
index 00000000000..608aba9d60d
--- /dev/null
+++ b/arch/arm/mach-shmobile/common.c
@@ -0,0 +1,24 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
14 *
15 */
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <mach/common.h>
19
20void __init shmobile_init_late(void)
21{
22 shmobile_suspend_init();
23 shmobile_cpuidle_init();
24}
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 7e6559105d4..7b541e911ab 100644
--- a/arch/arm/mach-shmobile/cpuidle.c
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -46,7 +46,7 @@ static struct cpuidle_driver shmobile_cpuidle_driver = {
46 46
47void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 47void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
48 48
49static int shmobile_cpuidle_init(void) 49int shmobile_cpuidle_init(void)
50{ 50{
51 struct cpuidle_device *dev = &shmobile_cpuidle_dev; 51 struct cpuidle_device *dev = &shmobile_cpuidle_dev;
52 struct cpuidle_driver *drv = &shmobile_cpuidle_driver; 52 struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
@@ -65,4 +65,3 @@ static int shmobile_cpuidle_init(void)
65 65
66 return 0; 66 return 0;
67} 67}
68late_initcall(shmobile_cpuidle_init);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index ff5f12fd742..01e2bc014f1 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -85,4 +85,18 @@ extern int r8a7779_boot_secondary(unsigned int cpu);
85extern void r8a7779_smp_prepare_cpus(void); 85extern void r8a7779_smp_prepare_cpus(void);
86extern void r8a7779_register_twd(void); 86extern void r8a7779_register_twd(void);
87 87
88extern void shmobile_init_late(void);
89
90#ifdef CONFIG_SUSPEND
91int shmobile_suspend_init(void);
92#else
93static inline int shmobile_suspend_init(void) { return 0; }
94#endif
95
96#ifdef CONFIG_CPU_IDLE
97int shmobile_cpuidle_init(void);
98#else
99static inline int shmobile_cpuidle_init(void) { return 0; }
100#endif
101
88#endif /* __ARCH_MACH_COMMON_H */ 102#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
index 4d1b86a4992..47d83f7a70b 100644
--- a/arch/arm/mach-shmobile/suspend.c
+++ b/arch/arm/mach-shmobile/suspend.c
@@ -39,9 +39,8 @@ struct platform_suspend_ops shmobile_suspend_ops = {
39 .valid = suspend_valid_only_mem, 39 .valid = suspend_valid_only_mem,
40}; 40};
41 41
42static int __init shmobile_suspend_init(void) 42int __init shmobile_suspend_init(void)
43{ 43{
44 suspend_set_ops(&shmobile_suspend_ops); 44 suspend_set_ops(&shmobile_suspend_ops);
45 return 0; 45 return 0;
46} 46}
47late_initcall(shmobile_suspend_init);
diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
new file mode 100644
index 00000000000..eaadc66d96b
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -0,0 +1,20 @@
1#
2# SPEAr13XX Machine configuration file
3#
4
5if ARCH_SPEAR13XX
6
7menu "SPEAr13xx Implementations"
8config MACH_SPEAR1310
9 bool "SPEAr1310 Machine support with Device Tree"
10 select PINCTRL_SPEAR1310
11 help
12 Supports ST SPEAr1310 machine configured via the device-tree
13
14config MACH_SPEAR1340
15 bool "SPEAr1340 Machine support with Device Tree"
16 select PINCTRL_SPEAR1340
17 help
18 Supports ST SPEAr1340 machine configured via the device-tree
19endmenu
20endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
new file mode 100644
index 00000000000..3435ea78c15
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for SPEAr13XX machine series
3#
4
5obj-$(CONFIG_SMP) += headsmp.o platsmp.o
6obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
7
8obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o
9obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o
10obj-$(CONFIG_MACH_SPEAR1340) += spear1340.o
diff --git a/arch/arm/mach-spear13xx/Makefile.boot b/arch/arm/mach-spear13xx/Makefile.boot
new file mode 100644
index 00000000000..403efd7e6d2
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile.boot
@@ -0,0 +1,6 @@
1zreladdr-y += 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
4
5dtb-$(CONFIG_MACH_SPEAR1310) += spear1310-evb.dtb
6dtb-$(CONFIG_MACH_SPEAR1340) += spear1340-evb.dtb
diff --git a/arch/arm/mach-spear13xx/headsmp.S b/arch/arm/mach-spear13xx/headsmp.S
new file mode 100644
index 00000000000..ed85473a047
--- /dev/null
+++ b/arch/arm/mach-spear13xx/headsmp.S
@@ -0,0 +1,47 @@
1/*
2 * arch/arm/mach-spear13XX/headsmp.S
3 *
4 * Picked from realview
5 * Copyright (c) 2012 ST Microelectronics Limited
6 * Shiraz Hashim <shiraz.hashim@st.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <linux/init.h>
15
16 __INIT
17
18/*
19 * spear13xx specific entry point for secondary CPUs. This provides
20 * a "holding pen" into which all secondary cores are held until we're
21 * ready for them to initialise.
22 */
23ENTRY(spear13xx_secondary_startup)
24 mrc p15, 0, r0, c0, c0, 5
25 and r0, r0, #15
26 adr r4, 1f
27 ldmia r4, {r5, r6}
28 sub r4, r4, r5
29 add r6, r6, r4
30pen: ldr r7, [r6]
31 cmp r7, r0
32 bne pen
33
34 /* re-enable coherency */
35 mrc p15, 0, r0, c1, c0, 1
36 orr r0, r0, #(1 << 6) | (1 << 0)
37 mcr p15, 0, r0, c1, c0, 1
38 /*
39 * we've been released from the holding pen: secondary_stack
40 * should now contain the SVC stack for this core
41 */
42 b secondary_startup
43
44 .align
451: .long .
46 .long pen_release
47ENDPROC(spear13xx_secondary_startup)
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c
new file mode 100644
index 00000000000..5c6867b46d0
--- /dev/null
+++ b/arch/arm/mach-spear13xx/hotplug.c
@@ -0,0 +1,119 @@
1/*
2 * linux/arch/arm/mach-spear13xx/hotplug.c
3 *
4 * Copyright (C) 2012 ST Microelectronics Ltd.
5 * Deepak Sikri <deepak.sikri@st.com>
6 *
7 * based upon linux/arch/arm/mach-realview/hotplug.c
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#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/smp.h>
16#include <asm/cacheflush.h>
17#include <asm/cp15.h>
18#include <asm/smp_plat.h>
19
20extern volatile int pen_release;
21
22static inline void cpu_enter_lowpower(void)
23{
24 unsigned int v;
25
26 flush_cache_all();
27 asm volatile(
28 " mcr p15, 0, %1, c7, c5, 0\n"
29 " dsb\n"
30 /*
31 * Turn off coherency
32 */
33 " mrc p15, 0, %0, c1, c0, 1\n"
34 " bic %0, %0, #0x20\n"
35 " mcr p15, 0, %0, c1, c0, 1\n"
36 " mrc p15, 0, %0, c1, c0, 0\n"
37 " bic %0, %0, %2\n"
38 " mcr p15, 0, %0, c1, c0, 0\n"
39 : "=&r" (v)
40 : "r" (0), "Ir" (CR_C)
41 : "cc", "memory");
42}
43
44static inline void cpu_leave_lowpower(void)
45{
46 unsigned int v;
47
48 asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
49 " orr %0, %0, %1\n"
50 " mcr p15, 0, %0, c1, c0, 0\n"
51 " mrc p15, 0, %0, c1, c0, 1\n"
52 " orr %0, %0, #0x20\n"
53 " mcr p15, 0, %0, c1, c0, 1\n"
54 : "=&r" (v)
55 : "Ir" (CR_C)
56 : "cc");
57}
58
59static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
60{
61 for (;;) {
62 wfi();
63
64 if (pen_release == cpu) {
65 /*
66 * OK, proper wakeup, we're done
67 */
68 break;
69 }
70
71 /*
72 * Getting here, means that we have come out of WFI without
73 * having been woken up - this shouldn't happen
74 *
75 * Just note it happening - when we're woken, we can report
76 * its occurrence.
77 */
78 (*spurious)++;
79 }
80}
81
82int platform_cpu_kill(unsigned int cpu)
83{
84 return 1;
85}
86
87/*
88 * platform-specific code to shutdown a CPU
89 *
90 * Called with IRQs disabled
91 */
92void __cpuinit platform_cpu_die(unsigned int cpu)
93{
94 int spurious = 0;
95
96 /*
97 * we're ready for shutdown now, so do it
98 */
99 cpu_enter_lowpower();
100 platform_do_lowpower(cpu, &spurious);
101
102 /*
103 * bring this CPU back into the world of cache
104 * coherency, and then restore interrupts
105 */
106 cpu_leave_lowpower();
107
108 if (spurious)
109 pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
110}
111
112int platform_cpu_disable(unsigned int cpu)
113{
114 /*
115 * we don't allow CPU 0 to be shutdown (it is still too special
116 * e.g. clock tick interrupts)
117 */
118 return cpu == 0 ? -EPERM : 0;
119}
diff --git a/arch/arm/mach-spear13xx/include/mach/debug-macro.S b/arch/arm/mach-spear13xx/include/mach/debug-macro.S
new file mode 100644
index 00000000000..ea1564609bd
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/debug-macro.S
3 *
4 * Debugging macro include header spear13xx machine family
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear13xx/include/mach/dma.h b/arch/arm/mach-spear13xx/include/mach/dma.h
new file mode 100644
index 00000000000..383ab04dc6c
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/dma.h
@@ -0,0 +1,128 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/dma.h
3 *
4 * DMA information for SPEAr13xx machine family
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_DMA_H
15#define __MACH_DMA_H
16
17/* request id of all the peripherals */
18enum dma_master_info {
19 /* Accessible from only one master */
20 DMA_MASTER_MCIF = 0,
21 DMA_MASTER_FSMC = 1,
22 /* Accessible from both 0 & 1 */
23 DMA_MASTER_MEMORY = 0,
24 DMA_MASTER_ADC = 0,
25 DMA_MASTER_UART0 = 0,
26 DMA_MASTER_SSP0 = 0,
27 DMA_MASTER_I2C0 = 0,
28
29#ifdef CONFIG_MACH_SPEAR1310
30 /* Accessible from only one master */
31 SPEAR1310_DMA_MASTER_JPEG = 1,
32
33 /* Accessible from both 0 & 1 */
34 SPEAR1310_DMA_MASTER_I2S = 0,
35 SPEAR1310_DMA_MASTER_UART1 = 0,
36 SPEAR1310_DMA_MASTER_UART2 = 0,
37 SPEAR1310_DMA_MASTER_UART3 = 0,
38 SPEAR1310_DMA_MASTER_UART4 = 0,
39 SPEAR1310_DMA_MASTER_UART5 = 0,
40 SPEAR1310_DMA_MASTER_I2C1 = 0,
41 SPEAR1310_DMA_MASTER_I2C2 = 0,
42 SPEAR1310_DMA_MASTER_I2C3 = 0,
43 SPEAR1310_DMA_MASTER_I2C4 = 0,
44 SPEAR1310_DMA_MASTER_I2C5 = 0,
45 SPEAR1310_DMA_MASTER_I2C6 = 0,
46 SPEAR1310_DMA_MASTER_I2C7 = 0,
47 SPEAR1310_DMA_MASTER_SSP1 = 0,
48#endif
49
50#ifdef CONFIG_MACH_SPEAR1340
51 /* Accessible from only one master */
52 SPEAR1340_DMA_MASTER_I2S_PLAY = 1,
53 SPEAR1340_DMA_MASTER_I2S_REC = 1,
54 SPEAR1340_DMA_MASTER_I2C1 = 1,
55 SPEAR1340_DMA_MASTER_UART1 = 1,
56
57 /* following are accessible from both master 0 & 1 */
58 SPEAR1340_DMA_MASTER_SPDIF = 0,
59 SPEAR1340_DMA_MASTER_CAM = 1,
60 SPEAR1340_DMA_MASTER_VIDEO_IN = 0,
61 SPEAR1340_DMA_MASTER_MALI = 0,
62#endif
63};
64
65enum request_id {
66 DMA_REQ_ADC = 0,
67 DMA_REQ_SSP0_TX = 4,
68 DMA_REQ_SSP0_RX = 5,
69 DMA_REQ_UART0_TX = 6,
70 DMA_REQ_UART0_RX = 7,
71 DMA_REQ_I2C0_TX = 8,
72 DMA_REQ_I2C0_RX = 9,
73
74#ifdef CONFIG_MACH_SPEAR1310
75 SPEAR1310_DMA_REQ_FROM_JPEG = 2,
76 SPEAR1310_DMA_REQ_TO_JPEG = 3,
77 SPEAR1310_DMA_REQ_I2S_TX = 10,
78 SPEAR1310_DMA_REQ_I2S_RX = 11,
79
80 SPEAR1310_DMA_REQ_I2C1_RX = 0,
81 SPEAR1310_DMA_REQ_I2C1_TX = 1,
82 SPEAR1310_DMA_REQ_I2C2_RX = 2,
83 SPEAR1310_DMA_REQ_I2C2_TX = 3,
84 SPEAR1310_DMA_REQ_I2C3_RX = 4,
85 SPEAR1310_DMA_REQ_I2C3_TX = 5,
86 SPEAR1310_DMA_REQ_I2C4_RX = 6,
87 SPEAR1310_DMA_REQ_I2C4_TX = 7,
88 SPEAR1310_DMA_REQ_I2C5_RX = 8,
89 SPEAR1310_DMA_REQ_I2C5_TX = 9,
90 SPEAR1310_DMA_REQ_I2C6_RX = 10,
91 SPEAR1310_DMA_REQ_I2C6_TX = 11,
92 SPEAR1310_DMA_REQ_UART1_RX = 12,
93 SPEAR1310_DMA_REQ_UART1_TX = 13,
94 SPEAR1310_DMA_REQ_UART2_RX = 14,
95 SPEAR1310_DMA_REQ_UART2_TX = 15,
96 SPEAR1310_DMA_REQ_UART5_RX = 16,
97 SPEAR1310_DMA_REQ_UART5_TX = 17,
98 SPEAR1310_DMA_REQ_SSP1_RX = 18,
99 SPEAR1310_DMA_REQ_SSP1_TX = 19,
100 SPEAR1310_DMA_REQ_I2C7_RX = 20,
101 SPEAR1310_DMA_REQ_I2C7_TX = 21,
102 SPEAR1310_DMA_REQ_UART3_RX = 28,
103 SPEAR1310_DMA_REQ_UART3_TX = 29,
104 SPEAR1310_DMA_REQ_UART4_RX = 30,
105 SPEAR1310_DMA_REQ_UART4_TX = 31,
106#endif
107
108#ifdef CONFIG_MACH_SPEAR1340
109 SPEAR1340_DMA_REQ_SPDIF_TX = 2,
110 SPEAR1340_DMA_REQ_SPDIF_RX = 3,
111 SPEAR1340_DMA_REQ_I2S_TX = 10,
112 SPEAR1340_DMA_REQ_I2S_RX = 11,
113 SPEAR1340_DMA_REQ_UART1_TX = 12,
114 SPEAR1340_DMA_REQ_UART1_RX = 13,
115 SPEAR1340_DMA_REQ_I2C1_TX = 14,
116 SPEAR1340_DMA_REQ_I2C1_RX = 15,
117 SPEAR1340_DMA_REQ_CAM0_EVEN = 0,
118 SPEAR1340_DMA_REQ_CAM0_ODD = 1,
119 SPEAR1340_DMA_REQ_CAM1_EVEN = 2,
120 SPEAR1340_DMA_REQ_CAM1_ODD = 3,
121 SPEAR1340_DMA_REQ_CAM2_EVEN = 4,
122 SPEAR1340_DMA_REQ_CAM2_ODD = 5,
123 SPEAR1340_DMA_REQ_CAM3_EVEN = 6,
124 SPEAR1340_DMA_REQ_CAM3_ODD = 7,
125#endif
126};
127
128#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h
new file mode 100644
index 00000000000..6d8c45b9f29
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -0,0 +1,49 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/generic.h
3 *
4 * spear13xx machine family generic header file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_GENERIC_H
15#define __MACH_GENERIC_H
16
17#include <linux/dmaengine.h>
18#include <asm/mach/time.h>
19
20/* Add spear13xx structure declarations here */
21extern struct sys_timer spear13xx_timer;
22extern struct pl022_ssp_controller pl022_plat_data;
23extern struct dw_dma_platform_data dmac_plat_data;
24extern struct dw_dma_slave cf_dma_priv;
25extern struct dw_dma_slave nand_read_dma_priv;
26extern struct dw_dma_slave nand_write_dma_priv;
27
28/* Add spear13xx family function declarations here */
29void __init spear_setup_of_timer(void);
30void __init spear13xx_map_io(void);
31void __init spear13xx_dt_init_irq(void);
32void __init spear13xx_l2x0_init(void);
33bool dw_dma_filter(struct dma_chan *chan, void *slave);
34void spear_restart(char, const char *);
35void spear13xx_secondary_startup(void);
36
37#ifdef CONFIG_MACH_SPEAR1310
38void __init spear1310_clk_init(void);
39#else
40static inline void spear1310_clk_init(void) {}
41#endif
42
43#ifdef CONFIG_MACH_SPEAR1340
44void __init spear1340_clk_init(void);
45#else
46static inline void spear1340_clk_init(void) {}
47#endif
48
49#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/gpio.h b/arch/arm/mach-spear13xx/include/mach/gpio.h
new file mode 100644
index 00000000000..cd6f4f86a56
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/gpio.h
3 *
4 * GPIO macros for SPEAr13xx machine family
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_GPIO_H
15#define __MACH_GPIO_H
16
17#include <plat/gpio.h>
18
19#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/hardware.h b/arch/arm/mach-spear13xx/include/mach/hardware.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/hardware.h
@@ -0,0 +1 @@
/* empty */
diff --git a/arch/arm/mach-spear13xx/include/mach/irqs.h b/arch/arm/mach-spear13xx/include/mach/irqs.h
new file mode 100644
index 00000000000..f542a24aa5f
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -0,0 +1,20 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/irqs.h
3 *
4 * IRQ helper macros for spear13xx machine family
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_IRQS_H
15#define __MACH_IRQS_H
16
17#define IRQ_GIC_END 160
18#define NR_IRQS IRQ_GIC_END
19
20#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h
new file mode 100644
index 00000000000..30c57ef7268
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -0,0 +1,62 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/spear.h
3 *
4 * spear13xx Machine family specific definition
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_SPEAR13XX_H
15#define __MACH_SPEAR13XX_H
16
17#include <asm/memory.h>
18
19#define PERIP_GRP2_BASE UL(0xB3000000)
20#define VA_PERIP_GRP2_BASE UL(0xFE000000)
21#define MCIF_SDHCI_BASE UL(0xB3000000)
22#define SYSRAM0_BASE UL(0xB3800000)
23#define VA_SYSRAM0_BASE UL(0xFE800000)
24#define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600)
25
26#define PERIP_GRP1_BASE UL(0xE0000000)
27#define VA_PERIP_GRP1_BASE UL(0xFD000000)
28#define UART_BASE UL(0xE0000000)
29#define VA_UART_BASE UL(0xFD000000)
30#define SSP_BASE UL(0xE0100000)
31#define MISC_BASE UL(0xE0700000)
32#define VA_MISC_BASE IOMEM(UL(0xFD700000))
33
34#define A9SM_AND_MPMC_BASE UL(0xEC000000)
35#define VA_A9SM_AND_MPMC_BASE UL(0xFC000000)
36
37/* A9SM peripheral offsets */
38#define A9SM_PERIP_BASE UL(0xEC800000)
39#define VA_A9SM_PERIP_BASE UL(0xFC800000)
40#define VA_SCU_BASE (VA_A9SM_PERIP_BASE + 0x00)
41
42#define L2CC_BASE UL(0xED000000)
43#define VA_L2CC_BASE IOMEM(UL(0xFB000000))
44
45/* others */
46#define DMAC0_BASE UL(0xEA800000)
47#define DMAC1_BASE UL(0xEB000000)
48#define MCIF_CF_BASE UL(0xB2800000)
49
50/* Devices present in SPEAr1310 */
51#ifdef CONFIG_MACH_SPEAR1310
52#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000)
53#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000)
54#define SPEAR1310_RAS_BASE UL(0xD8400000)
55#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000))
56#endif /* CONFIG_MACH_SPEAR1310 */
57
58/* Debug uart for linux, will be used for debug and uncompress messages */
59#define SPEAR_DBG_UART_BASE UART_BASE
60#define VA_SPEAR_DBG_UART_BASE VA_UART_BASE
61
62#endif /* __MACH_SPEAR13XX_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h b/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear1310_misc_regs.h
diff --git a/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h b/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear1340_misc_regs.h
diff --git a/arch/arm/mach-spear13xx/include/mach/timex.h b/arch/arm/mach-spear13xx/include/mach/timex.h
new file mode 100644
index 00000000000..31af3e8d976
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/timex.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-spear3xx/include/mach/timex.h
3 *
4 * SPEAr3XX machine family specific timex definitions
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_TIMEX_H
15#define __MACH_TIMEX_H
16
17#include <plat/timex.h>
18
19#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear13xx/include/mach/uncompress.h b/arch/arm/mach-spear13xx/include/mach/uncompress.h
new file mode 100644
index 00000000000..c7840896ae6
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-spear13xx/include/mach/uncompress.h
3 *
4 * Serial port stubs for kernel decompress status messages
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __MACH_UNCOMPRESS_H
15#define __MACH_UNCOMPRESS_H
16
17#include <plat/uncompress.h>
18
19#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear13xx/platsmp.c b/arch/arm/mach-spear13xx/platsmp.c
new file mode 100644
index 00000000000..f5d07f2663d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -0,0 +1,127 @@
1/*
2 * arch/arm/mach-spear13xx/platsmp.c
3 *
4 * based upon linux/arch/arm/mach-realview/platsmp.c
5 *
6 * Copyright (C) 2012 ST Microelectronics Ltd.
7 * Shiraz Hashim <shiraz.hashim@st.com>
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#include <linux/delay.h>
15#include <linux/jiffies.h>
16#include <linux/io.h>
17#include <linux/smp.h>
18#include <asm/cacheflush.h>
19#include <asm/hardware/gic.h>
20#include <asm/smp_scu.h>
21#include <mach/spear.h>
22
23/*
24 * control for which core is the next to come out of the secondary
25 * boot "holding pen"
26 */
27volatile int __cpuinitdata pen_release = -1;
28static DEFINE_SPINLOCK(boot_lock);
29
30static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
31extern void spear13xx_secondary_startup(void);
32
33void __cpuinit platform_secondary_init(unsigned int cpu)
34{
35 /*
36 * if any interrupts are already enabled for the primary
37 * core (e.g. timer irq), then they will not have been enabled
38 * for us: do so
39 */
40 gic_secondary_init(0);
41
42 /*
43 * let the primary processor know we're out of the
44 * pen, then head off into the C entry point
45 */
46 pen_release = -1;
47 smp_wmb();
48
49 /*
50 * Synchronise with the boot thread.
51 */
52 spin_lock(&boot_lock);
53 spin_unlock(&boot_lock);
54}
55
56int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
57{
58 unsigned long timeout;
59
60 /*
61 * set synchronisation state between this boot processor
62 * and the secondary one
63 */
64 spin_lock(&boot_lock);
65
66 /*
67 * The secondary processor is waiting to be released from
68 * the holding pen - release it, then wait for it to flag
69 * that it has been released by resetting pen_release.
70 *
71 * Note that "pen_release" is the hardware CPU ID, whereas
72 * "cpu" is Linux's internal ID.
73 */
74 pen_release = cpu;
75 flush_cache_all();
76 outer_flush_all();
77
78 timeout = jiffies + (1 * HZ);
79 while (time_before(jiffies, timeout)) {
80 smp_rmb();
81 if (pen_release == -1)
82 break;
83
84 udelay(10);
85 }
86
87 /*
88 * now the secondary core is starting up let it run its
89 * calibrations, then wait for it to finish
90 */
91 spin_unlock(&boot_lock);
92
93 return pen_release != -1 ? -ENOSYS : 0;
94}
95
96/*
97 * Initialise the CPU possible map early - this describes the CPUs
98 * which may be present or become present in the system.
99 */
100void __init smp_init_cpus(void)
101{
102 unsigned int i, ncores = scu_get_core_count(scu_base);
103
104 if (ncores > nr_cpu_ids) {
105 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
106 ncores, nr_cpu_ids);
107 ncores = nr_cpu_ids;
108 }
109
110 for (i = 0; i < ncores; i++)
111 set_cpu_possible(i, true);
112
113 set_smp_cross_call(gic_raise_softirq);
114}
115
116void __init platform_smp_prepare_cpus(unsigned int max_cpus)
117{
118
119 scu_enable(scu_base);
120
121 /*
122 * Write the address of secondary startup into the system-wide location
123 * (presently it is in SRAM). The BootMonitor waits until it receives a
124 * soft interrupt, and then the secondary CPU branches to this address.
125 */
126 __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
127}
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
new file mode 100644
index 00000000000..fefd15b2f38
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -0,0 +1,88 @@
1/*
2 * arch/arm/mach-spear13xx/spear1310.c
3 *
4 * SPEAr1310 machine source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr1310: " fmt
15
16#include <linux/amba/pl022.h>
17#include <linux/of_platform.h>
18#include <asm/hardware/gic.h>
19#include <asm/mach/arch.h>
20#include <asm/mach/map.h>
21#include <mach/generic.h>
22#include <mach/spear.h>
23
24/* Base addresses */
25#define SPEAR1310_SSP1_BASE UL(0x5D400000)
26#define SPEAR1310_SATA0_BASE UL(0xB1000000)
27#define SPEAR1310_SATA1_BASE UL(0xB1800000)
28#define SPEAR1310_SATA2_BASE UL(0xB4000000)
29
30/* ssp device registration */
31static struct pl022_ssp_controller ssp1_plat_data = {
32 .bus_id = 0,
33 .enable_dma = 0,
34 .num_chipselect = 3,
35};
36
37/* Add SPEAr1310 auxdata to pass platform data */
38static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
39 OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
40 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
41 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
42 OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
43
44 OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
45 {}
46};
47
48static void __init spear1310_dt_init(void)
49{
50 of_platform_populate(NULL, of_default_bus_match_table,
51 spear1310_auxdata_lookup, NULL);
52}
53
54static const char * const spear1310_dt_board_compat[] = {
55 "st,spear1310",
56 "st,spear1310-evb",
57 NULL,
58};
59
60/*
61 * Following will create 16MB static virtual/physical mappings
62 * PHYSICAL VIRTUAL
63 * 0xD8000000 0xFA000000
64 */
65struct map_desc spear1310_io_desc[] __initdata = {
66 {
67 .virtual = VA_SPEAR1310_RAS_GRP1_BASE,
68 .pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
69 .length = SZ_16M,
70 .type = MT_DEVICE
71 },
72};
73
74static void __init spear1310_map_io(void)
75{
76 iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
77 spear13xx_map_io();
78}
79
80DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
81 .map_io = spear1310_map_io,
82 .init_irq = spear13xx_dt_init_irq,
83 .handle_irq = gic_handle_irq,
84 .timer = &spear13xx_timer,
85 .init_machine = spear1310_dt_init,
86 .restart = spear_restart,
87 .dt_compat = spear1310_dt_board_compat,
88MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c
new file mode 100644
index 00000000000..ee38cbc5686
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1340.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/mach-spear13xx/spear1340.c
3 *
4 * SPEAr1340 machine source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr1340: " fmt
15
16#include <linux/ahci_platform.h>
17#include <linux/amba/serial.h>
18#include <linux/delay.h>
19#include <linux/dw_dmac.h>
20#include <linux/of_platform.h>
21#include <asm/hardware/gic.h>
22#include <asm/mach/arch.h>
23#include <mach/dma.h>
24#include <mach/generic.h>
25#include <mach/spear.h>
26
27/* Base addresses */
28#define SPEAR1340_SATA_BASE UL(0xB1000000)
29#define SPEAR1340_UART1_BASE UL(0xB4100000)
30
31/* Power Management Registers */
32#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
33#define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104)
34#define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108)
35
36#define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318)
37#define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C)
38#define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320)
39
40/* PCIE - SATA configuration registers */
41#define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424)
42 /* PCIE CFG MASks */
43 #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11)
44 #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10)
45 #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9)
46 #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8)
47 #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4)
48 #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3)
49 #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2)
50 #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1)
51 #define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
52 #define SPEAR1340_PCIE_SATA_SEL_SATA (1)
53 #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F
54 #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
55 SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
56 SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
57 SPEAR1340_PCIE_CFG_POWERUP_RESET | \
58 SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
59 #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
60 SPEAR1340_SATA_CFG_PM_CLK_EN | \
61 SPEAR1340_SATA_CFG_POWERUP_RESET | \
62 SPEAR1340_SATA_CFG_RX_CLK_EN | \
63 SPEAR1340_SATA_CFG_TX_CLK_EN)
64
65#define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428)
66 #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31)
67 #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27)
68 #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
69 #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
70 #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
71 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
72 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
73 SPEAR1340_MIPHY_CLK_REF_DIV2 | \
74 SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
75 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
76 (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
77 #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
78 (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
79 SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
80
81static struct dw_dma_slave uart1_dma_param[] = {
82 {
83 /* Tx */
84 .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
85 .cfg_lo = 0,
86 .src_master = DMA_MASTER_MEMORY,
87 .dst_master = SPEAR1340_DMA_MASTER_UART1,
88 }, {
89 /* Rx */
90 .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
91 .cfg_lo = 0,
92 .src_master = SPEAR1340_DMA_MASTER_UART1,
93 .dst_master = DMA_MASTER_MEMORY,
94 }
95};
96
97static struct amba_pl011_data uart1_data = {
98 .dma_filter = dw_dma_filter,
99 .dma_tx_param = &uart1_dma_param[0],
100 .dma_rx_param = &uart1_dma_param[1],
101};
102
103/* SATA device registration */
104static int sata_miphy_init(struct device *dev, void __iomem *addr)
105{
106 writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
107 writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
108 SPEAR1340_PCIE_MIPHY_CFG);
109 /* Switch on sata power domain */
110 writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
111 msleep(20);
112 /* Disable PCIE SATA Controller reset */
113 writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
114 SPEAR1340_PERIP1_SW_RST);
115 msleep(20);
116
117 return 0;
118}
119
120void sata_miphy_exit(struct device *dev)
121{
122 writel(0, SPEAR1340_PCIE_SATA_CFG);
123 writel(0, SPEAR1340_PCIE_MIPHY_CFG);
124
125 /* Enable PCIE SATA Controller reset */
126 writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
127 SPEAR1340_PERIP1_SW_RST);
128 msleep(20);
129 /* Switch off sata power domain */
130 writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
131 msleep(20);
132}
133
134int sata_suspend(struct device *dev)
135{
136 if (dev->power.power_state.event == PM_EVENT_FREEZE)
137 return 0;
138
139 sata_miphy_exit(dev);
140
141 return 0;
142}
143
144int sata_resume(struct device *dev)
145{
146 if (dev->power.power_state.event == PM_EVENT_THAW)
147 return 0;
148
149 return sata_miphy_init(dev, NULL);
150}
151
152static struct ahci_platform_data sata_pdata = {
153 .init = sata_miphy_init,
154 .exit = sata_miphy_exit,
155 .suspend = sata_suspend,
156 .resume = sata_resume,
157};
158
159/* Add SPEAr1340 auxdata to pass platform data */
160static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
161 OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
162 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
163 OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
164 OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
165
166 OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
167 &sata_pdata),
168 OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
169 {}
170};
171
172static void __init spear1340_dt_init(void)
173{
174 of_platform_populate(NULL, of_default_bus_match_table,
175 spear1340_auxdata_lookup, NULL);
176}
177
178static const char * const spear1340_dt_board_compat[] = {
179 "st,spear1340",
180 "st,spear1340-evb",
181 NULL,
182};
183
184DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
185 .map_io = spear13xx_map_io,
186 .init_irq = spear13xx_dt_init_irq,
187 .handle_irq = gic_handle_irq,
188 .timer = &spear13xx_timer,
189 .init_machine = spear1340_dt_init,
190 .restart = spear_restart,
191 .dt_compat = spear1340_dt_board_compat,
192MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
new file mode 100644
index 00000000000..50b349ae863
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -0,0 +1,197 @@
1/*
2 * arch/arm/mach-spear13xx/spear13xx.c
3 *
4 * SPEAr13XX machines common source file
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Viresh Kumar <viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#define pr_fmt(fmt) "SPEAr13xx: " fmt
15
16#include <linux/amba/pl022.h>
17#include <linux/clk.h>
18#include <linux/dw_dmac.h>
19#include <linux/err.h>
20#include <linux/of_irq.h>
21#include <asm/hardware/cache-l2x0.h>
22#include <asm/hardware/gic.h>
23#include <asm/mach/map.h>
24#include <asm/smp_twd.h>
25#include <mach/dma.h>
26#include <mach/generic.h>
27#include <mach/spear.h>
28
29/* common dw_dma filter routine to be used by peripherals */
30bool dw_dma_filter(struct dma_chan *chan, void *slave)
31{
32 struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
33
34 if (chan->device->dev == dws->dma_dev) {
35 chan->private = slave;
36 return true;
37 } else {
38 return false;
39 }
40}
41
42/* ssp device registration */
43static struct dw_dma_slave ssp_dma_param[] = {
44 {
45 /* Tx */
46 .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
47 .cfg_lo = 0,
48 .src_master = DMA_MASTER_MEMORY,
49 .dst_master = DMA_MASTER_SSP0,
50 }, {
51 /* Rx */
52 .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
53 .cfg_lo = 0,
54 .src_master = DMA_MASTER_SSP0,
55 .dst_master = DMA_MASTER_MEMORY,
56 }
57};
58
59struct pl022_ssp_controller pl022_plat_data = {
60 .bus_id = 0,
61 .enable_dma = 1,
62 .dma_filter = dw_dma_filter,
63 .dma_rx_param = &ssp_dma_param[1],
64 .dma_tx_param = &ssp_dma_param[0],
65 .num_chipselect = 3,
66};
67
68/* CF device registration */
69struct dw_dma_slave cf_dma_priv = {
70 .cfg_hi = 0,
71 .cfg_lo = 0,
72 .src_master = 0,
73 .dst_master = 0,
74};
75
76/* dmac device registeration */
77struct dw_dma_platform_data dmac_plat_data = {
78 .nr_channels = 8,
79 .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
80 .chan_priority = CHAN_PRIORITY_DESCENDING,
81};
82
83void __init spear13xx_l2x0_init(void)
84{
85 /*
86 * 512KB (64KB/way), 8-way associativity, parity supported
87 *
88 * FIXME: 9th bit, of Auxillary Controller register must be set
89 * for some spear13xx devices for stable L2 operation.
90 *
91 * Enable Early BRESP, L2 prefetch for Instruction and Data,
92 * write alloc and 'Full line of zero' options
93 *
94 */
95
96 writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
97
98 /*
99 * Program following latencies in order to make
100 * SPEAr1340 work at 600 MHz
101 */
102 writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
103 writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
104 l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
105}
106
107/*
108 * Following will create 16MB static virtual/physical mappings
109 * PHYSICAL VIRTUAL
110 * 0xB3000000 0xFE000000
111 * 0xE0000000 0xFD000000
112 * 0xEC000000 0xFC000000
113 * 0xED000000 0xFB000000
114 */
115struct map_desc spear13xx_io_desc[] __initdata = {
116 {
117 .virtual = VA_PERIP_GRP2_BASE,
118 .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
119 .length = SZ_16M,
120 .type = MT_DEVICE
121 }, {
122 .virtual = VA_PERIP_GRP1_BASE,
123 .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
124 .length = SZ_16M,
125 .type = MT_DEVICE
126 }, {
127 .virtual = VA_A9SM_AND_MPMC_BASE,
128 .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
129 .length = SZ_16M,
130 .type = MT_DEVICE
131 }, {
132 .virtual = (unsigned long)VA_L2CC_BASE,
133 .pfn = __phys_to_pfn(L2CC_BASE),
134 .length = SZ_4K,
135 .type = MT_DEVICE
136 },
137};
138
139/* This will create static memory mapping for selected devices */
140void __init spear13xx_map_io(void)
141{
142 iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
143}
144
145static void __init spear13xx_clk_init(void)
146{
147 if (of_machine_is_compatible("st,spear1310"))
148 spear1310_clk_init();
149 else if (of_machine_is_compatible("st,spear1340"))
150 spear1340_clk_init();
151 else
152 pr_err("%s: Unknown machine\n", __func__);
153}
154
155static void __init spear13xx_timer_init(void)
156{
157 char pclk_name[] = "osc_24m_clk";
158 struct clk *gpt_clk, *pclk;
159
160 spear13xx_clk_init();
161
162 /* get the system timer clock */
163 gpt_clk = clk_get_sys("gpt0", NULL);
164 if (IS_ERR(gpt_clk)) {
165 pr_err("%s:couldn't get clk for gpt\n", __func__);
166 BUG();
167 }
168
169 /* get the suitable parent clock for timer*/
170 pclk = clk_get(NULL, pclk_name);
171 if (IS_ERR(pclk)) {
172 pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
173 pclk_name);
174 BUG();
175 }
176
177 clk_set_parent(gpt_clk, pclk);
178 clk_put(gpt_clk);
179 clk_put(pclk);
180
181 spear_setup_of_timer();
182 twd_local_timer_of_register();
183}
184
185struct sys_timer spear13xx_timer = {
186 .init = spear13xx_timer_init,
187};
188
189static const struct of_device_id gic_of_match[] __initconst = {
190 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
191 { /* Sentinel */ }
192};
193
194void __init spear13xx_dt_init_irq(void)
195{
196 of_irq_init(gic_of_match);
197}
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
index 17b5d83cf2d..8d12faa178f 100644
--- a/arch/arm/mach-spear3xx/Makefile
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# common files 5# common files
6obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o clock.o 6obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o
7 7
8# spear300 specific files 8# spear300 specific files
9obj-$(CONFIG_MACH_SPEAR300) += spear300.o 9obj-$(CONFIG_MACH_SPEAR300) += spear300.o
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
deleted file mode 100644
index cd6c1109908..00000000000
--- a/arch/arm/mach-spear3xx/clock.c
+++ /dev/null
@@ -1,892 +0,0 @@
1/*
2 * arch/arm/mach-spear3xx/clock.c
3 *
4 * SPEAr3xx machines clock framework source file
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/clkdev.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/kernel.h>
18#include <linux/of_platform.h>
19#include <asm/mach-types.h>
20#include <plat/clock.h>
21#include <mach/misc_regs.h>
22#include <mach/spear.h>
23
24#define PLL1_CTR (MISC_BASE + 0x008)
25#define PLL1_FRQ (MISC_BASE + 0x00C)
26#define PLL1_MOD (MISC_BASE + 0x010)
27#define PLL2_CTR (MISC_BASE + 0x014)
28/* PLL_CTR register masks */
29#define PLL_ENABLE 2
30#define PLL_MODE_SHIFT 4
31#define PLL_MODE_MASK 0x3
32#define PLL_MODE_NORMAL 0
33#define PLL_MODE_FRACTION 1
34#define PLL_MODE_DITH_DSB 2
35#define PLL_MODE_DITH_SSB 3
36
37#define PLL2_FRQ (MISC_BASE + 0x018)
38/* PLL FRQ register masks */
39#define PLL_DIV_N_SHIFT 0
40#define PLL_DIV_N_MASK 0xFF
41#define PLL_DIV_P_SHIFT 8
42#define PLL_DIV_P_MASK 0x7
43#define PLL_NORM_FDBK_M_SHIFT 24
44#define PLL_NORM_FDBK_M_MASK 0xFF
45#define PLL_DITH_FDBK_M_SHIFT 16
46#define PLL_DITH_FDBK_M_MASK 0xFFFF
47
48#define PLL2_MOD (MISC_BASE + 0x01C)
49#define PLL_CLK_CFG (MISC_BASE + 0x020)
50#define CORE_CLK_CFG (MISC_BASE + 0x024)
51/* CORE CLK CFG register masks */
52#define PLL_HCLK_RATIO_SHIFT 10
53#define PLL_HCLK_RATIO_MASK 0x3
54#define HCLK_PCLK_RATIO_SHIFT 8
55#define HCLK_PCLK_RATIO_MASK 0x3
56
57#define PERIP_CLK_CFG (MISC_BASE + 0x028)
58/* PERIP_CLK_CFG register masks */
59#define UART_CLK_SHIFT 4
60#define UART_CLK_MASK 0x1
61#define FIRDA_CLK_SHIFT 5
62#define FIRDA_CLK_MASK 0x3
63#define GPT0_CLK_SHIFT 8
64#define GPT1_CLK_SHIFT 11
65#define GPT2_CLK_SHIFT 12
66#define GPT_CLK_MASK 0x1
67#define AUX_CLK_PLL3_VAL 0
68#define AUX_CLK_PLL1_VAL 1
69
70#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
71/* PERIP1_CLK_ENB register masks */
72#define UART_CLK_ENB 3
73#define SSP_CLK_ENB 5
74#define I2C_CLK_ENB 7
75#define JPEG_CLK_ENB 8
76#define FIRDA_CLK_ENB 10
77#define GPT1_CLK_ENB 11
78#define GPT2_CLK_ENB 12
79#define ADC_CLK_ENB 15
80#define RTC_CLK_ENB 17
81#define GPIO_CLK_ENB 18
82#define DMA_CLK_ENB 19
83#define SMI_CLK_ENB 21
84#define GMAC_CLK_ENB 23
85#define USBD_CLK_ENB 24
86#define USBH_CLK_ENB 25
87#define C3_CLK_ENB 31
88
89#define RAS_CLK_ENB (MISC_BASE + 0x034)
90
91#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
92#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
93#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
94/* gpt synthesizer register masks */
95#define GPT_MSCALE_SHIFT 0
96#define GPT_MSCALE_MASK 0xFFF
97#define GPT_NSCALE_SHIFT 12
98#define GPT_NSCALE_MASK 0xF
99
100#define AMEM_CLK_CFG (MISC_BASE + 0x050)
101#define EXPI_CLK_CFG (MISC_BASE + 0x054)
102#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
103#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
104#define UART_CLK_SYNT (MISC_BASE + 0x064)
105#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
106#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
107#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
108#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
109#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
110/* aux clk synthesiser register masks for irda to ras4 */
111#define AUX_SYNT_ENB 31
112#define AUX_EQ_SEL_SHIFT 30
113#define AUX_EQ_SEL_MASK 1
114#define AUX_EQ1_SEL 0
115#define AUX_EQ2_SEL 1
116#define AUX_XSCALE_SHIFT 16
117#define AUX_XSCALE_MASK 0xFFF
118#define AUX_YSCALE_SHIFT 0
119#define AUX_YSCALE_MASK 0xFFF
120
121/* root clks */
122/* 32 KHz oscillator clock */
123static struct clk osc_32k_clk = {
124 .flags = ALWAYS_ENABLED,
125 .rate = 32000,
126};
127
128/* 24 MHz oscillator clock */
129static struct clk osc_24m_clk = {
130 .flags = ALWAYS_ENABLED,
131 .rate = 24000000,
132};
133
134/* clock derived from 32 KHz osc clk */
135/* rtc clock */
136static struct clk rtc_clk = {
137 .pclk = &osc_32k_clk,
138 .en_reg = PERIP1_CLK_ENB,
139 .en_reg_bit = RTC_CLK_ENB,
140 .recalc = &follow_parent,
141};
142
143/* clock derived from 24 MHz osc clk */
144/* pll masks structure */
145static struct pll_clk_masks pll1_masks = {
146 .mode_mask = PLL_MODE_MASK,
147 .mode_shift = PLL_MODE_SHIFT,
148 .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
149 .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
150 .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
151 .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
152 .div_p_mask = PLL_DIV_P_MASK,
153 .div_p_shift = PLL_DIV_P_SHIFT,
154 .div_n_mask = PLL_DIV_N_MASK,
155 .div_n_shift = PLL_DIV_N_SHIFT,
156};
157
158/* pll1 configuration structure */
159static struct pll_clk_config pll1_config = {
160 .mode_reg = PLL1_CTR,
161 .cfg_reg = PLL1_FRQ,
162 .masks = &pll1_masks,
163};
164
165/* pll rate configuration table, in ascending order of rates */
166struct pll_rate_tbl pll_rtbl[] = {
167 {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
168 {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
169};
170
171/* PLL1 clock */
172static struct clk pll1_clk = {
173 .flags = ENABLED_ON_INIT,
174 .pclk = &osc_24m_clk,
175 .en_reg = PLL1_CTR,
176 .en_reg_bit = PLL_ENABLE,
177 .calc_rate = &pll_calc_rate,
178 .recalc = &pll_clk_recalc,
179 .set_rate = &pll_clk_set_rate,
180 .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
181 .private_data = &pll1_config,
182};
183
184/* PLL3 48 MHz clock */
185static struct clk pll3_48m_clk = {
186 .flags = ALWAYS_ENABLED,
187 .pclk = &osc_24m_clk,
188 .rate = 48000000,
189};
190
191/* watch dog timer clock */
192static struct clk wdt_clk = {
193 .flags = ALWAYS_ENABLED,
194 .pclk = &osc_24m_clk,
195 .recalc = &follow_parent,
196};
197
198/* clock derived from pll1 clk */
199/* cpu clock */
200static struct clk cpu_clk = {
201 .flags = ALWAYS_ENABLED,
202 .pclk = &pll1_clk,
203 .recalc = &follow_parent,
204};
205
206/* ahb masks structure */
207static struct bus_clk_masks ahb_masks = {
208 .mask = PLL_HCLK_RATIO_MASK,
209 .shift = PLL_HCLK_RATIO_SHIFT,
210};
211
212/* ahb configuration structure */
213static struct bus_clk_config ahb_config = {
214 .reg = CORE_CLK_CFG,
215 .masks = &ahb_masks,
216};
217
218/* ahb rate configuration table, in ascending order of rates */
219struct bus_rate_tbl bus_rtbl[] = {
220 {.div = 3}, /* == parent divided by 4 */
221 {.div = 2}, /* == parent divided by 3 */
222 {.div = 1}, /* == parent divided by 2 */
223 {.div = 0}, /* == parent divided by 1 */
224};
225
226/* ahb clock */
227static struct clk ahb_clk = {
228 .flags = ALWAYS_ENABLED,
229 .pclk = &pll1_clk,
230 .calc_rate = &bus_calc_rate,
231 .recalc = &bus_clk_recalc,
232 .set_rate = &bus_clk_set_rate,
233 .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
234 .private_data = &ahb_config,
235};
236
237/* auxiliary synthesizers masks */
238static struct aux_clk_masks aux_masks = {
239 .eq_sel_mask = AUX_EQ_SEL_MASK,
240 .eq_sel_shift = AUX_EQ_SEL_SHIFT,
241 .eq1_mask = AUX_EQ1_SEL,
242 .eq2_mask = AUX_EQ2_SEL,
243 .xscale_sel_mask = AUX_XSCALE_MASK,
244 .xscale_sel_shift = AUX_XSCALE_SHIFT,
245 .yscale_sel_mask = AUX_YSCALE_MASK,
246 .yscale_sel_shift = AUX_YSCALE_SHIFT,
247};
248
249/* uart synth configurations */
250static struct aux_clk_config uart_synth_config = {
251 .synth_reg = UART_CLK_SYNT,
252 .masks = &aux_masks,
253};
254
255/* aux rate configuration table, in ascending order of rates */
256struct aux_rate_tbl aux_rtbl[] = {
257 /* For PLL1 = 332 MHz */
258 {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
259 {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
260 {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
261};
262
263/* uart synth clock */
264static struct clk uart_synth_clk = {
265 .en_reg = UART_CLK_SYNT,
266 .en_reg_bit = AUX_SYNT_ENB,
267 .pclk = &pll1_clk,
268 .calc_rate = &aux_calc_rate,
269 .recalc = &aux_clk_recalc,
270 .set_rate = &aux_clk_set_rate,
271 .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
272 .private_data = &uart_synth_config,
273};
274
275/* uart parents */
276static struct pclk_info uart_pclk_info[] = {
277 {
278 .pclk = &uart_synth_clk,
279 .pclk_val = AUX_CLK_PLL1_VAL,
280 }, {
281 .pclk = &pll3_48m_clk,
282 .pclk_val = AUX_CLK_PLL3_VAL,
283 },
284};
285
286/* uart parent select structure */
287static struct pclk_sel uart_pclk_sel = {
288 .pclk_info = uart_pclk_info,
289 .pclk_count = ARRAY_SIZE(uart_pclk_info),
290 .pclk_sel_reg = PERIP_CLK_CFG,
291 .pclk_sel_mask = UART_CLK_MASK,
292};
293
294/* uart clock */
295static struct clk uart_clk = {
296 .en_reg = PERIP1_CLK_ENB,
297 .en_reg_bit = UART_CLK_ENB,
298 .pclk_sel = &uart_pclk_sel,
299 .pclk_sel_shift = UART_CLK_SHIFT,
300 .recalc = &follow_parent,
301};
302
303/* firda configurations */
304static struct aux_clk_config firda_synth_config = {
305 .synth_reg = FIRDA_CLK_SYNT,
306 .masks = &aux_masks,
307};
308
309/* firda synth clock */
310static struct clk firda_synth_clk = {
311 .en_reg = FIRDA_CLK_SYNT,
312 .en_reg_bit = AUX_SYNT_ENB,
313 .pclk = &pll1_clk,
314 .calc_rate = &aux_calc_rate,
315 .recalc = &aux_clk_recalc,
316 .set_rate = &aux_clk_set_rate,
317 .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
318 .private_data = &firda_synth_config,
319};
320
321/* firda parents */
322static struct pclk_info firda_pclk_info[] = {
323 {
324 .pclk = &firda_synth_clk,
325 .pclk_val = AUX_CLK_PLL1_VAL,
326 }, {
327 .pclk = &pll3_48m_clk,
328 .pclk_val = AUX_CLK_PLL3_VAL,
329 },
330};
331
332/* firda parent select structure */
333static struct pclk_sel firda_pclk_sel = {
334 .pclk_info = firda_pclk_info,
335 .pclk_count = ARRAY_SIZE(firda_pclk_info),
336 .pclk_sel_reg = PERIP_CLK_CFG,
337 .pclk_sel_mask = FIRDA_CLK_MASK,
338};
339
340/* firda clock */
341static struct clk firda_clk = {
342 .en_reg = PERIP1_CLK_ENB,
343 .en_reg_bit = FIRDA_CLK_ENB,
344 .pclk_sel = &firda_pclk_sel,
345 .pclk_sel_shift = FIRDA_CLK_SHIFT,
346 .recalc = &follow_parent,
347};
348
349/* gpt synthesizer masks */
350static struct gpt_clk_masks gpt_masks = {
351 .mscale_sel_mask = GPT_MSCALE_MASK,
352 .mscale_sel_shift = GPT_MSCALE_SHIFT,
353 .nscale_sel_mask = GPT_NSCALE_MASK,
354 .nscale_sel_shift = GPT_NSCALE_SHIFT,
355};
356
357/* gpt rate configuration table, in ascending order of rates */
358struct gpt_rate_tbl gpt_rtbl[] = {
359 /* For pll1 = 332 MHz */
360 {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
361 {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
362 {.mscale = 1, .nscale = 0}, /* 83 MHz */
363};
364
365/* gpt0 synth clk config*/
366static struct gpt_clk_config gpt0_synth_config = {
367 .synth_reg = PRSC1_CLK_CFG,
368 .masks = &gpt_masks,
369};
370
371/* gpt synth clock */
372static struct clk gpt0_synth_clk = {
373 .flags = ALWAYS_ENABLED,
374 .pclk = &pll1_clk,
375 .calc_rate = &gpt_calc_rate,
376 .recalc = &gpt_clk_recalc,
377 .set_rate = &gpt_clk_set_rate,
378 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
379 .private_data = &gpt0_synth_config,
380};
381
382/* gpt parents */
383static struct pclk_info gpt0_pclk_info[] = {
384 {
385 .pclk = &gpt0_synth_clk,
386 .pclk_val = AUX_CLK_PLL1_VAL,
387 }, {
388 .pclk = &pll3_48m_clk,
389 .pclk_val = AUX_CLK_PLL3_VAL,
390 },
391};
392
393/* gpt parent select structure */
394static struct pclk_sel gpt0_pclk_sel = {
395 .pclk_info = gpt0_pclk_info,
396 .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
397 .pclk_sel_reg = PERIP_CLK_CFG,
398 .pclk_sel_mask = GPT_CLK_MASK,
399};
400
401/* gpt0 timer clock */
402static struct clk gpt0_clk = {
403 .flags = ALWAYS_ENABLED,
404 .pclk_sel = &gpt0_pclk_sel,
405 .pclk_sel_shift = GPT0_CLK_SHIFT,
406 .recalc = &follow_parent,
407};
408
409/* gpt1 synth clk configurations */
410static struct gpt_clk_config gpt1_synth_config = {
411 .synth_reg = PRSC2_CLK_CFG,
412 .masks = &gpt_masks,
413};
414
415/* gpt1 synth clock */
416static struct clk gpt1_synth_clk = {
417 .flags = ALWAYS_ENABLED,
418 .pclk = &pll1_clk,
419 .calc_rate = &gpt_calc_rate,
420 .recalc = &gpt_clk_recalc,
421 .set_rate = &gpt_clk_set_rate,
422 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
423 .private_data = &gpt1_synth_config,
424};
425
426static struct pclk_info gpt1_pclk_info[] = {
427 {
428 .pclk = &gpt1_synth_clk,
429 .pclk_val = AUX_CLK_PLL1_VAL,
430 }, {
431 .pclk = &pll3_48m_clk,
432 .pclk_val = AUX_CLK_PLL3_VAL,
433 },
434};
435
436/* gpt parent select structure */
437static struct pclk_sel gpt1_pclk_sel = {
438 .pclk_info = gpt1_pclk_info,
439 .pclk_count = ARRAY_SIZE(gpt1_pclk_info),
440 .pclk_sel_reg = PERIP_CLK_CFG,
441 .pclk_sel_mask = GPT_CLK_MASK,
442};
443
444/* gpt1 timer clock */
445static struct clk gpt1_clk = {
446 .en_reg = PERIP1_CLK_ENB,
447 .en_reg_bit = GPT1_CLK_ENB,
448 .pclk_sel = &gpt1_pclk_sel,
449 .pclk_sel_shift = GPT1_CLK_SHIFT,
450 .recalc = &follow_parent,
451};
452
453/* gpt2 synth clk configurations */
454static struct gpt_clk_config gpt2_synth_config = {
455 .synth_reg = PRSC3_CLK_CFG,
456 .masks = &gpt_masks,
457};
458
459/* gpt1 synth clock */
460static struct clk gpt2_synth_clk = {
461 .flags = ALWAYS_ENABLED,
462 .pclk = &pll1_clk,
463 .calc_rate = &gpt_calc_rate,
464 .recalc = &gpt_clk_recalc,
465 .set_rate = &gpt_clk_set_rate,
466 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
467 .private_data = &gpt2_synth_config,
468};
469
470static struct pclk_info gpt2_pclk_info[] = {
471 {
472 .pclk = &gpt2_synth_clk,
473 .pclk_val = AUX_CLK_PLL1_VAL,
474 }, {
475 .pclk = &pll3_48m_clk,
476 .pclk_val = AUX_CLK_PLL3_VAL,
477 },
478};
479
480/* gpt parent select structure */
481static struct pclk_sel gpt2_pclk_sel = {
482 .pclk_info = gpt2_pclk_info,
483 .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
484 .pclk_sel_reg = PERIP_CLK_CFG,
485 .pclk_sel_mask = GPT_CLK_MASK,
486};
487
488/* gpt2 timer clock */
489static struct clk gpt2_clk = {
490 .en_reg = PERIP1_CLK_ENB,
491 .en_reg_bit = GPT2_CLK_ENB,
492 .pclk_sel = &gpt2_pclk_sel,
493 .pclk_sel_shift = GPT2_CLK_SHIFT,
494 .recalc = &follow_parent,
495};
496
497/* clock derived from pll3 clk */
498/* usbh clock */
499static struct clk usbh_clk = {
500 .pclk = &pll3_48m_clk,
501 .en_reg = PERIP1_CLK_ENB,
502 .en_reg_bit = USBH_CLK_ENB,
503 .recalc = &follow_parent,
504};
505
506/* usbd clock */
507static struct clk usbd_clk = {
508 .pclk = &pll3_48m_clk,
509 .en_reg = PERIP1_CLK_ENB,
510 .en_reg_bit = USBD_CLK_ENB,
511 .recalc = &follow_parent,
512};
513
514/* clock derived from usbh clk */
515/* usbh0 clock */
516static struct clk usbh0_clk = {
517 .flags = ALWAYS_ENABLED,
518 .pclk = &usbh_clk,
519 .recalc = &follow_parent,
520};
521
522/* usbh1 clock */
523static struct clk usbh1_clk = {
524 .flags = ALWAYS_ENABLED,
525 .pclk = &usbh_clk,
526 .recalc = &follow_parent,
527};
528
529/* clock derived from ahb clk */
530/* apb masks structure */
531static struct bus_clk_masks apb_masks = {
532 .mask = HCLK_PCLK_RATIO_MASK,
533 .shift = HCLK_PCLK_RATIO_SHIFT,
534};
535
536/* apb configuration structure */
537static struct bus_clk_config apb_config = {
538 .reg = CORE_CLK_CFG,
539 .masks = &apb_masks,
540};
541
542/* apb clock */
543static struct clk apb_clk = {
544 .flags = ALWAYS_ENABLED,
545 .pclk = &ahb_clk,
546 .calc_rate = &bus_calc_rate,
547 .recalc = &bus_clk_recalc,
548 .set_rate = &bus_clk_set_rate,
549 .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
550 .private_data = &apb_config,
551};
552
553/* i2c clock */
554static struct clk i2c_clk = {
555 .pclk = &ahb_clk,
556 .en_reg = PERIP1_CLK_ENB,
557 .en_reg_bit = I2C_CLK_ENB,
558 .recalc = &follow_parent,
559};
560
561/* dma clock */
562static struct clk dma_clk = {
563 .pclk = &ahb_clk,
564 .en_reg = PERIP1_CLK_ENB,
565 .en_reg_bit = DMA_CLK_ENB,
566 .recalc = &follow_parent,
567};
568
569/* jpeg clock */
570static struct clk jpeg_clk = {
571 .pclk = &ahb_clk,
572 .en_reg = PERIP1_CLK_ENB,
573 .en_reg_bit = JPEG_CLK_ENB,
574 .recalc = &follow_parent,
575};
576
577/* gmac clock */
578static struct clk gmac_clk = {
579 .pclk = &ahb_clk,
580 .en_reg = PERIP1_CLK_ENB,
581 .en_reg_bit = GMAC_CLK_ENB,
582 .recalc = &follow_parent,
583};
584
585/* smi clock */
586static struct clk smi_clk = {
587 .pclk = &ahb_clk,
588 .en_reg = PERIP1_CLK_ENB,
589 .en_reg_bit = SMI_CLK_ENB,
590 .recalc = &follow_parent,
591};
592
593/* c3 clock */
594static struct clk c3_clk = {
595 .pclk = &ahb_clk,
596 .en_reg = PERIP1_CLK_ENB,
597 .en_reg_bit = C3_CLK_ENB,
598 .recalc = &follow_parent,
599};
600
601/* clock derived from apb clk */
602/* adc clock */
603static struct clk adc_clk = {
604 .pclk = &apb_clk,
605 .en_reg = PERIP1_CLK_ENB,
606 .en_reg_bit = ADC_CLK_ENB,
607 .recalc = &follow_parent,
608};
609
610#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
611/* emi clock */
612static struct clk emi_clk = {
613 .flags = ALWAYS_ENABLED,
614 .pclk = &ahb_clk,
615 .recalc = &follow_parent,
616};
617#endif
618
619/* ssp clock */
620static struct clk ssp0_clk = {
621 .pclk = &apb_clk,
622 .en_reg = PERIP1_CLK_ENB,
623 .en_reg_bit = SSP_CLK_ENB,
624 .recalc = &follow_parent,
625};
626
627/* gpio clock */
628static struct clk gpio_clk = {
629 .pclk = &apb_clk,
630 .en_reg = PERIP1_CLK_ENB,
631 .en_reg_bit = GPIO_CLK_ENB,
632 .recalc = &follow_parent,
633};
634
635static struct clk dummy_apb_pclk;
636
637#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
638 defined(CONFIG_MACH_SPEAR320)
639/* fsmc clock */
640static struct clk fsmc_clk = {
641 .flags = ALWAYS_ENABLED,
642 .pclk = &ahb_clk,
643 .recalc = &follow_parent,
644};
645#endif
646
647/* common clocks to spear310 and spear320 */
648#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
649/* uart1 clock */
650static struct clk uart1_clk = {
651 .flags = ALWAYS_ENABLED,
652 .pclk = &apb_clk,
653 .recalc = &follow_parent,
654};
655
656/* uart2 clock */
657static struct clk uart2_clk = {
658 .flags = ALWAYS_ENABLED,
659 .pclk = &apb_clk,
660 .recalc = &follow_parent,
661};
662#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
663
664/* common clocks to spear300 and spear320 */
665#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
666/* clcd clock */
667static struct clk clcd_clk = {
668 .flags = ALWAYS_ENABLED,
669 .pclk = &pll3_48m_clk,
670 .recalc = &follow_parent,
671};
672
673/* sdhci clock */
674static struct clk sdhci_clk = {
675 .flags = ALWAYS_ENABLED,
676 .pclk = &ahb_clk,
677 .recalc = &follow_parent,
678};
679#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
680
681/* spear300 machine specific clock structures */
682#ifdef CONFIG_MACH_SPEAR300
683/* gpio1 clock */
684static struct clk gpio1_clk = {
685 .flags = ALWAYS_ENABLED,
686 .pclk = &apb_clk,
687 .recalc = &follow_parent,
688};
689
690/* keyboard clock */
691static struct clk kbd_clk = {
692 .flags = ALWAYS_ENABLED,
693 .pclk = &apb_clk,
694 .recalc = &follow_parent,
695};
696
697#endif
698
699/* spear310 machine specific clock structures */
700#ifdef CONFIG_MACH_SPEAR310
701/* uart3 clock */
702static struct clk uart3_clk = {
703 .flags = ALWAYS_ENABLED,
704 .pclk = &apb_clk,
705 .recalc = &follow_parent,
706};
707
708/* uart4 clock */
709static struct clk uart4_clk = {
710 .flags = ALWAYS_ENABLED,
711 .pclk = &apb_clk,
712 .recalc = &follow_parent,
713};
714
715/* uart5 clock */
716static struct clk uart5_clk = {
717 .flags = ALWAYS_ENABLED,
718 .pclk = &apb_clk,
719 .recalc = &follow_parent,
720};
721#endif
722
723/* spear320 machine specific clock structures */
724#ifdef CONFIG_MACH_SPEAR320
725/* can0 clock */
726static struct clk can0_clk = {
727 .flags = ALWAYS_ENABLED,
728 .pclk = &apb_clk,
729 .recalc = &follow_parent,
730};
731
732/* can1 clock */
733static struct clk can1_clk = {
734 .flags = ALWAYS_ENABLED,
735 .pclk = &apb_clk,
736 .recalc = &follow_parent,
737};
738
739/* i2c1 clock */
740static struct clk i2c1_clk = {
741 .flags = ALWAYS_ENABLED,
742 .pclk = &ahb_clk,
743 .recalc = &follow_parent,
744};
745
746/* ssp1 clock */
747static struct clk ssp1_clk = {
748 .flags = ALWAYS_ENABLED,
749 .pclk = &apb_clk,
750 .recalc = &follow_parent,
751};
752
753/* ssp2 clock */
754static struct clk ssp2_clk = {
755 .flags = ALWAYS_ENABLED,
756 .pclk = &apb_clk,
757 .recalc = &follow_parent,
758};
759
760/* pwm clock */
761static struct clk pwm_clk = {
762 .flags = ALWAYS_ENABLED,
763 .pclk = &apb_clk,
764 .recalc = &follow_parent,
765};
766#endif
767
768/* array of all spear 3xx clock lookups */
769static struct clk_lookup spear_clk_lookups[] = {
770 CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
771 /* root clks */
772 CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
773 CLKDEV_INIT(NULL, "osc_24m_clk", &osc_24m_clk),
774 /* clock derived from 32 KHz osc clk */
775 CLKDEV_INIT("fc900000.rtc", NULL, &rtc_clk),
776 /* clock derived from 24 MHz osc clk */
777 CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
778 CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
779 CLKDEV_INIT("fc880000.wdt", NULL, &wdt_clk),
780 /* clock derived from pll1 clk */
781 CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
782 CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
783 CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
784 CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
785 CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
786 CLKDEV_INIT(NULL, "gpt1_synth_clk", &gpt1_synth_clk),
787 CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
788 CLKDEV_INIT("d0000000.serial", NULL, &uart_clk),
789 CLKDEV_INIT("firda", NULL, &firda_clk),
790 CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
791 CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
792 CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
793 /* clock derived from pll3 clk */
794 CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
795 CLKDEV_INIT(NULL, "usbh_clk", &usbh_clk),
796 /* clock derived from usbh clk */
797 CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
798 CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
799 /* clock derived from ahb clk */
800 CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
801 CLKDEV_INIT("d0180000.i2c", NULL, &i2c_clk),
802 CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
803 CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
804 CLKDEV_INIT("e0800000.eth", NULL, &gmac_clk),
805 CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
806 CLKDEV_INIT("c3", NULL, &c3_clk),
807 /* clock derived from apb clk */
808 CLKDEV_INIT("adc", NULL, &adc_clk),
809 CLKDEV_INIT("d0100000.spi", NULL, &ssp0_clk),
810 CLKDEV_INIT("fc980000.gpio", NULL, &gpio_clk),
811};
812
813/* array of all spear 300 clock lookups */
814#ifdef CONFIG_MACH_SPEAR300
815static struct clk_lookup spear300_clk_lookups[] = {
816 CLKDEV_INIT("60000000.clcd", NULL, &clcd_clk),
817 CLKDEV_INIT("94000000.flash", NULL, &fsmc_clk),
818 CLKDEV_INIT("a9000000.gpio", NULL, &gpio1_clk),
819 CLKDEV_INIT("a0000000.kbd", NULL, &kbd_clk),
820 CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
821};
822
823void __init spear300_clk_init(void)
824{
825 int i;
826
827 for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
828 clk_register(&spear_clk_lookups[i]);
829
830 for (i = 0; i < ARRAY_SIZE(spear300_clk_lookups); i++)
831 clk_register(&spear300_clk_lookups[i]);
832
833 clk_init();
834}
835#endif
836
837/* array of all spear 310 clock lookups */
838#ifdef CONFIG_MACH_SPEAR310
839static struct clk_lookup spear310_clk_lookups[] = {
840 CLKDEV_INIT("44000000.flash", NULL, &fsmc_clk),
841 CLKDEV_INIT(NULL, "emi", &emi_clk),
842 CLKDEV_INIT("b2000000.serial", NULL, &uart1_clk),
843 CLKDEV_INIT("b2080000.serial", NULL, &uart2_clk),
844 CLKDEV_INIT("b2100000.serial", NULL, &uart3_clk),
845 CLKDEV_INIT("b2180000.serial", NULL, &uart4_clk),
846 CLKDEV_INIT("b2200000.serial", NULL, &uart5_clk),
847};
848
849void __init spear310_clk_init(void)
850{
851 int i;
852
853 for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
854 clk_register(&spear_clk_lookups[i]);
855
856 for (i = 0; i < ARRAY_SIZE(spear310_clk_lookups); i++)
857 clk_register(&spear310_clk_lookups[i]);
858
859 clk_init();
860}
861#endif
862
863/* array of all spear 320 clock lookups */
864#ifdef CONFIG_MACH_SPEAR320
865static struct clk_lookup spear320_clk_lookups[] = {
866 CLKDEV_INIT("90000000.clcd", NULL, &clcd_clk),
867 CLKDEV_INIT("4c000000.flash", NULL, &fsmc_clk),
868 CLKDEV_INIT("a7000000.i2c", NULL, &i2c1_clk),
869 CLKDEV_INIT(NULL, "emi", &emi_clk),
870 CLKDEV_INIT("pwm", NULL, &pwm_clk),
871 CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
872 CLKDEV_INIT("c_can_platform.0", NULL, &can0_clk),
873 CLKDEV_INIT("c_can_platform.1", NULL, &can1_clk),
874 CLKDEV_INIT("a5000000.spi", NULL, &ssp1_clk),
875 CLKDEV_INIT("a6000000.spi", NULL, &ssp2_clk),
876 CLKDEV_INIT("a3000000.serial", NULL, &uart1_clk),
877 CLKDEV_INIT("a4000000.serial", NULL, &uart2_clk),
878};
879
880void __init spear320_clk_init(void)
881{
882 int i;
883
884 for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
885 clk_register(&spear_clk_lookups[i]);
886
887 for (i = 0; i < ARRAY_SIZE(spear320_clk_lookups); i++)
888 clk_register(&spear320_clk_lookups[i]);
889
890 clk_init();
891}
892#endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index bdb304551ca..4a95b9453c2 100644
--- a/arch/arm/mach-spear3xx/include/mach/generic.h
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -27,28 +27,11 @@ extern struct pl022_ssp_controller pl022_plat_data;
27extern struct pl08x_platform_data pl080_plat_data; 27extern struct pl08x_platform_data pl080_plat_data;
28 28
29/* Add spear3xx family function declarations here */ 29/* Add spear3xx family function declarations here */
30void __init spear_setup_timer(resource_size_t base, int irq); 30void __init spear_setup_of_timer(void);
31void __init spear3xx_clk_init(void);
31void __init spear3xx_map_io(void); 32void __init spear3xx_map_io(void);
32void __init spear3xx_dt_init_irq(void); 33void __init spear3xx_dt_init_irq(void);
33 34
34void spear_restart(char, const char *); 35void spear_restart(char, const char *);
35 36
36/* spear300 declarations */
37#ifdef CONFIG_MACH_SPEAR300
38void __init spear300_clk_init(void);
39
40#endif /* CONFIG_MACH_SPEAR300 */
41
42/* spear310 declarations */
43#ifdef CONFIG_MACH_SPEAR310
44void __init spear310_clk_init(void);
45
46#endif /* CONFIG_MACH_SPEAR310 */
47
48/* spear320 declarations */
49#ifdef CONFIG_MACH_SPEAR320
50void __init spear320_clk_init(void);
51
52#endif /* CONFIG_MACH_SPEAR320 */
53
54#endif /* __MACH_GENERIC_H */ 37#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index 319620a1afb..51bd62a0254 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -16,7 +16,6 @@
16 16
17/* FIXME: probe all these from DT */ 17/* FIXME: probe all these from DT */
18#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1 18#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1
19#define SPEAR3XX_IRQ_CPU_GPT1_1 2
20#define SPEAR3XX_IRQ_GEN_RAS_1 28 19#define SPEAR3XX_IRQ_GEN_RAS_1 28
21#define SPEAR3XX_IRQ_GEN_RAS_2 29 20#define SPEAR3XX_IRQ_GEN_RAS_2 29
22#define SPEAR3XX_IRQ_GEN_RAS_3 30 21#define SPEAR3XX_IRQ_GEN_RAS_3 30
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
index e0ab72e6150..18e2ac576f2 100644
--- a/arch/arm/mach-spear3xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
@@ -14,6 +14,8 @@
14#ifndef __MACH_MISC_REGS_H 14#ifndef __MACH_MISC_REGS_H
15#define __MACH_MISC_REGS_H 15#define __MACH_MISC_REGS_H
16 16
17#include <mach/spear.h>
18
17#define MISC_BASE IOMEM(VA_SPEAR3XX_ICM3_MISC_REG_BASE) 19#define MISC_BASE IOMEM(VA_SPEAR3XX_ICM3_MISC_REG_BASE)
18#define DMA_CHN_CFG (MISC_BASE + 0x0A0) 20#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
19 21
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
index 6d4dadc6763..51eb953148a 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -26,7 +26,6 @@
26/* ML1 - Multi Layer CPU Subsystem */ 26/* ML1 - Multi Layer CPU Subsystem */
27#define SPEAR3XX_ICM3_ML1_2_BASE UL(0xF0000000) 27#define SPEAR3XX_ICM3_ML1_2_BASE UL(0xF0000000)
28#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000) 28#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
29#define SPEAR3XX_CPU_TMR_BASE UL(0xF0000000)
30 29
31/* ICM3 - Basic Subsystem */ 30/* ICM3 - Basic Subsystem */
32#define SPEAR3XX_ICM3_SMI_CTRL_BASE UL(0xFC000000) 31#define SPEAR3XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
@@ -45,4 +44,17 @@
45#define SPEAR_SYS_CTRL_BASE SPEAR3XX_ICM3_SYS_CTRL_BASE 44#define SPEAR_SYS_CTRL_BASE SPEAR3XX_ICM3_SYS_CTRL_BASE
46#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR3XX_ICM3_SYS_CTRL_BASE 45#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR3XX_ICM3_SYS_CTRL_BASE
47 46
47/* SPEAr320 Macros */
48#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
49#define VA_SPEAR320_SOC_CONFIG_BASE UL(0xFE000000)
50#define SPEAR320_CONTROL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE)
51#define SPEAR320_EXT_CTRL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE + 0x0018)
52 #define SPEAR320_UARTX_PCLK_MASK 0x1
53 #define SPEAR320_UART2_PCLK_SHIFT 8
54 #define SPEAR320_UART3_PCLK_SHIFT 9
55 #define SPEAR320_UART4_PCLK_SHIFT 10
56 #define SPEAR320_UART5_PCLK_SHIFT 11
57 #define SPEAR320_UART6_PCLK_SHIFT 12
58 #define SPEAR320_RS485_PCLK_SHIFT 13
59
48#endif /* __MACH_SPEAR3XX_H */ 60#endif /* __MACH_SPEAR3XX_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index f75fe25a620..f74a05bdb82 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -337,7 +337,6 @@ static const char * const spear300_dt_board_compat[] = {
337static void __init spear300_map_io(void) 337static void __init spear300_map_io(void)
338{ 338{
339 spear3xx_map_io(); 339 spear3xx_map_io();
340 spear300_clk_init();
341} 340}
342 341
343DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree") 342DT_MACHINE_START(SPEAR300_DT, "ST SPEAr300 SoC with Flattened Device Tree")
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index f0842a58dc0..84dfb090074 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -478,7 +478,6 @@ static const char * const spear310_dt_board_compat[] = {
478static void __init spear310_map_io(void) 478static void __init spear310_map_io(void)
479{ 479{
480 spear3xx_map_io(); 480 spear3xx_map_io();
481 spear310_clk_init();
482} 481}
483 482
484DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree") 483DT_MACHINE_START(SPEAR310_DT, "ST SPEAr310 SoC with Flattened Device Tree")
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index e8caeef50a5..a88fa841d29 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -27,7 +27,6 @@
27#define SPEAR320_UART2_BASE UL(0xA4000000) 27#define SPEAR320_UART2_BASE UL(0xA4000000)
28#define SPEAR320_SSP0_BASE UL(0xA5000000) 28#define SPEAR320_SSP0_BASE UL(0xA5000000)
29#define SPEAR320_SSP1_BASE UL(0xA6000000) 29#define SPEAR320_SSP1_BASE UL(0xA6000000)
30#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
31 30
32/* Interrupt registers offsets and masks */ 31/* Interrupt registers offsets and masks */
33#define SPEAR320_INT_STS_MASK_REG 0x04 32#define SPEAR320_INT_STS_MASK_REG 0x04
@@ -481,10 +480,19 @@ static const char * const spear320_dt_board_compat[] = {
481 NULL, 480 NULL,
482}; 481};
483 482
483struct map_desc spear320_io_desc[] __initdata = {
484 {
485 .virtual = VA_SPEAR320_SOC_CONFIG_BASE,
486 .pfn = __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE),
487 .length = SZ_16M,
488 .type = MT_DEVICE
489 },
490};
491
484static void __init spear320_map_io(void) 492static void __init spear320_map_io(void)
485{ 493{
494 iotable_init(spear320_io_desc, ARRAY_SIZE(spear320_io_desc));
486 spear3xx_map_io(); 495 spear3xx_map_io();
487 spear320_clk_init();
488} 496}
489 497
490DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree") 498DT_MACHINE_START(SPEAR320_DT, "ST SPEAr320 SoC with Flattened Device Tree")
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 826ac20ef1e..f22419ed74a 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -90,6 +90,8 @@ static void __init spear3xx_timer_init(void)
90 char pclk_name[] = "pll3_48m_clk"; 90 char pclk_name[] = "pll3_48m_clk";
91 struct clk *gpt_clk, *pclk; 91 struct clk *gpt_clk, *pclk;
92 92
93 spear3xx_clk_init();
94
93 /* get the system timer clock */ 95 /* get the system timer clock */
94 gpt_clk = clk_get_sys("gpt0", NULL); 96 gpt_clk = clk_get_sys("gpt0", NULL);
95 if (IS_ERR(gpt_clk)) { 97 if (IS_ERR(gpt_clk)) {
@@ -109,7 +111,7 @@ static void __init spear3xx_timer_init(void)
109 clk_put(gpt_clk); 111 clk_put(gpt_clk);
110 clk_put(pclk); 112 clk_put(pclk);
111 113
112 spear_setup_timer(SPEAR3XX_CPU_TMR_BASE, SPEAR3XX_IRQ_CPU_GPT1_1); 114 spear_setup_of_timer();
113} 115}
114 116
115struct sys_timer spear3xx_timer = { 117struct sys_timer spear3xx_timer = {
diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile
index 76e5750552f..898831d93f3 100644
--- a/arch/arm/mach-spear6xx/Makefile
+++ b/arch/arm/mach-spear6xx/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5# common files 5# common files
6obj-y += clock.o spear6xx.o 6obj-y += spear6xx.o
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
deleted file mode 100644
index bef77d43db8..00000000000
--- a/arch/arm/mach-spear6xx/clock.c
+++ /dev/null
@@ -1,789 +0,0 @@
1/*
2 * arch/arm/mach-spear6xx/clock.c
3 *
4 * SPEAr6xx machines clock framework source file
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <plat/clock.h>
18#include <mach/misc_regs.h>
19#include <mach/spear.h>
20
21#define PLL1_CTR (MISC_BASE + 0x008)
22#define PLL1_FRQ (MISC_BASE + 0x00C)
23#define PLL1_MOD (MISC_BASE + 0x010)
24#define PLL2_CTR (MISC_BASE + 0x014)
25/* PLL_CTR register masks */
26#define PLL_ENABLE 2
27#define PLL_MODE_SHIFT 4
28#define PLL_MODE_MASK 0x3
29#define PLL_MODE_NORMAL 0
30#define PLL_MODE_FRACTION 1
31#define PLL_MODE_DITH_DSB 2
32#define PLL_MODE_DITH_SSB 3
33
34#define PLL2_FRQ (MISC_BASE + 0x018)
35/* PLL FRQ register masks */
36#define PLL_DIV_N_SHIFT 0
37#define PLL_DIV_N_MASK 0xFF
38#define PLL_DIV_P_SHIFT 8
39#define PLL_DIV_P_MASK 0x7
40#define PLL_NORM_FDBK_M_SHIFT 24
41#define PLL_NORM_FDBK_M_MASK 0xFF
42#define PLL_DITH_FDBK_M_SHIFT 16
43#define PLL_DITH_FDBK_M_MASK 0xFFFF
44
45#define PLL2_MOD (MISC_BASE + 0x01C)
46#define PLL_CLK_CFG (MISC_BASE + 0x020)
47#define CORE_CLK_CFG (MISC_BASE + 0x024)
48/* CORE CLK CFG register masks */
49#define PLL_HCLK_RATIO_SHIFT 10
50#define PLL_HCLK_RATIO_MASK 0x3
51#define HCLK_PCLK_RATIO_SHIFT 8
52#define HCLK_PCLK_RATIO_MASK 0x3
53
54#define PERIP_CLK_CFG (MISC_BASE + 0x028)
55/* PERIP_CLK_CFG register masks */
56#define CLCD_CLK_SHIFT 2
57#define CLCD_CLK_MASK 0x3
58#define UART_CLK_SHIFT 4
59#define UART_CLK_MASK 0x1
60#define FIRDA_CLK_SHIFT 5
61#define FIRDA_CLK_MASK 0x3
62#define GPT0_CLK_SHIFT 8
63#define GPT1_CLK_SHIFT 10
64#define GPT2_CLK_SHIFT 11
65#define GPT3_CLK_SHIFT 12
66#define GPT_CLK_MASK 0x1
67#define AUX_CLK_PLL3_VAL 0
68#define AUX_CLK_PLL1_VAL 1
69
70#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
71/* PERIP1_CLK_ENB register masks */
72#define UART0_CLK_ENB 3
73#define UART1_CLK_ENB 4
74#define SSP0_CLK_ENB 5
75#define SSP1_CLK_ENB 6
76#define I2C_CLK_ENB 7
77#define JPEG_CLK_ENB 8
78#define FSMC_CLK_ENB 9
79#define FIRDA_CLK_ENB 10
80#define GPT2_CLK_ENB 11
81#define GPT3_CLK_ENB 12
82#define GPIO2_CLK_ENB 13
83#define SSP2_CLK_ENB 14
84#define ADC_CLK_ENB 15
85#define GPT1_CLK_ENB 11
86#define RTC_CLK_ENB 17
87#define GPIO1_CLK_ENB 18
88#define DMA_CLK_ENB 19
89#define SMI_CLK_ENB 21
90#define CLCD_CLK_ENB 22
91#define GMAC_CLK_ENB 23
92#define USBD_CLK_ENB 24
93#define USBH0_CLK_ENB 25
94#define USBH1_CLK_ENB 26
95
96#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
97#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
98#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
99/* gpt synthesizer register masks */
100#define GPT_MSCALE_SHIFT 0
101#define GPT_MSCALE_MASK 0xFFF
102#define GPT_NSCALE_SHIFT 12
103#define GPT_NSCALE_MASK 0xF
104
105#define AMEM_CLK_CFG (MISC_BASE + 0x050)
106#define EXPI_CLK_CFG (MISC_BASE + 0x054)
107#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
108#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
109#define UART_CLK_SYNT (MISC_BASE + 0x064)
110#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
111#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
112#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
113#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
114#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
115/* aux clk synthesiser register masks for irda to ras4 */
116#define AUX_SYNT_ENB 31
117#define AUX_EQ_SEL_SHIFT 30
118#define AUX_EQ_SEL_MASK 1
119#define AUX_EQ1_SEL 0
120#define AUX_EQ2_SEL 1
121#define AUX_XSCALE_SHIFT 16
122#define AUX_XSCALE_MASK 0xFFF
123#define AUX_YSCALE_SHIFT 0
124#define AUX_YSCALE_MASK 0xFFF
125
126/* root clks */
127/* 32 KHz oscillator clock */
128static struct clk osc_32k_clk = {
129 .flags = ALWAYS_ENABLED,
130 .rate = 32000,
131};
132
133/* 30 MHz oscillator clock */
134static struct clk osc_30m_clk = {
135 .flags = ALWAYS_ENABLED,
136 .rate = 30000000,
137};
138
139/* clock derived from 32 KHz osc clk */
140/* rtc clock */
141static struct clk rtc_clk = {
142 .pclk = &osc_32k_clk,
143 .en_reg = PERIP1_CLK_ENB,
144 .en_reg_bit = RTC_CLK_ENB,
145 .recalc = &follow_parent,
146};
147
148/* clock derived from 30 MHz osc clk */
149/* pll masks structure */
150static struct pll_clk_masks pll1_masks = {
151 .mode_mask = PLL_MODE_MASK,
152 .mode_shift = PLL_MODE_SHIFT,
153 .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
154 .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
155 .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
156 .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
157 .div_p_mask = PLL_DIV_P_MASK,
158 .div_p_shift = PLL_DIV_P_SHIFT,
159 .div_n_mask = PLL_DIV_N_MASK,
160 .div_n_shift = PLL_DIV_N_SHIFT,
161};
162
163/* pll1 configuration structure */
164static struct pll_clk_config pll1_config = {
165 .mode_reg = PLL1_CTR,
166 .cfg_reg = PLL1_FRQ,
167 .masks = &pll1_masks,
168};
169
170/* pll rate configuration table, in ascending order of rates */
171struct pll_rate_tbl pll_rtbl[] = {
172 {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
173 {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
174};
175
176/* PLL1 clock */
177static struct clk pll1_clk = {
178 .flags = ENABLED_ON_INIT,
179 .pclk = &osc_30m_clk,
180 .en_reg = PLL1_CTR,
181 .en_reg_bit = PLL_ENABLE,
182 .calc_rate = &pll_calc_rate,
183 .recalc = &pll_clk_recalc,
184 .set_rate = &pll_clk_set_rate,
185 .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
186 .private_data = &pll1_config,
187};
188
189/* PLL3 48 MHz clock */
190static struct clk pll3_48m_clk = {
191 .flags = ALWAYS_ENABLED,
192 .pclk = &osc_30m_clk,
193 .rate = 48000000,
194};
195
196/* watch dog timer clock */
197static struct clk wdt_clk = {
198 .flags = ALWAYS_ENABLED,
199 .pclk = &osc_30m_clk,
200 .recalc = &follow_parent,
201};
202
203/* clock derived from pll1 clk */
204/* cpu clock */
205static struct clk cpu_clk = {
206 .flags = ALWAYS_ENABLED,
207 .pclk = &pll1_clk,
208 .recalc = &follow_parent,
209};
210
211/* ahb masks structure */
212static struct bus_clk_masks ahb_masks = {
213 .mask = PLL_HCLK_RATIO_MASK,
214 .shift = PLL_HCLK_RATIO_SHIFT,
215};
216
217/* ahb configuration structure */
218static struct bus_clk_config ahb_config = {
219 .reg = CORE_CLK_CFG,
220 .masks = &ahb_masks,
221};
222
223/* ahb rate configuration table, in ascending order of rates */
224struct bus_rate_tbl bus_rtbl[] = {
225 {.div = 3}, /* == parent divided by 4 */
226 {.div = 2}, /* == parent divided by 3 */
227 {.div = 1}, /* == parent divided by 2 */
228 {.div = 0}, /* == parent divided by 1 */
229};
230
231/* ahb clock */
232static struct clk ahb_clk = {
233 .flags = ALWAYS_ENABLED,
234 .pclk = &pll1_clk,
235 .calc_rate = &bus_calc_rate,
236 .recalc = &bus_clk_recalc,
237 .set_rate = &bus_clk_set_rate,
238 .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
239 .private_data = &ahb_config,
240};
241
242/* auxiliary synthesizers masks */
243static struct aux_clk_masks aux_masks = {
244 .eq_sel_mask = AUX_EQ_SEL_MASK,
245 .eq_sel_shift = AUX_EQ_SEL_SHIFT,
246 .eq1_mask = AUX_EQ1_SEL,
247 .eq2_mask = AUX_EQ2_SEL,
248 .xscale_sel_mask = AUX_XSCALE_MASK,
249 .xscale_sel_shift = AUX_XSCALE_SHIFT,
250 .yscale_sel_mask = AUX_YSCALE_MASK,
251 .yscale_sel_shift = AUX_YSCALE_SHIFT,
252};
253
254/* uart configurations */
255static struct aux_clk_config uart_synth_config = {
256 .synth_reg = UART_CLK_SYNT,
257 .masks = &aux_masks,
258};
259
260/* aux rate configuration table, in ascending order of rates */
261struct aux_rate_tbl aux_rtbl[] = {
262 /* For PLL1 = 332 MHz */
263 {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
264 {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
265 {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
266};
267
268/* uart synth clock */
269static struct clk uart_synth_clk = {
270 .en_reg = UART_CLK_SYNT,
271 .en_reg_bit = AUX_SYNT_ENB,
272 .pclk = &pll1_clk,
273 .calc_rate = &aux_calc_rate,
274 .recalc = &aux_clk_recalc,
275 .set_rate = &aux_clk_set_rate,
276 .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
277 .private_data = &uart_synth_config,
278};
279
280/* uart parents */
281static struct pclk_info uart_pclk_info[] = {
282 {
283 .pclk = &uart_synth_clk,
284 .pclk_val = AUX_CLK_PLL1_VAL,
285 }, {
286 .pclk = &pll3_48m_clk,
287 .pclk_val = AUX_CLK_PLL3_VAL,
288 },
289};
290
291/* uart parent select structure */
292static struct pclk_sel uart_pclk_sel = {
293 .pclk_info = uart_pclk_info,
294 .pclk_count = ARRAY_SIZE(uart_pclk_info),
295 .pclk_sel_reg = PERIP_CLK_CFG,
296 .pclk_sel_mask = UART_CLK_MASK,
297};
298
299/* uart0 clock */
300static struct clk uart0_clk = {
301 .en_reg = PERIP1_CLK_ENB,
302 .en_reg_bit = UART0_CLK_ENB,
303 .pclk_sel = &uart_pclk_sel,
304 .pclk_sel_shift = UART_CLK_SHIFT,
305 .recalc = &follow_parent,
306};
307
308/* uart1 clock */
309static struct clk uart1_clk = {
310 .en_reg = PERIP1_CLK_ENB,
311 .en_reg_bit = UART1_CLK_ENB,
312 .pclk_sel = &uart_pclk_sel,
313 .pclk_sel_shift = UART_CLK_SHIFT,
314 .recalc = &follow_parent,
315};
316
317/* firda configurations */
318static struct aux_clk_config firda_synth_config = {
319 .synth_reg = FIRDA_CLK_SYNT,
320 .masks = &aux_masks,
321};
322
323/* firda synth clock */
324static struct clk firda_synth_clk = {
325 .en_reg = FIRDA_CLK_SYNT,
326 .en_reg_bit = AUX_SYNT_ENB,
327 .pclk = &pll1_clk,
328 .calc_rate = &aux_calc_rate,
329 .recalc = &aux_clk_recalc,
330 .set_rate = &aux_clk_set_rate,
331 .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
332 .private_data = &firda_synth_config,
333};
334
335/* firda parents */
336static struct pclk_info firda_pclk_info[] = {
337 {
338 .pclk = &firda_synth_clk,
339 .pclk_val = AUX_CLK_PLL1_VAL,
340 }, {
341 .pclk = &pll3_48m_clk,
342 .pclk_val = AUX_CLK_PLL3_VAL,
343 },
344};
345
346/* firda parent select structure */
347static struct pclk_sel firda_pclk_sel = {
348 .pclk_info = firda_pclk_info,
349 .pclk_count = ARRAY_SIZE(firda_pclk_info),
350 .pclk_sel_reg = PERIP_CLK_CFG,
351 .pclk_sel_mask = FIRDA_CLK_MASK,
352};
353
354/* firda clock */
355static struct clk firda_clk = {
356 .en_reg = PERIP1_CLK_ENB,
357 .en_reg_bit = FIRDA_CLK_ENB,
358 .pclk_sel = &firda_pclk_sel,
359 .pclk_sel_shift = FIRDA_CLK_SHIFT,
360 .recalc = &follow_parent,
361};
362
363/* clcd configurations */
364static struct aux_clk_config clcd_synth_config = {
365 .synth_reg = CLCD_CLK_SYNT,
366 .masks = &aux_masks,
367};
368
369/* firda synth clock */
370static struct clk clcd_synth_clk = {
371 .en_reg = CLCD_CLK_SYNT,
372 .en_reg_bit = AUX_SYNT_ENB,
373 .pclk = &pll1_clk,
374 .calc_rate = &aux_calc_rate,
375 .recalc = &aux_clk_recalc,
376 .set_rate = &aux_clk_set_rate,
377 .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
378 .private_data = &clcd_synth_config,
379};
380
381/* clcd parents */
382static struct pclk_info clcd_pclk_info[] = {
383 {
384 .pclk = &clcd_synth_clk,
385 .pclk_val = AUX_CLK_PLL1_VAL,
386 }, {
387 .pclk = &pll3_48m_clk,
388 .pclk_val = AUX_CLK_PLL3_VAL,
389 },
390};
391
392/* clcd parent select structure */
393static struct pclk_sel clcd_pclk_sel = {
394 .pclk_info = clcd_pclk_info,
395 .pclk_count = ARRAY_SIZE(clcd_pclk_info),
396 .pclk_sel_reg = PERIP_CLK_CFG,
397 .pclk_sel_mask = CLCD_CLK_MASK,
398};
399
400/* clcd clock */
401static struct clk clcd_clk = {
402 .en_reg = PERIP1_CLK_ENB,
403 .en_reg_bit = CLCD_CLK_ENB,
404 .pclk_sel = &clcd_pclk_sel,
405 .pclk_sel_shift = CLCD_CLK_SHIFT,
406 .recalc = &follow_parent,
407};
408
409/* gpt synthesizer masks */
410static struct gpt_clk_masks gpt_masks = {
411 .mscale_sel_mask = GPT_MSCALE_MASK,
412 .mscale_sel_shift = GPT_MSCALE_SHIFT,
413 .nscale_sel_mask = GPT_NSCALE_MASK,
414 .nscale_sel_shift = GPT_NSCALE_SHIFT,
415};
416
417/* gpt rate configuration table, in ascending order of rates */
418struct gpt_rate_tbl gpt_rtbl[] = {
419 /* For pll1 = 332 MHz */
420 {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
421 {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
422 {.mscale = 1, .nscale = 0}, /* 83 MHz */
423};
424
425/* gpt0 synth clk config*/
426static struct gpt_clk_config gpt0_synth_config = {
427 .synth_reg = PRSC1_CLK_CFG,
428 .masks = &gpt_masks,
429};
430
431/* gpt synth clock */
432static struct clk gpt0_synth_clk = {
433 .flags = ALWAYS_ENABLED,
434 .pclk = &pll1_clk,
435 .calc_rate = &gpt_calc_rate,
436 .recalc = &gpt_clk_recalc,
437 .set_rate = &gpt_clk_set_rate,
438 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
439 .private_data = &gpt0_synth_config,
440};
441
442/* gpt parents */
443static struct pclk_info gpt0_pclk_info[] = {
444 {
445 .pclk = &gpt0_synth_clk,
446 .pclk_val = AUX_CLK_PLL1_VAL,
447 }, {
448 .pclk = &pll3_48m_clk,
449 .pclk_val = AUX_CLK_PLL3_VAL,
450 },
451};
452
453/* gpt parent select structure */
454static struct pclk_sel gpt0_pclk_sel = {
455 .pclk_info = gpt0_pclk_info,
456 .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
457 .pclk_sel_reg = PERIP_CLK_CFG,
458 .pclk_sel_mask = GPT_CLK_MASK,
459};
460
461/* gpt0 ARM1 subsystem timer clock */
462static struct clk gpt0_clk = {
463 .flags = ALWAYS_ENABLED,
464 .pclk_sel = &gpt0_pclk_sel,
465 .pclk_sel_shift = GPT0_CLK_SHIFT,
466 .recalc = &follow_parent,
467};
468
469
470/* Note: gpt0 and gpt1 share same parent clocks */
471/* gpt parent select structure */
472static struct pclk_sel gpt1_pclk_sel = {
473 .pclk_info = gpt0_pclk_info,
474 .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
475 .pclk_sel_reg = PERIP_CLK_CFG,
476 .pclk_sel_mask = GPT_CLK_MASK,
477};
478
479/* gpt1 timer clock */
480static struct clk gpt1_clk = {
481 .flags = ALWAYS_ENABLED,
482 .pclk_sel = &gpt1_pclk_sel,
483 .pclk_sel_shift = GPT1_CLK_SHIFT,
484 .recalc = &follow_parent,
485};
486
487/* gpt2 synth clk config*/
488static struct gpt_clk_config gpt2_synth_config = {
489 .synth_reg = PRSC2_CLK_CFG,
490 .masks = &gpt_masks,
491};
492
493/* gpt synth clock */
494static struct clk gpt2_synth_clk = {
495 .flags = ALWAYS_ENABLED,
496 .pclk = &pll1_clk,
497 .calc_rate = &gpt_calc_rate,
498 .recalc = &gpt_clk_recalc,
499 .set_rate = &gpt_clk_set_rate,
500 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
501 .private_data = &gpt2_synth_config,
502};
503
504/* gpt parents */
505static struct pclk_info gpt2_pclk_info[] = {
506 {
507 .pclk = &gpt2_synth_clk,
508 .pclk_val = AUX_CLK_PLL1_VAL,
509 }, {
510 .pclk = &pll3_48m_clk,
511 .pclk_val = AUX_CLK_PLL3_VAL,
512 },
513};
514
515/* gpt parent select structure */
516static struct pclk_sel gpt2_pclk_sel = {
517 .pclk_info = gpt2_pclk_info,
518 .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
519 .pclk_sel_reg = PERIP_CLK_CFG,
520 .pclk_sel_mask = GPT_CLK_MASK,
521};
522
523/* gpt2 timer clock */
524static struct clk gpt2_clk = {
525 .flags = ALWAYS_ENABLED,
526 .pclk_sel = &gpt2_pclk_sel,
527 .pclk_sel_shift = GPT2_CLK_SHIFT,
528 .recalc = &follow_parent,
529};
530
531/* gpt3 synth clk config*/
532static struct gpt_clk_config gpt3_synth_config = {
533 .synth_reg = PRSC3_CLK_CFG,
534 .masks = &gpt_masks,
535};
536
537/* gpt synth clock */
538static struct clk gpt3_synth_clk = {
539 .flags = ALWAYS_ENABLED,
540 .pclk = &pll1_clk,
541 .calc_rate = &gpt_calc_rate,
542 .recalc = &gpt_clk_recalc,
543 .set_rate = &gpt_clk_set_rate,
544 .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
545 .private_data = &gpt3_synth_config,
546};
547
548/* gpt parents */
549static struct pclk_info gpt3_pclk_info[] = {
550 {
551 .pclk = &gpt3_synth_clk,
552 .pclk_val = AUX_CLK_PLL1_VAL,
553 }, {
554 .pclk = &pll3_48m_clk,
555 .pclk_val = AUX_CLK_PLL3_VAL,
556 },
557};
558
559/* gpt parent select structure */
560static struct pclk_sel gpt3_pclk_sel = {
561 .pclk_info = gpt3_pclk_info,
562 .pclk_count = ARRAY_SIZE(gpt3_pclk_info),
563 .pclk_sel_reg = PERIP_CLK_CFG,
564 .pclk_sel_mask = GPT_CLK_MASK,
565};
566
567/* gpt3 timer clock */
568static struct clk gpt3_clk = {
569 .flags = ALWAYS_ENABLED,
570 .pclk_sel = &gpt3_pclk_sel,
571 .pclk_sel_shift = GPT3_CLK_SHIFT,
572 .recalc = &follow_parent,
573};
574
575/* clock derived from pll3 clk */
576/* usbh0 clock */
577static struct clk usbh0_clk = {
578 .pclk = &pll3_48m_clk,
579 .en_reg = PERIP1_CLK_ENB,
580 .en_reg_bit = USBH0_CLK_ENB,
581 .recalc = &follow_parent,
582};
583
584/* usbh1 clock */
585static struct clk usbh1_clk = {
586 .pclk = &pll3_48m_clk,
587 .en_reg = PERIP1_CLK_ENB,
588 .en_reg_bit = USBH1_CLK_ENB,
589 .recalc = &follow_parent,
590};
591
592/* usbd clock */
593static struct clk usbd_clk = {
594 .pclk = &pll3_48m_clk,
595 .en_reg = PERIP1_CLK_ENB,
596 .en_reg_bit = USBD_CLK_ENB,
597 .recalc = &follow_parent,
598};
599
600/* clock derived from ahb clk */
601/* apb masks structure */
602static struct bus_clk_masks apb_masks = {
603 .mask = HCLK_PCLK_RATIO_MASK,
604 .shift = HCLK_PCLK_RATIO_SHIFT,
605};
606
607/* apb configuration structure */
608static struct bus_clk_config apb_config = {
609 .reg = CORE_CLK_CFG,
610 .masks = &apb_masks,
611};
612
613/* apb clock */
614static struct clk apb_clk = {
615 .flags = ALWAYS_ENABLED,
616 .pclk = &ahb_clk,
617 .calc_rate = &bus_calc_rate,
618 .recalc = &bus_clk_recalc,
619 .set_rate = &bus_clk_set_rate,
620 .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
621 .private_data = &apb_config,
622};
623
624/* i2c clock */
625static struct clk i2c_clk = {
626 .pclk = &ahb_clk,
627 .en_reg = PERIP1_CLK_ENB,
628 .en_reg_bit = I2C_CLK_ENB,
629 .recalc = &follow_parent,
630};
631
632/* dma clock */
633static struct clk dma_clk = {
634 .pclk = &ahb_clk,
635 .en_reg = PERIP1_CLK_ENB,
636 .en_reg_bit = DMA_CLK_ENB,
637 .recalc = &follow_parent,
638};
639
640/* jpeg clock */
641static struct clk jpeg_clk = {
642 .pclk = &ahb_clk,
643 .en_reg = PERIP1_CLK_ENB,
644 .en_reg_bit = JPEG_CLK_ENB,
645 .recalc = &follow_parent,
646};
647
648/* gmac clock */
649static struct clk gmac_clk = {
650 .pclk = &ahb_clk,
651 .en_reg = PERIP1_CLK_ENB,
652 .en_reg_bit = GMAC_CLK_ENB,
653 .recalc = &follow_parent,
654};
655
656/* smi clock */
657static struct clk smi_clk = {
658 .pclk = &ahb_clk,
659 .en_reg = PERIP1_CLK_ENB,
660 .en_reg_bit = SMI_CLK_ENB,
661 .recalc = &follow_parent,
662};
663
664/* fsmc clock */
665static struct clk fsmc_clk = {
666 .pclk = &ahb_clk,
667 .en_reg = PERIP1_CLK_ENB,
668 .en_reg_bit = FSMC_CLK_ENB,
669 .recalc = &follow_parent,
670};
671
672/* clock derived from apb clk */
673/* adc clock */
674static struct clk adc_clk = {
675 .pclk = &apb_clk,
676 .en_reg = PERIP1_CLK_ENB,
677 .en_reg_bit = ADC_CLK_ENB,
678 .recalc = &follow_parent,
679};
680
681/* ssp0 clock */
682static struct clk ssp0_clk = {
683 .pclk = &apb_clk,
684 .en_reg = PERIP1_CLK_ENB,
685 .en_reg_bit = SSP0_CLK_ENB,
686 .recalc = &follow_parent,
687};
688
689/* ssp1 clock */
690static struct clk ssp1_clk = {
691 .pclk = &apb_clk,
692 .en_reg = PERIP1_CLK_ENB,
693 .en_reg_bit = SSP1_CLK_ENB,
694 .recalc = &follow_parent,
695};
696
697/* ssp2 clock */
698static struct clk ssp2_clk = {
699 .pclk = &apb_clk,
700 .en_reg = PERIP1_CLK_ENB,
701 .en_reg_bit = SSP2_CLK_ENB,
702 .recalc = &follow_parent,
703};
704
705/* gpio0 ARM subsystem clock */
706static struct clk gpio0_clk = {
707 .flags = ALWAYS_ENABLED,
708 .pclk = &apb_clk,
709 .recalc = &follow_parent,
710};
711
712/* gpio1 clock */
713static struct clk gpio1_clk = {
714 .pclk = &apb_clk,
715 .en_reg = PERIP1_CLK_ENB,
716 .en_reg_bit = GPIO1_CLK_ENB,
717 .recalc = &follow_parent,
718};
719
720/* gpio2 clock */
721static struct clk gpio2_clk = {
722 .pclk = &apb_clk,
723 .en_reg = PERIP1_CLK_ENB,
724 .en_reg_bit = GPIO2_CLK_ENB,
725 .recalc = &follow_parent,
726};
727
728static struct clk dummy_apb_pclk;
729
730/* array of all spear 6xx clock lookups */
731static struct clk_lookup spear_clk_lookups[] = {
732 CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
733 /* root clks */
734 CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
735 CLKDEV_INIT(NULL, "osc_30m_clk", &osc_30m_clk),
736 /* clock derived from 32 KHz os clk */
737 CLKDEV_INIT("rtc-spear", NULL, &rtc_clk),
738 /* clock derived from 30 MHz os clk */
739 CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
740 CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
741 CLKDEV_INIT("wdt", NULL, &wdt_clk),
742 /* clock derived from pll1 clk */
743 CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
744 CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
745 CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
746 CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
747 CLKDEV_INIT(NULL, "clcd_synth_clk", &clcd_synth_clk),
748 CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
749 CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
750 CLKDEV_INIT(NULL, "gpt3_synth_clk", &gpt3_synth_clk),
751 CLKDEV_INIT("d0000000.serial", NULL, &uart0_clk),
752 CLKDEV_INIT("d0080000.serial", NULL, &uart1_clk),
753 CLKDEV_INIT("firda", NULL, &firda_clk),
754 CLKDEV_INIT("clcd", NULL, &clcd_clk),
755 CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
756 CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
757 CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
758 CLKDEV_INIT("gpt3", NULL, &gpt3_clk),
759 /* clock derived from pll3 clk */
760 CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
761 CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
762 CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
763 /* clock derived from ahb clk */
764 CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
765 CLKDEV_INIT("d0200000.i2c", NULL, &i2c_clk),
766 CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
767 CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
768 CLKDEV_INIT("gmac", NULL, &gmac_clk),
769 CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
770 CLKDEV_INIT("d1800000.flash", NULL, &fsmc_clk),
771 /* clock derived from apb clk */
772 CLKDEV_INIT("adc", NULL, &adc_clk),
773 CLKDEV_INIT("ssp-pl022.0", NULL, &ssp0_clk),
774 CLKDEV_INIT("ssp-pl022.1", NULL, &ssp1_clk),
775 CLKDEV_INIT("ssp-pl022.2", NULL, &ssp2_clk),
776 CLKDEV_INIT("f0100000.gpio", NULL, &gpio0_clk),
777 CLKDEV_INIT("fc980000.gpio", NULL, &gpio1_clk),
778 CLKDEV_INIT("d8100000.gpio", NULL, &gpio2_clk),
779};
780
781void __init spear6xx_clk_init(void)
782{
783 int i;
784
785 for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
786 clk_register(&spear_clk_lookups[i]);
787
788 clk_init();
789}
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 7167fd331d8..65514b15937 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -16,7 +16,7 @@
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18 18
19void __init spear_setup_timer(resource_size_t base, int irq); 19void __init spear_setup_of_timer(void);
20void spear_restart(char, const char *); 20void spear_restart(char, const char *);
21void __init spear6xx_clk_init(void); 21void __init spear6xx_clk_init(void);
22 22
diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h
index 2b735389e74..37a5c411a86 100644
--- a/arch/arm/mach-spear6xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear6xx/include/mach/irqs.h
@@ -16,9 +16,6 @@
16 16
17/* IRQ definitions */ 17/* IRQ definitions */
18/* VIC 1 */ 18/* VIC 1 */
19/* FIXME: probe this from DT */
20#define IRQ_CPU_GPT1_1 16
21
22#define IRQ_VIC_END 64 19#define IRQ_VIC_END 64
23 20
24/* GPIO pins virtual irqs */ 21/* GPIO pins virtual irqs */
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
index 2b9aaa6cdd1..179e45774b3 100644
--- a/arch/arm/mach-spear6xx/include/mach/misc_regs.h
+++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
@@ -14,6 +14,8 @@
14#ifndef __MACH_MISC_REGS_H 14#ifndef __MACH_MISC_REGS_H
15#define __MACH_MISC_REGS_H 15#define __MACH_MISC_REGS_H
16 16
17#include <mach/spear.h>
18
17#define MISC_BASE IOMEM(VA_SPEAR6XX_ICM3_MISC_REG_BASE) 19#define MISC_BASE IOMEM(VA_SPEAR6XX_ICM3_MISC_REG_BASE)
18#define DMA_CHN_CFG (MISC_BASE + 0x0A0) 20#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
19 21
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
index d278ed047a5..cb8ed2f4dc8 100644
--- a/arch/arm/mach-spear6xx/include/mach/spear.h
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -25,7 +25,6 @@
25/* ML-1, 2 - Multi Layer CPU Subsystem */ 25/* ML-1, 2 - Multi Layer CPU Subsystem */
26#define SPEAR6XX_ML_CPU_BASE UL(0xF0000000) 26#define SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
27#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000) 27#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
28#define SPEAR6XX_CPU_TMR_BASE UL(0xF0000000)
29 28
30/* ICM3 - Basic Subsystem */ 29/* ICM3 - Basic Subsystem */
31#define SPEAR6XX_ICM3_SMI_CTRL_BASE UL(0xFC000000) 30#define SPEAR6XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index de194dbb837..2e2e3596583 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -419,9 +419,6 @@ struct map_desc spear6xx_io_desc[] __initdata = {
419void __init spear6xx_map_io(void) 419void __init spear6xx_map_io(void)
420{ 420{
421 iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc)); 421 iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
422
423 /* This will initialize clock framework */
424 spear6xx_clk_init();
425} 422}
426 423
427static void __init spear6xx_timer_init(void) 424static void __init spear6xx_timer_init(void)
@@ -429,6 +426,8 @@ static void __init spear6xx_timer_init(void)
429 char pclk_name[] = "pll3_48m_clk"; 426 char pclk_name[] = "pll3_48m_clk";
430 struct clk *gpt_clk, *pclk; 427 struct clk *gpt_clk, *pclk;
431 428
429 spear6xx_clk_init();
430
432 /* get the system timer clock */ 431 /* get the system timer clock */
433 gpt_clk = clk_get_sys("gpt0", NULL); 432 gpt_clk = clk_get_sys("gpt0", NULL);
434 if (IS_ERR(gpt_clk)) { 433 if (IS_ERR(gpt_clk)) {
@@ -448,7 +447,7 @@ static void __init spear6xx_timer_init(void)
448 clk_put(gpt_clk); 447 clk_put(gpt_clk);
449 clk_put(pclk); 448 clk_put(pclk);
450 449
451 spear_setup_timer(SPEAR6XX_CPU_TMR_BASE, IRQ_CPU_GPT1_1); 450 spear_setup_of_timer();
452} 451}
453 452
454struct sys_timer spear6xx_timer = { 453struct sys_timer spear6xx_timer = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d0f2546706c..6a113a9bb87 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -50,6 +50,14 @@ config TEGRA_PCI
50 depends on ARCH_TEGRA_2x_SOC 50 depends on ARCH_TEGRA_2x_SOC
51 select PCI 51 select PCI
52 52
53config TEGRA_AHB
54 bool "Enable AHB driver for NVIDIA Tegra SoCs"
55 default y
56 help
57 Adds AHB configuration functionality for NVIDIA Tegra SoCs,
58 which controls AHB bus master arbitration and some
59 perfomance parameters(priority, prefech size).
60
53comment "Tegra board type" 61comment "Tegra board type"
54 62
55config MACH_HARMONY 63config MACH_HARMONY
@@ -111,7 +119,7 @@ config MACH_VENTANA
111 Support for the nVidia Ventana development platform 119 Support for the nVidia Ventana development platform
112 120
113choice 121choice
114 prompt "Low-level debug console UART" 122 prompt "Default low-level debug console UART"
115 default TEGRA_DEBUG_UART_NONE 123 default TEGRA_DEBUG_UART_NONE
116 124
117config TEGRA_DEBUG_UART_NONE 125config TEGRA_DEBUG_UART_NONE
@@ -134,6 +142,33 @@ config TEGRA_DEBUG_UARTE
134 142
135endchoice 143endchoice
136 144
145choice
146 prompt "Automatic low-level debug console UART"
147 default TEGRA_DEBUG_UART_AUTO_NONE
148
149config TEGRA_DEBUG_UART_AUTO_NONE
150 bool "None"
151
152config TEGRA_DEBUG_UART_AUTO_ODMDATA
153 bool "Via ODMDATA"
154 help
155 Automatically determines which UART to use for low-level debug based
156 on the ODMDATA value. This value is part of the BCT, and is written
157 to the boot memory device using nvflash, or other flashing tool.
158 When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
159 0/1/2/3/4 are UART A/B/C/D/E.
160
161config TEGRA_DEBUG_UART_AUTO_SCRATCH
162 bool "Via UART scratch register"
163 help
164 Automatically determines which UART to use for low-level debug based
165 on the UART scratch register value. Some bootloaders put ASCII 'D'
166 in this register when they initialize their own console UART output.
167 Using this option allows the kernel to automatically pick the same
168 UART.
169
170endchoice
171
137config TEGRA_SYSTEM_DMA 172config TEGRA_SYSTEM_DMA
138 bool "Enable system DMA driver for NVIDIA Tegra SoCs" 173 bool "Enable system DMA driver for NVIDIA Tegra SoCs"
139 default y 174 default y
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index fac3eb1af17..eb7249db50a 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -110,6 +110,7 @@ DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
110 .handle_irq = gic_handle_irq, 110 .handle_irq = gic_handle_irq,
111 .timer = &tegra_timer, 111 .timer = &tegra_timer,
112 .init_machine = tegra_dt_init, 112 .init_machine = tegra_dt_init,
113 .init_late = tegra_init_late,
113 .restart = tegra_assert_system_reset, 114 .restart = tegra_assert_system_reset,
114 .dt_compat = tegra20_dt_board_compat, 115 .dt_compat = tegra20_dt_board_compat,
115MACHINE_END 116MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 5f7c03e972f..4f76fa7a5da 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -51,12 +51,22 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
51 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL), 51 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
52 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL), 52 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
53 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL), 53 OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
54 OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
54 {} 55 {}
55}; 56};
56 57
57static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { 58static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
58 /* name parent rate enabled */ 59 /* name parent rate enabled */
59 { "uarta", "pll_p", 408000000, true }, 60 { "uarta", "pll_p", 408000000, true },
61 { "pll_a", "pll_p_out1", 564480000, true },
62 { "pll_a_out0", "pll_a", 11289600, true },
63 { "extern1", "pll_a_out0", 0, true },
64 { "clk_out_1", "extern1", 0, true },
65 { "i2s0", "pll_a_out0", 11289600, false},
66 { "i2s1", "pll_a_out0", 11289600, false},
67 { "i2s2", "pll_a_out0", 11289600, false},
68 { "i2s3", "pll_a_out0", 11289600, false},
69 { "i2s4", "pll_a_out0", 11289600, false},
60 { NULL, NULL, 0, 0}, 70 { NULL, NULL, 0, 0},
61}; 71};
62 72
@@ -80,6 +90,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
80 .handle_irq = gic_handle_irq, 90 .handle_irq = gic_handle_irq,
81 .timer = &tegra_timer, 91 .timer = &tegra_timer,
82 .init_machine = tegra30_dt_init, 92 .init_machine = tegra30_dt_init,
93 .init_late = tegra_init_late,
83 .restart = tegra_assert_system_reset, 94 .restart = tegra_assert_system_reset,
84 .dt_compat = tegra30_dt_board_compat, 95 .dt_compat = tegra30_dt_board_compat,
85MACHINE_END 96MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index b906b3b6077..e65e837f401 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -192,5 +192,6 @@ MACHINE_START(HARMONY, "harmony")
192 .handle_irq = gic_handle_irq, 192 .handle_irq = gic_handle_irq,
193 .timer = &tegra_timer, 193 .timer = &tegra_timer,
194 .init_machine = tegra_harmony_init, 194 .init_machine = tegra_harmony_init,
195 .init_late = tegra_init_late,
195 .restart = tegra_assert_system_reset, 196 .restart = tegra_assert_system_reset,
196MACHINE_END 197MACHINE_END
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index d0735c70d68..bbc1907e98a 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -162,6 +162,8 @@ static void paz00_i2c_init(void)
162 162
163static void paz00_usb_init(void) 163static void paz00_usb_init(void)
164{ 164{
165 tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_ULPI_RST;
166
165 platform_device_register(&tegra_ehci2_device); 167 platform_device_register(&tegra_ehci2_device);
166 platform_device_register(&tegra_ehci3_device); 168 platform_device_register(&tegra_ehci3_device);
167} 169}
@@ -179,7 +181,6 @@ static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
179 { "uarta", "pll_p", 216000000, true }, 181 { "uarta", "pll_p", 216000000, true },
180 { "uartc", "pll_p", 216000000, true }, 182 { "uartc", "pll_p", 216000000, true },
181 183
182 { "pll_p_out4", "pll_p", 24000000, true },
183 { "usbd", "clk_m", 12000000, false }, 184 { "usbd", "clk_m", 12000000, false },
184 { "usb2", "clk_m", 12000000, false }, 185 { "usb2", "clk_m", 12000000, false },
185 { "usb3", "clk_m", 12000000, false }, 186 { "usb3", "clk_m", 12000000, false },
@@ -224,5 +225,6 @@ MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ")
224 .handle_irq = gic_handle_irq, 225 .handle_irq = gic_handle_irq,
225 .timer = &tegra_timer, 226 .timer = &tegra_timer,
226 .init_machine = tegra_paz00_init, 227 .init_machine = tegra_paz00_init,
228 .init_late = tegra_init_late,
227 .restart = tegra_assert_system_reset, 229 .restart = tegra_assert_system_reset,
228MACHINE_END 230MACHINE_END
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index 79064c7a790..71e9f3fc7fb 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -277,6 +277,7 @@ MACHINE_START(SEABOARD, "seaboard")
277 .handle_irq = gic_handle_irq, 277 .handle_irq = gic_handle_irq,
278 .timer = &tegra_timer, 278 .timer = &tegra_timer,
279 .init_machine = tegra_seaboard_init, 279 .init_machine = tegra_seaboard_init,
280 .init_late = tegra_init_late,
280 .restart = tegra_assert_system_reset, 281 .restart = tegra_assert_system_reset,
281MACHINE_END 282MACHINE_END
282 283
@@ -288,6 +289,7 @@ MACHINE_START(KAEN, "kaen")
288 .handle_irq = gic_handle_irq, 289 .handle_irq = gic_handle_irq,
289 .timer = &tegra_timer, 290 .timer = &tegra_timer,
290 .init_machine = tegra_kaen_init, 291 .init_machine = tegra_kaen_init,
292 .init_late = tegra_init_late,
291 .restart = tegra_assert_system_reset, 293 .restart = tegra_assert_system_reset,
292MACHINE_END 294MACHINE_END
293 295
@@ -299,5 +301,6 @@ MACHINE_START(WARIO, "wario")
299 .handle_irq = gic_handle_irq, 301 .handle_irq = gic_handle_irq,
300 .timer = &tegra_timer, 302 .timer = &tegra_timer,
301 .init_machine = tegra_wario_init, 303 .init_machine = tegra_wario_init,
304 .init_late = tegra_init_late,
302 .restart = tegra_assert_system_reset, 305 .restart = tegra_assert_system_reset,
303MACHINE_END 306MACHINE_END
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index bc59b379c6f..776aa9564d5 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -118,6 +118,8 @@ static void trimslice_usb_init(void)
118 pdata = tegra_ehci1_device.dev.platform_data; 118 pdata = tegra_ehci1_device.dev.platform_data;
119 pdata->vbus_gpio = TRIMSLICE_GPIO_USB1_MODE; 119 pdata->vbus_gpio = TRIMSLICE_GPIO_USB1_MODE;
120 120
121 tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_GPIO_PV0;
122
121 platform_device_register(&tegra_ehci3_device); 123 platform_device_register(&tegra_ehci3_device);
122 platform_device_register(&tegra_ehci2_device); 124 platform_device_register(&tegra_ehci2_device);
123 platform_device_register(&tegra_ehci1_device); 125 platform_device_register(&tegra_ehci1_device);
@@ -176,5 +178,6 @@ MACHINE_START(TRIMSLICE, "trimslice")
176 .handle_irq = gic_handle_irq, 178 .handle_irq = gic_handle_irq,
177 .timer = &tegra_timer, 179 .timer = &tegra_timer,
178 .init_machine = tegra_trimslice_init, 180 .init_machine = tegra_trimslice_init,
181 .init_late = tegra_init_late,
179 .restart = tegra_assert_system_reset, 182 .restart = tegra_assert_system_reset,
180MACHINE_END 183MACHINE_END
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 75d1543d77c..65014968fc6 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -32,5 +32,19 @@ void __init tegra_init_irq(void);
32void __init tegra_dt_init_irq(void); 32void __init tegra_dt_init_irq(void);
33int __init tegra_pcie_init(bool init_port0, bool init_port1); 33int __init tegra_pcie_init(bool init_port0, bool init_port1);
34 34
35void tegra_init_late(void);
36
37#ifdef CONFIG_DEBUG_FS
38int tegra_clk_debugfs_init(void);
39#else
40static inline int tegra_clk_debugfs_init(void) { return 0; }
41#endif
42
43#if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS)
44int __init tegra_powergate_debugfs_init(void);
45#else
46static inline int tegra_powergate_debugfs_init(void) { return 0; }
47#endif
48
35extern struct sys_timer tegra_timer; 49extern struct sys_timer tegra_timer;
36#endif 50#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 8dad8d18cb4..58f981c0819 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -642,7 +642,7 @@ static int clk_debugfs_register(struct clk *c)
642 return 0; 642 return 0;
643} 643}
644 644
645static int __init clk_debugfs_init(void) 645int __init tegra_clk_debugfs_init(void)
646{ 646{
647 struct clk *c; 647 struct clk *c;
648 struct dentry *d; 648 struct dentry *d;
@@ -669,5 +669,4 @@ err_out:
669 return err; 669 return err;
670} 670}
671 671
672late_initcall(clk_debugfs_init);
673#endif 672#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 22df10fb997..204a5c8b0b5 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -82,10 +82,12 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
82 { "pll_p_out1", "pll_p", 28800000, true }, 82 { "pll_p_out1", "pll_p", 28800000, true },
83 { "pll_p_out2", "pll_p", 48000000, true }, 83 { "pll_p_out2", "pll_p", 48000000, true },
84 { "pll_p_out3", "pll_p", 72000000, true }, 84 { "pll_p_out3", "pll_p", 72000000, true },
85 { "pll_p_out4", "pll_p", 108000000, true }, 85 { "pll_p_out4", "pll_p", 24000000, true },
86 { "sclk", "pll_p_out4", 108000000, true }, 86 { "pll_c", "clk_m", 600000000, true },
87 { "hclk", "sclk", 108000000, true }, 87 { "pll_c_out1", "pll_c", 120000000, true },
88 { "pclk", "hclk", 54000000, true }, 88 { "sclk", "pll_c_out1", 120000000, true },
89 { "hclk", "sclk", 120000000, true },
90 { "pclk", "hclk", 60000000, true },
89 { "csite", NULL, 0, true }, 91 { "csite", NULL, 0, true },
90 { "emc", NULL, 0, true }, 92 { "emc", NULL, 0, true },
91 { "cpu", NULL, 0, true }, 93 { "cpu", NULL, 0, true },
@@ -93,6 +95,17 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
93}; 95};
94#endif 96#endif
95 97
98#ifdef CONFIG_ARCH_TEGRA_3x_SOC
99static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
100 /* name parent rate enabled */
101 { "clk_m", NULL, 0, true },
102 { "pll_p", "clk_m", 408000000, true },
103 { "pll_p_out1", "pll_p", 9600000, true },
104 { NULL, NULL, 0, 0},
105};
106#endif
107
108
96static void __init tegra_init_cache(u32 tag_latency, u32 data_latency) 109static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
97{ 110{
98#ifdef CONFIG_CACHE_L2X0 111#ifdef CONFIG_CACHE_L2X0
@@ -127,8 +140,15 @@ void __init tegra30_init_early(void)
127{ 140{
128 tegra_init_fuse(); 141 tegra_init_fuse();
129 tegra30_init_clocks(); 142 tegra30_init_clocks();
143 tegra_clk_init_from_table(tegra30_clk_init_table);
130 tegra_init_cache(0x441, 0x551); 144 tegra_init_cache(0x441, 0x551);
131 tegra_pmc_init(); 145 tegra_pmc_init();
132 tegra_powergate_init(); 146 tegra_powergate_init();
133} 147}
134#endif 148#endif
149
150void __init tegra_init_late(void)
151{
152 tegra_clk_debugfs_init();
153 tegra_powergate_debugfs_init();
154}
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 2d8dfa2faf8..c70e65ffa36 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -439,9 +439,8 @@ static struct resource tegra_usb3_resources[] = {
439 }, 439 },
440}; 440};
441 441
442static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = { 442struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
443 /* All existing boards use GPIO PV0 for phy reset */ 443 .reset_gpio = -1,
444 .reset_gpio = TEGRA_GPIO_PV0,
445 .clk = "cdev2", 444 .clk = "cdev2",
446}; 445};
447 446
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 138c642e59f..4f505272649 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -22,6 +22,10 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/platform_data/tegra_usb.h> 23#include <linux/platform_data/tegra_usb.h>
24 24
25#include <mach/usb_phy.h>
26
27extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config;
28
25extern struct tegra_ehci_platform_data tegra_ehci1_pdata; 29extern struct tegra_ehci_platform_data tegra_ehci1_pdata;
26extern struct tegra_ehci_platform_data tegra_ehci2_pdata; 30extern struct tegra_ehci_platform_data tegra_ehci2_pdata;
27extern struct tegra_ehci_platform_data tegra_ehci3_pdata; 31extern struct tegra_ehci_platform_data tegra_ehci3_pdata;
diff --git a/arch/arm/mach-tegra/include/mach/tegra-ahb.h b/arch/arm/mach-tegra/include/mach/tegra-ahb.h
new file mode 100644
index 00000000000..e0f8c84b1d8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra-ahb.h
@@ -0,0 +1,19 @@
1/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 */
13
14#ifndef __MACH_TEGRA_AHB_H__
15#define __MACH_TEGRA_AHB_H__
16
17extern int tegra_ahb_enable_smmu(struct device_node *ahb);
18
19#endif /* __MACH_TEGRA_AHB_H__ */
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 5a440f315e5..937c4c50219 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -63,52 +63,86 @@ static inline void save_uart_address(void)
63 buf[0] = 0; 63 buf[0] = 0;
64} 64}
65 65
66/* 66static const struct {
67 * Setup before decompression. This is where we do UART selection for 67 u32 base;
68 * earlyprintk and init the uart_base register. 68 u32 reset_reg;
69 */ 69 u32 clock_reg;
70static inline void arch_decomp_setup(void) 70 u32 bit;
71} uarts[] = {
72 {
73 TEGRA_UARTA_BASE,
74 TEGRA_CLK_RESET_BASE + 0x04,
75 TEGRA_CLK_RESET_BASE + 0x10,
76 6,
77 },
78 {
79 TEGRA_UARTB_BASE,
80 TEGRA_CLK_RESET_BASE + 0x04,
81 TEGRA_CLK_RESET_BASE + 0x10,
82 7,
83 },
84 {
85 TEGRA_UARTC_BASE,
86 TEGRA_CLK_RESET_BASE + 0x08,
87 TEGRA_CLK_RESET_BASE + 0x14,
88 23,
89 },
90 {
91 TEGRA_UARTD_BASE,
92 TEGRA_CLK_RESET_BASE + 0x0c,
93 TEGRA_CLK_RESET_BASE + 0x18,
94 1,
95 },
96 {
97 TEGRA_UARTE_BASE,
98 TEGRA_CLK_RESET_BASE + 0x0c,
99 TEGRA_CLK_RESET_BASE + 0x18,
100 2,
101 },
102};
103
104static inline bool uart_clocked(int i)
105{
106 if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
107 return false;
108
109 if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
110 return false;
111
112 return true;
113}
114
115#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
116int auto_odmdata(void)
117{
118 volatile u32 *pmc = (volatile u32 *)TEGRA_PMC_BASE;
119 u32 odmdata = pmc[0xa0 / 4];
120
121 /*
122 * Bits 19:18 are the console type: 0=default, 1=none, 2==DCC, 3==UART
123 * Some boards apparently swap the last two values, but we don't have
124 * any way of catering for that here, so we just accept either. If this
125 * doesn't make sense for your board, just don't enable this feature.
126 *
127 * Bits 17:15 indicate the UART to use, 0/1/2/3/4 are UART A/B/C/D/E.
128 */
129
130 switch ((odmdata >> 18) & 3) {
131 case 2:
132 case 3:
133 break;
134 default:
135 return -1;
136 }
137
138 return (odmdata >> 15) & 7;
139}
140#endif
141
142#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH
143int auto_scratch(void)
71{ 144{
72 static const struct {
73 u32 base;
74 u32 reset_reg;
75 u32 clock_reg;
76 u32 bit;
77 } uarts[] = {
78 {
79 TEGRA_UARTA_BASE,
80 TEGRA_CLK_RESET_BASE + 0x04,
81 TEGRA_CLK_RESET_BASE + 0x10,
82 6,
83 },
84 {
85 TEGRA_UARTB_BASE,
86 TEGRA_CLK_RESET_BASE + 0x04,
87 TEGRA_CLK_RESET_BASE + 0x10,
88 7,
89 },
90 {
91 TEGRA_UARTC_BASE,
92 TEGRA_CLK_RESET_BASE + 0x08,
93 TEGRA_CLK_RESET_BASE + 0x14,
94 23,
95 },
96 {
97 TEGRA_UARTD_BASE,
98 TEGRA_CLK_RESET_BASE + 0x0c,
99 TEGRA_CLK_RESET_BASE + 0x18,
100 1,
101 },
102 {
103 TEGRA_UARTE_BASE,
104 TEGRA_CLK_RESET_BASE + 0x0c,
105 TEGRA_CLK_RESET_BASE + 0x18,
106 2,
107 },
108 };
109 int i; 145 int i;
110 volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
111 u32 chip, div;
112 146
113 /* 147 /*
114 * Look for the first UART that: 148 * Look for the first UART that:
@@ -125,20 +159,60 @@ static inline void arch_decomp_setup(void)
125 * back to what's specified in TEGRA_DEBUG_UART_BASE. 159 * back to what's specified in TEGRA_DEBUG_UART_BASE.
126 */ 160 */
127 for (i = 0; i < ARRAY_SIZE(uarts); i++) { 161 for (i = 0; i < ARRAY_SIZE(uarts); i++) {
128 if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit)) 162 if (!uart_clocked(i))
129 continue;
130
131 if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
132 continue; 163 continue;
133 164
134 uart = (volatile u8 *)uarts[i].base; 165 uart = (volatile u8 *)uarts[i].base;
135 if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D') 166 if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
136 continue; 167 continue;
137 168
138 break; 169 return i;
139 } 170 }
140 if (i == ARRAY_SIZE(uarts)) 171
141 uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE; 172 return -1;
173}
174#endif
175
176/*
177 * Setup before decompression. This is where we do UART selection for
178 * earlyprintk and init the uart_base register.
179 */
180static inline void arch_decomp_setup(void)
181{
182 int uart_id, auto_uart_id;
183 volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
184 u32 chip, div;
185
186#if defined(CONFIG_TEGRA_DEBUG_UARTA)
187 uart_id = 0;
188#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
189 uart_id = 1;
190#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
191 uart_id = 2;
192#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
193 uart_id = 3;
194#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
195 uart_id = 4;
196#else
197 uart_id = -1;
198#endif
199
200#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
201 auto_uart_id = auto_odmdata();
202#elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH)
203 auto_uart_id = auto_scratch();
204#else
205 auto_uart_id = -1;
206#endif
207 if (auto_uart_id != -1)
208 uart_id = auto_uart_id;
209
210 if (uart_id < 0 || uart_id >= ARRAY_SIZE(uarts) ||
211 !uart_clocked(uart_id))
212 uart = NULL;
213 else
214 uart = (volatile u8 *)uarts[uart_id].base;
215
142 save_uart_address(); 216 save_uart_address();
143 if (uart == NULL) 217 if (uart == NULL)
144 return; 218 return;
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index de1a0f602b2..935ce9f6559 100644
--- a/arch/arm/mach-tegra/include/mach/usb_phy.h
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -61,8 +61,8 @@ struct tegra_usb_phy {
61 struct usb_phy *ulpi; 61 struct usb_phy *ulpi;
62}; 62};
63 63
64struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, 64struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
65 void *config, enum tegra_usb_phy_mode phy_mode); 65 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
66 66
67int tegra_usb_phy_power_on(struct tegra_usb_phy *phy); 67int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
68 68
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index c238699ae86..f5b12fb4ff1 100644
--- a/arch/arm/mach-tegra/powergate.c
+++ b/arch/arm/mach-tegra/powergate.c
@@ -234,7 +234,7 @@ static const struct file_operations powergate_fops = {
234 .release = single_release, 234 .release = single_release,
235}; 235};
236 236
237static int __init powergate_debugfs_init(void) 237int __init tegra_powergate_debugfs_init(void)
238{ 238{
239 struct dentry *d; 239 struct dentry *d;
240 int err = -ENOMEM; 240 int err = -ENOMEM;
@@ -247,6 +247,4 @@ static int __init powergate_debugfs_init(void)
247 return err; 247 return err;
248} 248}
249 249
250late_initcall(powergate_debugfs_init);
251
252#endif 250#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index bae09b85989..b59315ce369 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -1486,6 +1486,10 @@ static struct clk tegra_clk_m = {
1486}; 1486};
1487 1487
1488static struct clk_pll_freq_table tegra_pll_c_freq_table[] = { 1488static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
1489 { 12000000, 600000000, 600, 12, 1, 8 },
1490 { 13000000, 600000000, 600, 13, 1, 8 },
1491 { 19200000, 600000000, 500, 16, 1, 6 },
1492 { 26000000, 600000000, 600, 26, 1, 8 },
1489 { 0, 0, 0, 0, 0, 0 }, 1493 { 0, 0, 0, 0, 0, 0 },
1490}; 1494};
1491 1495
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
index 6d08b53f92d..e33fe4b14a2 100644
--- a/arch/arm/mach-tegra/tegra30_clocks.c
+++ b/arch/arm/mach-tegra/tegra30_clocks.c
@@ -3015,6 +3015,15 @@ struct clk_duplicate tegra_clk_duplicates[] = {
3015 CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL), 3015 CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
3016 CLK_DUPLICATE("twd", "smp_twd", NULL), 3016 CLK_DUPLICATE("twd", "smp_twd", NULL),
3017 CLK_DUPLICATE("vcp", "nvavp", "vcp"), 3017 CLK_DUPLICATE("vcp", "nvavp", "vcp"),
3018 CLK_DUPLICATE("i2s0", NULL, "i2s0"),
3019 CLK_DUPLICATE("i2s1", NULL, "i2s1"),
3020 CLK_DUPLICATE("i2s2", NULL, "i2s2"),
3021 CLK_DUPLICATE("i2s3", NULL, "i2s3"),
3022 CLK_DUPLICATE("i2s4", NULL, "i2s4"),
3023 CLK_DUPLICATE("dam0", NULL, "dam0"),
3024 CLK_DUPLICATE("dam1", NULL, "dam1"),
3025 CLK_DUPLICATE("dam2", NULL, "dam2"),
3026 CLK_DUPLICATE("spdif_in", NULL, "spdif_in"),
3018}; 3027};
3019 3028
3020struct clk *tegra_ptr_clks[] = { 3029struct clk *tegra_ptr_clks[] = {
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index d71d2fed672..54e353c8e30 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/of_gpio.h>
29#include <linux/usb/otg.h> 30#include <linux/usb/otg.h>
30#include <linux/usb/ulpi.h> 31#include <linux/usb/ulpi.h>
31#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -654,8 +655,8 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
654 clk_disable(phy->clk); 655 clk_disable(phy->clk);
655} 656}
656 657
657struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs, 658struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
658 void *config, enum tegra_usb_phy_mode phy_mode) 659 void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
659{ 660{
660 struct tegra_usb_phy *phy; 661 struct tegra_usb_phy *phy;
661 struct tegra_ulpi_config *ulpi_config; 662 struct tegra_ulpi_config *ulpi_config;
@@ -711,6 +712,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
711 err = -ENXIO; 712 err = -ENXIO;
712 goto err1; 713 goto err1;
713 } 714 }
715 if (!gpio_is_valid(ulpi_config->reset_gpio))
716 ulpi_config->reset_gpio =
717 of_get_named_gpio(dev->of_node,
718 "nvidia,phy-reset-gpio", 0);
719 if (!gpio_is_valid(ulpi_config->reset_gpio)) {
720 pr_err("%s: invalid reset gpio: %d\n", __func__,
721 ulpi_config->reset_gpio);
722 err = -EINVAL;
723 goto err1;
724 }
714 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b"); 725 gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
715 gpio_direction_output(ulpi_config->reset_gpio, 0); 726 gpio_direction_output(ulpi_config->reset_gpio, 0);
716 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); 727 phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index f943687acaf..fba8adea421 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -206,7 +206,7 @@ static struct resource ab8500_resources[] = {
206}; 206};
207 207
208struct platform_device ab8500_device = { 208struct platform_device ab8500_device = {
209 .name = "ab8500-i2c", 209 .name = "ab8500-core",
210 .id = 0, 210 .id = 0,
211 .dev = { 211 .dev = {
212 .platform_data = &ab8500_platdata, 212 .platform_data = &ab8500_platdata,
@@ -785,6 +785,7 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
785 .timer = &ux500_timer, 785 .timer = &ux500_timer,
786 .handle_irq = gic_handle_irq, 786 .handle_irq = gic_handle_irq,
787 .init_machine = mop500_init_machine, 787 .init_machine = mop500_init_machine,
788 .init_late = ux500_init_late,
788MACHINE_END 789MACHINE_END
789 790
790MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") 791MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
@@ -794,6 +795,7 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
794 .timer = &ux500_timer, 795 .timer = &ux500_timer,
795 .handle_irq = gic_handle_irq, 796 .handle_irq = gic_handle_irq,
796 .init_machine = hrefv60_init_machine, 797 .init_machine = hrefv60_init_machine,
798 .init_late = ux500_init_late,
797MACHINE_END 799MACHINE_END
798 800
799MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") 801MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
@@ -804,6 +806,7 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
804 .timer = &ux500_timer, 806 .timer = &ux500_timer,
805 .handle_irq = gic_handle_irq, 807 .handle_irq = gic_handle_irq,
806 .init_machine = snowball_init_machine, 808 .init_machine = snowball_init_machine,
809 .init_late = ux500_init_late,
807MACHINE_END 810MACHINE_END
808 811
809#ifdef CONFIG_MACH_UX500_DT 812#ifdef CONFIG_MACH_UX500_DT
@@ -918,6 +921,7 @@ DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
918 .timer = &ux500_timer, 921 .timer = &ux500_timer,
919 .handle_irq = gic_handle_irq, 922 .handle_irq = gic_handle_irq,
920 .init_machine = u8500_init_machine, 923 .init_machine = u8500_init_machine,
924 .init_late = ux500_init_late,
921 .dt_compat = u8500_dt_board_compat, 925 .dt_compat = u8500_dt_board_compat,
922MACHINE_END 926MACHINE_END
923#endif 927#endif
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 1762c4728f1..8d73b066a18 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -635,7 +635,7 @@ static int clk_debugfs_register(struct clk *c)
635 return 0; 635 return 0;
636} 636}
637 637
638static int __init clk_debugfs_init(void) 638int __init clk_debugfs_init(void)
639{ 639{
640 struct clk *c; 640 struct clk *c;
641 struct dentry *d; 641 struct dentry *d;
@@ -657,7 +657,6 @@ err_out:
657 return err; 657 return err;
658} 658}
659 659
660late_initcall(clk_debugfs_init);
661#endif /* defined(CONFIG_DEBUG_FS) */ 660#endif /* defined(CONFIG_DEBUG_FS) */
662 661
663unsigned long clk_smp_twd_rate = 500000000; 662unsigned long clk_smp_twd_rate = 500000000;
@@ -696,12 +695,11 @@ static struct notifier_block clk_twd_cpufreq_nb = {
696 .notifier_call = clk_twd_cpufreq_transition, 695 .notifier_call = clk_twd_cpufreq_transition,
697}; 696};
698 697
699static int clk_init_smp_twd_cpufreq(void) 698int clk_init_smp_twd_cpufreq(void)
700{ 699{
701 return cpufreq_register_notifier(&clk_twd_cpufreq_nb, 700 return cpufreq_register_notifier(&clk_twd_cpufreq_nb,
702 CPUFREQ_TRANSITION_NOTIFIER); 701 CPUFREQ_TRANSITION_NOTIFIER);
703} 702}
704late_initcall(clk_init_smp_twd_cpufreq);
705 703
706#endif 704#endif
707 705
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
index d776ada08db..65d27a13f46 100644
--- a/arch/arm/mach-ux500/clock.h
+++ b/arch/arm/mach-ux500/clock.h
@@ -150,3 +150,15 @@ struct clk clk_##_name = { \
150 150
151int __init clk_db8500_ed_fixup(void); 151int __init clk_db8500_ed_fixup(void);
152int __init clk_init(void); 152int __init clk_init(void);
153
154#ifdef CONFIG_DEBUG_FS
155int clk_debugfs_init(void);
156#else
157static inline int clk_debugfs_init(void) { return 0; }
158#endif
159
160#ifdef CONFIG_CPU_FREQ
161int clk_init_smp_twd_cpufreq(void);
162#else
163static inline int clk_init_smp_twd_cpufreq(void) { return 0; }
164#endif
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index a29a0e3adcf..e2360e7c770 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -73,6 +73,12 @@ void __init ux500_init_irq(void)
73 clk_init(); 73 clk_init();
74} 74}
75 75
76void __init ux500_init_late(void)
77{
78 clk_debugfs_init();
79 clk_init_smp_twd_cpufreq();
80}
81
76static const char * __init ux500_get_machine(void) 82static const char * __init ux500_get_machine(void)
77{ 83{
78 return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); 84 return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index 4e369f1645e..8b7ed82a286 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -20,6 +20,7 @@ extern void __init u8500_map_io(void);
20extern struct device * __init u8500_init_devices(void); 20extern struct device * __init u8500_init_devices(void);
21 21
22extern void __init ux500_init_irq(void); 22extern void __init ux500_init_irq(void);
23extern void __init ux500_init_late(void);
23 24
24extern struct device *ux500_soc_device_init(const char *soc_id); 25extern struct device *ux500_soc_device_init(const char *soc_id);
25 26
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index db23ae4aaaa..ea6b4315409 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -17,8 +17,12 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
20#include <linux/dma-contiguous.h>
20#include <linux/highmem.h> 21#include <linux/highmem.h>
22#include <linux/memblock.h>
21#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/iommu.h>
25#include <linux/vmalloc.h>
22 26
23#include <asm/memory.h> 27#include <asm/memory.h>
24#include <asm/highmem.h> 28#include <asm/highmem.h>
@@ -26,9 +30,112 @@
26#include <asm/tlbflush.h> 30#include <asm/tlbflush.h>
27#include <asm/sizes.h> 31#include <asm/sizes.h>
28#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
33#include <asm/dma-iommu.h>
34#include <asm/mach/map.h>
35#include <asm/system_info.h>
36#include <asm/dma-contiguous.h>
29 37
30#include "mm.h" 38#include "mm.h"
31 39
40/*
41 * The DMA API is built upon the notion of "buffer ownership". A buffer
42 * is either exclusively owned by the CPU (and therefore may be accessed
43 * by it) or exclusively owned by the DMA device. These helper functions
44 * represent the transitions between these two ownership states.
45 *
46 * Note, however, that on later ARMs, this notion does not work due to
47 * speculative prefetches. We model our approach on the assumption that
48 * the CPU does do speculative prefetches, which means we clean caches
49 * before transfers and delay cache invalidation until transfer completion.
50 *
51 */
52static void __dma_page_cpu_to_dev(struct page *, unsigned long,
53 size_t, enum dma_data_direction);
54static void __dma_page_dev_to_cpu(struct page *, unsigned long,
55 size_t, enum dma_data_direction);
56
57/**
58 * arm_dma_map_page - map a portion of a page for streaming DMA
59 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
60 * @page: page that buffer resides in
61 * @offset: offset into page for start of buffer
62 * @size: size of buffer to map
63 * @dir: DMA transfer direction
64 *
65 * Ensure that any data held in the cache is appropriately discarded
66 * or written back.
67 *
68 * The device owns this memory once this call has completed. The CPU
69 * can regain ownership by calling dma_unmap_page().
70 */
71static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
72 unsigned long offset, size_t size, enum dma_data_direction dir,
73 struct dma_attrs *attrs)
74{
75 if (!arch_is_coherent())
76 __dma_page_cpu_to_dev(page, offset, size, dir);
77 return pfn_to_dma(dev, page_to_pfn(page)) + offset;
78}
79
80/**
81 * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
82 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
83 * @handle: DMA address of buffer
84 * @size: size of buffer (same as passed to dma_map_page)
85 * @dir: DMA transfer direction (same as passed to dma_map_page)
86 *
87 * Unmap a page streaming mode DMA translation. The handle and size
88 * must match what was provided in the previous dma_map_page() call.
89 * All other usages are undefined.
90 *
91 * After this call, reads by the CPU to the buffer are guaranteed to see
92 * whatever the device wrote there.
93 */
94static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
95 size_t size, enum dma_data_direction dir,
96 struct dma_attrs *attrs)
97{
98 if (!arch_is_coherent())
99 __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
100 handle & ~PAGE_MASK, size, dir);
101}
102
103static void arm_dma_sync_single_for_cpu(struct device *dev,
104 dma_addr_t handle, size_t size, enum dma_data_direction dir)
105{
106 unsigned int offset = handle & (PAGE_SIZE - 1);
107 struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
108 if (!arch_is_coherent())
109 __dma_page_dev_to_cpu(page, offset, size, dir);
110}
111
112static void arm_dma_sync_single_for_device(struct device *dev,
113 dma_addr_t handle, size_t size, enum dma_data_direction dir)
114{
115 unsigned int offset = handle & (PAGE_SIZE - 1);
116 struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
117 if (!arch_is_coherent())
118 __dma_page_cpu_to_dev(page, offset, size, dir);
119}
120
121static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
122
123struct dma_map_ops arm_dma_ops = {
124 .alloc = arm_dma_alloc,
125 .free = arm_dma_free,
126 .mmap = arm_dma_mmap,
127 .map_page = arm_dma_map_page,
128 .unmap_page = arm_dma_unmap_page,
129 .map_sg = arm_dma_map_sg,
130 .unmap_sg = arm_dma_unmap_sg,
131 .sync_single_for_cpu = arm_dma_sync_single_for_cpu,
132 .sync_single_for_device = arm_dma_sync_single_for_device,
133 .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
134 .sync_sg_for_device = arm_dma_sync_sg_for_device,
135 .set_dma_mask = arm_dma_set_mask,
136};
137EXPORT_SYMBOL(arm_dma_ops);
138
32static u64 get_coherent_dma_mask(struct device *dev) 139static u64 get_coherent_dma_mask(struct device *dev)
33{ 140{
34 u64 mask = (u64)arm_dma_limit; 141 u64 mask = (u64)arm_dma_limit;
@@ -56,6 +163,21 @@ static u64 get_coherent_dma_mask(struct device *dev)
56 return mask; 163 return mask;
57} 164}
58 165
166static void __dma_clear_buffer(struct page *page, size_t size)
167{
168 void *ptr;
169 /*
170 * Ensure that the allocated pages are zeroed, and that any data
171 * lurking in the kernel direct-mapped region is invalidated.
172 */
173 ptr = page_address(page);
174 if (ptr) {
175 memset(ptr, 0, size);
176 dmac_flush_range(ptr, ptr + size);
177 outer_flush_range(__pa(ptr), __pa(ptr) + size);
178 }
179}
180
59/* 181/*
60 * Allocate a DMA buffer for 'dev' of size 'size' using the 182 * Allocate a DMA buffer for 'dev' of size 'size' using the
61 * specified gfp mask. Note that 'size' must be page aligned. 183 * specified gfp mask. Note that 'size' must be page aligned.
@@ -64,23 +186,6 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
64{ 186{
65 unsigned long order = get_order(size); 187 unsigned long order = get_order(size);
66 struct page *page, *p, *e; 188 struct page *page, *p, *e;
67 void *ptr;
68 u64 mask = get_coherent_dma_mask(dev);
69
70#ifdef CONFIG_DMA_API_DEBUG
71 u64 limit = (mask + 1) & ~mask;
72 if (limit && size >= limit) {
73 dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
74 size, mask);
75 return NULL;
76 }
77#endif
78
79 if (!mask)
80 return NULL;
81
82 if (mask < 0xffffffffULL)
83 gfp |= GFP_DMA;
84 189
85 page = alloc_pages(gfp, order); 190 page = alloc_pages(gfp, order);
86 if (!page) 191 if (!page)
@@ -93,14 +198,7 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
93 for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++) 198 for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
94 __free_page(p); 199 __free_page(p);
95 200
96 /* 201 __dma_clear_buffer(page, size);
97 * Ensure that the allocated pages are zeroed, and that any data
98 * lurking in the kernel direct-mapped region is invalidated.
99 */
100 ptr = page_address(page);
101 memset(ptr, 0, size);
102 dmac_flush_range(ptr, ptr + size);
103 outer_flush_range(__pa(ptr), __pa(ptr) + size);
104 202
105 return page; 203 return page;
106} 204}
@@ -170,6 +268,11 @@ static int __init consistent_init(void)
170 unsigned long base = consistent_base; 268 unsigned long base = consistent_base;
171 unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT; 269 unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
172 270
271#ifndef CONFIG_ARM_DMA_USE_IOMMU
272 if (cpu_architecture() >= CPU_ARCH_ARMv6)
273 return 0;
274#endif
275
173 consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL); 276 consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
174 if (!consistent_pte) { 277 if (!consistent_pte) {
175 pr_err("%s: no memory\n", __func__); 278 pr_err("%s: no memory\n", __func__);
@@ -184,14 +287,14 @@ static int __init consistent_init(void)
184 287
185 pud = pud_alloc(&init_mm, pgd, base); 288 pud = pud_alloc(&init_mm, pgd, base);
186 if (!pud) { 289 if (!pud) {
187 printk(KERN_ERR "%s: no pud tables\n", __func__); 290 pr_err("%s: no pud tables\n", __func__);
188 ret = -ENOMEM; 291 ret = -ENOMEM;
189 break; 292 break;
190 } 293 }
191 294
192 pmd = pmd_alloc(&init_mm, pud, base); 295 pmd = pmd_alloc(&init_mm, pud, base);
193 if (!pmd) { 296 if (!pmd) {
194 printk(KERN_ERR "%s: no pmd tables\n", __func__); 297 pr_err("%s: no pmd tables\n", __func__);
195 ret = -ENOMEM; 298 ret = -ENOMEM;
196 break; 299 break;
197 } 300 }
@@ -199,7 +302,7 @@ static int __init consistent_init(void)
199 302
200 pte = pte_alloc_kernel(pmd, base); 303 pte = pte_alloc_kernel(pmd, base);
201 if (!pte) { 304 if (!pte) {
202 printk(KERN_ERR "%s: no pte tables\n", __func__); 305 pr_err("%s: no pte tables\n", __func__);
203 ret = -ENOMEM; 306 ret = -ENOMEM;
204 break; 307 break;
205 } 308 }
@@ -210,9 +313,101 @@ static int __init consistent_init(void)
210 313
211 return ret; 314 return ret;
212} 315}
213
214core_initcall(consistent_init); 316core_initcall(consistent_init);
215 317
318static void *__alloc_from_contiguous(struct device *dev, size_t size,
319 pgprot_t prot, struct page **ret_page);
320
321static struct arm_vmregion_head coherent_head = {
322 .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
323 .vm_list = LIST_HEAD_INIT(coherent_head.vm_list),
324};
325
326size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8;
327
328static int __init early_coherent_pool(char *p)
329{
330 coherent_pool_size = memparse(p, &p);
331 return 0;
332}
333early_param("coherent_pool", early_coherent_pool);
334
335/*
336 * Initialise the coherent pool for atomic allocations.
337 */
338static int __init coherent_init(void)
339{
340 pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
341 size_t size = coherent_pool_size;
342 struct page *page;
343 void *ptr;
344
345 if (cpu_architecture() < CPU_ARCH_ARMv6)
346 return 0;
347
348 ptr = __alloc_from_contiguous(NULL, size, prot, &page);
349 if (ptr) {
350 coherent_head.vm_start = (unsigned long) ptr;
351 coherent_head.vm_end = (unsigned long) ptr + size;
352 printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n",
353 (unsigned)size / 1024);
354 return 0;
355 }
356 printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
357 (unsigned)size / 1024);
358 return -ENOMEM;
359}
360/*
361 * CMA is activated by core_initcall, so we must be called after it.
362 */
363postcore_initcall(coherent_init);
364
365struct dma_contig_early_reserve {
366 phys_addr_t base;
367 unsigned long size;
368};
369
370static struct dma_contig_early_reserve dma_mmu_remap[MAX_CMA_AREAS] __initdata;
371
372static int dma_mmu_remap_num __initdata;
373
374void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
375{
376 dma_mmu_remap[dma_mmu_remap_num].base = base;
377 dma_mmu_remap[dma_mmu_remap_num].size = size;
378 dma_mmu_remap_num++;
379}
380
381void __init dma_contiguous_remap(void)
382{
383 int i;
384 for (i = 0; i < dma_mmu_remap_num; i++) {
385 phys_addr_t start = dma_mmu_remap[i].base;
386 phys_addr_t end = start + dma_mmu_remap[i].size;
387 struct map_desc map;
388 unsigned long addr;
389
390 if (end > arm_lowmem_limit)
391 end = arm_lowmem_limit;
392 if (start >= end)
393 return;
394
395 map.pfn = __phys_to_pfn(start);
396 map.virtual = __phys_to_virt(start);
397 map.length = end - start;
398 map.type = MT_MEMORY_DMA_READY;
399
400 /*
401 * Clear previous low-memory mapping
402 */
403 for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
404 addr += PMD_SIZE)
405 pmd_clear(pmd_off_k(addr));
406
407 iotable_init(&map, 1);
408 }
409}
410
216static void * 411static void *
217__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, 412__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
218 const void *caller) 413 const void *caller)
@@ -222,7 +417,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
222 int bit; 417 int bit;
223 418
224 if (!consistent_pte) { 419 if (!consistent_pte) {
225 printk(KERN_ERR "%s: not initialised\n", __func__); 420 pr_err("%s: not initialised\n", __func__);
226 dump_stack(); 421 dump_stack();
227 return NULL; 422 return NULL;
228 } 423 }
@@ -249,7 +444,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
249 u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); 444 u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
250 445
251 pte = consistent_pte[idx] + off; 446 pte = consistent_pte[idx] + off;
252 c->vm_pages = page; 447 c->priv = page;
253 448
254 do { 449 do {
255 BUG_ON(!pte_none(*pte)); 450 BUG_ON(!pte_none(*pte));
@@ -281,14 +476,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
281 476
282 c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); 477 c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
283 if (!c) { 478 if (!c) {
284 printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", 479 pr_err("%s: trying to free invalid coherent area: %p\n",
285 __func__, cpu_addr); 480 __func__, cpu_addr);
286 dump_stack(); 481 dump_stack();
287 return; 482 return;
288 } 483 }
289 484
290 if ((c->vm_end - c->vm_start) != size) { 485 if ((c->vm_end - c->vm_start) != size) {
291 printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", 486 pr_err("%s: freeing wrong coherent size (%ld != %d)\n",
292 __func__, c->vm_end - c->vm_start, size); 487 __func__, c->vm_end - c->vm_start, size);
293 dump_stack(); 488 dump_stack();
294 size = c->vm_end - c->vm_start; 489 size = c->vm_end - c->vm_start;
@@ -310,8 +505,8 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
310 } 505 }
311 506
312 if (pte_none(pte) || !pte_present(pte)) 507 if (pte_none(pte) || !pte_present(pte))
313 printk(KERN_CRIT "%s: bad page in kernel page table\n", 508 pr_crit("%s: bad page in kernel page table\n",
314 __func__); 509 __func__);
315 } while (size -= PAGE_SIZE); 510 } while (size -= PAGE_SIZE);
316 511
317 flush_tlb_kernel_range(c->vm_start, c->vm_end); 512 flush_tlb_kernel_range(c->vm_start, c->vm_end);
@@ -319,20 +514,182 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
319 arm_vmregion_free(&consistent_head, c); 514 arm_vmregion_free(&consistent_head, c);
320} 515}
321 516
517static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
518 void *data)
519{
520 struct page *page = virt_to_page(addr);
521 pgprot_t prot = *(pgprot_t *)data;
522
523 set_pte_ext(pte, mk_pte(page, prot), 0);
524 return 0;
525}
526
527static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
528{
529 unsigned long start = (unsigned long) page_address(page);
530 unsigned end = start + size;
531
532 apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot);
533 dsb();
534 flush_tlb_kernel_range(start, end);
535}
536
537static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
538 pgprot_t prot, struct page **ret_page,
539 const void *caller)
540{
541 struct page *page;
542 void *ptr;
543 page = __dma_alloc_buffer(dev, size, gfp);
544 if (!page)
545 return NULL;
546
547 ptr = __dma_alloc_remap(page, size, gfp, prot, caller);
548 if (!ptr) {
549 __dma_free_buffer(page, size);
550 return NULL;
551 }
552
553 *ret_page = page;
554 return ptr;
555}
556
557static void *__alloc_from_pool(struct device *dev, size_t size,
558 struct page **ret_page, const void *caller)
559{
560 struct arm_vmregion *c;
561 size_t align;
562
563 if (!coherent_head.vm_start) {
564 printk(KERN_ERR "%s: coherent pool not initialised!\n",
565 __func__);
566 dump_stack();
567 return NULL;
568 }
569
570 /*
571 * Align the region allocation - allocations from pool are rather
572 * small, so align them to their order in pages, minimum is a page
573 * size. This helps reduce fragmentation of the DMA space.
574 */
575 align = PAGE_SIZE << get_order(size);
576 c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller);
577 if (c) {
578 void *ptr = (void *)c->vm_start;
579 struct page *page = virt_to_page(ptr);
580 *ret_page = page;
581 return ptr;
582 }
583 return NULL;
584}
585
586static int __free_from_pool(void *cpu_addr, size_t size)
587{
588 unsigned long start = (unsigned long)cpu_addr;
589 unsigned long end = start + size;
590 struct arm_vmregion *c;
591
592 if (start < coherent_head.vm_start || end > coherent_head.vm_end)
593 return 0;
594
595 c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start);
596
597 if ((c->vm_end - c->vm_start) != size) {
598 printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
599 __func__, c->vm_end - c->vm_start, size);
600 dump_stack();
601 size = c->vm_end - c->vm_start;
602 }
603
604 arm_vmregion_free(&coherent_head, c);
605 return 1;
606}
607
608static void *__alloc_from_contiguous(struct device *dev, size_t size,
609 pgprot_t prot, struct page **ret_page)
610{
611 unsigned long order = get_order(size);
612 size_t count = size >> PAGE_SHIFT;
613 struct page *page;
614
615 page = dma_alloc_from_contiguous(dev, count, order);
616 if (!page)
617 return NULL;
618
619 __dma_clear_buffer(page, size);
620 __dma_remap(page, size, prot);
621
622 *ret_page = page;
623 return page_address(page);
624}
625
626static void __free_from_contiguous(struct device *dev, struct page *page,
627 size_t size)
628{
629 __dma_remap(page, size, pgprot_kernel);
630 dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
631}
632
633static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
634{
635 prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
636 pgprot_writecombine(prot) :
637 pgprot_dmacoherent(prot);
638 return prot;
639}
640
641#define nommu() 0
642
322#else /* !CONFIG_MMU */ 643#else /* !CONFIG_MMU */
323 644
324#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page) 645#define nommu() 1
325#define __dma_free_remap(addr, size) do { } while (0) 646
647#define __get_dma_pgprot(attrs, prot) __pgprot(0)
648#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL
649#define __alloc_from_pool(dev, size, ret_page, c) NULL
650#define __alloc_from_contiguous(dev, size, prot, ret) NULL
651#define __free_from_pool(cpu_addr, size) 0
652#define __free_from_contiguous(dev, page, size) do { } while (0)
653#define __dma_free_remap(cpu_addr, size) do { } while (0)
326 654
327#endif /* CONFIG_MMU */ 655#endif /* CONFIG_MMU */
328 656
329static void * 657static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
330__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, 658 struct page **ret_page)
331 pgprot_t prot, const void *caller) 659{
660 struct page *page;
661 page = __dma_alloc_buffer(dev, size, gfp);
662 if (!page)
663 return NULL;
664
665 *ret_page = page;
666 return page_address(page);
667}
668
669
670
671static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
672 gfp_t gfp, pgprot_t prot, const void *caller)
332{ 673{
674 u64 mask = get_coherent_dma_mask(dev);
333 struct page *page; 675 struct page *page;
334 void *addr; 676 void *addr;
335 677
678#ifdef CONFIG_DMA_API_DEBUG
679 u64 limit = (mask + 1) & ~mask;
680 if (limit && size >= limit) {
681 dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
682 size, mask);
683 return NULL;
684 }
685#endif
686
687 if (!mask)
688 return NULL;
689
690 if (mask < 0xffffffffULL)
691 gfp |= GFP_DMA;
692
336 /* 693 /*
337 * Following is a work-around (a.k.a. hack) to prevent pages 694 * Following is a work-around (a.k.a. hack) to prevent pages
338 * with __GFP_COMP being passed to split_page() which cannot 695 * with __GFP_COMP being passed to split_page() which cannot
@@ -342,22 +699,20 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
342 */ 699 */
343 gfp &= ~(__GFP_COMP); 700 gfp &= ~(__GFP_COMP);
344 701
345 *handle = ~0; 702 *handle = DMA_ERROR_CODE;
346 size = PAGE_ALIGN(size); 703 size = PAGE_ALIGN(size);
347 704
348 page = __dma_alloc_buffer(dev, size, gfp); 705 if (arch_is_coherent() || nommu())
349 if (!page) 706 addr = __alloc_simple_buffer(dev, size, gfp, &page);
350 return NULL; 707 else if (cpu_architecture() < CPU_ARCH_ARMv6)
351 708 addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
352 if (!arch_is_coherent()) 709 else if (gfp & GFP_ATOMIC)
353 addr = __dma_alloc_remap(page, size, gfp, prot, caller); 710 addr = __alloc_from_pool(dev, size, &page, caller);
354 else 711 else
355 addr = page_address(page); 712 addr = __alloc_from_contiguous(dev, size, prot, &page);
356 713
357 if (addr) 714 if (addr)
358 *handle = pfn_to_dma(dev, page_to_pfn(page)); 715 *handle = pfn_to_dma(dev, page_to_pfn(page));
359 else
360 __dma_free_buffer(page, size);
361 716
362 return addr; 717 return addr;
363} 718}
@@ -366,138 +721,71 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
366 * Allocate DMA-coherent memory space and return both the kernel remapped 721 * Allocate DMA-coherent memory space and return both the kernel remapped
367 * virtual and bus address for that space. 722 * virtual and bus address for that space.
368 */ 723 */
369void * 724void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
370dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 725 gfp_t gfp, struct dma_attrs *attrs)
371{ 726{
727 pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
372 void *memory; 728 void *memory;
373 729
374 if (dma_alloc_from_coherent(dev, size, handle, &memory)) 730 if (dma_alloc_from_coherent(dev, size, handle, &memory))
375 return memory; 731 return memory;
376 732
377 return __dma_alloc(dev, size, handle, gfp, 733 return __dma_alloc(dev, size, handle, gfp, prot,
378 pgprot_dmacoherent(pgprot_kernel),
379 __builtin_return_address(0)); 734 __builtin_return_address(0));
380} 735}
381EXPORT_SYMBOL(dma_alloc_coherent);
382 736
383/* 737/*
384 * Allocate a writecombining region, in much the same way as 738 * Create userspace mapping for the DMA-coherent memory.
385 * dma_alloc_coherent above.
386 */ 739 */
387void * 740int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
388dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) 741 void *cpu_addr, dma_addr_t dma_addr, size_t size,
389{ 742 struct dma_attrs *attrs)
390 return __dma_alloc(dev, size, handle, gfp,
391 pgprot_writecombine(pgprot_kernel),
392 __builtin_return_address(0));
393}
394EXPORT_SYMBOL(dma_alloc_writecombine);
395
396static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
397 void *cpu_addr, dma_addr_t dma_addr, size_t size)
398{ 743{
399 int ret = -ENXIO; 744 int ret = -ENXIO;
400#ifdef CONFIG_MMU 745#ifdef CONFIG_MMU
401 unsigned long user_size, kern_size; 746 unsigned long pfn = dma_to_pfn(dev, dma_addr);
402 struct arm_vmregion *c; 747 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
403 748
404 user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 749 if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
750 return ret;
405 751
406 c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); 752 ret = remap_pfn_range(vma, vma->vm_start,
407 if (c) { 753 pfn + vma->vm_pgoff,
408 unsigned long off = vma->vm_pgoff; 754 vma->vm_end - vma->vm_start,
409 755 vma->vm_page_prot);
410 kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
411
412 if (off < kern_size &&
413 user_size <= (kern_size - off)) {
414 ret = remap_pfn_range(vma, vma->vm_start,
415 page_to_pfn(c->vm_pages) + off,
416 user_size << PAGE_SHIFT,
417 vma->vm_page_prot);
418 }
419 }
420#endif /* CONFIG_MMU */ 756#endif /* CONFIG_MMU */
421 757
422 return ret; 758 return ret;
423} 759}
424 760
425int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
426 void *cpu_addr, dma_addr_t dma_addr, size_t size)
427{
428 vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
429 return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
430}
431EXPORT_SYMBOL(dma_mmap_coherent);
432
433int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
434 void *cpu_addr, dma_addr_t dma_addr, size_t size)
435{
436 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
437 return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
438}
439EXPORT_SYMBOL(dma_mmap_writecombine);
440
441/* 761/*
442 * free a page as defined by the above mapping. 762 * Free a buffer as defined by the above mapping.
443 * Must not be called with IRQs disabled.
444 */ 763 */
445void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) 764void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
765 dma_addr_t handle, struct dma_attrs *attrs)
446{ 766{
447 WARN_ON(irqs_disabled()); 767 struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
448 768
449 if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) 769 if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
450 return; 770 return;
451 771
452 size = PAGE_ALIGN(size); 772 size = PAGE_ALIGN(size);
453 773
454 if (!arch_is_coherent()) 774 if (arch_is_coherent() || nommu()) {
775 __dma_free_buffer(page, size);
776 } else if (cpu_architecture() < CPU_ARCH_ARMv6) {
455 __dma_free_remap(cpu_addr, size); 777 __dma_free_remap(cpu_addr, size);
456 778 __dma_free_buffer(page, size);
457 __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
458}
459EXPORT_SYMBOL(dma_free_coherent);
460
461/*
462 * Make an area consistent for devices.
463 * Note: Drivers should NOT use this function directly, as it will break
464 * platforms with CONFIG_DMABOUNCE.
465 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
466 */
467void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
468 enum dma_data_direction dir)
469{
470 unsigned long paddr;
471
472 BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
473
474 dmac_map_area(kaddr, size, dir);
475
476 paddr = __pa(kaddr);
477 if (dir == DMA_FROM_DEVICE) {
478 outer_inv_range(paddr, paddr + size);
479 } else { 779 } else {
480 outer_clean_range(paddr, paddr + size); 780 if (__free_from_pool(cpu_addr, size))
481 } 781 return;
482 /* FIXME: non-speculating: flush on bidirectional mappings? */ 782 /*
483} 783 * Non-atomic allocations cannot be freed with IRQs disabled
484EXPORT_SYMBOL(___dma_single_cpu_to_dev); 784 */
485 785 WARN_ON(irqs_disabled());
486void ___dma_single_dev_to_cpu(const void *kaddr, size_t size, 786 __free_from_contiguous(dev, page, size);
487 enum dma_data_direction dir)
488{
489 BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
490
491 /* FIXME: non-speculating: not required */
492 /* don't bother invalidating if DMA to device */
493 if (dir != DMA_TO_DEVICE) {
494 unsigned long paddr = __pa(kaddr);
495 outer_inv_range(paddr, paddr + size);
496 } 787 }
497
498 dmac_unmap_area(kaddr, size, dir);
499} 788}
500EXPORT_SYMBOL(___dma_single_dev_to_cpu);
501 789
502static void dma_cache_maint_page(struct page *page, unsigned long offset, 790static void dma_cache_maint_page(struct page *page, unsigned long offset,
503 size_t size, enum dma_data_direction dir, 791 size_t size, enum dma_data_direction dir,
@@ -543,7 +831,13 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
543 } while (left); 831 } while (left);
544} 832}
545 833
546void ___dma_page_cpu_to_dev(struct page *page, unsigned long off, 834/*
835 * Make an area consistent for devices.
836 * Note: Drivers should NOT use this function directly, as it will break
837 * platforms with CONFIG_DMABOUNCE.
838 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
839 */
840static void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
547 size_t size, enum dma_data_direction dir) 841 size_t size, enum dma_data_direction dir)
548{ 842{
549 unsigned long paddr; 843 unsigned long paddr;
@@ -558,9 +852,8 @@ void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
558 } 852 }
559 /* FIXME: non-speculating: flush on bidirectional mappings? */ 853 /* FIXME: non-speculating: flush on bidirectional mappings? */
560} 854}
561EXPORT_SYMBOL(___dma_page_cpu_to_dev);
562 855
563void ___dma_page_dev_to_cpu(struct page *page, unsigned long off, 856static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
564 size_t size, enum dma_data_direction dir) 857 size_t size, enum dma_data_direction dir)
565{ 858{
566 unsigned long paddr = page_to_phys(page) + off; 859 unsigned long paddr = page_to_phys(page) + off;
@@ -578,10 +871,9 @@ void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
578 if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE) 871 if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
579 set_bit(PG_dcache_clean, &page->flags); 872 set_bit(PG_dcache_clean, &page->flags);
580} 873}
581EXPORT_SYMBOL(___dma_page_dev_to_cpu);
582 874
583/** 875/**
584 * dma_map_sg - map a set of SG buffers for streaming mode DMA 876 * arm_dma_map_sg - map a set of SG buffers for streaming mode DMA
585 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 877 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
586 * @sg: list of buffers 878 * @sg: list of buffers
587 * @nents: number of buffers to map 879 * @nents: number of buffers to map
@@ -596,32 +888,32 @@ EXPORT_SYMBOL(___dma_page_dev_to_cpu);
596 * Device ownership issues as mentioned for dma_map_single are the same 888 * Device ownership issues as mentioned for dma_map_single are the same
597 * here. 889 * here.
598 */ 890 */
599int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 891int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
600 enum dma_data_direction dir) 892 enum dma_data_direction dir, struct dma_attrs *attrs)
601{ 893{
894 struct dma_map_ops *ops = get_dma_ops(dev);
602 struct scatterlist *s; 895 struct scatterlist *s;
603 int i, j; 896 int i, j;
604 897
605 BUG_ON(!valid_dma_direction(dir));
606
607 for_each_sg(sg, s, nents, i) { 898 for_each_sg(sg, s, nents, i) {
608 s->dma_address = __dma_map_page(dev, sg_page(s), s->offset, 899#ifdef CONFIG_NEED_SG_DMA_LENGTH
609 s->length, dir); 900 s->dma_length = s->length;
901#endif
902 s->dma_address = ops->map_page(dev, sg_page(s), s->offset,
903 s->length, dir, attrs);
610 if (dma_mapping_error(dev, s->dma_address)) 904 if (dma_mapping_error(dev, s->dma_address))
611 goto bad_mapping; 905 goto bad_mapping;
612 } 906 }
613 debug_dma_map_sg(dev, sg, nents, nents, dir);
614 return nents; 907 return nents;
615 908
616 bad_mapping: 909 bad_mapping:
617 for_each_sg(sg, s, i, j) 910 for_each_sg(sg, s, i, j)
618 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 911 ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
619 return 0; 912 return 0;
620} 913}
621EXPORT_SYMBOL(dma_map_sg);
622 914
623/** 915/**
624 * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg 916 * arm_dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
625 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 917 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
626 * @sg: list of buffers 918 * @sg: list of buffers
627 * @nents: number of buffers to unmap (same as was passed to dma_map_sg) 919 * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
@@ -630,70 +922,55 @@ EXPORT_SYMBOL(dma_map_sg);
630 * Unmap a set of streaming mode DMA translations. Again, CPU access 922 * Unmap a set of streaming mode DMA translations. Again, CPU access
631 * rules concerning calls here are the same as for dma_unmap_single(). 923 * rules concerning calls here are the same as for dma_unmap_single().
632 */ 924 */
633void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, 925void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
634 enum dma_data_direction dir) 926 enum dma_data_direction dir, struct dma_attrs *attrs)
635{ 927{
928 struct dma_map_ops *ops = get_dma_ops(dev);
636 struct scatterlist *s; 929 struct scatterlist *s;
637 int i;
638 930
639 debug_dma_unmap_sg(dev, sg, nents, dir); 931 int i;
640 932
641 for_each_sg(sg, s, nents, i) 933 for_each_sg(sg, s, nents, i)
642 __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir); 934 ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
643} 935}
644EXPORT_SYMBOL(dma_unmap_sg);
645 936
646/** 937/**
647 * dma_sync_sg_for_cpu 938 * arm_dma_sync_sg_for_cpu
648 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 939 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
649 * @sg: list of buffers 940 * @sg: list of buffers
650 * @nents: number of buffers to map (returned from dma_map_sg) 941 * @nents: number of buffers to map (returned from dma_map_sg)
651 * @dir: DMA transfer direction (same as was passed to dma_map_sg) 942 * @dir: DMA transfer direction (same as was passed to dma_map_sg)
652 */ 943 */
653void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, 944void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
654 int nents, enum dma_data_direction dir) 945 int nents, enum dma_data_direction dir)
655{ 946{
947 struct dma_map_ops *ops = get_dma_ops(dev);
656 struct scatterlist *s; 948 struct scatterlist *s;
657 int i; 949 int i;
658 950
659 for_each_sg(sg, s, nents, i) { 951 for_each_sg(sg, s, nents, i)
660 if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0, 952 ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
661 sg_dma_len(s), dir)) 953 dir);
662 continue;
663
664 __dma_page_dev_to_cpu(sg_page(s), s->offset,
665 s->length, dir);
666 }
667
668 debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
669} 954}
670EXPORT_SYMBOL(dma_sync_sg_for_cpu);
671 955
672/** 956/**
673 * dma_sync_sg_for_device 957 * arm_dma_sync_sg_for_device
674 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 958 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
675 * @sg: list of buffers 959 * @sg: list of buffers
676 * @nents: number of buffers to map (returned from dma_map_sg) 960 * @nents: number of buffers to map (returned from dma_map_sg)
677 * @dir: DMA transfer direction (same as was passed to dma_map_sg) 961 * @dir: DMA transfer direction (same as was passed to dma_map_sg)
678 */ 962 */
679void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, 963void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
680 int nents, enum dma_data_direction dir) 964 int nents, enum dma_data_direction dir)
681{ 965{
966 struct dma_map_ops *ops = get_dma_ops(dev);
682 struct scatterlist *s; 967 struct scatterlist *s;
683 int i; 968 int i;
684 969
685 for_each_sg(sg, s, nents, i) { 970 for_each_sg(sg, s, nents, i)
686 if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0, 971 ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
687 sg_dma_len(s), dir)) 972 dir);
688 continue;
689
690 __dma_page_cpu_to_dev(sg_page(s), s->offset,
691 s->length, dir);
692 }
693
694 debug_dma_sync_sg_for_device(dev, sg, nents, dir);
695} 973}
696EXPORT_SYMBOL(dma_sync_sg_for_device);
697 974
698/* 975/*
699 * Return whether the given device DMA address mask can be supported 976 * Return whether the given device DMA address mask can be supported
@@ -709,18 +986,15 @@ int dma_supported(struct device *dev, u64 mask)
709} 986}
710EXPORT_SYMBOL(dma_supported); 987EXPORT_SYMBOL(dma_supported);
711 988
712int dma_set_mask(struct device *dev, u64 dma_mask) 989static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
713{ 990{
714 if (!dev->dma_mask || !dma_supported(dev, dma_mask)) 991 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
715 return -EIO; 992 return -EIO;
716 993
717#ifndef CONFIG_DMABOUNCE
718 *dev->dma_mask = dma_mask; 994 *dev->dma_mask = dma_mask;
719#endif
720 995
721 return 0; 996 return 0;
722} 997}
723EXPORT_SYMBOL(dma_set_mask);
724 998
725#define PREALLOC_DMA_DEBUG_ENTRIES 4096 999#define PREALLOC_DMA_DEBUG_ENTRIES 4096
726 1000
@@ -733,3 +1007,679 @@ static int __init dma_debug_do_init(void)
733 return 0; 1007 return 0;
734} 1008}
735fs_initcall(dma_debug_do_init); 1009fs_initcall(dma_debug_do_init);
1010
1011#ifdef CONFIG_ARM_DMA_USE_IOMMU
1012
1013/* IOMMU */
1014
1015static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
1016 size_t size)
1017{
1018 unsigned int order = get_order(size);
1019 unsigned int align = 0;
1020 unsigned int count, start;
1021 unsigned long flags;
1022
1023 count = ((PAGE_ALIGN(size) >> PAGE_SHIFT) +
1024 (1 << mapping->order) - 1) >> mapping->order;
1025
1026 if (order > mapping->order)
1027 align = (1 << (order - mapping->order)) - 1;
1028
1029 spin_lock_irqsave(&mapping->lock, flags);
1030 start = bitmap_find_next_zero_area(mapping->bitmap, mapping->bits, 0,
1031 count, align);
1032 if (start > mapping->bits) {
1033 spin_unlock_irqrestore(&mapping->lock, flags);
1034 return DMA_ERROR_CODE;
1035 }
1036
1037 bitmap_set(mapping->bitmap, start, count);
1038 spin_unlock_irqrestore(&mapping->lock, flags);
1039
1040 return mapping->base + (start << (mapping->order + PAGE_SHIFT));
1041}
1042
1043static inline void __free_iova(struct dma_iommu_mapping *mapping,
1044 dma_addr_t addr, size_t size)
1045{
1046 unsigned int start = (addr - mapping->base) >>
1047 (mapping->order + PAGE_SHIFT);
1048 unsigned int count = ((size >> PAGE_SHIFT) +
1049 (1 << mapping->order) - 1) >> mapping->order;
1050 unsigned long flags;
1051
1052 spin_lock_irqsave(&mapping->lock, flags);
1053 bitmap_clear(mapping->bitmap, start, count);
1054 spin_unlock_irqrestore(&mapping->lock, flags);
1055}
1056
1057static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
1058{
1059 struct page **pages;
1060 int count = size >> PAGE_SHIFT;
1061 int array_size = count * sizeof(struct page *);
1062 int i = 0;
1063
1064 if (array_size <= PAGE_SIZE)
1065 pages = kzalloc(array_size, gfp);
1066 else
1067 pages = vzalloc(array_size);
1068 if (!pages)
1069 return NULL;
1070
1071 while (count) {
1072 int j, order = __ffs(count);
1073
1074 pages[i] = alloc_pages(gfp | __GFP_NOWARN, order);
1075 while (!pages[i] && order)
1076 pages[i] = alloc_pages(gfp | __GFP_NOWARN, --order);
1077 if (!pages[i])
1078 goto error;
1079
1080 if (order)
1081 split_page(pages[i], order);
1082 j = 1 << order;
1083 while (--j)
1084 pages[i + j] = pages[i] + j;
1085
1086 __dma_clear_buffer(pages[i], PAGE_SIZE << order);
1087 i += 1 << order;
1088 count -= 1 << order;
1089 }
1090
1091 return pages;
1092error:
1093 while (--i)
1094 if (pages[i])
1095 __free_pages(pages[i], 0);
1096 if (array_size < PAGE_SIZE)
1097 kfree(pages);
1098 else
1099 vfree(pages);
1100 return NULL;
1101}
1102
1103static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size)
1104{
1105 int count = size >> PAGE_SHIFT;
1106 int array_size = count * sizeof(struct page *);
1107 int i;
1108 for (i = 0; i < count; i++)
1109 if (pages[i])
1110 __free_pages(pages[i], 0);
1111 if (array_size < PAGE_SIZE)
1112 kfree(pages);
1113 else
1114 vfree(pages);
1115 return 0;
1116}
1117
1118/*
1119 * Create a CPU mapping for a specified pages
1120 */
1121static void *
1122__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot)
1123{
1124 struct arm_vmregion *c;
1125 size_t align;
1126 size_t count = size >> PAGE_SHIFT;
1127 int bit;
1128
1129 if (!consistent_pte[0]) {
1130 pr_err("%s: not initialised\n", __func__);
1131 dump_stack();
1132 return NULL;
1133 }
1134
1135 /*
1136 * Align the virtual region allocation - maximum alignment is
1137 * a section size, minimum is a page size. This helps reduce
1138 * fragmentation of the DMA space, and also prevents allocations
1139 * smaller than a section from crossing a section boundary.
1140 */
1141 bit = fls(size - 1);
1142 if (bit > SECTION_SHIFT)
1143 bit = SECTION_SHIFT;
1144 align = 1 << bit;
1145
1146 /*
1147 * Allocate a virtual address in the consistent mapping region.
1148 */
1149 c = arm_vmregion_alloc(&consistent_head, align, size,
1150 gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL);
1151 if (c) {
1152 pte_t *pte;
1153 int idx = CONSISTENT_PTE_INDEX(c->vm_start);
1154 int i = 0;
1155 u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
1156
1157 pte = consistent_pte[idx] + off;
1158 c->priv = pages;
1159
1160 do {
1161 BUG_ON(!pte_none(*pte));
1162
1163 set_pte_ext(pte, mk_pte(pages[i], prot), 0);
1164 pte++;
1165 off++;
1166 i++;
1167 if (off >= PTRS_PER_PTE) {
1168 off = 0;
1169 pte = consistent_pte[++idx];
1170 }
1171 } while (i < count);
1172
1173 dsb();
1174
1175 return (void *)c->vm_start;
1176 }
1177 return NULL;
1178}
1179
1180/*
1181 * Create a mapping in device IO address space for specified pages
1182 */
1183static dma_addr_t
1184__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
1185{
1186 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1187 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
1188 dma_addr_t dma_addr, iova;
1189 int i, ret = DMA_ERROR_CODE;
1190
1191 dma_addr = __alloc_iova(mapping, size);
1192 if (dma_addr == DMA_ERROR_CODE)
1193 return dma_addr;
1194
1195 iova = dma_addr;
1196 for (i = 0; i < count; ) {
1197 unsigned int next_pfn = page_to_pfn(pages[i]) + 1;
1198 phys_addr_t phys = page_to_phys(pages[i]);
1199 unsigned int len, j;
1200
1201 for (j = i + 1; j < count; j++, next_pfn++)
1202 if (page_to_pfn(pages[j]) != next_pfn)
1203 break;
1204
1205 len = (j - i) << PAGE_SHIFT;
1206 ret = iommu_map(mapping->domain, iova, phys, len, 0);
1207 if (ret < 0)
1208 goto fail;
1209 iova += len;
1210 i = j;
1211 }
1212 return dma_addr;
1213fail:
1214 iommu_unmap(mapping->domain, dma_addr, iova-dma_addr);
1215 __free_iova(mapping, dma_addr, size);
1216 return DMA_ERROR_CODE;
1217}
1218
1219static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t size)
1220{
1221 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1222
1223 /*
1224 * add optional in-page offset from iova to size and align
1225 * result to page size
1226 */
1227 size = PAGE_ALIGN((iova & ~PAGE_MASK) + size);
1228 iova &= PAGE_MASK;
1229
1230 iommu_unmap(mapping->domain, iova, size);
1231 __free_iova(mapping, iova, size);
1232 return 0;
1233}
1234
1235static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
1236 dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
1237{
1238 pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
1239 struct page **pages;
1240 void *addr = NULL;
1241
1242 *handle = DMA_ERROR_CODE;
1243 size = PAGE_ALIGN(size);
1244
1245 pages = __iommu_alloc_buffer(dev, size, gfp);
1246 if (!pages)
1247 return NULL;
1248
1249 *handle = __iommu_create_mapping(dev, pages, size);
1250 if (*handle == DMA_ERROR_CODE)
1251 goto err_buffer;
1252
1253 addr = __iommu_alloc_remap(pages, size, gfp, prot);
1254 if (!addr)
1255 goto err_mapping;
1256
1257 return addr;
1258
1259err_mapping:
1260 __iommu_remove_mapping(dev, *handle, size);
1261err_buffer:
1262 __iommu_free_buffer(dev, pages, size);
1263 return NULL;
1264}
1265
1266static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
1267 void *cpu_addr, dma_addr_t dma_addr, size_t size,
1268 struct dma_attrs *attrs)
1269{
1270 struct arm_vmregion *c;
1271
1272 vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
1273 c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
1274
1275 if (c) {
1276 struct page **pages = c->priv;
1277
1278 unsigned long uaddr = vma->vm_start;
1279 unsigned long usize = vma->vm_end - vma->vm_start;
1280 int i = 0;
1281
1282 do {
1283 int ret;
1284
1285 ret = vm_insert_page(vma, uaddr, pages[i++]);
1286 if (ret) {
1287 pr_err("Remapping memory, error: %d\n", ret);
1288 return ret;
1289 }
1290
1291 uaddr += PAGE_SIZE;
1292 usize -= PAGE_SIZE;
1293 } while (usize > 0);
1294 }
1295 return 0;
1296}
1297
1298/*
1299 * free a page as defined by the above mapping.
1300 * Must not be called with IRQs disabled.
1301 */
1302void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
1303 dma_addr_t handle, struct dma_attrs *attrs)
1304{
1305 struct arm_vmregion *c;
1306 size = PAGE_ALIGN(size);
1307
1308 c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
1309 if (c) {
1310 struct page **pages = c->priv;
1311 __dma_free_remap(cpu_addr, size);
1312 __iommu_remove_mapping(dev, handle, size);
1313 __iommu_free_buffer(dev, pages, size);
1314 }
1315}
1316
1317/*
1318 * Map a part of the scatter-gather list into contiguous io address space
1319 */
1320static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
1321 size_t size, dma_addr_t *handle,
1322 enum dma_data_direction dir)
1323{
1324 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1325 dma_addr_t iova, iova_base;
1326 int ret = 0;
1327 unsigned int count;
1328 struct scatterlist *s;
1329
1330 size = PAGE_ALIGN(size);
1331 *handle = DMA_ERROR_CODE;
1332
1333 iova_base = iova = __alloc_iova(mapping, size);
1334 if (iova == DMA_ERROR_CODE)
1335 return -ENOMEM;
1336
1337 for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
1338 phys_addr_t phys = page_to_phys(sg_page(s));
1339 unsigned int len = PAGE_ALIGN(s->offset + s->length);
1340
1341 if (!arch_is_coherent())
1342 __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
1343
1344 ret = iommu_map(mapping->domain, iova, phys, len, 0);
1345 if (ret < 0)
1346 goto fail;
1347 count += len >> PAGE_SHIFT;
1348 iova += len;
1349 }
1350 *handle = iova_base;
1351
1352 return 0;
1353fail:
1354 iommu_unmap(mapping->domain, iova_base, count * PAGE_SIZE);
1355 __free_iova(mapping, iova_base, size);
1356 return ret;
1357}
1358
1359/**
1360 * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
1361 * @dev: valid struct device pointer
1362 * @sg: list of buffers
1363 * @nents: number of buffers to map
1364 * @dir: DMA transfer direction
1365 *
1366 * Map a set of buffers described by scatterlist in streaming mode for DMA.
1367 * The scatter gather list elements are merged together (if possible) and
1368 * tagged with the appropriate dma address and length. They are obtained via
1369 * sg_dma_{address,length}.
1370 */
1371int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
1372 enum dma_data_direction dir, struct dma_attrs *attrs)
1373{
1374 struct scatterlist *s = sg, *dma = sg, *start = sg;
1375 int i, count = 0;
1376 unsigned int offset = s->offset;
1377 unsigned int size = s->offset + s->length;
1378 unsigned int max = dma_get_max_seg_size(dev);
1379
1380 for (i = 1; i < nents; i++) {
1381 s = sg_next(s);
1382
1383 s->dma_address = DMA_ERROR_CODE;
1384 s->dma_length = 0;
1385
1386 if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
1387 if (__map_sg_chunk(dev, start, size, &dma->dma_address,
1388 dir) < 0)
1389 goto bad_mapping;
1390
1391 dma->dma_address += offset;
1392 dma->dma_length = size - offset;
1393
1394 size = offset = s->offset;
1395 start = s;
1396 dma = sg_next(dma);
1397 count += 1;
1398 }
1399 size += s->length;
1400 }
1401 if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0)
1402 goto bad_mapping;
1403
1404 dma->dma_address += offset;
1405 dma->dma_length = size - offset;
1406
1407 return count+1;
1408
1409bad_mapping:
1410 for_each_sg(sg, s, count, i)
1411 __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s));
1412 return 0;
1413}
1414
1415/**
1416 * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
1417 * @dev: valid struct device pointer
1418 * @sg: list of buffers
1419 * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
1420 * @dir: DMA transfer direction (same as was passed to dma_map_sg)
1421 *
1422 * Unmap a set of streaming mode DMA translations. Again, CPU access
1423 * rules concerning calls here are the same as for dma_unmap_single().
1424 */
1425void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
1426 enum dma_data_direction dir, struct dma_attrs *attrs)
1427{
1428 struct scatterlist *s;
1429 int i;
1430
1431 for_each_sg(sg, s, nents, i) {
1432 if (sg_dma_len(s))
1433 __iommu_remove_mapping(dev, sg_dma_address(s),
1434 sg_dma_len(s));
1435 if (!arch_is_coherent())
1436 __dma_page_dev_to_cpu(sg_page(s), s->offset,
1437 s->length, dir);
1438 }
1439}
1440
1441/**
1442 * arm_iommu_sync_sg_for_cpu
1443 * @dev: valid struct device pointer
1444 * @sg: list of buffers
1445 * @nents: number of buffers to map (returned from dma_map_sg)
1446 * @dir: DMA transfer direction (same as was passed to dma_map_sg)
1447 */
1448void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
1449 int nents, enum dma_data_direction dir)
1450{
1451 struct scatterlist *s;
1452 int i;
1453
1454 for_each_sg(sg, s, nents, i)
1455 if (!arch_is_coherent())
1456 __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
1457
1458}
1459
1460/**
1461 * arm_iommu_sync_sg_for_device
1462 * @dev: valid struct device pointer
1463 * @sg: list of buffers
1464 * @nents: number of buffers to map (returned from dma_map_sg)
1465 * @dir: DMA transfer direction (same as was passed to dma_map_sg)
1466 */
1467void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
1468 int nents, enum dma_data_direction dir)
1469{
1470 struct scatterlist *s;
1471 int i;
1472
1473 for_each_sg(sg, s, nents, i)
1474 if (!arch_is_coherent())
1475 __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
1476}
1477
1478
1479/**
1480 * arm_iommu_map_page
1481 * @dev: valid struct device pointer
1482 * @page: page that buffer resides in
1483 * @offset: offset into page for start of buffer
1484 * @size: size of buffer to map
1485 * @dir: DMA transfer direction
1486 *
1487 * IOMMU aware version of arm_dma_map_page()
1488 */
1489static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
1490 unsigned long offset, size_t size, enum dma_data_direction dir,
1491 struct dma_attrs *attrs)
1492{
1493 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1494 dma_addr_t dma_addr;
1495 int ret, len = PAGE_ALIGN(size + offset);
1496
1497 if (!arch_is_coherent())
1498 __dma_page_cpu_to_dev(page, offset, size, dir);
1499
1500 dma_addr = __alloc_iova(mapping, len);
1501 if (dma_addr == DMA_ERROR_CODE)
1502 return dma_addr;
1503
1504 ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, 0);
1505 if (ret < 0)
1506 goto fail;
1507
1508 return dma_addr + offset;
1509fail:
1510 __free_iova(mapping, dma_addr, len);
1511 return DMA_ERROR_CODE;
1512}
1513
1514/**
1515 * arm_iommu_unmap_page
1516 * @dev: valid struct device pointer
1517 * @handle: DMA address of buffer
1518 * @size: size of buffer (same as passed to dma_map_page)
1519 * @dir: DMA transfer direction (same as passed to dma_map_page)
1520 *
1521 * IOMMU aware version of arm_dma_unmap_page()
1522 */
1523static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
1524 size_t size, enum dma_data_direction dir,
1525 struct dma_attrs *attrs)
1526{
1527 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1528 dma_addr_t iova = handle & PAGE_MASK;
1529 struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
1530 int offset = handle & ~PAGE_MASK;
1531 int len = PAGE_ALIGN(size + offset);
1532
1533 if (!iova)
1534 return;
1535
1536 if (!arch_is_coherent())
1537 __dma_page_dev_to_cpu(page, offset, size, dir);
1538
1539 iommu_unmap(mapping->domain, iova, len);
1540 __free_iova(mapping, iova, len);
1541}
1542
1543static void arm_iommu_sync_single_for_cpu(struct device *dev,
1544 dma_addr_t handle, size_t size, enum dma_data_direction dir)
1545{
1546 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1547 dma_addr_t iova = handle & PAGE_MASK;
1548 struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
1549 unsigned int offset = handle & ~PAGE_MASK;
1550
1551 if (!iova)
1552 return;
1553
1554 if (!arch_is_coherent())
1555 __dma_page_dev_to_cpu(page, offset, size, dir);
1556}
1557
1558static void arm_iommu_sync_single_for_device(struct device *dev,
1559 dma_addr_t handle, size_t size, enum dma_data_direction dir)
1560{
1561 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
1562 dma_addr_t iova = handle & PAGE_MASK;
1563 struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
1564 unsigned int offset = handle & ~PAGE_MASK;
1565
1566 if (!iova)
1567 return;
1568
1569 __dma_page_cpu_to_dev(page, offset, size, dir);
1570}
1571
1572struct dma_map_ops iommu_ops = {
1573 .alloc = arm_iommu_alloc_attrs,
1574 .free = arm_iommu_free_attrs,
1575 .mmap = arm_iommu_mmap_attrs,
1576
1577 .map_page = arm_iommu_map_page,
1578 .unmap_page = arm_iommu_unmap_page,
1579 .sync_single_for_cpu = arm_iommu_sync_single_for_cpu,
1580 .sync_single_for_device = arm_iommu_sync_single_for_device,
1581
1582 .map_sg = arm_iommu_map_sg,
1583 .unmap_sg = arm_iommu_unmap_sg,
1584 .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu,
1585 .sync_sg_for_device = arm_iommu_sync_sg_for_device,
1586};
1587
1588/**
1589 * arm_iommu_create_mapping
1590 * @bus: pointer to the bus holding the client device (for IOMMU calls)
1591 * @base: start address of the valid IO address space
1592 * @size: size of the valid IO address space
1593 * @order: accuracy of the IO addresses allocations
1594 *
1595 * Creates a mapping structure which holds information about used/unused
1596 * IO address ranges, which is required to perform memory allocation and
1597 * mapping with IOMMU aware functions.
1598 *
1599 * The client device need to be attached to the mapping with
1600 * arm_iommu_attach_device function.
1601 */
1602struct dma_iommu_mapping *
1603arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
1604 int order)
1605{
1606 unsigned int count = size >> (PAGE_SHIFT + order);
1607 unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
1608 struct dma_iommu_mapping *mapping;
1609 int err = -ENOMEM;
1610
1611 if (!count)
1612 return ERR_PTR(-EINVAL);
1613
1614 mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
1615 if (!mapping)
1616 goto err;
1617
1618 mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
1619 if (!mapping->bitmap)
1620 goto err2;
1621
1622 mapping->base = base;
1623 mapping->bits = BITS_PER_BYTE * bitmap_size;
1624 mapping->order = order;
1625 spin_lock_init(&mapping->lock);
1626
1627 mapping->domain = iommu_domain_alloc(bus);
1628 if (!mapping->domain)
1629 goto err3;
1630
1631 kref_init(&mapping->kref);
1632 return mapping;
1633err3:
1634 kfree(mapping->bitmap);
1635err2:
1636 kfree(mapping);
1637err:
1638 return ERR_PTR(err);
1639}
1640
1641static void release_iommu_mapping(struct kref *kref)
1642{
1643 struct dma_iommu_mapping *mapping =
1644 container_of(kref, struct dma_iommu_mapping, kref);
1645
1646 iommu_domain_free(mapping->domain);
1647 kfree(mapping->bitmap);
1648 kfree(mapping);
1649}
1650
1651void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
1652{
1653 if (mapping)
1654 kref_put(&mapping->kref, release_iommu_mapping);
1655}
1656
1657/**
1658 * arm_iommu_attach_device
1659 * @dev: valid struct device pointer
1660 * @mapping: io address space mapping structure (returned from
1661 * arm_iommu_create_mapping)
1662 *
1663 * Attaches specified io address space mapping to the provided device,
1664 * this replaces the dma operations (dma_map_ops pointer) with the
1665 * IOMMU aware version. More than one client might be attached to
1666 * the same io address space mapping.
1667 */
1668int arm_iommu_attach_device(struct device *dev,
1669 struct dma_iommu_mapping *mapping)
1670{
1671 int err;
1672
1673 err = iommu_attach_device(mapping->domain, dev);
1674 if (err)
1675 return err;
1676
1677 kref_get(&mapping->kref);
1678 dev->archdata.mapping = mapping;
1679 set_dma_ops(dev, &iommu_ops);
1680
1681 pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev));
1682 return 0;
1683}
1684
1685#endif
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8f5813bbffb..c21d06c7dd7 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -20,6 +20,7 @@
20#include <linux/highmem.h> 20#include <linux/highmem.h>
21#include <linux/gfp.h> 21#include <linux/gfp.h>
22#include <linux/memblock.h> 22#include <linux/memblock.h>
23#include <linux/dma-contiguous.h>
23 24
24#include <asm/mach-types.h> 25#include <asm/mach-types.h>
25#include <asm/memblock.h> 26#include <asm/memblock.h>
@@ -226,6 +227,17 @@ static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
226} 227}
227#endif 228#endif
228 229
230void __init setup_dma_zone(struct machine_desc *mdesc)
231{
232#ifdef CONFIG_ZONE_DMA
233 if (mdesc->dma_zone_size) {
234 arm_dma_zone_size = mdesc->dma_zone_size;
235 arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
236 } else
237 arm_dma_limit = 0xffffffff;
238#endif
239}
240
229static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, 241static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
230 unsigned long max_high) 242 unsigned long max_high)
231{ 243{
@@ -273,12 +285,9 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
273 * Adjust the sizes according to any special requirements for 285 * Adjust the sizes according to any special requirements for
274 * this machine type. 286 * this machine type.
275 */ 287 */
276 if (arm_dma_zone_size) { 288 if (arm_dma_zone_size)
277 arm_adjust_dma_zone(zone_size, zhole_size, 289 arm_adjust_dma_zone(zone_size, zhole_size,
278 arm_dma_zone_size >> PAGE_SHIFT); 290 arm_dma_zone_size >> PAGE_SHIFT);
279 arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
280 } else
281 arm_dma_limit = 0xffffffff;
282#endif 291#endif
283 292
284 free_area_init_node(0, zone_size, min, zhole_size); 293 free_area_init_node(0, zone_size, min, zhole_size);
@@ -364,6 +373,12 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
364 if (mdesc->reserve) 373 if (mdesc->reserve)
365 mdesc->reserve(); 374 mdesc->reserve();
366 375
376 /*
377 * reserve memory for DMA contigouos allocations,
378 * must come from DMA area inside low memory
379 */
380 dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
381
367 arm_memblock_steal_permitted = false; 382 arm_memblock_steal_permitted = false;
368 memblock_allow_resize(); 383 memblock_allow_resize();
369 memblock_dump_all(); 384 memblock_dump_all();
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 27f4a619b35..93dc0c17cdc 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -67,5 +67,8 @@ extern u32 arm_dma_limit;
67#define arm_dma_limit ((u32)~0) 67#define arm_dma_limit ((u32)~0)
68#endif 68#endif
69 69
70extern phys_addr_t arm_lowmem_limit;
71
70void __init bootmem_init(void); 72void __init bootmem_init(void);
71void arm_mm_memblock_reserve(void); 73void arm_mm_memblock_reserve(void);
74void dma_contiguous_remap(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index aa78de8bfdd..e5dad60b558 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -288,6 +288,11 @@ static struct mem_type mem_types[] = {
288 PMD_SECT_UNCACHED | PMD_SECT_XN, 288 PMD_SECT_UNCACHED | PMD_SECT_XN,
289 .domain = DOMAIN_KERNEL, 289 .domain = DOMAIN_KERNEL,
290 }, 290 },
291 [MT_MEMORY_DMA_READY] = {
292 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
293 .prot_l1 = PMD_TYPE_TABLE,
294 .domain = DOMAIN_KERNEL,
295 },
291}; 296};
292 297
293const struct mem_type *get_mem_type(unsigned int type) 298const struct mem_type *get_mem_type(unsigned int type)
@@ -429,6 +434,7 @@ static void __init build_mem_type_table(void)
429 if (arch_is_coherent() && cpu_is_xsc3()) { 434 if (arch_is_coherent() && cpu_is_xsc3()) {
430 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; 435 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
431 mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; 436 mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
437 mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
432 mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; 438 mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
433 mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; 439 mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
434 } 440 }
@@ -460,6 +466,7 @@ static void __init build_mem_type_table(void)
460 mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; 466 mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
461 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; 467 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
462 mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; 468 mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
469 mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
463 mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; 470 mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
464 mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; 471 mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
465 } 472 }
@@ -512,6 +519,7 @@ static void __init build_mem_type_table(void)
512 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; 519 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
513 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; 520 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
514 mem_types[MT_MEMORY].prot_pte |= kern_pgprot; 521 mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
522 mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
515 mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; 523 mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
516 mem_types[MT_ROM].prot_sect |= cp->pmd; 524 mem_types[MT_ROM].prot_sect |= cp->pmd;
517 525
@@ -596,7 +604,7 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
596 * L1 entries, whereas PGDs refer to a group of L1 entries making 604 * L1 entries, whereas PGDs refer to a group of L1 entries making
597 * up one logical pointer to an L2 table. 605 * up one logical pointer to an L2 table.
598 */ 606 */
599 if (((addr | end | phys) & ~SECTION_MASK) == 0) { 607 if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
600 pmd_t *p = pmd; 608 pmd_t *p = pmd;
601 609
602#ifndef CONFIG_ARM_LPAE 610#ifndef CONFIG_ARM_LPAE
@@ -814,7 +822,7 @@ static int __init early_vmalloc(char *arg)
814} 822}
815early_param("vmalloc", early_vmalloc); 823early_param("vmalloc", early_vmalloc);
816 824
817static phys_addr_t lowmem_limit __initdata = 0; 825phys_addr_t arm_lowmem_limit __initdata = 0;
818 826
819void __init sanity_check_meminfo(void) 827void __init sanity_check_meminfo(void)
820{ 828{
@@ -897,8 +905,8 @@ void __init sanity_check_meminfo(void)
897 bank->size = newsize; 905 bank->size = newsize;
898 } 906 }
899#endif 907#endif
900 if (!bank->highmem && bank->start + bank->size > lowmem_limit) 908 if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
901 lowmem_limit = bank->start + bank->size; 909 arm_lowmem_limit = bank->start + bank->size;
902 910
903 j++; 911 j++;
904 } 912 }
@@ -923,8 +931,8 @@ void __init sanity_check_meminfo(void)
923 } 931 }
924#endif 932#endif
925 meminfo.nr_banks = j; 933 meminfo.nr_banks = j;
926 high_memory = __va(lowmem_limit - 1) + 1; 934 high_memory = __va(arm_lowmem_limit - 1) + 1;
927 memblock_set_current_limit(lowmem_limit); 935 memblock_set_current_limit(arm_lowmem_limit);
928} 936}
929 937
930static inline void prepare_page_table(void) 938static inline void prepare_page_table(void)
@@ -949,8 +957,8 @@ static inline void prepare_page_table(void)
949 * Find the end of the first block of lowmem. 957 * Find the end of the first block of lowmem.
950 */ 958 */
951 end = memblock.memory.regions[0].base + memblock.memory.regions[0].size; 959 end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
952 if (end >= lowmem_limit) 960 if (end >= arm_lowmem_limit)
953 end = lowmem_limit; 961 end = arm_lowmem_limit;
954 962
955 /* 963 /*
956 * Clear out all the kernel space mappings, except for the first 964 * Clear out all the kernel space mappings, except for the first
@@ -1093,8 +1101,8 @@ static void __init map_lowmem(void)
1093 phys_addr_t end = start + reg->size; 1101 phys_addr_t end = start + reg->size;
1094 struct map_desc map; 1102 struct map_desc map;
1095 1103
1096 if (end > lowmem_limit) 1104 if (end > arm_lowmem_limit)
1097 end = lowmem_limit; 1105 end = arm_lowmem_limit;
1098 if (start >= end) 1106 if (start >= end)
1099 break; 1107 break;
1100 1108
@@ -1115,11 +1123,12 @@ void __init paging_init(struct machine_desc *mdesc)
1115{ 1123{
1116 void *zero_page; 1124 void *zero_page;
1117 1125
1118 memblock_set_current_limit(lowmem_limit); 1126 memblock_set_current_limit(arm_lowmem_limit);
1119 1127
1120 build_mem_type_table(); 1128 build_mem_type_table();
1121 prepare_page_table(); 1129 prepare_page_table();
1122 map_lowmem(); 1130 map_lowmem();
1131 dma_contiguous_remap();
1123 devicemaps_init(mdesc); 1132 devicemaps_init(mdesc);
1124 kmap_init(); 1133 kmap_init();
1125 1134
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 162be662c08..bf312c354a2 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -17,7 +17,7 @@ struct arm_vmregion {
17 struct list_head vm_list; 17 struct list_head vm_list;
18 unsigned long vm_start; 18 unsigned long vm_start;
19 unsigned long vm_end; 19 unsigned long vm_end;
20 struct page *vm_pages; 20 void *priv;
21 int vm_active; 21 int vm_active;
22 const void *caller; 22 const void *caller;
23}; 23};
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 2ed3ab173ad..5079787273d 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -41,6 +41,7 @@
41#include <mach/clock.h> 41#include <mach/clock.h>
42#include <mach/hardware.h> 42#include <mach/hardware.h>
43 43
44#ifndef CONFIG_COMMON_CLK
44static LIST_HEAD(clocks); 45static LIST_HEAD(clocks);
45static DEFINE_MUTEX(clocks_mutex); 46static DEFINE_MUTEX(clocks_mutex);
46 47
@@ -200,6 +201,16 @@ struct clk *clk_get_parent(struct clk *clk)
200} 201}
201EXPORT_SYMBOL(clk_get_parent); 202EXPORT_SYMBOL(clk_get_parent);
202 203
204#else
205
206/*
207 * Lock to protect the clock module (ccm) registers. Used
208 * on all i.MXs
209 */
210DEFINE_SPINLOCK(imx_ccm_lock);
211
212#endif /* CONFIG_COMMON_CLK */
213
203/* 214/*
204 * Get the resulting clock rate from a PLL register value and the input 215 * Get the resulting clock rate from a PLL register value and the input
205 * frequency. PLLs with this register layout can at least be found on 216 * frequency. PLLs with this register layout can at least be found on
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 753a5988d85..bd940c795cb 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -23,6 +23,7 @@
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24#include <linux/list.h> 24#include <linux/list.h>
25 25
26#ifndef CONFIG_COMMON_CLK
26struct module; 27struct module;
27 28
28struct clk { 29struct clk {
@@ -59,6 +60,9 @@ struct clk {
59 60
60int clk_register(struct clk *clk); 61int clk_register(struct clk *clk);
61void clk_unregister(struct clk *clk); 62void clk_unregister(struct clk *clk);
63#endif /* CONFIG_COMMON_CLK */
64
65extern spinlock_t imx_ccm_lock;
62 66
63unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref); 67unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
64 68
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 0319c4a0caf..cf663d84e7c 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -53,6 +53,7 @@ extern void imx35_soc_init(void);
53extern void imx50_soc_init(void); 53extern void imx50_soc_init(void);
54extern void imx51_soc_init(void); 54extern void imx51_soc_init(void);
55extern void imx53_soc_init(void); 55extern void imx53_soc_init(void);
56extern void imx51_init_late(void);
56extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); 57extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
57extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); 58extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
58extern int mx1_clocks_init(unsigned long fref); 59extern int mx1_clocks_init(unsigned long fref);
@@ -149,4 +150,10 @@ extern void imx6q_pm_init(void);
149static inline void imx6q_pm_init(void) {} 150static inline void imx6q_pm_init(void) {}
150#endif 151#endif
151 152
153#ifdef CONFIG_NEON
154extern int mx51_neon_fixup(void);
155#else
156static inline int mx51_neon_fixup(void) { return 0; }
157#endif
158
152#endif 159#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 8ddda365f1a..761e45f9456 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -24,6 +24,8 @@
24#define UART_PADDR MX51_UART1_BASE_ADDR 24#define UART_PADDR MX51_UART1_BASE_ADDR
25#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART) 25#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
26#define UART_PADDR MX53_UART1_BASE_ADDR 26#define UART_PADDR MX53_UART1_BASE_ADDR
27#elif defined (CONFIG_DEBUG_IMX6Q_UART2)
28#define UART_PADDR MX6Q_UART2_BASE_ADDR
27#elif defined (CONFIG_DEBUG_IMX6Q_UART4) 29#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
28#define UART_PADDR MX6Q_UART4_BASE_ADDR 30#define UART_PADDR MX6Q_UART4_BASE_ADDR
29#endif 31#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
index 254a561a279..f7e7dbac8f4 100644
--- a/arch/arm/plat-mxc/include/mach/mx6q.h
+++ b/arch/arm/plat-mxc/include/mach/mx6q.h
@@ -27,6 +27,8 @@
27#define MX6Q_CCM_SIZE 0x4000 27#define MX6Q_CCM_SIZE 0x4000
28#define MX6Q_ANATOP_BASE_ADDR 0x020c8000 28#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
29#define MX6Q_ANATOP_SIZE 0x1000 29#define MX6Q_ANATOP_SIZE 0x1000
30#define MX6Q_UART2_BASE_ADDR 0x021e8000
31#define MX6Q_UART2_SIZE 0x4000
30#define MX6Q_UART4_BASE_ADDR 0x021f0000 32#define MX6Q_UART4_BASE_ADDR 0x021f0000
31#define MX6Q_UART4_SIZE 0x4000 33#define MX6Q_UART4_SIZE 0x4000
32 34
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 7daf7c9a413..99f958ca6cb 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -25,6 +25,7 @@
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/clockchips.h> 26#include <linux/clockchips.h>
27#include <linux/clk.h> 27#include <linux/clk.h>
28#include <linux/err.h>
28 29
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30#include <asm/sched_clock.h> 31#include <asm/sched_clock.h>
@@ -282,6 +283,19 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
282void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) 283void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
283{ 284{
284 uint32_t tctl_val; 285 uint32_t tctl_val;
286 struct clk *timer_ipg_clk;
287
288 if (!timer_clk) {
289 timer_clk = clk_get_sys("imx-gpt.0", "per");
290 if (IS_ERR(timer_clk)) {
291 pr_err("i.MX timer: unable to get clk\n");
292 return;
293 }
294
295 timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg");
296 if (!IS_ERR(timer_ipg_clk))
297 clk_prepare_enable(timer_ipg_clk);
298 }
285 299
286 clk_prepare_enable(timer_clk); 300 clk_prepare_enable(timer_clk);
287 301
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 44ae077dbc2..2132c4f389e 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -28,19 +28,20 @@
28 28
29#include <plat/clock.h> 29#include <plat/clock.h>
30 30
31/* OMAP2_32KSYNCNT_CR_OFF: offset of 32ksync counter register */
32#define OMAP2_32KSYNCNT_CR_OFF 0x10
33
31/* 34/*
32 * 32KHz clocksource ... always available, on pretty most chips except 35 * 32KHz clocksource ... always available, on pretty most chips except
33 * OMAP 730 and 1510. Other timers could be used as clocksources, with 36 * OMAP 730 and 1510. Other timers could be used as clocksources, with
34 * higher resolution in free-running counter modes (e.g. 12 MHz xtal), 37 * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
35 * but systems won't necessarily want to spend resources that way. 38 * but systems won't necessarily want to spend resources that way.
36 */ 39 */
37static void __iomem *timer_32k_base; 40static void __iomem *sync32k_cnt_reg;
38
39#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
40 41
41static u32 notrace omap_32k_read_sched_clock(void) 42static u32 notrace omap_32k_read_sched_clock(void)
42{ 43{
43 return timer_32k_base ? __raw_readl(timer_32k_base) : 0; 44 return sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
44} 45}
45 46
46/** 47/**
@@ -60,7 +61,7 @@ static void omap_read_persistent_clock(struct timespec *ts)
60 struct timespec *tsp = &persistent_ts; 61 struct timespec *tsp = &persistent_ts;
61 62
62 last_cycles = cycles; 63 last_cycles = cycles;
63 cycles = timer_32k_base ? __raw_readl(timer_32k_base) : 0; 64 cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
64 delta = cycles - last_cycles; 65 delta = cycles - last_cycles;
65 66
66 nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift); 67 nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
@@ -69,55 +70,41 @@ static void omap_read_persistent_clock(struct timespec *ts)
69 *ts = *tsp; 70 *ts = *tsp;
70} 71}
71 72
72int __init omap_init_clocksource_32k(void) 73/**
74 * omap_init_clocksource_32k - setup and register counter 32k as a
75 * kernel clocksource
76 * @pbase: base addr of counter_32k module
77 * @size: size of counter_32k to map
78 *
79 * Returns 0 upon success or negative error code upon failure.
80 *
81 */
82int __init omap_init_clocksource_32k(void __iomem *vbase)
73{ 83{
74 static char err[] __initdata = KERN_ERR 84 int ret;
75 "%s: can't register clocksource!\n"; 85
76 86 /*
77 if (cpu_is_omap16xx() || cpu_class_is_omap2()) { 87 * 32k sync Counter register offset is at 0x10
78 u32 pbase; 88 */
79 unsigned long size = SZ_4K; 89 sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF;
80 void __iomem *base; 90
81 struct clk *sync_32k_ick; 91 /*
82 92 * 120000 rough estimate from the calculations in
83 if (cpu_is_omap16xx()) { 93 * __clocksource_updatefreq_scale.
84 pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED; 94 */
85 size = SZ_1K; 95 clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
86 } else if (cpu_is_omap2420()) 96 32768, NSEC_PER_SEC, 120000);
87 pbase = OMAP2420_32KSYNCT_BASE + 0x10; 97
88 else if (cpu_is_omap2430()) 98 ret = clocksource_mmio_init(sync32k_cnt_reg, "32k_counter", 32768,
89 pbase = OMAP2430_32KSYNCT_BASE + 0x10; 99 250, 32, clocksource_mmio_readl_up);
90 else if (cpu_is_omap34xx()) 100 if (ret) {
91 pbase = OMAP3430_32KSYNCT_BASE + 0x10; 101 pr_err("32k_counter: can't register clocksource\n");
92 else if (cpu_is_omap44xx()) 102 return ret;
93 pbase = OMAP4430_32KSYNCT_BASE + 0x10;
94 else
95 return -ENODEV;
96
97 /* For this to work we must have a static mapping in io.c for this area */
98 base = ioremap(pbase, size);
99 if (!base)
100 return -ENODEV;
101
102 sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
103 if (!IS_ERR(sync_32k_ick))
104 clk_enable(sync_32k_ick);
105
106 timer_32k_base = base;
107
108 /*
109 * 120000 rough estimate from the calculations in
110 * __clocksource_updatefreq_scale.
111 */
112 clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
113 32768, NSEC_PER_SEC, 120000);
114
115 if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
116 clocksource_mmio_readl_up))
117 printk(err, "32k_counter");
118
119 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
120 register_persistent_clock(NULL, omap_read_persistent_clock);
121 } 103 }
104
105 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
106 register_persistent_clock(NULL, omap_read_persistent_clock);
107 pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
108
122 return 0; 109 return 0;
123} 110}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 09b07d25289..1cba9273d2c 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -28,54 +28,6 @@
28#include <plat/menelaus.h> 28#include <plat/menelaus.h>
29#include <plat/omap44xx.h> 29#include <plat/omap44xx.h>
30 30
31#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
32 defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
33
34#define OMAP_MMC_NR_RES 2
35
36/*
37 * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
38 */
39int __init omap_mmc_add(const char *name, int id, unsigned long base,
40 unsigned long size, unsigned int irq,
41 struct omap_mmc_platform_data *data)
42{
43 struct platform_device *pdev;
44 struct resource res[OMAP_MMC_NR_RES];
45 int ret;
46
47 pdev = platform_device_alloc(name, id);
48 if (!pdev)
49 return -ENOMEM;
50
51 memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
52 res[0].start = base;
53 res[0].end = base + size - 1;
54 res[0].flags = IORESOURCE_MEM;
55 res[1].start = res[1].end = irq;
56 res[1].flags = IORESOURCE_IRQ;
57
58 ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
59 if (ret == 0)
60 ret = platform_device_add_data(pdev, data, sizeof(*data));
61 if (ret)
62 goto fail;
63
64 ret = platform_device_add(pdev);
65 if (ret)
66 goto fail;
67
68 /* return device handle to board setup code */
69 data->dev = &pdev->dev;
70 return 0;
71
72fail:
73 platform_device_put(pdev);
74 return ret;
75}
76
77#endif
78
79/*-------------------------------------------------------------------------*/ 31/*-------------------------------------------------------------------------*/
80 32
81#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE) 33#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
@@ -109,79 +61,6 @@ static void omap_init_rng(void)
109static inline void omap_init_rng(void) {} 61static inline void omap_init_rng(void) {}
110#endif 62#endif
111 63
112/*-------------------------------------------------------------------------*/
113
114/* Numbering for the SPI-capable controllers when used for SPI:
115 * spi = 1
116 * uwire = 2
117 * mmc1..2 = 3..4
118 * mcbsp1..3 = 5..7
119 */
120
121#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
122
123#define OMAP_UWIRE_BASE 0xfffb3000
124
125static struct resource uwire_resources[] = {
126 {
127 .start = OMAP_UWIRE_BASE,
128 .end = OMAP_UWIRE_BASE + 0x20,
129 .flags = IORESOURCE_MEM,
130 },
131};
132
133static struct platform_device omap_uwire_device = {
134 .name = "omap_uwire",
135 .id = -1,
136 .num_resources = ARRAY_SIZE(uwire_resources),
137 .resource = uwire_resources,
138};
139
140static void omap_init_uwire(void)
141{
142 /* FIXME define and use a boot tag; not all boards will be hooking
143 * up devices to the microwire controller, and multi-board configs
144 * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
145 */
146
147 /* board-specific code must configure chipselects (only a few
148 * are normally used) and SCLK/SDI/SDO (each has two choices).
149 */
150 (void) platform_device_register(&omap_uwire_device);
151}
152#else
153static inline void omap_init_uwire(void) {}
154#endif
155
156#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
157
158static phys_addr_t omap_dsp_phys_mempool_base;
159
160void __init omap_dsp_reserve_sdram_memblock(void)
161{
162 phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
163 phys_addr_t paddr;
164
165 if (!size)
166 return;
167
168 paddr = arm_memblock_steal(size, SZ_1M);
169 if (!paddr) {
170 pr_err("%s: failed to reserve %llx bytes\n",
171 __func__, (unsigned long long)size);
172 return;
173 }
174
175 omap_dsp_phys_mempool_base = paddr;
176}
177
178phys_addr_t omap_dsp_get_mempool_base(void)
179{
180 return omap_dsp_phys_mempool_base;
181}
182EXPORT_SYMBOL(omap_dsp_get_mempool_base);
183#endif
184
185/* 64/*
186 * This gets called after board-specific INIT_MACHINE, and initializes most 65 * This gets called after board-specific INIT_MACHINE, and initializes most
187 * on-chip peripherals accessible on this board (except for few like USB): 66 * on-chip peripherals accessible on this board (except for few like USB):
@@ -208,7 +87,6 @@ static int __init omap_init_devices(void)
208 * in alphabetical order so they're easier to sort through. 87 * in alphabetical order so they're easier to sort through.
209 */ 88 */
210 omap_init_rng(); 89 omap_init_rng();
211 omap_init_uwire();
212 return 0; 90 return 0;
213} 91}
214arch_initcall(omap_init_devices); 92arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 987e6101267..cb16ade437c 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -852,7 +852,7 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
852 } 852 }
853 l = p->dma_read(CCR, lch); 853 l = p->dma_read(CCR, lch);
854 l &= ~((1 << 6) | (1 << 26)); 854 l &= ~((1 << 6) | (1 << 26));
855 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) 855 if (cpu_class_is_omap2() && !cpu_is_omap242x())
856 l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); 856 l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
857 else 857 else
858 l |= ((read_prio & 0x1) << 6); 858 l |= ((read_prio & 0x1) << 6);
@@ -2080,7 +2080,7 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
2080 } 2080 }
2081 } 2081 }
2082 2082
2083 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) 2083 if (cpu_class_is_omap2() && !cpu_is_omap242x())
2084 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 2084 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
2085 DMA_DEFAULT_FIFO_DEPTH, 0); 2085 DMA_DEFAULT_FIFO_DEPTH, 0);
2086 2086
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index c4ed35e89fb..3b0cfeb33d0 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -82,8 +82,6 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
82 82
83static void omap_timer_restore_context(struct omap_dm_timer *timer) 83static void omap_timer_restore_context(struct omap_dm_timer *timer)
84{ 84{
85 __raw_writel(timer->context.tiocp_cfg,
86 timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
87 if (timer->revision == 1) 85 if (timer->revision == 1)
88 __raw_writel(timer->context.tistat, timer->sys_stat); 86 __raw_writel(timer->context.tistat, timer->sys_stat);
89 87
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index a557b8484e6..d1cb6f527b7 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -30,7 +30,7 @@
30#include <plat/i2c.h> 30#include <plat/i2c.h>
31#include <plat/omap_hwmod.h> 31#include <plat/omap_hwmod.h>
32 32
33extern int __init omap_init_clocksource_32k(void); 33extern int __init omap_init_clocksource_32k(void __iomem *vbase);
34 34
35extern void __init omap_check_revision(void); 35extern void __init omap_check_revision(void);
36 36
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 4bdf14ec674..297245dba66 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -121,6 +121,7 @@ IS_OMAP_CLASS(16xx, 0x16)
121IS_OMAP_CLASS(24xx, 0x24) 121IS_OMAP_CLASS(24xx, 0x24)
122IS_OMAP_CLASS(34xx, 0x34) 122IS_OMAP_CLASS(34xx, 0x34)
123IS_OMAP_CLASS(44xx, 0x44) 123IS_OMAP_CLASS(44xx, 0x44)
124IS_AM_CLASS(35xx, 0x35)
124IS_AM_CLASS(33xx, 0x33) 125IS_AM_CLASS(33xx, 0x33)
125 126
126IS_TI_CLASS(81xx, 0x81) 127IS_TI_CLASS(81xx, 0x81)
@@ -148,6 +149,7 @@ IS_AM_SUBCLASS(335x, 0x335)
148#define cpu_is_ti81xx() 0 149#define cpu_is_ti81xx() 0
149#define cpu_is_ti816x() 0 150#define cpu_is_ti816x() 0
150#define cpu_is_ti814x() 0 151#define cpu_is_ti814x() 0
152#define soc_is_am35xx() 0
151#define cpu_is_am33xx() 0 153#define cpu_is_am33xx() 0
152#define cpu_is_am335x() 0 154#define cpu_is_am335x() 0
153#define cpu_is_omap44xx() 0 155#define cpu_is_omap44xx() 0
@@ -357,6 +359,7 @@ IS_OMAP_TYPE(3517, 0x3517)
357# undef cpu_is_ti81xx 359# undef cpu_is_ti81xx
358# undef cpu_is_ti816x 360# undef cpu_is_ti816x
359# undef cpu_is_ti814x 361# undef cpu_is_ti814x
362# undef soc_is_am35xx
360# undef cpu_is_am33xx 363# undef cpu_is_am33xx
361# undef cpu_is_am335x 364# undef cpu_is_am335x
362# define cpu_is_omap3430() is_omap3430() 365# define cpu_is_omap3430() is_omap3430()
@@ -378,6 +381,7 @@ IS_OMAP_TYPE(3517, 0x3517)
378# define cpu_is_ti81xx() is_ti81xx() 381# define cpu_is_ti81xx() is_ti81xx()
379# define cpu_is_ti816x() is_ti816x() 382# define cpu_is_ti816x() is_ti816x()
380# define cpu_is_ti814x() is_ti814x() 383# define cpu_is_ti814x() is_ti814x()
384# define soc_is_am35xx() is_am35xx()
381# define cpu_is_am33xx() is_am33xx() 385# define cpu_is_am33xx() is_am33xx()
382# define cpu_is_am335x() is_am335x() 386# define cpu_is_am335x() is_am335x()
383#endif 387#endif
@@ -433,6 +437,10 @@ IS_OMAP_TYPE(3517, 0x3517)
433#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8)) 437#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
434#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8)) 438#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
435 439
440#define AM35XX_CLASS 0x35170034
441#define AM35XX_REV_ES1_0 AM35XX_CLASS
442#define AM35XX_REV_ES1_1 (AM35XX_CLASS | (0x1 << 8))
443
436#define AM335X_CLASS 0x33500034 444#define AM335X_CLASS 0x33500034
437#define AM335X_REV_ES1_0 AM335X_CLASS 445#define AM335X_REV_ES1_0 AM335X_CLASS
438 446
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 42afb4c4551..c5811d4409b 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -312,6 +312,11 @@
312#define CLEAR_CSR_ON_READ BIT(0xC) 312#define CLEAR_CSR_ON_READ BIT(0xC)
313#define IS_WORD_16 BIT(0xD) 313#define IS_WORD_16 BIT(0xD)
314 314
315/* Defines for DMA Capabilities */
316#define DMA_HAS_TRANSPARENT_CAPS (0x1 << 18)
317#define DMA_HAS_CONSTANT_FILL_CAPS (0x1 << 19)
318#define DMA_HAS_DESCRIPTOR_CAPS (0x3 << 20)
319
315enum omap_reg_offsets { 320enum omap_reg_offsets {
316 321
317GCR, GSCR, GRST1, HW_ID, 322GCR, GSCR, GRST1, HW_ID,
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index bdf871a84d6..5da73562e48 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -75,7 +75,6 @@ struct clk;
75 75
76struct timer_regs { 76struct timer_regs {
77 u32 tidr; 77 u32 tidr;
78 u32 tiocp_cfg;
79 u32 tistat; 78 u32 tistat;
80 u32 tisr; 79 u32 tisr;
81 u32 tier; 80 u32 tier;
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 3e7ae0f0215..a7754a886d4 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -177,9 +177,6 @@ extern void omap_mmc_notify_cover_event(struct device *dev, int slot,
177void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, 177void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
178 int nr_controllers); 178 int nr_controllers);
179void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); 179void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data);
180int omap_mmc_add(const char *name, int id, unsigned long base,
181 unsigned long size, unsigned int irq,
182 struct omap_mmc_platform_data *data);
183#else 180#else
184static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, 181static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
185 int nr_controllers) 182 int nr_controllers)
@@ -188,12 +185,6 @@ static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
188static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) 185static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
189{ 186{
190} 187}
191static inline int omap_mmc_add(const char *name, int id, unsigned long base,
192 unsigned long size, unsigned int irq,
193 struct omap_mmc_platform_data *data)
194{
195 return 0;
196}
197 188
198#endif 189#endif
199 190
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 74daf5ed143..61fd837624a 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -14,15 +14,41 @@
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/serial_8250.h> 15#include <linux/serial_8250.h>
16#include <linux/ata_platform.h> 16#include <linux/ata_platform.h>
17#include <linux/clk.h>
18#include <linux/clkdev.h>
17#include <linux/mv643xx_eth.h> 19#include <linux/mv643xx_eth.h>
18#include <linux/mv643xx_i2c.h> 20#include <linux/mv643xx_i2c.h>
19#include <net/dsa.h> 21#include <net/dsa.h>
20#include <linux/spi/orion_spi.h>
21#include <plat/orion_wdt.h>
22#include <plat/mv_xor.h> 22#include <plat/mv_xor.h>
23#include <plat/ehci-orion.h> 23#include <plat/ehci-orion.h>
24#include <mach/bridge-regs.h> 24#include <mach/bridge-regs.h>
25 25
26/* Create a clkdev entry for a given device/clk */
27void __init orion_clkdev_add(const char *con_id, const char *dev_id,
28 struct clk *clk)
29{
30 struct clk_lookup *cl;
31
32 cl = clkdev_alloc(clk, con_id, dev_id);
33 if (cl)
34 clkdev_add(cl);
35}
36
37/* Create clkdev entries for all orion platforms except kirkwood.
38 Kirkwood has gated clocks for some of its peripherals, so creates
39 its own clkdev entries. For all the other orion devices, create
40 clkdev entries to the tclk. */
41void __init orion_clkdev_init(struct clk *tclk)
42{
43 orion_clkdev_add(NULL, "orion_spi.0", tclk);
44 orion_clkdev_add(NULL, "orion_spi.1", tclk);
45 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk);
46 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk);
47 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
48 orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
49 orion_clkdev_add(NULL, "orion_wdt", tclk);
50}
51
26/* Fill in the resources structure and link it into the platform 52/* Fill in the resources structure and link it into the platform
27 device structure. There is always a memory region, and nearly 53 device structure. There is always a memory region, and nearly
28 always an interrupt.*/ 54 always an interrupt.*/
@@ -49,6 +75,12 @@ static void fill_resources(struct platform_device *device,
49/***************************************************************************** 75/*****************************************************************************
50 * UART 76 * UART
51 ****************************************************************************/ 77 ****************************************************************************/
78static unsigned long __init uart_get_clk_rate(struct clk *clk)
79{
80 clk_prepare_enable(clk);
81 return clk_get_rate(clk);
82}
83
52static void __init uart_complete( 84static void __init uart_complete(
53 struct platform_device *orion_uart, 85 struct platform_device *orion_uart,
54 struct plat_serial8250_port *data, 86 struct plat_serial8250_port *data,
@@ -56,12 +88,12 @@ static void __init uart_complete(
56 unsigned int membase, 88 unsigned int membase,
57 resource_size_t mapbase, 89 resource_size_t mapbase,
58 unsigned int irq, 90 unsigned int irq,
59 unsigned int uartclk) 91 struct clk *clk)
60{ 92{
61 data->mapbase = mapbase; 93 data->mapbase = mapbase;
62 data->membase = (void __iomem *)membase; 94 data->membase = (void __iomem *)membase;
63 data->irq = irq; 95 data->irq = irq;
64 data->uartclk = uartclk; 96 data->uartclk = uart_get_clk_rate(clk);
65 orion_uart->dev.platform_data = data; 97 orion_uart->dev.platform_data = data;
66 98
67 fill_resources(orion_uart, resources, mapbase, 0xff, irq); 99 fill_resources(orion_uart, resources, mapbase, 0xff, irq);
@@ -90,10 +122,10 @@ static struct platform_device orion_uart0 = {
90void __init orion_uart0_init(unsigned int membase, 122void __init orion_uart0_init(unsigned int membase,
91 resource_size_t mapbase, 123 resource_size_t mapbase,
92 unsigned int irq, 124 unsigned int irq,
93 unsigned int uartclk) 125 struct clk *clk)
94{ 126{
95 uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources, 127 uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
96 membase, mapbase, irq, uartclk); 128 membase, mapbase, irq, clk);
97} 129}
98 130
99/***************************************************************************** 131/*****************************************************************************
@@ -118,10 +150,10 @@ static struct platform_device orion_uart1 = {
118void __init orion_uart1_init(unsigned int membase, 150void __init orion_uart1_init(unsigned int membase,
119 resource_size_t mapbase, 151 resource_size_t mapbase,
120 unsigned int irq, 152 unsigned int irq,
121 unsigned int uartclk) 153 struct clk *clk)
122{ 154{
123 uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources, 155 uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
124 membase, mapbase, irq, uartclk); 156 membase, mapbase, irq, clk);
125} 157}
126 158
127/***************************************************************************** 159/*****************************************************************************
@@ -146,10 +178,10 @@ static struct platform_device orion_uart2 = {
146void __init orion_uart2_init(unsigned int membase, 178void __init orion_uart2_init(unsigned int membase,
147 resource_size_t mapbase, 179 resource_size_t mapbase,
148 unsigned int irq, 180 unsigned int irq,
149 unsigned int uartclk) 181 struct clk *clk)
150{ 182{
151 uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources, 183 uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources,
152 membase, mapbase, irq, uartclk); 184 membase, mapbase, irq, clk);
153} 185}
154 186
155/***************************************************************************** 187/*****************************************************************************
@@ -174,10 +206,10 @@ static struct platform_device orion_uart3 = {
174void __init orion_uart3_init(unsigned int membase, 206void __init orion_uart3_init(unsigned int membase,
175 resource_size_t mapbase, 207 resource_size_t mapbase,
176 unsigned int irq, 208 unsigned int irq,
177 unsigned int uartclk) 209 struct clk *clk)
178{ 210{
179 uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources, 211 uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources,
180 membase, mapbase, irq, uartclk); 212 membase, mapbase, irq, clk);
181} 213}
182 214
183/***************************************************************************** 215/*****************************************************************************
@@ -203,13 +235,11 @@ void __init orion_rtc_init(unsigned long mapbase,
203 ****************************************************************************/ 235 ****************************************************************************/
204static __init void ge_complete( 236static __init void ge_complete(
205 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, 237 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
206 int tclk,
207 struct resource *orion_ge_resource, unsigned long irq, 238 struct resource *orion_ge_resource, unsigned long irq,
208 struct platform_device *orion_ge_shared, 239 struct platform_device *orion_ge_shared,
209 struct mv643xx_eth_platform_data *eth_data, 240 struct mv643xx_eth_platform_data *eth_data,
210 struct platform_device *orion_ge) 241 struct platform_device *orion_ge)
211{ 242{
212 orion_ge_shared_data->t_clk = tclk;
213 orion_ge_resource->start = irq; 243 orion_ge_resource->start = irq;
214 orion_ge_resource->end = irq; 244 orion_ge_resource->end = irq;
215 eth_data->shared = orion_ge_shared; 245 eth_data->shared = orion_ge_shared;
@@ -260,12 +290,11 @@ static struct platform_device orion_ge00 = {
260void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, 290void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
261 unsigned long mapbase, 291 unsigned long mapbase,
262 unsigned long irq, 292 unsigned long irq,
263 unsigned long irq_err, 293 unsigned long irq_err)
264 int tclk)
265{ 294{
266 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, 295 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
267 mapbase + 0x2000, SZ_16K - 1, irq_err); 296 mapbase + 0x2000, SZ_16K - 1, irq_err);
268 ge_complete(&orion_ge00_shared_data, tclk, 297 ge_complete(&orion_ge00_shared_data,
269 orion_ge00_resources, irq, &orion_ge00_shared, 298 orion_ge00_resources, irq, &orion_ge00_shared,
270 eth_data, &orion_ge00); 299 eth_data, &orion_ge00);
271} 300}
@@ -313,12 +342,11 @@ static struct platform_device orion_ge01 = {
313void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, 342void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
314 unsigned long mapbase, 343 unsigned long mapbase,
315 unsigned long irq, 344 unsigned long irq,
316 unsigned long irq_err, 345 unsigned long irq_err)
317 int tclk)
318{ 346{
319 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, 347 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
320 mapbase + 0x2000, SZ_16K - 1, irq_err); 348 mapbase + 0x2000, SZ_16K - 1, irq_err);
321 ge_complete(&orion_ge01_shared_data, tclk, 349 ge_complete(&orion_ge01_shared_data,
322 orion_ge01_resources, irq, &orion_ge01_shared, 350 orion_ge01_resources, irq, &orion_ge01_shared,
323 eth_data, &orion_ge01); 351 eth_data, &orion_ge01);
324} 352}
@@ -366,12 +394,11 @@ static struct platform_device orion_ge10 = {
366void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, 394void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
367 unsigned long mapbase, 395 unsigned long mapbase,
368 unsigned long irq, 396 unsigned long irq,
369 unsigned long irq_err, 397 unsigned long irq_err)
370 int tclk)
371{ 398{
372 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, 399 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
373 mapbase + 0x2000, SZ_16K - 1, irq_err); 400 mapbase + 0x2000, SZ_16K - 1, irq_err);
374 ge_complete(&orion_ge10_shared_data, tclk, 401 ge_complete(&orion_ge10_shared_data,
375 orion_ge10_resources, irq, &orion_ge10_shared, 402 orion_ge10_resources, irq, &orion_ge10_shared,
376 eth_data, &orion_ge10); 403 eth_data, &orion_ge10);
377} 404}
@@ -419,12 +446,11 @@ static struct platform_device orion_ge11 = {
419void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, 446void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
420 unsigned long mapbase, 447 unsigned long mapbase,
421 unsigned long irq, 448 unsigned long irq,
422 unsigned long irq_err, 449 unsigned long irq_err)
423 int tclk)
424{ 450{
425 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, 451 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
426 mapbase + 0x2000, SZ_16K - 1, irq_err); 452 mapbase + 0x2000, SZ_16K - 1, irq_err);
427 ge_complete(&orion_ge11_shared_data, tclk, 453 ge_complete(&orion_ge11_shared_data,
428 orion_ge11_resources, irq, &orion_ge11_shared, 454 orion_ge11_resources, irq, &orion_ge11_shared,
429 eth_data, &orion_ge11); 455 eth_data, &orion_ge11);
430} 456}
@@ -521,44 +547,32 @@ void __init orion_i2c_1_init(unsigned long mapbase,
521/***************************************************************************** 547/*****************************************************************************
522 * SPI 548 * SPI
523 ****************************************************************************/ 549 ****************************************************************************/
524static struct orion_spi_info orion_spi_plat_data;
525static struct resource orion_spi_resources; 550static struct resource orion_spi_resources;
526 551
527static struct platform_device orion_spi = { 552static struct platform_device orion_spi = {
528 .name = "orion_spi", 553 .name = "orion_spi",
529 .id = 0, 554 .id = 0,
530 .dev = {
531 .platform_data = &orion_spi_plat_data,
532 },
533}; 555};
534 556
535static struct orion_spi_info orion_spi_1_plat_data;
536static struct resource orion_spi_1_resources; 557static struct resource orion_spi_1_resources;
537 558
538static struct platform_device orion_spi_1 = { 559static struct platform_device orion_spi_1 = {
539 .name = "orion_spi", 560 .name = "orion_spi",
540 .id = 1, 561 .id = 1,
541 .dev = {
542 .platform_data = &orion_spi_1_plat_data,
543 },
544}; 562};
545 563
546/* Note: The SPI silicon core does have interrupts. However the 564/* Note: The SPI silicon core does have interrupts. However the
547 * current Linux software driver does not use interrupts. */ 565 * current Linux software driver does not use interrupts. */
548 566
549void __init orion_spi_init(unsigned long mapbase, 567void __init orion_spi_init(unsigned long mapbase)
550 unsigned long tclk)
551{ 568{
552 orion_spi_plat_data.tclk = tclk;
553 fill_resources(&orion_spi, &orion_spi_resources, 569 fill_resources(&orion_spi, &orion_spi_resources,
554 mapbase, SZ_512 - 1, NO_IRQ); 570 mapbase, SZ_512 - 1, NO_IRQ);
555 platform_device_register(&orion_spi); 571 platform_device_register(&orion_spi);
556} 572}
557 573
558void __init orion_spi_1_init(unsigned long mapbase, 574void __init orion_spi_1_init(unsigned long mapbase)
559 unsigned long tclk)
560{ 575{
561 orion_spi_1_plat_data.tclk = tclk;
562 fill_resources(&orion_spi_1, &orion_spi_1_resources, 576 fill_resources(&orion_spi_1, &orion_spi_1_resources,
563 mapbase, SZ_512 - 1, NO_IRQ); 577 mapbase, SZ_512 - 1, NO_IRQ);
564 platform_device_register(&orion_spi_1); 578 platform_device_register(&orion_spi_1);
@@ -567,24 +581,18 @@ void __init orion_spi_1_init(unsigned long mapbase,
567/***************************************************************************** 581/*****************************************************************************
568 * Watchdog 582 * Watchdog
569 ****************************************************************************/ 583 ****************************************************************************/
570static struct orion_wdt_platform_data orion_wdt_data;
571
572static struct resource orion_wdt_resource = 584static struct resource orion_wdt_resource =
573 DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); 585 DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28);
574 586
575static struct platform_device orion_wdt_device = { 587static struct platform_device orion_wdt_device = {
576 .name = "orion_wdt", 588 .name = "orion_wdt",
577 .id = -1, 589 .id = -1,
578 .dev = {
579 .platform_data = &orion_wdt_data,
580 },
581 .resource = &orion_wdt_resource,
582 .num_resources = 1, 590 .num_resources = 1,
591 .resource = &orion_wdt_resource,
583}; 592};
584 593
585void __init orion_wdt_init(unsigned long tclk) 594void __init orion_wdt_init(void)
586{ 595{
587 orion_wdt_data.tclk = tclk;
588 platform_device_register(&orion_wdt_device); 596 platform_device_register(&orion_wdt_device);
589} 597}
590 598
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index a7fa005a5a0..e00fdb21360 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -16,22 +16,22 @@ struct dsa_platform_data;
16void __init orion_uart0_init(unsigned int membase, 16void __init orion_uart0_init(unsigned int membase,
17 resource_size_t mapbase, 17 resource_size_t mapbase,
18 unsigned int irq, 18 unsigned int irq,
19 unsigned int uartclk); 19 struct clk *clk);
20 20
21void __init orion_uart1_init(unsigned int membase, 21void __init orion_uart1_init(unsigned int membase,
22 resource_size_t mapbase, 22 resource_size_t mapbase,
23 unsigned int irq, 23 unsigned int irq,
24 unsigned int uartclk); 24 struct clk *clk);
25 25
26void __init orion_uart2_init(unsigned int membase, 26void __init orion_uart2_init(unsigned int membase,
27 resource_size_t mapbase, 27 resource_size_t mapbase,
28 unsigned int irq, 28 unsigned int irq,
29 unsigned int uartclk); 29 struct clk *clk);
30 30
31void __init orion_uart3_init(unsigned int membase, 31void __init orion_uart3_init(unsigned int membase,
32 resource_size_t mapbase, 32 resource_size_t mapbase,
33 unsigned int irq, 33 unsigned int irq,
34 unsigned int uartclk); 34 struct clk *clk);
35 35
36void __init orion_rtc_init(unsigned long mapbase, 36void __init orion_rtc_init(unsigned long mapbase,
37 unsigned long irq); 37 unsigned long irq);
@@ -39,29 +39,26 @@ void __init orion_rtc_init(unsigned long mapbase,
39void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, 39void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
40 unsigned long mapbase, 40 unsigned long mapbase,
41 unsigned long irq, 41 unsigned long irq,
42 unsigned long irq_err, 42 unsigned long irq_err);
43 int tclk);
44 43
45void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, 44void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
46 unsigned long mapbase, 45 unsigned long mapbase,
47 unsigned long irq, 46 unsigned long irq,
48 unsigned long irq_err, 47 unsigned long irq_err);
49 int tclk);
50 48
51void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, 49void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
52 unsigned long mapbase, 50 unsigned long mapbase,
53 unsigned long irq, 51 unsigned long irq,
54 unsigned long irq_err, 52 unsigned long irq_err);
55 int tclk);
56 53
57void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, 54void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
58 unsigned long mapbase, 55 unsigned long mapbase,
59 unsigned long irq, 56 unsigned long irq,
60 unsigned long irq_err, 57 unsigned long irq_err);
61 int tclk);
62 58
63void __init orion_ge00_switch_init(struct dsa_platform_data *d, 59void __init orion_ge00_switch_init(struct dsa_platform_data *d,
64 int irq); 60 int irq);
61
65void __init orion_i2c_init(unsigned long mapbase, 62void __init orion_i2c_init(unsigned long mapbase,
66 unsigned long irq, 63 unsigned long irq,
67 unsigned long freq_m); 64 unsigned long freq_m);
@@ -70,13 +67,11 @@ void __init orion_i2c_1_init(unsigned long mapbase,
70 unsigned long irq, 67 unsigned long irq,
71 unsigned long freq_m); 68 unsigned long freq_m);
72 69
73void __init orion_spi_init(unsigned long mapbase, 70void __init orion_spi_init(unsigned long mapbase);
74 unsigned long tclk);
75 71
76void __init orion_spi_1_init(unsigned long mapbase, 72void __init orion_spi_1_init(unsigned long mapbase);
77 unsigned long tclk);
78 73
79void __init orion_wdt_init(unsigned long tclk); 74void __init orion_wdt_init(void);
80 75
81void __init orion_xor0_init(unsigned long mapbase_low, 76void __init orion_xor0_init(unsigned long mapbase_low,
82 unsigned long mapbase_high, 77 unsigned long mapbase_high,
@@ -106,4 +101,9 @@ void __init orion_crypto_init(unsigned long mapbase,
106 unsigned long srambase, 101 unsigned long srambase,
107 unsigned long sram_size, 102 unsigned long sram_size,
108 unsigned long irq); 103 unsigned long irq);
104
105void __init orion_clkdev_add(const char *con_id, const char *dev_id,
106 struct clk *clk);
107
108void __init orion_clkdev_init(struct clk *tclk);
109#endif 109#endif
diff --git a/arch/arm/plat-orion/include/plat/orion_wdt.h b/arch/arm/plat-orion/include/plat/orion_wdt.h
deleted file mode 100644
index 665c362a2fb..00000000000
--- a/arch/arm/plat-orion/include/plat/orion_wdt.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * arch/arm/plat-orion/include/plat/orion_wdt.h
3 *
4 * This file is licensed under the terms of the GNU General Public
5 * License version 2. This program is licensed "as is" without any
6 * warranty of any kind, whether express or implied.
7 */
8
9#ifndef __PLAT_ORION_WDT_H
10#define __PLAT_ORION_WDT_H
11
12struct orion_wdt_platform_data {
13 u32 tclk; /* no <linux/clk.h> support yet */
14};
15
16
17#endif
18
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
index 86dbb5bdb17..f20a321088a 100644
--- a/arch/arm/plat-orion/pcie.c
+++ b/arch/arm/plat-orion/pcie.c
@@ -52,12 +52,12 @@
52#define PCIE_DEBUG_SOFT_RESET (1<<20) 52#define PCIE_DEBUG_SOFT_RESET (1<<20)
53 53
54 54
55u32 __init orion_pcie_dev_id(void __iomem *base) 55u32 orion_pcie_dev_id(void __iomem *base)
56{ 56{
57 return readl(base + PCIE_DEV_ID_OFF) >> 16; 57 return readl(base + PCIE_DEV_ID_OFF) >> 16;
58} 58}
59 59
60u32 __init orion_pcie_rev(void __iomem *base) 60u32 orion_pcie_rev(void __iomem *base)
61{ 61{
62 return readl(base + PCIE_DEV_REV_OFF) & 0xff; 62 return readl(base + PCIE_DEV_REV_OFF) & 0xff;
63} 63}
diff --git a/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
index abcc36eb124..5ce8d5e6ea5 100644
--- a/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
+++ b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
@@ -44,6 +44,10 @@ struct pxa27x_keypad_platform_data {
44 /* direct keys */ 44 /* direct keys */
45 int direct_key_num; 45 int direct_key_num;
46 unsigned int direct_key_map[MAX_DIRECT_KEY_NUM]; 46 unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
47 /* the key output may be low active */
48 int direct_key_low_active;
49 /* give board a chance to choose the start direct key */
50 unsigned int direct_key_mask;
47 51
48 /* rotary encoders 0 */ 52 /* rotary encoders 0 */
49 int enable_rotary0; 53 int enable_rotary0;
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 2467b800cc7..9f60549c8da 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -12,10 +12,7 @@ obj- :=
12 12
13# Core files 13# Core files
14 14
15obj-y += cpu.o
16obj-y += irq.o 15obj-y += irq.o
17obj-y += dev-uart.o
18obj-y += clock.o
19obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o 16obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o
20 17
21obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o 18obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o
@@ -23,9 +20,6 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
23 20
24# Architecture dependent builds 21# Architecture dependent builds
25 22
26obj-$(CONFIG_PM) += pm.o
27obj-$(CONFIG_PM) += irq-pm.o
28obj-$(CONFIG_PM) += sleep.o
29obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o 23obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
30obj-$(CONFIG_S3C24XX_DMA) += dma.o 24obj-$(CONFIG_S3C24XX_DMA) += dma.o
31obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o 25obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
deleted file mode 100644
index 931d26d1a54..00000000000
--- a/arch/arm/plat-s3c24xx/clock.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/clock.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX Core clock control support
7 *
8 * Based on, and code from linux/arch/arm/mach-versatile/clock.c
9 **
10 ** Copyright (C) 2004 ARM Limited.
11 ** Written by Deep Blue Solutions Limited.
12 *
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/clk.h>
32#include <linux/io.h>
33
34#include <mach/hardware.h>
35#include <asm/irq.h>
36
37#include <mach/regs-clock.h>
38#include <mach/regs-gpio.h>
39
40#include <plat/cpu-freq.h>
41
42#include <plat/clock.h>
43#include <plat/cpu.h>
44#include <plat/pll.h>
45
46/* initialise all the clocks */
47
48void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
49 unsigned long hclk,
50 unsigned long pclk)
51{
52 clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
53 clk_xtal.rate);
54
55 clk_mpll.rate = fclk;
56 clk_h.rate = hclk;
57 clk_p.rate = pclk;
58 clk_f.rate = fclk;
59}
diff --git a/arch/arm/plat-s3c24xx/dev-uart.c b/arch/arm/plat-s3c24xx/dev-uart.c
deleted file mode 100644
index 9ab22e662ff..00000000000
--- a/arch/arm/plat-s3c24xx/dev-uart.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* linux/arch/arm/plat-s3c24xx/dev-uart.c
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Base S3C24XX UART resource and platform device definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/serial_core.h>
18#include <linux/platform_device.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach/map.h>
22#include <asm/mach/irq.h>
23#include <mach/hardware.h>
24#include <mach/map.h>
25
26#include <plat/devs.h>
27#include <plat/regs-serial.h>
28
29/* Serial port registrations */
30
31static struct resource s3c2410_uart0_resource[] = {
32 [0] = {
33 .start = S3C2410_PA_UART0,
34 .end = S3C2410_PA_UART0 + 0x3fff,
35 .flags = IORESOURCE_MEM,
36 },
37 [1] = {
38 .start = IRQ_S3CUART_RX0,
39 .end = IRQ_S3CUART_ERR0,
40 .flags = IORESOURCE_IRQ,
41 }
42};
43
44static struct resource s3c2410_uart1_resource[] = {
45 [0] = {
46 .start = S3C2410_PA_UART1,
47 .end = S3C2410_PA_UART1 + 0x3fff,
48 .flags = IORESOURCE_MEM,
49 },
50 [1] = {
51 .start = IRQ_S3CUART_RX1,
52 .end = IRQ_S3CUART_ERR1,
53 .flags = IORESOURCE_IRQ,
54 }
55};
56
57static struct resource s3c2410_uart2_resource[] = {
58 [0] = {
59 .start = S3C2410_PA_UART2,
60 .end = S3C2410_PA_UART2 + 0x3fff,
61 .flags = IORESOURCE_MEM,
62 },
63 [1] = {
64 .start = IRQ_S3CUART_RX2,
65 .end = IRQ_S3CUART_ERR2,
66 .flags = IORESOURCE_IRQ,
67 }
68};
69
70static struct resource s3c2410_uart3_resource[] = {
71 [0] = {
72 .start = S3C2443_PA_UART3,
73 .end = S3C2443_PA_UART3 + 0x3fff,
74 .flags = IORESOURCE_MEM,
75 },
76 [1] = {
77 .start = IRQ_S3CUART_RX3,
78 .end = IRQ_S3CUART_ERR3,
79 .flags = IORESOURCE_IRQ,
80 },
81};
82
83struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
84 [0] = {
85 .resources = s3c2410_uart0_resource,
86 .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
87 },
88 [1] = {
89 .resources = s3c2410_uart1_resource,
90 .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
91 },
92 [2] = {
93 .resources = s3c2410_uart2_resource,
94 .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
95 },
96 [3] = {
97 .resources = s3c2410_uart3_resource,
98 .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
99 },
100};
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
deleted file mode 100644
index 96bea320230..00000000000
--- a/arch/arm/plat-s5p/Kconfig
+++ /dev/null
@@ -1,140 +0,0 @@
1# arch/arm/plat-s5p/Kconfig
2#
3# Copyright (c) 2009 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8config PLAT_S5P
9 bool
10 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
11 default y
12 select ARM_VIC if !ARCH_EXYNOS
13 select ARM_GIC if ARCH_EXYNOS
14 select GIC_NON_BANKED if ARCH_EXYNOS4
15 select NO_IOPORT
16 select ARCH_REQUIRE_GPIOLIB
17 select S3C_GPIO_TRACK
18 select S5P_GPIO_DRVSTR
19 select SAMSUNG_GPIOLIB_4BIT
20 select PLAT_SAMSUNG
21 select SAMSUNG_CLKSRC
22 select SAMSUNG_IRQ_VIC_TIMER
23 help
24 Base platform code for Samsung's S5P series SoC.
25
26config S5P_EXT_INT
27 bool
28 help
29 Use the external interrupts (other than GPIO interrupts.)
30 Note: Do not choose this for S5P6440 and S5P6450.
31
32config S5P_GPIO_INT
33 bool
34 help
35 Common code for the GPIO interrupts (other than external interrupts.)
36
37config S5P_HRT
38 bool
39 select SAMSUNG_DEV_PWM
40 help
41 Use the High Resolution timer support
42
43config S5P_DEV_UART
44 def_bool y
45 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
46
47config S5P_PM
48 bool
49 help
50 Common code for power management support on S5P and newer SoCs
51 Note: Do not select this for S5P6440 and S5P6450.
52
53comment "System MMU"
54
55config S5P_SYSTEM_MMU
56 bool "S5P SYSTEM MMU"
57 depends on ARCH_EXYNOS4
58 help
59 Say Y here if you want to enable System MMU
60
61config S5P_SLEEP
62 bool
63 help
64 Internal config node to apply common S5P sleep management code.
65 Can be selected by S5P and newer SoCs with similar sleep procedure.
66
67config S5P_DEV_FIMC0
68 bool
69 help
70 Compile in platform device definitions for FIMC controller 0
71
72config S5P_DEV_FIMC1
73 bool
74 help
75 Compile in platform device definitions for FIMC controller 1
76
77config S5P_DEV_FIMC2
78 bool
79 help
80 Compile in platform device definitions for FIMC controller 2
81
82config S5P_DEV_FIMC3
83 bool
84 help
85 Compile in platform device definitions for FIMC controller 3
86
87config S5P_DEV_JPEG
88 bool
89 help
90 Compile in platform device definitions for JPEG codec
91
92config S5P_DEV_G2D
93 bool
94 help
95 Compile in platform device definitions for G2D device
96
97config S5P_DEV_FIMD0
98 bool
99 help
100 Compile in platform device definitions for FIMD controller 0
101
102config S5P_DEV_I2C_HDMIPHY
103 bool
104 help
105 Compile in platform device definitions for I2C HDMIPHY controller
106
107config S5P_DEV_MFC
108 bool
109 help
110 Compile in platform device definitions for MFC
111
112config S5P_DEV_ONENAND
113 bool
114 help
115 Compile in platform device definition for OneNAND controller
116
117config S5P_DEV_CSIS0
118 bool
119 help
120 Compile in platform device definitions for MIPI-CSIS channel 0
121
122config S5P_DEV_CSIS1
123 bool
124 help
125 Compile in platform device definitions for MIPI-CSIS channel 1
126
127config S5P_DEV_TV
128 bool
129 help
130 Compile in platform device definition for TV interface
131
132config S5P_DEV_USB_EHCI
133 bool
134 help
135 Compile in platform device definition for USB EHCI
136
137config S5P_SETUP_MIPIPHY
138 bool
139 help
140 Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
deleted file mode 100644
index 4bd82413665..00000000000
--- a/arch/arm/plat-s5p/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
1# arch/arm/plat-s5p/Makefile
2#
3# Copyright (c) 2009 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8obj-y :=
9obj-m :=
10obj-n := dummy.o
11obj- :=
12
13# Core files
14
15obj-y += clock.o
16obj-y += irq.o
17obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
18obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
19obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
20obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o
21obj-$(CONFIG_S5P_SLEEP) += sleep.o
22obj-$(CONFIG_S5P_HRT) += s5p-time.o
23
24# devices
25
26obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o
27obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
28obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
deleted file mode 100644
index c8bec9c7655..00000000000
--- a/arch/arm/plat-s5p/sysmmu.c
+++ /dev/null
@@ -1,313 +0,0 @@
1/* linux/arch/arm/plat-s5p/sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
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/io.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <linux/export.h>
15
16#include <asm/pgtable.h>
17
18#include <mach/map.h>
19#include <mach/regs-sysmmu.h>
20#include <plat/sysmmu.h>
21
22#define CTRL_ENABLE 0x5
23#define CTRL_BLOCK 0x7
24#define CTRL_DISABLE 0x0
25
26static struct device *dev;
27
28static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
29 S5P_PAGE_FAULT_ADDR,
30 S5P_AR_FAULT_ADDR,
31 S5P_AW_FAULT_ADDR,
32 S5P_DEFAULT_SLAVE_ADDR,
33 S5P_AR_FAULT_ADDR,
34 S5P_AR_FAULT_ADDR,
35 S5P_AW_FAULT_ADDR,
36 S5P_AW_FAULT_ADDR
37};
38
39static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
40 "PAGE FAULT",
41 "AR MULTI-HIT FAULT",
42 "AW MULTI-HIT FAULT",
43 "BUS ERROR",
44 "AR SECURITY PROTECTION FAULT",
45 "AR ACCESS PROTECTION FAULT",
46 "AW SECURITY PROTECTION FAULT",
47 "AW ACCESS PROTECTION FAULT"
48};
49
50static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])(
51 enum S5P_SYSMMU_INTERRUPT_TYPE itype,
52 unsigned long pgtable_base,
53 unsigned long fault_addr);
54
55/*
56 * If adjacent 2 bits are true, the system MMU is enabled.
57 * The system MMU is disabled, otherwise.
58 */
59static unsigned long sysmmu_states;
60
61static inline void set_sysmmu_active(sysmmu_ips ips)
62{
63 sysmmu_states |= 3 << (ips * 2);
64}
65
66static inline void set_sysmmu_inactive(sysmmu_ips ips)
67{
68 sysmmu_states &= ~(3 << (ips * 2));
69}
70
71static inline int is_sysmmu_active(sysmmu_ips ips)
72{
73 return sysmmu_states & (3 << (ips * 2));
74}
75
76static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM];
77
78static inline void sysmmu_block(sysmmu_ips ips)
79{
80 __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL);
81 dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]);
82}
83
84static inline void sysmmu_unblock(sysmmu_ips ips)
85{
86 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
87 dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]);
88}
89
90static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips)
91{
92 __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH);
93 dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]);
94}
95
96static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd)
97{
98 if (unlikely(pgd == 0)) {
99 pgd = (unsigned long)ZERO_PAGE(0);
100 __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */
101 } else {
102 __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */
103 }
104
105 __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
106
107 dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n",
108 sysmmu_ips_name[ips], pgd);
109 __sysmmu_tlb_invalidate(ips);
110}
111
112void sysmmu_set_fault_handler(sysmmu_ips ips,
113 int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
114 unsigned long pgtable_base,
115 unsigned long fault_addr))
116{
117 BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM)));
118 fault_handlers[ips] = handler;
119}
120
121static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
122{
123 /* SYSMMU is in blocked when interrupt occurred. */
124 unsigned long base = 0;
125 sysmmu_ips ips = (sysmmu_ips)dev_id;
126 enum S5P_SYSMMU_INTERRUPT_TYPE itype;
127
128 itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
129 __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS));
130
131 BUG_ON(!((itype >= 0) && (itype < 8)));
132
133 dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype],
134 sysmmu_ips_name[ips]);
135
136 if (fault_handlers[ips]) {
137 unsigned long addr;
138
139 base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
140 addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]);
141
142 if (fault_handlers[ips](itype, base, addr)) {
143 __raw_writel(1 << itype,
144 sysmmusfrs[ips] + S5P_INT_CLEAR);
145 dev_notice(dev, "%s from %s is resolved."
146 " Retrying translation.\n",
147 sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
148 } else {
149 base = 0;
150 }
151 }
152
153 sysmmu_unblock(ips);
154
155 if (!base)
156 dev_notice(dev, "%s from %s is not handled.\n",
157 sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
158
159 return IRQ_HANDLED;
160}
161
162void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
163{
164 if (is_sysmmu_active(ips)) {
165 sysmmu_block(ips);
166 __sysmmu_set_ptbase(ips, pgd);
167 sysmmu_unblock(ips);
168 } else {
169 dev_dbg(dev, "%s is disabled. "
170 "Skipping initializing page table base.\n",
171 sysmmu_ips_name[ips]);
172 }
173}
174
175void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
176{
177 if (!is_sysmmu_active(ips)) {
178 sysmmu_clk_enable(ips);
179
180 __sysmmu_set_ptbase(ips, pgd);
181
182 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
183
184 set_sysmmu_active(ips);
185 dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]);
186 } else {
187 dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]);
188 }
189}
190
191void s5p_sysmmu_disable(sysmmu_ips ips)
192{
193 if (is_sysmmu_active(ips)) {
194 __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
195 set_sysmmu_inactive(ips);
196 sysmmu_clk_disable(ips);
197 dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
198 } else {
199 dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
200 }
201}
202
203void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
204{
205 if (is_sysmmu_active(ips)) {
206 sysmmu_block(ips);
207 __sysmmu_tlb_invalidate(ips);
208 sysmmu_unblock(ips);
209 } else {
210 dev_dbg(dev, "%s is disabled. "
211 "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]);
212 }
213}
214
215static int s5p_sysmmu_probe(struct platform_device *pdev)
216{
217 int i, ret;
218 struct resource *res, *mem;
219
220 dev = &pdev->dev;
221
222 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
223 int irq;
224
225 sysmmu_clk_init(dev, i);
226 sysmmu_clk_disable(i);
227
228 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
229 if (!res) {
230 dev_err(dev, "Failed to get the resource of %s.\n",
231 sysmmu_ips_name[i]);
232 ret = -ENODEV;
233 goto err_res;
234 }
235
236 mem = request_mem_region(res->start, resource_size(res),
237 pdev->name);
238 if (!mem) {
239 dev_err(dev, "Failed to request the memory region of %s.\n",
240 sysmmu_ips_name[i]);
241 ret = -EBUSY;
242 goto err_res;
243 }
244
245 sysmmusfrs[i] = ioremap(res->start, resource_size(res));
246 if (!sysmmusfrs[i]) {
247 dev_err(dev, "Failed to ioremap() for %s.\n",
248 sysmmu_ips_name[i]);
249 ret = -ENXIO;
250 goto err_reg;
251 }
252
253 irq = platform_get_irq(pdev, i);
254 if (irq <= 0) {
255 dev_err(dev, "Failed to get the IRQ resource of %s.\n",
256 sysmmu_ips_name[i]);
257 ret = -ENOENT;
258 goto err_map;
259 }
260
261 if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED,
262 pdev->name, (void *)i)) {
263 dev_err(dev, "Failed to request IRQ for %s.\n",
264 sysmmu_ips_name[i]);
265 ret = -ENOENT;
266 goto err_map;
267 }
268 }
269
270 return 0;
271
272err_map:
273 iounmap(sysmmusfrs[i]);
274err_reg:
275 release_mem_region(mem->start, resource_size(mem));
276err_res:
277 return ret;
278}
279
280static int s5p_sysmmu_remove(struct platform_device *pdev)
281{
282 return 0;
283}
284int s5p_sysmmu_runtime_suspend(struct device *dev)
285{
286 return 0;
287}
288
289int s5p_sysmmu_runtime_resume(struct device *dev)
290{
291 return 0;
292}
293
294const struct dev_pm_ops s5p_sysmmu_pm_ops = {
295 .runtime_suspend = s5p_sysmmu_runtime_suspend,
296 .runtime_resume = s5p_sysmmu_runtime_resume,
297};
298
299static struct platform_driver s5p_sysmmu_driver = {
300 .probe = s5p_sysmmu_probe,
301 .remove = s5p_sysmmu_remove,
302 .driver = {
303 .owner = THIS_MODULE,
304 .name = "s5p-sysmmu",
305 .pm = &s5p_sysmmu_pm_ops,
306 }
307};
308
309static int __init s5p_sysmmu_init(void)
310{
311 return platform_driver_register(&s5p_sysmmu_driver);
312}
313arch_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index a0ffc77da80..a2fae4ea093 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -13,6 +13,24 @@ config PLAT_SAMSUNG
13 help 13 help
14 Base platform code for all Samsung SoC based systems 14 Base platform code for all Samsung SoC based systems
15 15
16config PLAT_S5P
17 bool
18 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
19 default y
20 select ARM_VIC if !ARCH_EXYNOS
21 select ARM_GIC if ARCH_EXYNOS
22 select GIC_NON_BANKED if ARCH_EXYNOS4
23 select NO_IOPORT
24 select ARCH_REQUIRE_GPIOLIB
25 select S3C_GPIO_TRACK
26 select S5P_GPIO_DRVSTR
27 select SAMSUNG_GPIOLIB_4BIT
28 select PLAT_SAMSUNG
29 select SAMSUNG_CLKSRC
30 select SAMSUNG_IRQ_VIC_TIMER
31 help
32 Base platform code for Samsung's S5P series SoC.
33
16if PLAT_SAMSUNG 34if PLAT_SAMSUNG
17 35
18# boot configurations 36# boot configurations
@@ -50,6 +68,14 @@ config S3C_LOWLEVEL_UART_PORT
50 this configuration should be between zero and two. The port 68 this configuration should be between zero and two. The port
51 must have been initialised by the boot-loader before use. 69 must have been initialised by the boot-loader before use.
52 70
71# timer options
72
73config S5P_HRT
74 bool
75 select SAMSUNG_DEV_PWM
76 help
77 Use the High Resolution timer support
78
53# clock options 79# clock options
54 80
55config SAMSUNG_CLKSRC 81config SAMSUNG_CLKSRC
@@ -58,6 +84,11 @@ config SAMSUNG_CLKSRC
58 Select the clock code for the clksrc implementation 84 Select the clock code for the clksrc implementation
59 used by newer systems such as the S3C64XX. 85 used by newer systems such as the S3C64XX.
60 86
87config S5P_CLOCK
88 def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
89 help
90 Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
91
61# options for IRQ support 92# options for IRQ support
62 93
63config SAMSUNG_IRQ_VIC_TIMER 94config SAMSUNG_IRQ_VIC_TIMER
@@ -65,6 +96,22 @@ config SAMSUNG_IRQ_VIC_TIMER
65 help 96 help
66 Internal configuration to build the VIC timer interrupt code. 97 Internal configuration to build the VIC timer interrupt code.
67 98
99config S5P_IRQ
100 def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
101 help
102 Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs
103
104config S5P_EXT_INT
105 bool
106 help
107 Use the external interrupts (other than GPIO interrupts.)
108 Note: Do not choose this for S5P6440 and S5P6450.
109
110config S5P_GPIO_INT
111 bool
112 help
113 Common code for the GPIO interrupts (other than external interrupts.)
114
68# options for gpio configuration support 115# options for gpio configuration support
69 116
70config SAMSUNG_GPIOLIB_4BIT 117config SAMSUNG_GPIOLIB_4BIT
@@ -117,6 +164,12 @@ config S3C_GPIO_TRACK
117 Internal configuration option to enable the s3c specific gpio 164 Internal configuration option to enable the s3c specific gpio
118 chip tracking if the platform requires it. 165 chip tracking if the platform requires it.
119 166
167# uart options
168
169config S5P_DEV_UART
170 def_bool y
171 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
172
120# ADC driver 173# ADC driver
121 174
122config S3C_ADC 175config S3C_ADC
@@ -274,6 +327,76 @@ config SAMSUNG_DEV_BACKLIGHT
274 help 327 help
275 Compile in platform device definition LCD backlight with PWM Timer 328 Compile in platform device definition LCD backlight with PWM Timer
276 329
330config S5P_DEV_CSIS0
331 bool
332 help
333 Compile in platform device definitions for MIPI-CSIS channel 0
334
335config S5P_DEV_CSIS1
336 bool
337 help
338 Compile in platform device definitions for MIPI-CSIS channel 1
339
340config S5P_DEV_FIMC0
341 bool
342 help
343 Compile in platform device definitions for FIMC controller 0
344
345config S5P_DEV_FIMC1
346 bool
347 help
348 Compile in platform device definitions for FIMC controller 1
349
350config S5P_DEV_FIMC2
351 bool
352 help
353 Compile in platform device definitions for FIMC controller 2
354
355config S5P_DEV_FIMC3
356 bool
357 help
358 Compile in platform device definitions for FIMC controller 3
359
360config S5P_DEV_FIMD0
361 bool
362 help
363 Compile in platform device definitions for FIMD controller 0
364
365config S5P_DEV_G2D
366 bool
367 help
368 Compile in platform device definitions for G2D device
369
370config S5P_DEV_I2C_HDMIPHY
371 bool
372 help
373 Compile in platform device definitions for I2C HDMIPHY controller
374
375config S5P_DEV_JPEG
376 bool
377 help
378 Compile in platform device definitions for JPEG codec
379
380config S5P_DEV_MFC
381 bool
382 help
383 Compile in setup memory (init) code for MFC
384
385config S5P_DEV_ONENAND
386 bool
387 help
388 Compile in platform device definition for OneNAND controller
389
390config S5P_DEV_TV
391 bool
392 help
393 Compile in platform device definition for TV interface
394
395config S5P_DEV_USB_EHCI
396 bool
397 help
398 Compile in platform device definition for USB EHCI
399
277config S3C24XX_PWM 400config S3C24XX_PWM
278 bool "PWM device support" 401 bool "PWM device support"
279 select HAVE_PWM 402 select HAVE_PWM
@@ -281,6 +404,11 @@ config S3C24XX_PWM
281 Support for exporting the PWM timer blocks via the pwm device 404 Support for exporting the PWM timer blocks via the pwm device
282 system 405 system
283 406
407config S5P_SETUP_MIPIPHY
408 bool
409 help
410 Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
411
284# DMA 412# DMA
285 413
286config S3C_DMA 414config S3C_DMA
@@ -291,7 +419,7 @@ config S3C_DMA
291config SAMSUNG_DMADEV 419config SAMSUNG_DMADEV
292 bool 420 bool
293 select DMADEVICES 421 select DMADEVICES
294 select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \ 422 select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \
295 CPU_S5P6450 || CPU_S5P6440) 423 CPU_S5P6450 || CPU_S5P6440)
296 select ARM_AMBA 424 select ARM_AMBA
297 help 425 help
@@ -351,6 +479,18 @@ config SAMSUNG_WAKEMASK
351 and above. This code allows a set of interrupt to wakeup-mask 479 and above. This code allows a set of interrupt to wakeup-mask
352 mappings. See <plat/wakeup-mask.h> 480 mappings. See <plat/wakeup-mask.h>
353 481
482config S5P_PM
483 bool
484 help
485 Common code for power management support on S5P and newer SoCs
486 Note: Do not select this for S5P6440 and S5P6450.
487
488config S5P_SLEEP
489 bool
490 help
491 Internal config node to apply common S5P sleep management code.
492 Can be selected by S5P and newer SoCs with similar sleep procedure.
493
354comment "Power Domain" 494comment "Power Domain"
355 495
356config SAMSUNG_PD 496config SAMSUNG_PD
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 6012366f33c..860b2db4db1 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -13,12 +13,18 @@ obj- :=
13 13
14obj-y += init.o cpu.o 14obj-y += init.o cpu.o
15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o 15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
16obj-$(CONFIG_S5P_HRT) += s5p-time.o
17
16obj-y += clock.o 18obj-y += clock.o
17obj-y += pwm-clock.o 19obj-y += pwm-clock.o
18 20
19obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o 21obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
22obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o
20 23
21obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o 24obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
25obj-$(CONFIG_S5P_IRQ) += s5p-irq.o
26obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o
27obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o
22 28
23# ADC 29# ADC
24 30
@@ -30,9 +36,13 @@ obj-y += platformdata.o
30 36
31obj-y += devs.o 37obj-y += devs.o
32obj-y += dev-uart.o 38obj-y += dev-uart.o
39obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o
40obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o
33 41
34obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o 42obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
35 43
44obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
45
36# DMA support 46# DMA support
37 47
38obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o 48obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
@@ -47,6 +57,9 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
47 57
48obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o 58obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
49 59
60obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o
61obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o
62
50# PD support 63# PD support
51 64
52obj-$(CONFIG_SAMSUNG_PD) += pd.o 65obj-$(CONFIG_SAMSUNG_PD) += pd.o
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 787ceaca0be..0721293fad6 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -202,7 +202,7 @@ extern struct bus_type s3c2443_subsys;
202extern struct bus_type s3c6410_subsys; 202extern struct bus_type s3c6410_subsys;
203extern struct bus_type s5p64x0_subsys; 203extern struct bus_type s5p64x0_subsys;
204extern struct bus_type s5pv210_subsys; 204extern struct bus_type s5pv210_subsys;
205extern struct bus_type exynos4_subsys; 205extern struct bus_type exynos_subsys;
206 206
207extern void (*s5pc1xx_idle)(void); 207extern void (*s5pc1xx_idle)(void);
208 208
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2155d4af62a..61ca2f356c5 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -133,7 +133,8 @@ extern struct platform_device exynos4_device_pcm1;
133extern struct platform_device exynos4_device_pcm2; 133extern struct platform_device exynos4_device_pcm2;
134extern struct platform_device exynos4_device_pd[]; 134extern struct platform_device exynos4_device_pd[];
135extern struct platform_device exynos4_device_spdif; 135extern struct platform_device exynos4_device_spdif;
136extern struct platform_device exynos4_device_sysmmu; 136
137extern struct platform_device exynos_device_drm;
137 138
138extern struct platform_device samsung_asoc_dma; 139extern struct platform_device samsung_asoc_dma;
139extern struct platform_device samsung_asoc_idma; 140extern struct platform_device samsung_asoc_idma;
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 0670f37aaae..d384a8016b4 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -90,6 +90,7 @@ enum dma_ch {
90 DMACH_MIPI_HSI5, 90 DMACH_MIPI_HSI5,
91 DMACH_MIPI_HSI6, 91 DMACH_MIPI_HSI6,
92 DMACH_MIPI_HSI7, 92 DMACH_MIPI_HSI7,
93 DMACH_DISP1,
93 DMACH_MTOM_0, 94 DMACH_MTOM_0,
94 DMACH_MTOM_1, 95 DMACH_MTOM_1,
95 DMACH_MTOM_2, 96 DMACH_MTOM_2,
diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h
index 1de4b32f98e..8364b4bea8b 100644
--- a/arch/arm/plat-samsung/include/plat/s5p-clock.h
+++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h
@@ -32,8 +32,10 @@ extern struct clk clk_48m;
32extern struct clk s5p_clk_27m; 32extern struct clk s5p_clk_27m;
33extern struct clk clk_fout_apll; 33extern struct clk clk_fout_apll;
34extern struct clk clk_fout_bpll; 34extern struct clk clk_fout_bpll;
35extern struct clk clk_fout_bpll_div2;
35extern struct clk clk_fout_cpll; 36extern struct clk clk_fout_cpll;
36extern struct clk clk_fout_mpll; 37extern struct clk clk_fout_mpll;
38extern struct clk clk_fout_mpll_div2;
37extern struct clk clk_fout_epll; 39extern struct clk clk_fout_epll;
38extern struct clk clk_fout_dpll; 40extern struct clk clk_fout_dpll;
39extern struct clk clk_fout_vpll; 41extern struct clk clk_fout_vpll;
@@ -42,8 +44,10 @@ extern struct clk clk_vpll;
42 44
43extern struct clksrc_sources clk_src_apll; 45extern struct clksrc_sources clk_src_apll;
44extern struct clksrc_sources clk_src_bpll; 46extern struct clksrc_sources clk_src_bpll;
47extern struct clksrc_sources clk_src_bpll_fout;
45extern struct clksrc_sources clk_src_cpll; 48extern struct clksrc_sources clk_src_cpll;
46extern struct clksrc_sources clk_src_mpll; 49extern struct clksrc_sources clk_src_mpll;
50extern struct clksrc_sources clk_src_mpll_fout;
47extern struct clksrc_sources clk_src_epll; 51extern struct clksrc_sources clk_src_epll;
48extern struct clksrc_sources clk_src_dpll; 52extern struct clksrc_sources clk_src_dpll;
49 53
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
deleted file mode 100644
index 5fe8ee01a5b..00000000000
--- a/arch/arm/plat-samsung/include/plat/sysmmu.h
+++ /dev/null
@@ -1,95 +0,0 @@
1/* linux/arch/arm/plat-samsung/include/plat/sysmmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung System MMU driver for S5P platform
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __PLAT_SAMSUNG_SYSMMU_H
14#define __PLAT_SAMSUNG_SYSMMU_H __FILE__
15
16enum S5P_SYSMMU_INTERRUPT_TYPE {
17 SYSMMU_PAGEFAULT,
18 SYSMMU_AR_MULTIHIT,
19 SYSMMU_AW_MULTIHIT,
20 SYSMMU_BUSERROR,
21 SYSMMU_AR_SECURITY,
22 SYSMMU_AR_ACCESS,
23 SYSMMU_AW_SECURITY,
24 SYSMMU_AW_PROTECTION, /* 7 */
25 SYSMMU_FAULTS_NUM
26};
27
28#ifdef CONFIG_S5P_SYSTEM_MMU
29
30#include <mach/sysmmu.h>
31
32/**
33 * s5p_sysmmu_enable() - enable system mmu of ip
34 * @ips: The ip connected system mmu.
35 * #pgd: Base physical address of the 1st level page table
36 *
37 * This function enable system mmu to transfer address
38 * from virtual address to physical address
39 */
40void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
41
42/**
43 * s5p_sysmmu_disable() - disable sysmmu mmu of ip
44 * @ips: The ip connected system mmu.
45 *
46 * This function disable system mmu to transfer address
47 * from virtual address to physical address
48 */
49void s5p_sysmmu_disable(sysmmu_ips ips);
50
51/**
52 * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
53 * @ips: The ip connected system mmu.
54 * @pgd: The page table base address.
55 *
56 * This function set page table base address
57 * When system mmu transfer address from virtaul address to physical address,
58 * system mmu refer address information from page table
59 */
60void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
61
62/**
63 * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
64 * @ips: The ip connected system mmu.
65 *
66 * This function flush all TLB entry in system mmu
67 */
68void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
69
70/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
71 * @itype: type of fault.
72 * @pgtable_base: the physical address of page table base. This is 0 if @ips is
73 * SYSMMU_BUSERROR.
74 * @fault_addr: the device (virtual) address that the System MMU tried to
75 * translated. This is 0 if @ips is SYSMMU_BUSERROR.
76 * Called when interrupt occurred by the System MMUs
77 * The device drivers of peripheral devices that has a System MMU can implement
78 * a fault handler to resolve address translation fault by System MMU.
79 * The meanings of return value and parameters are described below.
80
81 * return value: non-zero if the fault is correctly resolved.
82 * zero if the fault is not handled.
83 */
84void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
85 int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
86 unsigned long pgtable_base,
87 unsigned long fault_addr));
88#else
89#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
90#define s5p_sysmmu_disable(ips) do { } while (0)
91#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
92#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
93#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
94#endif
95#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-samsung/s5p-clock.c
index f68a9bb1194..031a61899be 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-samsung/s5p-clock.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/clock.c 1/*
2 *
3 * Copyright 2009 Samsung Electronics Co., Ltd. 2 * Copyright 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 3 * http://www.samsung.com/
5 * 4 *
@@ -68,6 +67,11 @@ struct clk clk_fout_bpll = {
68 .id = -1, 67 .id = -1,
69}; 68};
70 69
70struct clk clk_fout_bpll_div2 = {
71 .name = "fout_bpll_div2",
72 .id = -1,
73};
74
71/* CPLL clock output */ 75/* CPLL clock output */
72 76
73struct clk clk_fout_cpll = { 77struct clk clk_fout_cpll = {
@@ -83,6 +87,11 @@ struct clk clk_fout_mpll = {
83 .id = -1, 87 .id = -1,
84}; 88};
85 89
90struct clk clk_fout_mpll_div2 = {
91 .name = "fout_mpll_div2",
92 .id = -1,
93};
94
86/* EPLL clock output */ 95/* EPLL clock output */
87struct clk clk_fout_epll = { 96struct clk clk_fout_epll = {
88 .name = "fout_epll", 97 .name = "fout_epll",
@@ -126,6 +135,16 @@ struct clksrc_sources clk_src_bpll = {
126 .nr_sources = ARRAY_SIZE(clk_src_bpll_list), 135 .nr_sources = ARRAY_SIZE(clk_src_bpll_list),
127}; 136};
128 137
138static struct clk *clk_src_bpll_fout_list[] = {
139 [0] = &clk_fout_bpll_div2,
140 [1] = &clk_fout_bpll,
141};
142
143struct clksrc_sources clk_src_bpll_fout = {
144 .sources = clk_src_bpll_fout_list,
145 .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list),
146};
147
129/* Possible clock sources for CPLL Mux */ 148/* Possible clock sources for CPLL Mux */
130static struct clk *clk_src_cpll_list[] = { 149static struct clk *clk_src_cpll_list[] = {
131 [0] = &clk_fin_cpll, 150 [0] = &clk_fin_cpll,
@@ -148,6 +167,16 @@ struct clksrc_sources clk_src_mpll = {
148 .nr_sources = ARRAY_SIZE(clk_src_mpll_list), 167 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
149}; 168};
150 169
170static struct clk *clk_src_mpll_fout_list[] = {
171 [0] = &clk_fout_mpll_div2,
172 [1] = &clk_fout_mpll,
173};
174
175struct clksrc_sources clk_src_mpll_fout = {
176 .sources = clk_src_mpll_fout_list,
177 .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list),
178};
179
151/* Possible clock sources for EPLL Mux */ 180/* Possible clock sources for EPLL Mux */
152static struct clk *clk_src_epll_list[] = { 181static struct clk *clk_src_epll_list[] = {
153 [0] = &clk_fin_epll, 182 [0] = &clk_fin_epll,
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
index a30d36b7f61..ad6089465e2 100644
--- a/arch/arm/plat-s5p/dev-mfc.c
+++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/dev-mfc.c 1/*
2 *
3 * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd 2 * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
4 * 3 *
5 * Base S5P MFC resource and device definitions 4 * Base S5P MFC resource and device definitions
@@ -9,7 +8,6 @@
9 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
10 */ 9 */
11 10
12
13#include <linux/kernel.h> 11#include <linux/kernel.h>
14#include <linux/interrupt.h> 12#include <linux/interrupt.h>
15#include <linux/platform_device.h> 13#include <linux/platform_device.h>
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-samsung/s5p-dev-uart.c
index c9308db3618..cafa3deddcc 100644
--- a/arch/arm/plat-s5p/dev-uart.c
+++ b/arch/arm/plat-samsung/s5p-dev-uart.c
@@ -1,6 +1,5 @@
1/* linux/arch/arm/plat-s5p/dev-uart.c 1/*
2 * 2 * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd.
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 3 * http://www.samsung.com/
5 * 4 *
6 * Base S5P UART resource and device definitions 5 * Base S5P UART resource and device definitions
@@ -14,6 +13,7 @@
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/interrupt.h> 14#include <linux/interrupt.h>
16#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/ioport.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18 18
19#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
@@ -26,86 +26,38 @@
26 /* Serial port registrations */ 26 /* Serial port registrations */
27 27
28static struct resource s5p_uart0_resource[] = { 28static struct resource s5p_uart0_resource[] = {
29 [0] = { 29 [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART),
30 .start = S5P_PA_UART0, 30 [1] = DEFINE_RES_IRQ(IRQ_UART0),
31 .end = S5P_PA_UART0 + S5P_SZ_UART - 1,
32 .flags = IORESOURCE_MEM,
33 },
34 [1] = {
35 .start = IRQ_UART0,
36 .end = IRQ_UART0,
37 .flags = IORESOURCE_IRQ,
38 },
39}; 31};
40 32
41static struct resource s5p_uart1_resource[] = { 33static struct resource s5p_uart1_resource[] = {
42 [0] = { 34 [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART),
43 .start = S5P_PA_UART1, 35 [1] = DEFINE_RES_IRQ(IRQ_UART1),
44 .end = S5P_PA_UART1 + S5P_SZ_UART - 1,
45 .flags = IORESOURCE_MEM,
46 },
47 [1] = {
48 .start = IRQ_UART1,
49 .end = IRQ_UART1,
50 .flags = IORESOURCE_IRQ,
51 },
52}; 36};
53 37
54static struct resource s5p_uart2_resource[] = { 38static struct resource s5p_uart2_resource[] = {
55 [0] = { 39 [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART),
56 .start = S5P_PA_UART2, 40 [1] = DEFINE_RES_IRQ(IRQ_UART2),
57 .end = S5P_PA_UART2 + S5P_SZ_UART - 1,
58 .flags = IORESOURCE_MEM,
59 },
60 [1] = {
61 .start = IRQ_UART2,
62 .end = IRQ_UART2,
63 .flags = IORESOURCE_IRQ,
64 },
65}; 41};
66 42
67static struct resource s5p_uart3_resource[] = { 43static struct resource s5p_uart3_resource[] = {
68#if CONFIG_SERIAL_SAMSUNG_UARTS > 3 44#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
69 [0] = { 45 [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART),
70 .start = S5P_PA_UART3, 46 [1] = DEFINE_RES_IRQ(IRQ_UART3),
71 .end = S5P_PA_UART3 + S5P_SZ_UART - 1,
72 .flags = IORESOURCE_MEM,
73 },
74 [1] = {
75 .start = IRQ_UART3,
76 .end = IRQ_UART3,
77 .flags = IORESOURCE_IRQ,
78 },
79#endif 47#endif
80}; 48};
81 49
82static struct resource s5p_uart4_resource[] = { 50static struct resource s5p_uart4_resource[] = {
83#if CONFIG_SERIAL_SAMSUNG_UARTS > 4 51#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
84 [0] = { 52 [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART),
85 .start = S5P_PA_UART4, 53 [1] = DEFINE_RES_IRQ(IRQ_UART4),
86 .end = S5P_PA_UART4 + S5P_SZ_UART - 1,
87 .flags = IORESOURCE_MEM,
88 },
89 [1] = {
90 .start = IRQ_UART4,
91 .end = IRQ_UART4,
92 .flags = IORESOURCE_IRQ,
93 },
94#endif 54#endif
95}; 55};
96 56
97static struct resource s5p_uart5_resource[] = { 57static struct resource s5p_uart5_resource[] = {
98#if CONFIG_SERIAL_SAMSUNG_UARTS > 5 58#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
99 [0] = { 59 [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART),
100 .start = S5P_PA_UART5, 60 [1] = DEFINE_RES_IRQ(IRQ_UART5),
101 .end = S5P_PA_UART5 + S5P_SZ_UART - 1,
102 .flags = IORESOURCE_MEM,
103 },
104 [1] = {
105 .start = IRQ_UART5,
106 .end = IRQ_UART5,
107 .flags = IORESOURCE_IRQ,
108 },
109#endif 61#endif
110}; 62};
111 63
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c
index 139c050918c..33bd3f3d20f 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-samsung/s5p-irq-eint.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/irq-eint.c 1/*
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 3 * http://www.samsung.com
5 * 4 *
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
index 82c7311017a..f9431fe5b06 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/irq-gpioint.c 1/*
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * Author: Kyungmin Park <kyungmin.park@samsung.com> 3 * Author: Kyungmin Park <kyungmin.park@samsung.com>
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com> 4 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c
index d1bfecae6c9..7c1e3b7072f 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-samsung/s5p-irq-pm.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/irq-pm.c 1/*
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 3 * http://www.samsung.com
5 * 4 *
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-samsung/s5p-irq.c
index afdaa1082b9..dfb47d638f0 100644
--- a/arch/arm/plat-s5p/irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -1,5 +1,4 @@
1/* arch/arm/plat-s5p/irq.c 1/*
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 3 * http://www.samsung.com/
5 * 4 *
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-samsung/s5p-pm.c
index d15dc47b0e3..0747468f093 100644
--- a/arch/arm/plat-s5p/pm.c
+++ b/arch/arm/plat-samsung/s5p-pm.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/pm.c 1/*
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 3 * http://www.samsung.com
5 * 4 *
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
index 006bd01eda0..bdf6dadf879 100644
--- a/arch/arm/plat-s5p/sleep.S
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/sleep.S 1/*
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com 3 * http://www.samsung.com
5 * 4 *
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c
index 17c0a2c58df..028b6e877eb 100644
--- a/arch/arm/plat-s5p/s5p-time.c
+++ b/arch/arm/plat-samsung/s5p-time.c
@@ -1,5 +1,4 @@
1/* linux/arch/arm/plat-s5p/s5p-time.c 1/*
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/ 3 * http://www.samsung.com/
5 * 4 *
diff --git a/arch/arm/plat-s5p/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
index 683c466c0e6..683c466c0e6 100644
--- a/arch/arm/plat-s5p/setup-mipiphy.c
+++ b/arch/arm/plat-samsung/setup-mipiphy.c
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
index 387655b5ce0..4404f82d597 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -8,6 +8,17 @@ choice
8 prompt "ST SPEAr Family" 8 prompt "ST SPEAr Family"
9 default ARCH_SPEAR3XX 9 default ARCH_SPEAR3XX
10 10
11config ARCH_SPEAR13XX
12 bool "ST SPEAr13xx with Device Tree"
13 select ARM_GIC
14 select CPU_V7
15 select USE_OF
16 select HAVE_SMP
17 select MIGHT_HAVE_CACHE_L2X0
18 select PINCTRL
19 help
20 Supports for ARM's SPEAR13XX family
21
11config ARCH_SPEAR3XX 22config ARCH_SPEAR3XX
12 bool "ST SPEAr3xx with Device Tree" 23 bool "ST SPEAr3xx with Device Tree"
13 select ARM_VIC 24 select ARM_VIC
@@ -27,6 +38,7 @@ config ARCH_SPEAR6XX
27endchoice 38endchoice
28 39
29# Adding SPEAr machine specific configuration files 40# Adding SPEAr machine specific configuration files
41source "arch/arm/mach-spear13xx/Kconfig"
30source "arch/arm/mach-spear3xx/Kconfig" 42source "arch/arm/mach-spear3xx/Kconfig"
31source "arch/arm/mach-spear6xx/Kconfig" 43source "arch/arm/mach-spear6xx/Kconfig"
32 44
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 7744802c83e..2607bd05c52 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := clock.o restart.o time.o pl080.o 6obj-y := restart.o time.o
7 7
8obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o 8obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o shirq.o
9obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
deleted file mode 100644
index 67dd00381ea..00000000000
--- a/arch/arm/plat-spear/clock.c
+++ /dev/null
@@ -1,1005 +0,0 @@
1/*
2 * arch/arm/plat-spear/clock.c
3 *
4 * Clock framework for SPEAr platform
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/bug.h>
15#include <linux/clk.h>
16#include <linux/debugfs.h>
17#include <linux/err.h>
18#include <linux/io.h>
19#include <linux/list.h>
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <plat/clock.h>
23
24static DEFINE_SPINLOCK(clocks_lock);
25static LIST_HEAD(root_clks);
26#ifdef CONFIG_DEBUG_FS
27static LIST_HEAD(clocks);
28#endif
29
30static void propagate_rate(struct clk *, int on_init);
31#ifdef CONFIG_DEBUG_FS
32static int clk_debugfs_reparent(struct clk *);
33#endif
34
35static int generic_clk_enable(struct clk *clk)
36{
37 unsigned int val;
38
39 if (!clk->en_reg)
40 return -EFAULT;
41
42 val = readl(clk->en_reg);
43 if (unlikely(clk->flags & RESET_TO_ENABLE))
44 val &= ~(1 << clk->en_reg_bit);
45 else
46 val |= 1 << clk->en_reg_bit;
47
48 writel(val, clk->en_reg);
49
50 return 0;
51}
52
53static void generic_clk_disable(struct clk *clk)
54{
55 unsigned int val;
56
57 if (!clk->en_reg)
58 return;
59
60 val = readl(clk->en_reg);
61 if (unlikely(clk->flags & RESET_TO_ENABLE))
62 val |= 1 << clk->en_reg_bit;
63 else
64 val &= ~(1 << clk->en_reg_bit);
65
66 writel(val, clk->en_reg);
67}
68
69/* generic clk ops */
70static struct clkops generic_clkops = {
71 .enable = generic_clk_enable,
72 .disable = generic_clk_disable,
73};
74
75/* returns current programmed clocks clock info structure */
76static struct pclk_info *pclk_info_get(struct clk *clk)
77{
78 unsigned int val, i;
79 struct pclk_info *info = NULL;
80
81 val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
82 & clk->pclk_sel->pclk_sel_mask;
83
84 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
85 if (clk->pclk_sel->pclk_info[i].pclk_val == val)
86 info = &clk->pclk_sel->pclk_info[i];
87 }
88
89 return info;
90}
91
92/*
93 * Set Update pclk, and pclk_info of clk and add clock sibling node to current
94 * parents children list
95 */
96static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
97{
98 unsigned long flags;
99
100 spin_lock_irqsave(&clocks_lock, flags);
101 list_del(&clk->sibling);
102 list_add(&clk->sibling, &pclk_info->pclk->children);
103
104 clk->pclk = pclk_info->pclk;
105 spin_unlock_irqrestore(&clocks_lock, flags);
106
107#ifdef CONFIG_DEBUG_FS
108 clk_debugfs_reparent(clk);
109#endif
110}
111
112static void do_clk_disable(struct clk *clk)
113{
114 if (!clk)
115 return;
116
117 if (!clk->usage_count) {
118 WARN_ON(1);
119 return;
120 }
121
122 clk->usage_count--;
123
124 if (clk->usage_count == 0) {
125 /*
126 * Surely, there are no active childrens or direct users
127 * of this clock
128 */
129 if (clk->pclk)
130 do_clk_disable(clk->pclk);
131
132 if (clk->ops && clk->ops->disable)
133 clk->ops->disable(clk);
134 }
135}
136
137static int do_clk_enable(struct clk *clk)
138{
139 int ret = 0;
140
141 if (!clk)
142 return -EFAULT;
143
144 if (clk->usage_count == 0) {
145 if (clk->pclk) {
146 ret = do_clk_enable(clk->pclk);
147 if (ret)
148 goto err;
149 }
150 if (clk->ops && clk->ops->enable) {
151 ret = clk->ops->enable(clk);
152 if (ret) {
153 if (clk->pclk)
154 do_clk_disable(clk->pclk);
155 goto err;
156 }
157 }
158 /*
159 * Since the clock is going to be used for the first
160 * time please reclac
161 */
162 if (clk->recalc) {
163 ret = clk->recalc(clk);
164 if (ret)
165 goto err;
166 }
167 }
168 clk->usage_count++;
169err:
170 return ret;
171}
172
173/*
174 * clk_enable - inform the system when the clock source should be running.
175 * @clk: clock source
176 *
177 * If the clock can not be enabled/disabled, this should return success.
178 *
179 * Returns success (0) or negative errno.
180 */
181int clk_enable(struct clk *clk)
182{
183 unsigned long flags;
184 int ret = 0;
185
186 spin_lock_irqsave(&clocks_lock, flags);
187 ret = do_clk_enable(clk);
188 spin_unlock_irqrestore(&clocks_lock, flags);
189 return ret;
190}
191EXPORT_SYMBOL(clk_enable);
192
193/*
194 * clk_disable - inform the system when the clock source is no longer required.
195 * @clk: clock source
196 *
197 * Inform the system that a clock source is no longer required by
198 * a driver and may be shut down.
199 *
200 * Implementation detail: if the clock source is shared between
201 * multiple drivers, clk_enable() calls must be balanced by the
202 * same number of clk_disable() calls for the clock source to be
203 * disabled.
204 */
205void clk_disable(struct clk *clk)
206{
207 unsigned long flags;
208
209 spin_lock_irqsave(&clocks_lock, flags);
210 do_clk_disable(clk);
211 spin_unlock_irqrestore(&clocks_lock, flags);
212}
213EXPORT_SYMBOL(clk_disable);
214
215/**
216 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
217 * This is only valid once the clock source has been enabled.
218 * @clk: clock source
219 */
220unsigned long clk_get_rate(struct clk *clk)
221{
222 unsigned long flags, rate;
223
224 spin_lock_irqsave(&clocks_lock, flags);
225 rate = clk->rate;
226 spin_unlock_irqrestore(&clocks_lock, flags);
227
228 return rate;
229}
230EXPORT_SYMBOL(clk_get_rate);
231
232/**
233 * clk_set_parent - set the parent clock source for this clock
234 * @clk: clock source
235 * @parent: parent clock source
236 *
237 * Returns success (0) or negative errno.
238 */
239int clk_set_parent(struct clk *clk, struct clk *parent)
240{
241 int i, found = 0, val = 0;
242 unsigned long flags;
243
244 if (!clk || !parent)
245 return -EFAULT;
246 if (clk->pclk == parent)
247 return 0;
248 if (!clk->pclk_sel)
249 return -EPERM;
250
251 /* check if requested parent is in clk parent list */
252 for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
253 if (clk->pclk_sel->pclk_info[i].pclk == parent) {
254 found = 1;
255 break;
256 }
257 }
258
259 if (!found)
260 return -EINVAL;
261
262 spin_lock_irqsave(&clocks_lock, flags);
263 /* reflect parent change in hardware */
264 val = readl(clk->pclk_sel->pclk_sel_reg);
265 val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
266 val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
267 writel(val, clk->pclk_sel->pclk_sel_reg);
268 spin_unlock_irqrestore(&clocks_lock, flags);
269
270 /* reflect parent change in software */
271 clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
272
273 propagate_rate(clk, 0);
274 return 0;
275}
276EXPORT_SYMBOL(clk_set_parent);
277
278/**
279 * clk_set_rate - set the clock rate for a clock source
280 * @clk: clock source
281 * @rate: desired clock rate in Hz
282 *
283 * Returns success (0) or negative errno.
284 */
285int clk_set_rate(struct clk *clk, unsigned long rate)
286{
287 unsigned long flags;
288 int ret = -EINVAL;
289
290 if (!clk || !rate)
291 return -EFAULT;
292
293 if (clk->set_rate) {
294 spin_lock_irqsave(&clocks_lock, flags);
295 ret = clk->set_rate(clk, rate);
296 if (!ret)
297 /* if successful -> propagate */
298 propagate_rate(clk, 0);
299 spin_unlock_irqrestore(&clocks_lock, flags);
300 } else if (clk->pclk) {
301 u32 mult = clk->div_factor ? clk->div_factor : 1;
302 ret = clk_set_rate(clk->pclk, mult * rate);
303 }
304
305 return ret;
306}
307EXPORT_SYMBOL(clk_set_rate);
308
309/* registers clock in platform clock framework */
310void clk_register(struct clk_lookup *cl)
311{
312 struct clk *clk;
313 unsigned long flags;
314
315 if (!cl || !cl->clk)
316 return;
317 clk = cl->clk;
318
319 spin_lock_irqsave(&clocks_lock, flags);
320
321 INIT_LIST_HEAD(&clk->children);
322 if (clk->flags & ALWAYS_ENABLED)
323 clk->ops = NULL;
324 else if (!clk->ops)
325 clk->ops = &generic_clkops;
326
327 /* root clock don't have any parents */
328 if (!clk->pclk && !clk->pclk_sel) {
329 list_add(&clk->sibling, &root_clks);
330 } else if (clk->pclk && !clk->pclk_sel) {
331 /* add clocks with only one parent to parent's children list */
332 list_add(&clk->sibling, &clk->pclk->children);
333 } else {
334 /* clocks with more than one parent */
335 struct pclk_info *pclk_info;
336
337 pclk_info = pclk_info_get(clk);
338 if (!pclk_info) {
339 pr_err("CLKDEV: invalid pclk info of clk with"
340 " %s dev_id and %s con_id\n",
341 cl->dev_id, cl->con_id);
342 } else {
343 clk->pclk = pclk_info->pclk;
344 list_add(&clk->sibling, &pclk_info->pclk->children);
345 }
346 }
347
348 spin_unlock_irqrestore(&clocks_lock, flags);
349
350 /* debugfs specific */
351#ifdef CONFIG_DEBUG_FS
352 list_add(&clk->node, &clocks);
353 clk->cl = cl;
354#endif
355
356 /* add clock to arm clockdev framework */
357 clkdev_add(cl);
358}
359
360/**
361 * propagate_rate - recalculate and propagate all clocks to children
362 * @pclk: parent clock required to be propogated
363 * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
364 *
365 * Recalculates all children clocks
366 */
367void propagate_rate(struct clk *pclk, int on_init)
368{
369 struct clk *clk, *_temp;
370 int ret = 0;
371
372 list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
373 if (clk->recalc) {
374 ret = clk->recalc(clk);
375 /*
376 * recalc will return error if clk out is not programmed
377 * In this case configure default rate.
378 */
379 if (ret && clk->set_rate)
380 clk->set_rate(clk, 0);
381 }
382 propagate_rate(clk, on_init);
383
384 if (!on_init)
385 continue;
386
387 /* Enable clks enabled on init, in software view */
388 if (clk->flags & ENABLED_ON_INIT)
389 do_clk_enable(clk);
390 }
391}
392
393/**
394 * round_rate_index - return closest programmable rate index in rate_config tbl
395 * @clk: ptr to clock structure
396 * @drate: desired rate
397 * @rate: final rate will be returned in this variable only.
398 *
399 * Finds index in rate_config for highest clk rate which is less than
400 * requested rate. If there is no clk rate lesser than requested rate then
401 * -EINVAL is returned. This routine assumes that rate_config is written
402 * in incrementing order of clk rates.
403 * If drate passed is zero then default rate is programmed.
404 */
405static int
406round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate)
407{
408 unsigned long tmp = 0, prev_rate = 0;
409 int index;
410
411 if (!clk->calc_rate)
412 return -EFAULT;
413
414 if (!drate)
415 return -EINVAL;
416
417 /*
418 * This loops ends on two conditions:
419 * - as soon as clk is found with rate greater than requested rate.
420 * - if all clks in rate_config are smaller than requested rate.
421 */
422 for (index = 0; index < clk->rate_config.count; index++) {
423 prev_rate = tmp;
424 tmp = clk->calc_rate(clk, index);
425 if (drate < tmp) {
426 index--;
427 break;
428 }
429 }
430 /* return if can't find suitable clock */
431 if (index < 0) {
432 index = -EINVAL;
433 *rate = 0;
434 } else if (index == clk->rate_config.count) {
435 /* program with highest clk rate possible */
436 index = clk->rate_config.count - 1;
437 *rate = tmp;
438 } else
439 *rate = prev_rate;
440
441 return index;
442}
443
444/**
445 * clk_round_rate - adjust a rate to the exact rate a clock can provide
446 * @clk: clock source
447 * @rate: desired clock rate in Hz
448 *
449 * Returns rounded clock rate in Hz, or negative errno.
450 */
451long clk_round_rate(struct clk *clk, unsigned long drate)
452{
453 long rate = 0;
454 int index;
455
456 /*
457 * propagate call to parent who supports calc_rate. Similar approach is
458 * used in clk_set_rate.
459 */
460 if (!clk->calc_rate) {
461 u32 mult;
462 if (!clk->pclk)
463 return clk->rate;
464
465 mult = clk->div_factor ? clk->div_factor : 1;
466 return clk_round_rate(clk->pclk, mult * drate) / mult;
467 }
468
469 index = round_rate_index(clk, drate, &rate);
470 if (index >= 0)
471 return rate;
472 else
473 return index;
474}
475EXPORT_SYMBOL(clk_round_rate);
476
477/*All below functions are called with lock held */
478
479/*
480 * Calculates pll clk rate for specific value of mode, m, n and p
481 *
482 * In normal mode
483 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
484 *
485 * In Dithered mode
486 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
487 */
488unsigned long pll_calc_rate(struct clk *clk, int index)
489{
490 unsigned long rate = clk->pclk->rate;
491 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
492 unsigned int mode;
493
494 mode = tbls[index].mode ? 256 : 1;
495 return (((2 * rate / 10000) * tbls[index].m) /
496 (mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
497}
498
499/*
500 * calculates current programmed rate of pll1
501 *
502 * In normal mode
503 * rate = (2 * M[15:8] * Fin)/(N * 2^P)
504 *
505 * In Dithered mode
506 * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
507 */
508int pll_clk_recalc(struct clk *clk)
509{
510 struct pll_clk_config *config = clk->private_data;
511 unsigned int num = 2, den = 0, val, mode = 0;
512
513 mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
514 config->masks->mode_mask;
515
516 val = readl(config->cfg_reg);
517 /* calculate denominator */
518 den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
519 den = 1 << den;
520 den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
521
522 /* calculate numerator & denominator */
523 if (!mode) {
524 /* Normal mode */
525 num *= (val >> config->masks->norm_fdbk_m_shift) &
526 config->masks->norm_fdbk_m_mask;
527 } else {
528 /* Dithered mode */
529 num *= (val >> config->masks->dith_fdbk_m_shift) &
530 config->masks->dith_fdbk_m_mask;
531 den *= 256;
532 }
533
534 if (!den)
535 return -EINVAL;
536
537 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
538 return 0;
539}
540
541/*
542 * Configures new clock rate of pll
543 */
544int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
545{
546 struct pll_rate_tbl *tbls = clk->rate_config.tbls;
547 struct pll_clk_config *config = clk->private_data;
548 unsigned long val, rate;
549 int i;
550
551 i = round_rate_index(clk, desired_rate, &rate);
552 if (i < 0)
553 return i;
554
555 val = readl(config->mode_reg) &
556 ~(config->masks->mode_mask << config->masks->mode_shift);
557 val |= (tbls[i].mode & config->masks->mode_mask) <<
558 config->masks->mode_shift;
559 writel(val, config->mode_reg);
560
561 val = readl(config->cfg_reg) &
562 ~(config->masks->div_p_mask << config->masks->div_p_shift);
563 val |= (tbls[i].p & config->masks->div_p_mask) <<
564 config->masks->div_p_shift;
565 val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
566 val |= (tbls[i].n & config->masks->div_n_mask) <<
567 config->masks->div_n_shift;
568 val &= ~(config->masks->dith_fdbk_m_mask <<
569 config->masks->dith_fdbk_m_shift);
570 if (tbls[i].mode)
571 val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
572 config->masks->dith_fdbk_m_shift;
573 else
574 val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
575 config->masks->norm_fdbk_m_shift;
576
577 writel(val, config->cfg_reg);
578
579 clk->rate = rate;
580
581 return 0;
582}
583
584/*
585 * Calculates ahb, apb clk rate for specific value of div
586 */
587unsigned long bus_calc_rate(struct clk *clk, int index)
588{
589 unsigned long rate = clk->pclk->rate;
590 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
591
592 return rate / (tbls[index].div + 1);
593}
594
595/* calculates current programmed rate of ahb or apb bus */
596int bus_clk_recalc(struct clk *clk)
597{
598 struct bus_clk_config *config = clk->private_data;
599 unsigned int div;
600
601 div = ((readl(config->reg) >> config->masks->shift) &
602 config->masks->mask) + 1;
603
604 if (!div)
605 return -EINVAL;
606
607 clk->rate = (unsigned long)clk->pclk->rate / div;
608 return 0;
609}
610
611/* Configures new clock rate of AHB OR APB bus */
612int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
613{
614 struct bus_rate_tbl *tbls = clk->rate_config.tbls;
615 struct bus_clk_config *config = clk->private_data;
616 unsigned long val, rate;
617 int i;
618
619 i = round_rate_index(clk, desired_rate, &rate);
620 if (i < 0)
621 return i;
622
623 val = readl(config->reg) &
624 ~(config->masks->mask << config->masks->shift);
625 val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
626 writel(val, config->reg);
627
628 clk->rate = rate;
629
630 return 0;
631}
632
633/*
634 * gives rate for different values of eq, x and y
635 *
636 * Fout from synthesizer can be given from two equations:
637 * Fout1 = (Fin * X/Y)/2 EQ1
638 * Fout2 = Fin * X/Y EQ2
639 */
640unsigned long aux_calc_rate(struct clk *clk, int index)
641{
642 unsigned long rate = clk->pclk->rate;
643 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
644 u8 eq = tbls[index].eq ? 1 : 2;
645
646 return (((rate/10000) * tbls[index].xscale) /
647 (tbls[index].yscale * eq)) * 10000;
648}
649
650/*
651 * calculates current programmed rate of auxiliary synthesizers
652 * used by: UART, FIRDA
653 *
654 * Fout from synthesizer can be given from two equations:
655 * Fout1 = (Fin * X/Y)/2
656 * Fout2 = Fin * X/Y
657 *
658 * Selection of eqn 1 or 2 is programmed in register
659 */
660int aux_clk_recalc(struct clk *clk)
661{
662 struct aux_clk_config *config = clk->private_data;
663 unsigned int num = 1, den = 1, val, eqn;
664
665 val = readl(config->synth_reg);
666
667 eqn = (val >> config->masks->eq_sel_shift) &
668 config->masks->eq_sel_mask;
669 if (eqn == config->masks->eq1_mask)
670 den *= 2;
671
672 /* calculate numerator */
673 num = (val >> config->masks->xscale_sel_shift) &
674 config->masks->xscale_sel_mask;
675
676 /* calculate denominator */
677 den *= (val >> config->masks->yscale_sel_shift) &
678 config->masks->yscale_sel_mask;
679
680 if (!den)
681 return -EINVAL;
682
683 clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
684 return 0;
685}
686
687/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
688int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
689{
690 struct aux_rate_tbl *tbls = clk->rate_config.tbls;
691 struct aux_clk_config *config = clk->private_data;
692 unsigned long val, rate;
693 int i;
694
695 i = round_rate_index(clk, desired_rate, &rate);
696 if (i < 0)
697 return i;
698
699 val = readl(config->synth_reg) &
700 ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
701 val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
702 config->masks->eq_sel_shift;
703 val &= ~(config->masks->xscale_sel_mask <<
704 config->masks->xscale_sel_shift);
705 val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
706 config->masks->xscale_sel_shift;
707 val &= ~(config->masks->yscale_sel_mask <<
708 config->masks->yscale_sel_shift);
709 val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
710 config->masks->yscale_sel_shift;
711 writel(val, config->synth_reg);
712
713 clk->rate = rate;
714
715 return 0;
716}
717
718/*
719 * Calculates gpt clk rate for different values of mscale and nscale
720 *
721 * Fout= Fin/((2 ^ (N+1)) * (M+1))
722 */
723unsigned long gpt_calc_rate(struct clk *clk, int index)
724{
725 unsigned long rate = clk->pclk->rate;
726 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
727
728 return rate / ((1 << (tbls[index].nscale + 1)) *
729 (tbls[index].mscale + 1));
730}
731
732/*
733 * calculates current programmed rate of gpt synthesizers
734 * Fout from synthesizer can be given from below equations:
735 * Fout= Fin/((2 ^ (N+1)) * (M+1))
736 */
737int gpt_clk_recalc(struct clk *clk)
738{
739 struct gpt_clk_config *config = clk->private_data;
740 unsigned int div = 1, val;
741
742 val = readl(config->synth_reg);
743 div += (val >> config->masks->mscale_sel_shift) &
744 config->masks->mscale_sel_mask;
745 div *= 1 << (((val >> config->masks->nscale_sel_shift) &
746 config->masks->nscale_sel_mask) + 1);
747
748 if (!div)
749 return -EINVAL;
750
751 clk->rate = (unsigned long)clk->pclk->rate / div;
752 return 0;
753}
754
755/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
756int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
757{
758 struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
759 struct gpt_clk_config *config = clk->private_data;
760 unsigned long val, rate;
761 int i;
762
763 i = round_rate_index(clk, desired_rate, &rate);
764 if (i < 0)
765 return i;
766
767 val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
768 config->masks->mscale_sel_shift);
769 val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
770 config->masks->mscale_sel_shift;
771 val &= ~(config->masks->nscale_sel_mask <<
772 config->masks->nscale_sel_shift);
773 val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
774 config->masks->nscale_sel_shift;
775 writel(val, config->synth_reg);
776
777 clk->rate = rate;
778
779 return 0;
780}
781
782/*
783 * Calculates clcd clk rate for different values of div
784 *
785 * Fout from synthesizer can be given from below equation:
786 * Fout= Fin/2*div (division factor)
787 * div is 17 bits:-
788 * 0-13 (fractional part)
789 * 14-16 (integer part)
790 * To calculate Fout we left shift val by 14 bits and divide Fin by
791 * complete div (including fractional part) and then right shift the
792 * result by 14 places.
793 */
794unsigned long clcd_calc_rate(struct clk *clk, int index)
795{
796 unsigned long rate = clk->pclk->rate;
797 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
798
799 rate /= 1000;
800 rate <<= 12;
801 rate /= (2 * tbls[index].div);
802 rate >>= 12;
803 rate *= 1000;
804
805 return rate;
806}
807
808/*
809 * calculates current programmed rate of clcd synthesizer
810 * Fout from synthesizer can be given from below equation:
811 * Fout= Fin/2*div (division factor)
812 * div is 17 bits:-
813 * 0-13 (fractional part)
814 * 14-16 (integer part)
815 * To calculate Fout we left shift val by 14 bits and divide Fin by
816 * complete div (including fractional part) and then right shift the
817 * result by 14 places.
818 */
819int clcd_clk_recalc(struct clk *clk)
820{
821 struct clcd_clk_config *config = clk->private_data;
822 unsigned int div = 1;
823 unsigned long prate;
824 unsigned int val;
825
826 val = readl(config->synth_reg);
827 div = (val >> config->masks->div_factor_shift) &
828 config->masks->div_factor_mask;
829
830 if (!div)
831 return -EINVAL;
832
833 prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
834
835 clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
836 clk->rate *= 1000;
837 return 0;
838}
839
840/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
841int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
842{
843 struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
844 struct clcd_clk_config *config = clk->private_data;
845 unsigned long val, rate;
846 int i;
847
848 i = round_rate_index(clk, desired_rate, &rate);
849 if (i < 0)
850 return i;
851
852 val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
853 config->masks->div_factor_shift);
854 val |= (tbls[i].div & config->masks->div_factor_mask) <<
855 config->masks->div_factor_shift;
856 writel(val, config->synth_reg);
857
858 clk->rate = rate;
859
860 return 0;
861}
862
863/*
864 * Used for clocks that always have value as the parent clock divided by a
865 * fixed divisor
866 */
867int follow_parent(struct clk *clk)
868{
869 unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
870
871 clk->rate = clk->pclk->rate/div_factor;
872 return 0;
873}
874
875/**
876 * recalc_root_clocks - recalculate and propagate all root clocks
877 *
878 * Recalculates all root clocks (clocks with no parent), which if the
879 * clock's .recalc is set correctly, should also propagate their rates.
880 */
881void recalc_root_clocks(void)
882{
883 struct clk *pclk;
884 unsigned long flags;
885 int ret = 0;
886
887 spin_lock_irqsave(&clocks_lock, flags);
888 list_for_each_entry(pclk, &root_clks, sibling) {
889 if (pclk->recalc) {
890 ret = pclk->recalc(pclk);
891 /*
892 * recalc will return error if clk out is not programmed
893 * In this case configure default clock.
894 */
895 if (ret && pclk->set_rate)
896 pclk->set_rate(pclk, 0);
897 }
898 propagate_rate(pclk, 1);
899 /* Enable clks enabled on init, in software view */
900 if (pclk->flags & ENABLED_ON_INIT)
901 do_clk_enable(pclk);
902 }
903 spin_unlock_irqrestore(&clocks_lock, flags);
904}
905
906void __init clk_init(void)
907{
908 recalc_root_clocks();
909}
910
911#ifdef CONFIG_DEBUG_FS
912/*
913 * debugfs support to trace clock tree hierarchy and attributes
914 */
915static struct dentry *clk_debugfs_root;
916static int clk_debugfs_register_one(struct clk *c)
917{
918 int err;
919 struct dentry *d;
920 struct clk *pa = c->pclk;
921 char s[255];
922 char *p = s;
923
924 if (c) {
925 if (c->cl->con_id)
926 p += sprintf(p, "%s", c->cl->con_id);
927 if (c->cl->dev_id)
928 p += sprintf(p, "%s", c->cl->dev_id);
929 }
930 d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
931 if (!d)
932 return -ENOMEM;
933 c->dent = d;
934
935 d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
936 (u32 *)&c->usage_count);
937 if (!d) {
938 err = -ENOMEM;
939 goto err_out;
940 }
941 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
942 if (!d) {
943 err = -ENOMEM;
944 goto err_out;
945 }
946 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
947 if (!d) {
948 err = -ENOMEM;
949 goto err_out;
950 }
951 return 0;
952
953err_out:
954 debugfs_remove_recursive(c->dent);
955 return err;
956}
957
958static int clk_debugfs_register(struct clk *c)
959{
960 int err;
961 struct clk *pa = c->pclk;
962
963 if (pa && !pa->dent) {
964 err = clk_debugfs_register(pa);
965 if (err)
966 return err;
967 }
968
969 if (!c->dent) {
970 err = clk_debugfs_register_one(c);
971 if (err)
972 return err;
973 }
974 return 0;
975}
976
977static int __init clk_debugfs_init(void)
978{
979 struct clk *c;
980 struct dentry *d;
981 int err;
982
983 d = debugfs_create_dir("clock", NULL);
984 if (!d)
985 return -ENOMEM;
986 clk_debugfs_root = d;
987
988 list_for_each_entry(c, &clocks, node) {
989 err = clk_debugfs_register(c);
990 if (err)
991 goto err_out;
992 }
993 return 0;
994err_out:
995 debugfs_remove_recursive(clk_debugfs_root);
996 return err;
997}
998late_initcall(clk_debugfs_init);
999
1000static int clk_debugfs_reparent(struct clk *c)
1001{
1002 debugfs_remove(c->dent);
1003 return clk_debugfs_register_one(c);
1004}
1005#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
deleted file mode 100644
index 0062bafef12..00000000000
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * arch/arm/plat-spear/include/plat/clock.h
3 *
4 * Clock framework definitions for SPEAr platform
5 *
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#ifndef __PLAT_CLOCK_H
15#define __PLAT_CLOCK_H
16
17#include <linux/list.h>
18#include <linux/clkdev.h>
19#include <linux/types.h>
20
21/* clk structure flags */
22#define ALWAYS_ENABLED (1 << 0) /* clock always enabled */
23#define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */
24#define ENABLED_ON_INIT (1 << 2) /* clocks enabled at init */
25
26/**
27 * struct clkops - clock operations
28 * @enable: pointer to clock enable function
29 * @disable: pointer to clock disable function
30 */
31struct clkops {
32 int (*enable) (struct clk *);
33 void (*disable) (struct clk *);
34};
35
36/**
37 * struct pclk_info - parents info
38 * @pclk: pointer to parent clk
39 * @pclk_val: value to be written for selecting this parent
40 */
41struct pclk_info {
42 struct clk *pclk;
43 u8 pclk_val;
44};
45
46/**
47 * struct pclk_sel - parents selection configuration
48 * @pclk_info: pointer to array of parent clock info
49 * @pclk_count: number of parents
50 * @pclk_sel_reg: register for selecting a parent
51 * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
52 */
53struct pclk_sel {
54 struct pclk_info *pclk_info;
55 u8 pclk_count;
56 void __iomem *pclk_sel_reg;
57 unsigned int pclk_sel_mask;
58};
59
60/**
61 * struct rate_config - clk rate configurations
62 * @tbls: array of device specific clk rate tables, in ascending order of rates
63 * @count: size of tbls array
64 * @default_index: default setting when originally disabled
65 */
66struct rate_config {
67 void *tbls;
68 u8 count;
69 u8 default_index;
70};
71
72/**
73 * struct clk - clock structure
74 * @usage_count: num of users who enabled this clock
75 * @flags: flags for clock properties
76 * @rate: programmed clock rate in Hz
77 * @en_reg: clk enable/disable reg
78 * @en_reg_bit: clk enable/disable bit
79 * @ops: clk enable/disable ops - generic_clkops selected if NULL
80 * @recalc: pointer to clock rate recalculate function
81 * @set_rate: pointer to clock set rate function
82 * @calc_rate: pointer to clock get rate function for index
83 * @rate_config: rate configuration information, used by set_rate
84 * @div_factor: division factor to parent clock.
85 * @pclk: current parent clk
86 * @pclk_sel: pointer to parent selection structure
87 * @pclk_sel_shift: register shift for selecting parent of this clock
88 * @children: list for childrens or this clock
89 * @sibling: node for list of clocks having same parents
90 * @private_data: clock specific private data
91 * @node: list to maintain clocks linearly
92 * @cl: clocklook up associated with this clock
93 * @dent: object for debugfs
94 */
95struct clk {
96 unsigned int usage_count;
97 unsigned int flags;
98 unsigned long rate;
99 void __iomem *en_reg;
100 u8 en_reg_bit;
101 const struct clkops *ops;
102 int (*recalc) (struct clk *);
103 int (*set_rate) (struct clk *, unsigned long rate);
104 unsigned long (*calc_rate)(struct clk *, int index);
105 struct rate_config rate_config;
106 unsigned int div_factor;
107
108 struct clk *pclk;
109 struct pclk_sel *pclk_sel;
110 unsigned int pclk_sel_shift;
111
112 struct list_head children;
113 struct list_head sibling;
114 void *private_data;
115#ifdef CONFIG_DEBUG_FS
116 struct list_head node;
117 struct clk_lookup *cl;
118 struct dentry *dent;
119#endif
120};
121
122/* pll configuration structure */
123struct pll_clk_masks {
124 u32 mode_mask;
125 u32 mode_shift;
126
127 u32 norm_fdbk_m_mask;
128 u32 norm_fdbk_m_shift;
129 u32 dith_fdbk_m_mask;
130 u32 dith_fdbk_m_shift;
131 u32 div_p_mask;
132 u32 div_p_shift;
133 u32 div_n_mask;
134 u32 div_n_shift;
135};
136
137struct pll_clk_config {
138 void __iomem *mode_reg;
139 void __iomem *cfg_reg;
140 struct pll_clk_masks *masks;
141};
142
143/* pll clk rate config structure */
144struct pll_rate_tbl {
145 u8 mode;
146 u16 m;
147 u8 n;
148 u8 p;
149};
150
151/* ahb and apb bus configuration structure */
152struct bus_clk_masks {
153 u32 mask;
154 u32 shift;
155};
156
157struct bus_clk_config {
158 void __iomem *reg;
159 struct bus_clk_masks *masks;
160};
161
162/* ahb and apb clk bus rate config structure */
163struct bus_rate_tbl {
164 u8 div;
165};
166
167/* Aux clk configuration structure: applicable to UART and FIRDA */
168struct aux_clk_masks {
169 u32 eq_sel_mask;
170 u32 eq_sel_shift;
171 u32 eq1_mask;
172 u32 eq2_mask;
173 u32 xscale_sel_mask;
174 u32 xscale_sel_shift;
175 u32 yscale_sel_mask;
176 u32 yscale_sel_shift;
177};
178
179struct aux_clk_config {
180 void __iomem *synth_reg;
181 struct aux_clk_masks *masks;
182};
183
184/* aux clk rate config structure */
185struct aux_rate_tbl {
186 u16 xscale;
187 u16 yscale;
188 u8 eq;
189};
190
191/* GPT clk configuration structure */
192struct gpt_clk_masks {
193 u32 mscale_sel_mask;
194 u32 mscale_sel_shift;
195 u32 nscale_sel_mask;
196 u32 nscale_sel_shift;
197};
198
199struct gpt_clk_config {
200 void __iomem *synth_reg;
201 struct gpt_clk_masks *masks;
202};
203
204/* gpt clk rate config structure */
205struct gpt_rate_tbl {
206 u16 mscale;
207 u16 nscale;
208};
209
210/* clcd clk configuration structure */
211struct clcd_synth_masks {
212 u32 div_factor_mask;
213 u32 div_factor_shift;
214};
215
216struct clcd_clk_config {
217 void __iomem *synth_reg;
218 struct clcd_synth_masks *masks;
219};
220
221/* clcd clk rate config structure */
222struct clcd_rate_tbl {
223 u16 div;
224};
225
226/* platform specific clock functions */
227void __init clk_init(void);
228void clk_register(struct clk_lookup *cl);
229void recalc_root_clocks(void);
230
231/* clock recalc & set rate functions */
232int follow_parent(struct clk *clk);
233unsigned long pll_calc_rate(struct clk *clk, int index);
234int pll_clk_recalc(struct clk *clk);
235int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
236unsigned long bus_calc_rate(struct clk *clk, int index);
237int bus_clk_recalc(struct clk *clk);
238int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
239unsigned long gpt_calc_rate(struct clk *clk, int index);
240int gpt_clk_recalc(struct clk *clk);
241int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
242unsigned long aux_calc_rate(struct clk *clk, int index);
243int aux_clk_recalc(struct clk *clk);
244int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
245unsigned long clcd_calc_rate(struct clk *clk, int index);
246int clcd_clk_recalc(struct clk *clk);
247int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
248
249#endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c
index 4471a232713..ea0a61302b7 100644
--- a/arch/arm/plat-spear/restart.c
+++ b/arch/arm/plat-spear/restart.c
@@ -16,6 +16,7 @@
16#include <mach/spear.h> 16#include <mach/spear.h>
17#include <mach/generic.h> 17#include <mach/generic.h>
18 18
19#define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204)
19void spear_restart(char mode, const char *cmd) 20void spear_restart(char mode, const char *cmd)
20{ 21{
21 if (mode == 's') { 22 if (mode == 's') {
@@ -23,6 +24,10 @@ void spear_restart(char mode, const char *cmd)
23 soft_restart(0); 24 soft_restart(0);
24 } else { 25 } else {
25 /* hardware reset, Use on-chip reset capability */ 26 /* hardware reset, Use on-chip reset capability */
27#ifdef CONFIG_ARCH_SPEAR13XX
28 writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
29#else
26 sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE); 30 sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
31#endif
27 } 32 }
28} 33}
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index a3164d1647f..03321af5de9 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -18,6 +18,8 @@
18#include <linux/ioport.h> 18#include <linux/ioport.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/of_irq.h>
22#include <linux/of_address.h>
21#include <linux/time.h> 23#include <linux/time.h>
22#include <linux/irq.h> 24#include <linux/irq.h>
23#include <asm/mach/time.h> 25#include <asm/mach/time.h>
@@ -197,19 +199,32 @@ static void __init spear_clockevent_init(int irq)
197 setup_irq(irq, &spear_timer_irq); 199 setup_irq(irq, &spear_timer_irq);
198} 200}
199 201
200void __init spear_setup_timer(resource_size_t base, int irq) 202const static struct of_device_id timer_of_match[] __initconst = {
203 { .compatible = "st,spear-timer", },
204 { },
205};
206
207void __init spear_setup_of_timer(void)
201{ 208{
202 int ret; 209 struct device_node *np;
210 int irq, ret;
211
212 np = of_find_matching_node(NULL, timer_of_match);
213 if (!np) {
214 pr_err("%s: No timer passed via DT\n", __func__);
215 return;
216 }
203 217
204 if (!request_mem_region(base, SZ_1K, "gpt0")) { 218 irq = irq_of_parse_and_map(np, 0);
205 pr_err("%s:cannot get IO addr\n", __func__); 219 if (!irq) {
220 pr_err("%s: No irq passed for timer via DT\n", __func__);
206 return; 221 return;
207 } 222 }
208 223
209 gpt_base = ioremap(base, SZ_1K); 224 gpt_base = of_iomap(np, 0);
210 if (!gpt_base) { 225 if (!gpt_base) {
211 pr_err("%s:ioremap failed for gpt\n", __func__); 226 pr_err("%s: of iomap failed\n", __func__);
212 goto err_mem; 227 return;
213 } 228 }
214 229
215 gpt_clk = clk_get_sys("gpt0", NULL); 230 gpt_clk = clk_get_sys("gpt0", NULL);
@@ -218,10 +233,10 @@ void __init spear_setup_timer(resource_size_t base, int irq)
218 goto err_iomap; 233 goto err_iomap;
219 } 234 }
220 235
221 ret = clk_enable(gpt_clk); 236 ret = clk_prepare_enable(gpt_clk);
222 if (ret < 0) { 237 if (ret < 0) {
223 pr_err("%s:couldn't enable gpt clock\n", __func__); 238 pr_err("%s:couldn't prepare-enable gpt clock\n", __func__);
224 goto err_clk; 239 goto err_prepare_enable_clk;
225 } 240 }
226 241
227 spear_clockevent_init(irq); 242 spear_clockevent_init(irq);
@@ -229,10 +244,8 @@ void __init spear_setup_timer(resource_size_t base, int irq)
229 244
230 return; 245 return;
231 246
232err_clk: 247err_prepare_enable_clk:
233 clk_put(gpt_clk); 248 clk_put(gpt_clk);
234err_iomap: 249err_iomap:
235 iounmap(gpt_base); 250 iounmap(gpt_base);
236err_mem:
237 release_mem_region(base, SZ_1K);
238} 251}
diff --git a/arch/avr32/include/asm/kvm_para.h b/arch/avr32/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/avr32/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/blackfin/include/asm/kvm_para.h b/arch/blackfin/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/blackfin/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/c6x/include/asm/kvm_para.h b/arch/c6x/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/c6x/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 22d34d64cc8..bb344650a14 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -40,6 +40,7 @@ config CRIS
40 bool 40 bool
41 default y 41 default y
42 select HAVE_IDE 42 select HAVE_IDE
43 select GENERIC_ATOMIC64
43 select HAVE_GENERIC_HARDIRQS 44 select HAVE_GENERIC_HARDIRQS
44 select GENERIC_IRQ_SHOW 45 select GENERIC_IRQ_SHOW
45 select GENERIC_IOMAP 46 select GENERIC_IOMAP
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
deleted file mode 100644
index 74f99c688c8..00000000000
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ /dev/null
@@ -1,515 +0,0 @@
1/*!***************************************************************************
2*!
3*! FILE NAME : ds1302.c
4*!
5*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
6*!
7*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
8*!
9*! ---------------------------------------------------------------------------
10*!
11*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
12*!
13*!***************************************************************************/
14
15
16#include <linux/fs.h>
17#include <linux/init.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/miscdevice.h>
21#include <linux/delay.h>
22#include <linux/mutex.h>
23#include <linux/bcd.h>
24#include <linux/capability.h>
25
26#include <asm/uaccess.h>
27#include <arch/svinto.h>
28#include <asm/io.h>
29#include <asm/rtc.h>
30#include <arch/io_interface_mux.h>
31
32#include "i2c.h"
33
34#define RTC_MAJOR_NR 121 /* local major, change later */
35
36static DEFINE_MUTEX(ds1302_mutex);
37static const char ds1302_name[] = "ds1302";
38
39/* The DS1302 might be connected to different bits on different products.
40 * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
41 * but SDA can have a selected direction.
42 * For now, only PORT_PB is hardcoded.
43 */
44
45/* The RST bit may be on either the Generic Port or Port PB. */
46#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
47#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
48#define TK_RST_DIR(x)
49#else
50#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
51#define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
52#endif
53
54
55#define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
56#define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
57
58#define TK_SDA_IN() ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1)
59/* 1 is out, 0 is in */
60#define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
61#define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
62
63
64/*
65 * The reason for tempudelay and not udelay is that loops_per_usec
66 * (used in udelay) is not set when functions here are called from time.c
67 */
68
69static void tempudelay(int usecs)
70{
71 volatile int loops;
72
73 for(loops = usecs * 12; loops > 0; loops--)
74 /* nothing */;
75}
76
77
78/* Send 8 bits. */
79static void
80out_byte(unsigned char x)
81{
82 int i;
83 TK_SDA_DIR(1);
84 for (i = 8; i--;) {
85 /* The chip latches incoming bits on the rising edge of SCL. */
86 TK_SCL_OUT(0);
87 TK_SDA_OUT(x & 1);
88 tempudelay(1);
89 TK_SCL_OUT(1);
90 tempudelay(1);
91 x >>= 1;
92 }
93 TK_SDA_DIR(0);
94}
95
96static unsigned char
97in_byte(void)
98{
99 unsigned char x = 0;
100 int i;
101
102 /* Read byte. Bits come LSB first, on the falling edge of SCL.
103 * Assume SDA is in input direction already.
104 */
105 TK_SDA_DIR(0);
106
107 for (i = 8; i--;) {
108 TK_SCL_OUT(0);
109 tempudelay(1);
110 x >>= 1;
111 x |= (TK_SDA_IN() << 7);
112 TK_SCL_OUT(1);
113 tempudelay(1);
114 }
115
116 return x;
117}
118
119/* Prepares for a transaction by de-activating RST (active-low). */
120
121static void
122start(void)
123{
124 TK_SCL_OUT(0);
125 tempudelay(1);
126 TK_RST_OUT(0);
127 tempudelay(5);
128 TK_RST_OUT(1);
129}
130
131/* Ends a transaction by taking RST active again. */
132
133static void
134stop(void)
135{
136 tempudelay(2);
137 TK_RST_OUT(0);
138}
139
140/* Enable writing. */
141
142static void
143ds1302_wenable(void)
144{
145 start();
146 out_byte(0x8e); /* Write control register */
147 out_byte(0x00); /* Disable write protect bit 7 = 0 */
148 stop();
149}
150
151/* Disable writing. */
152
153static void
154ds1302_wdisable(void)
155{
156 start();
157 out_byte(0x8e); /* Write control register */
158 out_byte(0x80); /* Disable write protect bit 7 = 0 */
159 stop();
160}
161
162
163
164/* Read a byte from the selected register in the DS1302. */
165
166unsigned char
167ds1302_readreg(int reg)
168{
169 unsigned char x;
170
171 start();
172 out_byte(0x81 | (reg << 1)); /* read register */
173 x = in_byte();
174 stop();
175
176 return x;
177}
178
179/* Write a byte to the selected register. */
180
181void
182ds1302_writereg(int reg, unsigned char val)
183{
184#ifndef CONFIG_ETRAX_RTC_READONLY
185 int do_writereg = 1;
186#else
187 int do_writereg = 0;
188
189 if (reg == RTC_TRICKLECHARGER)
190 do_writereg = 1;
191#endif
192
193 if (do_writereg) {
194 ds1302_wenable();
195 start();
196 out_byte(0x80 | (reg << 1)); /* write register */
197 out_byte(val);
198 stop();
199 ds1302_wdisable();
200 }
201}
202
203void
204get_rtc_time(struct rtc_time *rtc_tm)
205{
206 unsigned long flags;
207
208 local_irq_save(flags);
209
210 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
211 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
212 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
213 rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
214 rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
215 rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
216
217 local_irq_restore(flags);
218
219 rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
220 rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
221 rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
222 rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
223 rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
224 rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
225
226 /*
227 * Account for differences between how the RTC uses the values
228 * and how they are defined in a struct rtc_time;
229 */
230
231 if (rtc_tm->tm_year <= 69)
232 rtc_tm->tm_year += 100;
233
234 rtc_tm->tm_mon--;
235}
236
237static unsigned char days_in_mo[] =
238 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
239
240/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
241
242static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
243{
244 unsigned long flags;
245
246 switch(cmd) {
247 case RTC_RD_TIME: /* read the time/date from RTC */
248 {
249 struct rtc_time rtc_tm;
250
251 memset(&rtc_tm, 0, sizeof (struct rtc_time));
252 get_rtc_time(&rtc_tm);
253 if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
254 return -EFAULT;
255 return 0;
256 }
257
258 case RTC_SET_TIME: /* set the RTC */
259 {
260 struct rtc_time rtc_tm;
261 unsigned char mon, day, hrs, min, sec, leap_yr;
262 unsigned int yrs;
263
264 if (!capable(CAP_SYS_TIME))
265 return -EPERM;
266
267 if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
268 return -EFAULT;
269
270 yrs = rtc_tm.tm_year + 1900;
271 mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
272 day = rtc_tm.tm_mday;
273 hrs = rtc_tm.tm_hour;
274 min = rtc_tm.tm_min;
275 sec = rtc_tm.tm_sec;
276
277
278 if ((yrs < 1970) || (yrs > 2069))
279 return -EINVAL;
280
281 leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
282
283 if ((mon > 12) || (day == 0))
284 return -EINVAL;
285
286 if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
287 return -EINVAL;
288
289 if ((hrs >= 24) || (min >= 60) || (sec >= 60))
290 return -EINVAL;
291
292 if (yrs >= 2000)
293 yrs -= 2000; /* RTC (0, 1, ... 69) */
294 else
295 yrs -= 1900; /* RTC (70, 71, ... 99) */
296
297 sec = bin2bcd(sec);
298 min = bin2bcd(min);
299 hrs = bin2bcd(hrs);
300 day = bin2bcd(day);
301 mon = bin2bcd(mon);
302 yrs = bin2bcd(yrs);
303
304 local_irq_save(flags);
305 CMOS_WRITE(yrs, RTC_YEAR);
306 CMOS_WRITE(mon, RTC_MONTH);
307 CMOS_WRITE(day, RTC_DAY_OF_MONTH);
308 CMOS_WRITE(hrs, RTC_HOURS);
309 CMOS_WRITE(min, RTC_MINUTES);
310 CMOS_WRITE(sec, RTC_SECONDS);
311 local_irq_restore(flags);
312
313 /* Notice that at this point, the RTC is updated but
314 * the kernel is still running with the old time.
315 * You need to set that separately with settimeofday
316 * or adjtimex.
317 */
318 return 0;
319 }
320
321 case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
322 {
323 int tcs_val;
324
325 if (!capable(CAP_SYS_TIME))
326 return -EPERM;
327
328 if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
329 return -EFAULT;
330
331 tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
332 ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
333 return 0;
334 }
335 case RTC_VL_READ:
336 {
337 /* TODO:
338 * Implement voltage low detection support
339 */
340 printk(KERN_WARNING "DS1302: RTC Voltage Low detection"
341 " is not supported\n");
342 return 0;
343 }
344 case RTC_VL_CLR:
345 {
346 /* TODO:
347 * Nothing to do since Voltage Low detection is not supported
348 */
349 return 0;
350 }
351 default:
352 return -ENOIOCTLCMD;
353 }
354}
355
356static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
357{
358 int ret;
359
360 mutex_lock(&ds1302_mutex);
361 ret = rtc_ioctl(file, cmd, arg);
362 mutex_unlock(&ds1302_mutex);
363
364 return ret;
365}
366
367static void
368print_rtc_status(void)
369{
370 struct rtc_time tm;
371
372 get_rtc_time(&tm);
373
374 /*
375 * There is no way to tell if the luser has the RTC set for local
376 * time or for Universal Standard Time (GMT). Probably local though.
377 */
378
379 printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n",
380 tm.tm_hour, tm.tm_min, tm.tm_sec);
381 printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n",
382 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
383}
384
385/* The various file operations we support. */
386
387static const struct file_operations rtc_fops = {
388 .owner = THIS_MODULE,
389 .unlocked_ioctl = rtc_unlocked_ioctl,
390 .llseek = noop_llseek,
391};
392
393/* Probe for the chip by writing something to its RAM and try reading it back. */
394
395#define MAGIC_PATTERN 0x42
396
397static int __init
398ds1302_probe(void)
399{
400 int retval, res;
401
402 TK_RST_DIR(1);
403 TK_SCL_DIR(1);
404 TK_SDA_DIR(0);
405
406 /* Try to talk to timekeeper. */
407
408 ds1302_wenable();
409 start();
410 out_byte(0xc0); /* write RAM byte 0 */
411 out_byte(MAGIC_PATTERN); /* write something magic */
412 start();
413 out_byte(0xc1); /* read RAM byte 0 */
414
415 if((res = in_byte()) == MAGIC_PATTERN) {
416 stop();
417 ds1302_wdisable();
418 printk(KERN_INFO "%s: RTC found.\n", ds1302_name);
419 printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
420 ds1302_name,
421 CONFIG_ETRAX_DS1302_SDABIT,
422 CONFIG_ETRAX_DS1302_SCLBIT,
423#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
424 "GENIO",
425#else
426 "PB",
427#endif
428 CONFIG_ETRAX_DS1302_RSTBIT);
429 print_rtc_status();
430 retval = 1;
431 } else {
432 stop();
433 retval = 0;
434 }
435
436 return retval;
437}
438
439
440/* Just probe for the RTC and register the device to handle the ioctl needed. */
441
442int __init
443ds1302_init(void)
444{
445#ifdef CONFIG_ETRAX_I2C
446 i2c_init();
447#endif
448
449 if (!ds1302_probe()) {
450#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
451#if CONFIG_ETRAX_DS1302_RSTBIT == 27
452 /*
453 * The only way to set g27 to output is to enable ATA.
454 *
455 * Make sure that R_GEN_CONFIG is setup correct.
456 */
457 /* Allocating the ATA interface will grab almost all
458 * pins in I/O groups a, b, c and d. A consequence of
459 * allocating the ATA interface is that the fixed
460 * interfaces shared RAM, parallel port 0, parallel
461 * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port
462 * 1, SCSI-W, serial port 2, serial port 3,
463 * synchronous serial port 3 and USB port 2 and almost
464 * all GPIO pins on port g cannot be used.
465 */
466 if (cris_request_io_interface(if_ata, "ds1302/ATA")) {
467 printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
468 return -1;
469 }
470
471#elif CONFIG_ETRAX_DS1302_RSTBIT == 0
472 if (cris_io_interface_allocate_pins(if_gpio_grp_a,
473 'g',
474 CONFIG_ETRAX_DS1302_RSTBIT,
475 CONFIG_ETRAX_DS1302_RSTBIT)) {
476 printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
477 return -1;
478 }
479
480 /* Set the direction of this bit to out. */
481 genconfig_shadow = ((genconfig_shadow &
482 ~IO_MASK(R_GEN_CONFIG, g0dir)) |
483 (IO_STATE(R_GEN_CONFIG, g0dir, out)));
484 *R_GEN_CONFIG = genconfig_shadow;
485#endif
486 if (!ds1302_probe()) {
487 printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
488 return -1;
489 }
490#else
491 printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
492 return -1;
493#endif
494 }
495 /* Initialise trickle charger */
496 ds1302_writereg(RTC_TRICKLECHARGER,
497 RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
498 /* Start clock by resetting CLOCK_HALT */
499 ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
500 return 0;
501}
502
503static int __init ds1302_register(void)
504{
505 ds1302_init();
506 if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
507 printk(KERN_INFO "%s: unable to get major %d for rtc\n",
508 ds1302_name, RTC_MAJOR_NR);
509 return -1;
510 }
511 return 0;
512
513}
514
515module_init(ds1302_register);
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
deleted file mode 100644
index 9da056860c9..00000000000
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/*
2 * PCF8563 RTC
3 *
4 * From Phillips' datasheet:
5 *
6 * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
7 * consumption. A programmable clock output, interrupt output and voltage
8 * low detector are also provided. All address and data are transferred
9 * serially via two-line bidirectional I2C-bus. Maximum bus speed is
10 * 400 kbits/s. The built-in word address register is incremented
11 * automatically after each written or read byte.
12 *
13 * Copyright (c) 2002-2007, Axis Communications AB
14 * All rights reserved.
15 *
16 * Author: Tobias Anderberg <tobiasa@axis.com>.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/types.h>
23#include <linux/sched.h>
24#include <linux/init.h>
25#include <linux/fs.h>
26#include <linux/ioctl.h>
27#include <linux/delay.h>
28#include <linux/bcd.h>
29#include <linux/mutex.h>
30
31#include <asm/uaccess.h>
32#include <asm/io.h>
33#include <asm/rtc.h>
34
35#include "i2c.h"
36
37#define PCF8563_MAJOR 121 /* Local major number. */
38#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
39#define PCF8563_NAME "PCF8563"
40#define DRIVER_VERSION "$Revision: 1.24 $"
41
42/* I2C bus slave registers. */
43#define RTC_I2C_READ 0xa3
44#define RTC_I2C_WRITE 0xa2
45
46/* Two simple wrapper macros, saves a few keystrokes. */
47#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
48#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
49
50static DEFINE_MUTEX(pcf8563_mutex);
51static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
52
53static const unsigned char days_in_month[] =
54 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
55
56static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long);
57
58/* Cache VL bit value read at driver init since writing the RTC_SECOND
59 * register clears the VL status.
60 */
61static int voltage_low;
62
63static const struct file_operations pcf8563_fops = {
64 .owner = THIS_MODULE,
65 .unlocked_ioctl = pcf8563_unlocked_ioctl,
66 .llseek = noop_llseek,
67};
68
69unsigned char
70pcf8563_readreg(int reg)
71{
72 unsigned char res = rtc_read(reg);
73
74 /* The PCF8563 does not return 0 for unimplemented bits. */
75 switch (reg) {
76 case RTC_SECONDS:
77 case RTC_MINUTES:
78 res &= 0x7F;
79 break;
80 case RTC_HOURS:
81 case RTC_DAY_OF_MONTH:
82 res &= 0x3F;
83 break;
84 case RTC_WEEKDAY:
85 res &= 0x07;
86 break;
87 case RTC_MONTH:
88 res &= 0x1F;
89 break;
90 case RTC_CONTROL1:
91 res &= 0xA8;
92 break;
93 case RTC_CONTROL2:
94 res &= 0x1F;
95 break;
96 case RTC_CLOCKOUT_FREQ:
97 case RTC_TIMER_CONTROL:
98 res &= 0x83;
99 break;
100 }
101 return res;
102}
103
104void
105pcf8563_writereg(int reg, unsigned char val)
106{
107 rtc_write(reg, val);
108}
109
110void
111get_rtc_time(struct rtc_time *tm)
112{
113 tm->tm_sec = rtc_read(RTC_SECONDS);
114 tm->tm_min = rtc_read(RTC_MINUTES);
115 tm->tm_hour = rtc_read(RTC_HOURS);
116 tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
117 tm->tm_wday = rtc_read(RTC_WEEKDAY);
118 tm->tm_mon = rtc_read(RTC_MONTH);
119 tm->tm_year = rtc_read(RTC_YEAR);
120
121 if (tm->tm_sec & 0x80) {
122 printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time "
123 "information is no longer guaranteed!\n", PCF8563_NAME);
124 }
125
126 tm->tm_year = bcd2bin(tm->tm_year) +
127 ((tm->tm_mon & 0x80) ? 100 : 0);
128 tm->tm_sec &= 0x7F;
129 tm->tm_min &= 0x7F;
130 tm->tm_hour &= 0x3F;
131 tm->tm_mday &= 0x3F;
132 tm->tm_wday &= 0x07; /* Not coded in BCD. */
133 tm->tm_mon &= 0x1F;
134
135 tm->tm_sec = bcd2bin(tm->tm_sec);
136 tm->tm_min = bcd2bin(tm->tm_min);
137 tm->tm_hour = bcd2bin(tm->tm_hour);
138 tm->tm_mday = bcd2bin(tm->tm_mday);
139 tm->tm_mon = bcd2bin(tm->tm_mon);
140 tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
141}
142
143int __init
144pcf8563_init(void)
145{
146 static int res;
147 static int first = 1;
148
149 if (!first)
150 return res;
151 first = 0;
152
153 /* Initiate the i2c protocol. */
154 res = i2c_init();
155 if (res < 0) {
156 printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
157 return res;
158 }
159
160 /*
161 * First of all we need to reset the chip. This is done by
162 * clearing control1, control2 and clk freq and resetting
163 * all alarms.
164 */
165 if (rtc_write(RTC_CONTROL1, 0x00) < 0)
166 goto err;
167
168 if (rtc_write(RTC_CONTROL2, 0x00) < 0)
169 goto err;
170
171 if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
172 goto err;
173
174 if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
175 goto err;
176
177 /* Reset the alarms. */
178 if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
179 goto err;
180
181 if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
182 goto err;
183
184 if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
185 goto err;
186
187 if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
188 goto err;
189
190 /* Check for low voltage, and warn about it. */
191 if (rtc_read(RTC_SECONDS) & 0x80) {
192 voltage_low = 1;
193 printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
194 "date/time information is no longer guaranteed!\n",
195 PCF8563_NAME);
196 }
197
198 return res;
199
200err:
201 printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
202 res = -1;
203 return res;
204}
205
206void __exit
207pcf8563_exit(void)
208{
209 unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME);
210}
211
212/*
213 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
214 * POSIX says so!
215 */
216static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
217{
218 /* Some sanity checks. */
219 if (_IOC_TYPE(cmd) != RTC_MAGIC)
220 return -ENOTTY;
221
222 if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
223 return -ENOTTY;
224
225 switch (cmd) {
226 case RTC_RD_TIME:
227 {
228 struct rtc_time tm;
229
230 mutex_lock(&rtc_lock);
231 memset(&tm, 0, sizeof tm);
232 get_rtc_time(&tm);
233
234 if (copy_to_user((struct rtc_time *) arg, &tm,
235 sizeof tm)) {
236 mutex_unlock(&rtc_lock);
237 return -EFAULT;
238 }
239
240 mutex_unlock(&rtc_lock);
241
242 return 0;
243 }
244 case RTC_SET_TIME:
245 {
246 int leap;
247 int year;
248 int century;
249 struct rtc_time tm;
250
251 memset(&tm, 0, sizeof tm);
252 if (!capable(CAP_SYS_TIME))
253 return -EPERM;
254
255 if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
256 return -EFAULT;
257
258 /* Convert from struct tm to struct rtc_time. */
259 tm.tm_year += 1900;
260 tm.tm_mon += 1;
261
262 /*
263 * Check if tm.tm_year is a leap year. A year is a leap
264 * year if it is divisible by 4 but not 100, except
265 * that years divisible by 400 _are_ leap years.
266 */
267 year = tm.tm_year;
268 leap = (tm.tm_mon == 2) &&
269 ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
270
271 /* Perform some sanity checks. */
272 if ((tm.tm_year < 1970) ||
273 (tm.tm_mon > 12) ||
274 (tm.tm_mday == 0) ||
275 (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
276 (tm.tm_wday >= 7) ||
277 (tm.tm_hour >= 24) ||
278 (tm.tm_min >= 60) ||
279 (tm.tm_sec >= 60))
280 return -EINVAL;
281
282 century = (tm.tm_year >= 2000) ? 0x80 : 0;
283 tm.tm_year = tm.tm_year % 100;
284
285 tm.tm_year = bin2bcd(tm.tm_year);
286 tm.tm_mon = bin2bcd(tm.tm_mon);
287 tm.tm_mday = bin2bcd(tm.tm_mday);
288 tm.tm_hour = bin2bcd(tm.tm_hour);
289 tm.tm_min = bin2bcd(tm.tm_min);
290 tm.tm_sec = bin2bcd(tm.tm_sec);
291 tm.tm_mon |= century;
292
293 mutex_lock(&rtc_lock);
294
295 rtc_write(RTC_YEAR, tm.tm_year);
296 rtc_write(RTC_MONTH, tm.tm_mon);
297 rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
298 rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
299 rtc_write(RTC_HOURS, tm.tm_hour);
300 rtc_write(RTC_MINUTES, tm.tm_min);
301 rtc_write(RTC_SECONDS, tm.tm_sec);
302
303 mutex_unlock(&rtc_lock);
304
305 return 0;
306 }
307 case RTC_VL_READ:
308 if (voltage_low) {
309 printk(KERN_ERR "%s: RTC Voltage Low - "
310 "reliable date/time information is no "
311 "longer guaranteed!\n", PCF8563_NAME);
312 }
313
314 if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
315 return -EFAULT;
316 return 0;
317
318 case RTC_VL_CLR:
319 {
320 /* Clear the VL bit in the seconds register in case
321 * the time has not been set already (which would
322 * have cleared it). This does not really matter
323 * because of the cached voltage_low value but do it
324 * anyway for consistency. */
325
326 int ret = rtc_read(RTC_SECONDS);
327
328 rtc_write(RTC_SECONDS, (ret & 0x7F));
329
330 /* Clear the cached value. */
331 voltage_low = 0;
332
333 return 0;
334 }
335 default:
336 return -ENOTTY;
337 }
338
339 return 0;
340}
341
342static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
343{
344 int ret;
345
346 mutex_lock(&pcf8563_mutex);
347 ret = pcf8563_ioctl(filp, cmd, arg);
348 mutex_unlock(&pcf8563_mutex);
349
350 return ret;
351}
352
353static int __init pcf8563_register(void)
354{
355 if (pcf8563_init() < 0) {
356 printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
357 "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
358 return -1;
359 }
360
361 if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
362 printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
363 PCF8563_NAME, PCF8563_MAJOR);
364 return -1;
365 }
366
367 printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
368 DRIVER_VERSION);
369
370 /* Check for low voltage, and warn about it. */
371 if (voltage_low) {
372 printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
373 "information is no longer guaranteed!\n", PCF8563_NAME);
374 }
375
376 return 0;
377}
378
379module_init(pcf8563_register);
380module_exit(pcf8563_exit);
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 8a8196ee8ce..082f1890bac 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -21,8 +21,6 @@
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/irq.h> 22#include <asm/irq.h>
23#include <asm/delay.h> 23#include <asm/delay.h>
24#include <asm/rtc.h>
25
26 24
27#include <arch/svinto.h> 25#include <arch/svinto.h>
28#include <asm/fasttimer.h> 26#include <asm/fasttimer.h>
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index b579dd02e09..37e6d2c50b7 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -264,7 +264,7 @@ static int write_register (int regno, char *val);
264 264
265/* Write a value to a specified register in the stack of a thread other 265/* Write a value to a specified register in the stack of a thread other
266 than the current thread. */ 266 than the current thread. */
267static write_stack_register (int thread_id, int regno, char *valptr); 267static int write_stack_register(int thread_id, int regno, char *valptr);
268 268
269/* Read a value from a specified register in the register image. Returns the 269/* Read a value from a specified register in the register image. Returns the
270 status of the read operation. The register value is returned in valptr. */ 270 status of the read operation. The register value is returned in valptr. */
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 20c85b5dc7d..bcffcb6a941 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -19,16 +19,12 @@
19#include <asm/signal.h> 19#include <asm/signal.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/delay.h> 21#include <asm/delay.h>
22#include <asm/rtc.h>
23#include <asm/irq_regs.h> 22#include <asm/irq_regs.h>
24 23
25/* define this if you need to use print_timestamp */ 24/* define this if you need to use print_timestamp */
26/* it will make jiffies at 96 hz instead of 100 hz though */ 25/* it will make jiffies at 96 hz instead of 100 hz though */
27#undef USE_CASCADE_TIMERS 26#undef USE_CASCADE_TIMERS
28 27
29extern int set_rtc_mmss(unsigned long nowtime);
30extern int have_rtc;
31
32unsigned long get_ns_in_jiffie(void) 28unsigned long get_ns_in_jiffie(void)
33{ 29{
34 unsigned char timer_count, t1; 30 unsigned char timer_count, t1;
@@ -203,11 +199,6 @@ time_init(void)
203 */ 199 */
204 loops_per_usec = 50; 200 loops_per_usec = 50;
205 201
206 if(RTC_INIT() < 0)
207 have_rtc = 0;
208 else
209 have_rtc = 1;
210
211 /* Setup the etrax timers 202 /* Setup the etrax timers
212 * Base frequency is 25000 hz, divider 250 -> 100 HZ 203 * Base frequency is 25000 hz, divider 250 -> 100 HZ
213 * In normal mode, we use timer0, so timer1 is free. In cascade 204 * In normal mode, we use timer0, so timer1 is free. In cascade
diff --git a/arch/cris/arch-v10/lib/Makefile b/arch/cris/arch-v10/lib/Makefile
index 36e9a9c5239..725153edb76 100644
--- a/arch/cris/arch-v10/lib/Makefile
+++ b/arch/cris/arch-v10/lib/Makefile
@@ -2,8 +2,5 @@
2# Makefile for Etrax-specific library files.. 2# Makefile for Etrax-specific library files..
3# 3#
4 4
5
6EXTRA_AFLAGS := -traditional
7
8lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o 5lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o
9 6
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index 642c6fed43d..f8476d9e856 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -1394,11 +1394,10 @@ static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char
1394 1394
1395 if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH; 1395 if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH;
1396 1396
1397 p = kmalloc(padlen, alloc_flag); 1397 p = kzalloc(padlen, alloc_flag);
1398 if (!p) return -ENOMEM; 1398 if (!p) return -ENOMEM;
1399 1399
1400 *p = 0x80; 1400 *p = 0x80;
1401 memset(p+1, 0, padlen - 1);
1402 1401
1403 DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length)); 1402 DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
1404 1403
@@ -1426,11 +1425,10 @@ static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, cha
1426 1425
1427 if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH; 1426 if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH;
1428 1427
1429 p = kmalloc(padlen, alloc_flag); 1428 p = kzalloc(padlen, alloc_flag);
1430 if (!p) return -ENOMEM; 1429 if (!p) return -ENOMEM;
1431 1430
1432 *p = 0x80; 1431 *p = 0x80;
1433 memset(p+1, 0, padlen - 1);
1434 1432
1435 DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length)); 1433 DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
1436 1434
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index f7ad9e8637d..f085229cf87 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -114,8 +114,6 @@ void user_disable_single_step(struct task_struct *child)
114void 114void
115ptrace_disable(struct task_struct *child) 115ptrace_disable(struct task_struct *child)
116{ 116{
117 unsigned long tmp;
118
119 /* Deconfigure SPC and S-bit. */ 117 /* Deconfigure SPC and S-bit. */
120 user_disable_single_step(child); 118 user_disable_single_step(child);
121 put_reg(child, PT_SPC, 0); 119 put_reg(child, PT_SPC, 0);
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 6773fc83a67..8c4b45efd7b 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -18,7 +18,6 @@
18#include <asm/signal.h> 18#include <asm/signal.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/delay.h> 20#include <asm/delay.h>
21#include <asm/rtc.h>
22#include <asm/irq.h> 21#include <asm/irq.h>
23#include <asm/irq_regs.h> 22#include <asm/irq_regs.h>
24 23
@@ -67,7 +66,6 @@ unsigned long timer_regs[NR_CPUS] =
67}; 66};
68 67
69extern int set_rtc_mmss(unsigned long nowtime); 68extern int set_rtc_mmss(unsigned long nowtime);
70extern int have_rtc;
71 69
72#ifdef CONFIG_CPU_FREQ 70#ifdef CONFIG_CPU_FREQ
73static int 71static int
@@ -265,11 +263,6 @@ void __init time_init(void)
265 */ 263 */
266 loops_per_usec = 50; 264 loops_per_usec = 50;
267 265
268 if(RTC_INIT() < 0)
269 have_rtc = 0;
270 else
271 have_rtc = 1;
272
273 /* Start CPU local timer. */ 266 /* Start CPU local timer. */
274 cris_timer_init(); 267 cris_timer_init();
275 268
diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
index 1de779f4f24..7caf25d58e6 100644
--- a/arch/cris/include/arch-v32/arch/cache.h
+++ b/arch/cris/include/arch-v32/arch/cache.h
@@ -7,7 +7,7 @@
7#define L1_CACHE_BYTES 32 7#define L1_CACHE_BYTES 32
8#define L1_CACHE_SHIFT 5 8#define L1_CACHE_SHIFT 5
9 9
10#define __read_mostly __attribute__((__section__(".data.read_mostly"))) 10#define __read_mostly __attribute__((__section__(".data..read_mostly")))
11 11
12void flush_dma_list(dma_descr_data *descr); 12void flush_dma_list(dma_descr_data *descr);
13void flush_dma_descr(dma_descr_data *descr, int flush_buf); 13void flush_dma_descr(dma_descr_data *descr, int flush_buf);
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 956eea246b9..04d02a51c5e 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -6,5 +6,4 @@ header-y += arch-v32/
6header-y += ethernet.h 6header-y += ethernet.h
7header-y += etraxgpio.h 7header-y += etraxgpio.h
8header-y += rs485.h 8header-y += rs485.h
9header-y += rtc.h
10header-y += sync_serial.h 9header-y += sync_serial.h
diff --git a/arch/cris/include/asm/posix_types.h b/arch/cris/include/asm/posix_types.h
index 72b3cd6eda0..234891c74e2 100644
--- a/arch/cris/include/asm/posix_types.h
+++ b/arch/cris/include/asm/posix_types.h
@@ -33,4 +33,6 @@ typedef int __kernel_ptrdiff_t;
33typedef unsigned short __kernel_old_dev_t; 33typedef unsigned short __kernel_old_dev_t;
34#define __kernel_old_dev_t __kernel_old_dev_t 34#define __kernel_old_dev_t __kernel_old_dev_t
35 35
36#include <asm-generic/posix_types.h>
37
36#endif /* __ARCH_CRIS_POSIX_TYPES_H */ 38#endif /* __ARCH_CRIS_POSIX_TYPES_H */
diff --git a/arch/cris/include/asm/rtc.h b/arch/cris/include/asm/rtc.h
deleted file mode 100644
index 17d3019529e..00000000000
--- a/arch/cris/include/asm/rtc.h
+++ /dev/null
@@ -1,107 +0,0 @@
1
2#ifndef __RTC_H__
3#define __RTC_H__
4
5#ifdef CONFIG_ETRAX_DS1302
6 /* Dallas DS1302 clock/calendar register numbers. */
7# define RTC_SECONDS 0
8# define RTC_MINUTES 1
9# define RTC_HOURS 2
10# define RTC_DAY_OF_MONTH 3
11# define RTC_MONTH 4
12# define RTC_WEEKDAY 5
13# define RTC_YEAR 6
14# define RTC_CONTROL 7
15
16 /* Bits in CONTROL register. */
17# define RTC_CONTROL_WRITEPROTECT 0x80
18# define RTC_TRICKLECHARGER 8
19
20 /* Bits in TRICKLECHARGER register TCS TCS TCS TCS DS DS RS RS. */
21# define RTC_TCR_PATTERN 0xA0 /* 1010xxxx */
22# define RTC_TCR_1DIOD 0x04 /* xxxx01xx */
23# define RTC_TCR_2DIOD 0x08 /* xxxx10xx */
24# define RTC_TCR_DISABLED 0x00 /* xxxxxx00 Disabled */
25# define RTC_TCR_2KOHM 0x01 /* xxxxxx01 2KOhm */
26# define RTC_TCR_4KOHM 0x02 /* xxxxxx10 4kOhm */
27# define RTC_TCR_8KOHM 0x03 /* xxxxxx11 8kOhm */
28
29#elif defined(CONFIG_ETRAX_PCF8563)
30 /* I2C bus slave registers. */
31# define RTC_I2C_READ 0xa3
32# define RTC_I2C_WRITE 0xa2
33
34 /* Phillips PCF8563 registers. */
35# define RTC_CONTROL1 0x00 /* Control/Status register 1. */
36# define RTC_CONTROL2 0x01 /* Control/Status register 2. */
37# define RTC_CLOCKOUT_FREQ 0x0d /* CLKOUT frequency. */
38# define RTC_TIMER_CONTROL 0x0e /* Timer control. */
39# define RTC_TIMER_CNTDOWN 0x0f /* Timer countdown. */
40
41 /* BCD encoded clock registers. */
42# define RTC_SECONDS 0x02
43# define RTC_MINUTES 0x03
44# define RTC_HOURS 0x04
45# define RTC_DAY_OF_MONTH 0x05
46# define RTC_WEEKDAY 0x06 /* Not coded in BCD! */
47# define RTC_MONTH 0x07
48# define RTC_YEAR 0x08
49# define RTC_MINUTE_ALARM 0x09
50# define RTC_HOUR_ALARM 0x0a
51# define RTC_DAY_ALARM 0x0b
52# define RTC_WEEKDAY_ALARM 0x0c
53
54#endif
55
56#ifdef CONFIG_ETRAX_DS1302
57extern unsigned char ds1302_readreg(int reg);
58extern void ds1302_writereg(int reg, unsigned char val);
59extern int ds1302_init(void);
60# define CMOS_READ(x) ds1302_readreg(x)
61# define CMOS_WRITE(val,reg) ds1302_writereg(reg,val)
62# define RTC_INIT() ds1302_init()
63#elif defined(CONFIG_ETRAX_PCF8563)
64extern unsigned char pcf8563_readreg(int reg);
65extern void pcf8563_writereg(int reg, unsigned char val);
66extern int pcf8563_init(void);
67# define CMOS_READ(x) pcf8563_readreg(x)
68# define CMOS_WRITE(val,reg) pcf8563_writereg(reg,val)
69# define RTC_INIT() pcf8563_init()
70#else
71 /* No RTC configured so we shouldn't try to access any. */
72# define CMOS_READ(x) 42
73# define CMOS_WRITE(x,y)
74# define RTC_INIT() (-1)
75#endif
76
77/*
78 * The struct used to pass data via the following ioctl. Similar to the
79 * struct tm in <time.h>, but it needs to be here so that the kernel
80 * source is self contained, allowing cross-compiles, etc. etc.
81 */
82struct rtc_time {
83 int tm_sec;
84 int tm_min;
85 int tm_hour;
86 int tm_mday;
87 int tm_mon;
88 int tm_year;
89 int tm_wday;
90 int tm_yday;
91 int tm_isdst;
92};
93
94/* ioctl() calls that are permitted to the /dev/rtc interface. */
95#define RTC_MAGIC 'p'
96/* Read RTC time. */
97#define RTC_RD_TIME _IOR(RTC_MAGIC, 0x09, struct rtc_time)
98/* Set RTC time. */
99#define RTC_SET_TIME _IOW(RTC_MAGIC, 0x0a, struct rtc_time)
100#define RTC_SET_CHARGE _IOW(RTC_MAGIC, 0x0b, int)
101/* Voltage low detector */
102#define RTC_VL_READ _IOR(RTC_MAGIC, 0x13, int)
103/* Clear voltage low information */
104#define RTC_VL_CLR _IO(RTC_MAGIC, 0x14)
105#define RTC_MAX_IOCTL 0x14
106
107#endif /* __RTC_H__ */
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 4e73092e85c..277ffc459e4 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <asm/rtc.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/module.h> 25#include <linux/module.h>
27#include <linux/param.h> 26#include <linux/param.h>
@@ -32,7 +31,8 @@
32#include <linux/profile.h> 31#include <linux/profile.h>
33#include <linux/sched.h> /* just for sched_clock() - funny that */ 32#include <linux/sched.h> /* just for sched_clock() - funny that */
34 33
35int have_rtc; /* used to remember if we have an RTC or not */; 34
35#define D(x)
36 36
37#define TICK_SIZE tick 37#define TICK_SIZE tick
38 38
@@ -50,78 +50,16 @@ u32 arch_gettimeoffset(void)
50} 50}
51#endif 51#endif
52 52
53/*
54 * BUG: This routine does not handle hour overflow properly; it just
55 * sets the minutes. Usually you'll only notice that after reboot!
56 */
57
58int set_rtc_mmss(unsigned long nowtime) 53int set_rtc_mmss(unsigned long nowtime)
59{ 54{
60 int retval = 0; 55 D(printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime));
61 int real_seconds, real_minutes, cmos_minutes; 56 return 0;
62
63 printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime);
64
65 if(!have_rtc)
66 return 0;
67
68 cmos_minutes = CMOS_READ(RTC_MINUTES);
69 cmos_minutes = bcd2bin(cmos_minutes);
70
71 /*
72 * since we're only adjusting minutes and seconds,
73 * don't interfere with hour overflow. This avoids
74 * messing with unknown time zones but requires your
75 * RTC not to be off by more than 15 minutes
76 */
77 real_seconds = nowtime % 60;
78 real_minutes = nowtime / 60;
79 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
80 real_minutes += 30; /* correct for half hour time zone */
81 real_minutes %= 60;
82
83 if (abs(real_minutes - cmos_minutes) < 30) {
84 real_seconds = bin2bcd(real_seconds);
85 real_minutes = bin2bcd(real_minutes);
86 CMOS_WRITE(real_seconds,RTC_SECONDS);
87 CMOS_WRITE(real_minutes,RTC_MINUTES);
88 } else {
89 printk_once(KERN_NOTICE
90 "set_rtc_mmss: can't update from %d to %d\n",
91 cmos_minutes, real_minutes);
92 retval = -1;
93 }
94
95 return retval;
96} 57}
97 58
98/* grab the time from the RTC chip */ 59/* grab the time from the RTC chip */
99 60unsigned long get_cmos_time(void)
100unsigned long
101get_cmos_time(void)
102{ 61{
103 unsigned int year, mon, day, hour, min, sec; 62 return 0;
104 if(!have_rtc)
105 return 0;
106
107 sec = CMOS_READ(RTC_SECONDS);
108 min = CMOS_READ(RTC_MINUTES);
109 hour = CMOS_READ(RTC_HOURS);
110 day = CMOS_READ(RTC_DAY_OF_MONTH);
111 mon = CMOS_READ(RTC_MONTH);
112 year = CMOS_READ(RTC_YEAR);
113
114 sec = bcd2bin(sec);
115 min = bcd2bin(min);
116 hour = bcd2bin(hour);
117 day = bcd2bin(day);
118 mon = bcd2bin(mon);
119 year = bcd2bin(year);
120
121 if ((year += 1900) < 1970)
122 year += 100;
123
124 return mktime(year, mon, day, hour, min, sec);
125} 63}
126 64
127 65
@@ -132,7 +70,7 @@ int update_persistent_clock(struct timespec now)
132 70
133void read_persistent_clock(struct timespec *ts) 71void read_persistent_clock(struct timespec *ts)
134{ 72{
135 ts->tv_sec = get_cmos_time(); 73 ts->tv_sec = 0;
136 ts->tv_nsec = 0; 74 ts->tv_nsec = 0;
137} 75}
138 76
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
index a6990cb0f09..a68b983dcea 100644
--- a/arch/cris/kernel/vmlinux.lds.S
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -52,6 +52,7 @@ SECTIONS
52 52
53 EXCEPTION_TABLE(4) 53 EXCEPTION_TABLE(4)
54 54
55 _sdata = .;
55 RODATA 56 RODATA
56 57
57 . = ALIGN (4); 58 . = ALIGN (4);
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index b4760d86e1b..45fd542cf17 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -58,6 +58,8 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
58 struct vm_area_struct * vma; 58 struct vm_area_struct * vma;
59 siginfo_t info; 59 siginfo_t info;
60 int fault; 60 int fault;
61 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
62 ((writeaccess & 1) ? FAULT_FLAG_WRITE : 0);
61 63
62 D(printk(KERN_DEBUG 64 D(printk(KERN_DEBUG
63 "Page fault for %lX on %X at %lX, prot %d write %d\n", 65 "Page fault for %lX on %X at %lX, prot %d write %d\n",
@@ -115,6 +117,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
115 if (in_atomic() || !mm) 117 if (in_atomic() || !mm)
116 goto no_context; 118 goto no_context;
117 119
120retry:
118 down_read(&mm->mmap_sem); 121 down_read(&mm->mmap_sem);
119 vma = find_vma(mm, address); 122 vma = find_vma(mm, address);
120 if (!vma) 123 if (!vma)
@@ -163,7 +166,11 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
163 * the fault. 166 * the fault.
164 */ 167 */
165 168
166 fault = handle_mm_fault(mm, vma, address, (writeaccess & 1) ? FAULT_FLAG_WRITE : 0); 169 fault = handle_mm_fault(mm, vma, address, flags);
170
171 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
172 return;
173
167 if (unlikely(fault & VM_FAULT_ERROR)) { 174 if (unlikely(fault & VM_FAULT_ERROR)) {
168 if (fault & VM_FAULT_OOM) 175 if (fault & VM_FAULT_OOM)
169 goto out_of_memory; 176 goto out_of_memory;
@@ -171,10 +178,24 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
171 goto do_sigbus; 178 goto do_sigbus;
172 BUG(); 179 BUG();
173 } 180 }
174 if (fault & VM_FAULT_MAJOR) 181
175 tsk->maj_flt++; 182 if (flags & FAULT_FLAG_ALLOW_RETRY) {
176 else 183 if (fault & VM_FAULT_MAJOR)
177 tsk->min_flt++; 184 tsk->maj_flt++;
185 else
186 tsk->min_flt++;
187 if (fault & VM_FAULT_RETRY) {
188 flags &= ~FAULT_FLAG_ALLOW_RETRY;
189
190 /*
191 * No need to up_read(&mm->mmap_sem) as we would
192 * have already released it in __lock_page_or_retry
193 * in mm/filemap.c.
194 */
195
196 goto retry;
197 }
198 }
178 199
179 up_read(&mm->mmap_sem); 200 up_read(&mm->mmap_sem);
180 return; 201 return;
diff --git a/arch/frv/include/asm/kvm_para.h b/arch/frv/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/frv/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/h8300/include/asm/kvm_para.h b/arch/h8300/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/h8300/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/hexagon/include/asm/kvm_para.h b/arch/hexagon/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/hexagon/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index e35b3a84a40..6d6a5ac48d8 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -365,6 +365,7 @@ struct thash_cb {
365}; 365};
366 366
367struct kvm_vcpu_stat { 367struct kvm_vcpu_stat {
368 u32 halt_wakeup;
368}; 369};
369 370
370struct kvm_vcpu_arch { 371struct kvm_vcpu_arch {
@@ -448,6 +449,8 @@ struct kvm_vcpu_arch {
448 char log_buf[VMM_LOG_LEN]; 449 char log_buf[VMM_LOG_LEN];
449 union context host; 450 union context host;
450 union context guest; 451 union context guest;
452
453 char mmio_data[8];
451}; 454};
452 455
453struct kvm_vm_stat { 456struct kvm_vm_stat {
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
index 1588aee781a..2019cb99335 100644
--- a/arch/ia64/include/asm/kvm_para.h
+++ b/arch/ia64/include/asm/kvm_para.h
@@ -26,6 +26,11 @@ static inline unsigned int kvm_arch_para_features(void)
26 return 0; 26 return 0;
27} 27}
28 28
29static inline bool kvm_check_and_clear_guest_paused(void)
30{
31 return false;
32}
33
29#endif 34#endif
30 35
31#endif 36#endif
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 463fb3bbe11..bd77cb507c1 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -232,12 +232,12 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
232 if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS) 232 if ((p->addr & PAGE_MASK) == IOAPIC_DEFAULT_BASE_ADDRESS)
233 goto mmio; 233 goto mmio;
234 vcpu->mmio_needed = 1; 234 vcpu->mmio_needed = 1;
235 vcpu->mmio_phys_addr = kvm_run->mmio.phys_addr = p->addr; 235 vcpu->mmio_fragments[0].gpa = kvm_run->mmio.phys_addr = p->addr;
236 vcpu->mmio_size = kvm_run->mmio.len = p->size; 236 vcpu->mmio_fragments[0].len = kvm_run->mmio.len = p->size;
237 vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir; 237 vcpu->mmio_is_write = kvm_run->mmio.is_write = !p->dir;
238 238
239 if (vcpu->mmio_is_write) 239 if (vcpu->mmio_is_write)
240 memcpy(vcpu->mmio_data, &p->data, p->size); 240 memcpy(vcpu->arch.mmio_data, &p->data, p->size);
241 memcpy(kvm_run->mmio.data, &p->data, p->size); 241 memcpy(kvm_run->mmio.data, &p->data, p->size);
242 kvm_run->exit_reason = KVM_EXIT_MMIO; 242 kvm_run->exit_reason = KVM_EXIT_MMIO;
243 return 0; 243 return 0;
@@ -719,7 +719,7 @@ static void kvm_set_mmio_data(struct kvm_vcpu *vcpu)
719 struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu); 719 struct kvm_mmio_req *p = kvm_get_vcpu_ioreq(vcpu);
720 720
721 if (!vcpu->mmio_is_write) 721 if (!vcpu->mmio_is_write)
722 memcpy(&p->data, vcpu->mmio_data, 8); 722 memcpy(&p->data, vcpu->arch.mmio_data, 8);
723 p->state = STATE_IORESP_READY; 723 p->state = STATE_IORESP_READY;
724} 724}
725 725
@@ -739,7 +739,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
739 } 739 }
740 740
741 if (vcpu->mmio_needed) { 741 if (vcpu->mmio_needed) {
742 memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); 742 memcpy(vcpu->arch.mmio_data, kvm_run->mmio.data, 8);
743 kvm_set_mmio_data(vcpu); 743 kvm_set_mmio_data(vcpu);
744 vcpu->mmio_read_completed = 1; 744 vcpu->mmio_read_completed = 1;
745 vcpu->mmio_needed = 0; 745 vcpu->mmio_needed = 0;
@@ -1872,21 +1872,6 @@ void kvm_arch_hardware_unsetup(void)
1872{ 1872{
1873} 1873}
1874 1874
1875void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
1876{
1877 int me;
1878 int cpu = vcpu->cpu;
1879
1880 if (waitqueue_active(&vcpu->wq))
1881 wake_up_interruptible(&vcpu->wq);
1882
1883 me = get_cpu();
1884 if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
1885 if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
1886 smp_send_reschedule(cpu);
1887 put_cpu();
1888}
1889
1890int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq) 1875int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq)
1891{ 1876{
1892 return __apic_accept_irq(vcpu, irq->vector); 1877 return __apic_accept_irq(vcpu, irq->vector);
@@ -1956,6 +1941,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
1956 (kvm_highest_pending_irq(vcpu) != -1); 1941 (kvm_highest_pending_irq(vcpu) != -1);
1957} 1942}
1958 1943
1944int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
1945{
1946 return (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests));
1947}
1948
1959int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, 1949int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
1960 struct kvm_mp_state *mp_state) 1950 struct kvm_mp_state *mp_state)
1961{ 1951{
diff --git a/arch/m68k/include/asm/kvm_para.h b/arch/m68k/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/m68k/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 83460468998..0bf44231aaf 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -52,7 +52,7 @@ config GENERIC_CALIBRATE_DELAY
52 def_bool y 52 def_bool y
53 53
54config GENERIC_GPIO 54config GENERIC_GPIO
55 def_bool y 55 bool
56 56
57config GENERIC_CSUM 57config GENERIC_CSUM
58 def_bool y 58 def_bool y
diff --git a/arch/microblaze/include/asm/kvm_para.h b/arch/microblaze/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/microblaze/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index daff9e5e4a1..03f7b8ce6b6 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -492,10 +492,11 @@ C_ENTRY(sys_clone):
492 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ 492 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
493 lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */ 493 lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
4941: addik r7, r1, 0; /* Arg 2: parent context */ 4941: addik r7, r1, 0; /* Arg 2: parent context */
495 add r8, r0, r0; /* Arg 3: (unused) */ 495 lwi r9, r1, PT_R8; /* parent tid. */
496 add r9, r0, r0; /* Arg 4: (unused) */ 496 lwi r10, r1, PT_R9; /* child tid. */
497 /* do_fork will pick up TLS from regs->r10. */
497 brid do_fork /* Do real work (tail-call) */ 498 brid do_fork /* Do real work (tail-call) */
498 add r10, r0, r0; /* Arg 5: (unused) */ 499 add r8, r0, r0; /* Arg 3: (unused) */
499 500
500C_ENTRY(sys_execve): 501C_ENTRY(sys_execve):
501 brid microblaze_execve; /* Do real work (tail-call).*/ 502 brid microblaze_execve; /* Do real work (tail-call).*/
diff --git a/arch/microblaze/kernel/mcount.S b/arch/microblaze/kernel/mcount.S
index e7eaa7a8cbd..fc1e1322ce4 100644
--- a/arch/microblaze/kernel/mcount.S
+++ b/arch/microblaze/kernel/mcount.S
@@ -138,7 +138,7 @@ NOALIGN_ENTRY(ftrace_call)
138#endif /* CONFIG_DYNAMIC_FTRACE */ 138#endif /* CONFIG_DYNAMIC_FTRACE */
139/* static normal trace */ 139/* static normal trace */
140 lwi r6, r1, 120; /* MS: load parent addr */ 140 lwi r6, r1, 120; /* MS: load parent addr */
141 addik r5, r15, 0; /* MS: load current function addr */ 141 addik r5, r15, -4; /* MS: load current function addr */
142 /* MS: here is dependency on previous code */ 142 /* MS: here is dependency on previous code */
143 brald r15, r20; /* MS: jump to ftrace handler */ 143 brald r15, r20; /* MS: jump to ftrace handler */
144 nop; 144 nop;
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 883b92789cd..1944e00f07e 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -182,8 +182,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
182#endif 182#endif
183 ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8; 183 ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
184 184
185 /*
186 * r21 is the thread reg, r10 is 6th arg to clone
187 * which contains TLS area
188 */
185 if (clone_flags & CLONE_SETTLS) 189 if (clone_flags & CLONE_SETTLS)
186 ; 190 childregs->r21 = childregs->r10;
187 191
188 return 0; 192 return 0;
189} 193}
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index c38a265846d..eb365d6795f 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -92,6 +92,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
92 int code = SEGV_MAPERR; 92 int code = SEGV_MAPERR;
93 int is_write = error_code & ESR_S; 93 int is_write = error_code & ESR_S;
94 int fault; 94 int fault;
95 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
96 (is_write ? FAULT_FLAG_WRITE : 0);
95 97
96 regs->ear = address; 98 regs->ear = address;
97 regs->esr = error_code; 99 regs->esr = error_code;
@@ -138,6 +140,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
138 if (kernel_mode(regs) && !search_exception_tables(regs->pc)) 140 if (kernel_mode(regs) && !search_exception_tables(regs->pc))
139 goto bad_area_nosemaphore; 141 goto bad_area_nosemaphore;
140 142
143retry:
141 down_read(&mm->mmap_sem); 144 down_read(&mm->mmap_sem);
142 } 145 }
143 146
@@ -210,7 +213,11 @@ good_area:
210 * make sure we exit gracefully rather than endlessly redo 213 * make sure we exit gracefully rather than endlessly redo
211 * the fault. 214 * the fault.
212 */ 215 */
213 fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); 216 fault = handle_mm_fault(mm, vma, address, flags);
217
218 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
219 return;
220
214 if (unlikely(fault & VM_FAULT_ERROR)) { 221 if (unlikely(fault & VM_FAULT_ERROR)) {
215 if (fault & VM_FAULT_OOM) 222 if (fault & VM_FAULT_OOM)
216 goto out_of_memory; 223 goto out_of_memory;
@@ -218,11 +225,27 @@ good_area:
218 goto do_sigbus; 225 goto do_sigbus;
219 BUG(); 226 BUG();
220 } 227 }
221 if (unlikely(fault & VM_FAULT_MAJOR)) 228
222 current->maj_flt++; 229 if (flags & FAULT_FLAG_ALLOW_RETRY) {
223 else 230 if (unlikely(fault & VM_FAULT_MAJOR))
224 current->min_flt++; 231 current->maj_flt++;
232 else
233 current->min_flt++;
234 if (fault & VM_FAULT_RETRY) {
235 flags &= ~FAULT_FLAG_ALLOW_RETRY;
236
237 /*
238 * No need to up_read(&mm->mmap_sem) as we would
239 * have already released it in __lock_page_or_retry
240 * in mm/filemap.c.
241 */
242
243 goto retry;
244 }
245 }
246
225 up_read(&mm->mmap_sem); 247 up_read(&mm->mmap_sem);
248
226 /* 249 /*
227 * keep track of tlb+htab misses that are good addrs but 250 * keep track of tlb+htab misses that are good addrs but
228 * just need pte's created via handle_mm_fault() 251 * just need pte's created via handle_mm_fault()
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 77050671eee..09ab87ee6fe 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -233,8 +233,9 @@ config LANTIQ
233 select ARCH_REQUIRE_GPIOLIB 233 select ARCH_REQUIRE_GPIOLIB
234 select SWAP_IO_SPACE 234 select SWAP_IO_SPACE
235 select BOOT_RAW 235 select BOOT_RAW
236 select HAVE_CLK 236 select HAVE_MACH_CLKDEV
237 select MIPS_MACHINE 237 select CLKDEV_LOOKUP
238 select USE_OF
238 239
239config LASAT 240config LASAT
240 bool "LASAT Networks platforms" 241 bool "LASAT Networks platforms"
@@ -1783,10 +1784,12 @@ endchoice
1783 1784
1784config FORCE_MAX_ZONEORDER 1785config FORCE_MAX_ZONEORDER
1785 int "Maximum zone order" 1786 int "Maximum zone order"
1786 range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB 1787 range 14 64 if HUGETLB_PAGE && PAGE_SIZE_64KB
1787 default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB 1788 default "14" if HUGETLB_PAGE && PAGE_SIZE_64KB
1788 range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB 1789 range 13 64 if HUGETLB_PAGE && PAGE_SIZE_32KB
1789 default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB 1790 default "13" if HUGETLB_PAGE && PAGE_SIZE_32KB
1791 range 12 64 if HUGETLB_PAGE && PAGE_SIZE_16KB
1792 default "12" if HUGETLB_PAGE && PAGE_SIZE_16KB
1790 range 11 64 1793 range 11 64
1791 default "11" 1794 default "11"
1792 help 1795 help
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 76017c25a9e..764e37a9dbb 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -219,8 +219,8 @@ endif
219 219
220KBUILD_AFLAGS += $(cflags-y) 220KBUILD_AFLAGS += $(cflags-y)
221KBUILD_CFLAGS += $(cflags-y) 221KBUILD_CFLAGS += $(cflags-y)
222KBUILD_CPPFLAGS += -D"VMLINUX_LOAD_ADDRESS=$(load-y)" 222KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y)
223KBUILD_CPPFLAGS += -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" 223KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
224 224
225LDFLAGS += -m $(ld-emul) 225LDFLAGS += -m $(ld-emul)
226 226
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
index a83302b96c0..7dde01642d6 100644
--- a/arch/mips/alchemy/devboards/db1200.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -22,6 +22,7 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/module.h>
25#include <linux/interrupt.h> 26#include <linux/interrupt.h>
26#include <linux/io.h> 27#include <linux/io.h>
27#include <linux/leds.h> 28#include <linux/leds.h>
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index e0fae8f4442..f44feee2d67 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -26,6 +26,18 @@ config ATH79_MACH_AP81
26 Say 'Y' here if you want your kernel to support the 26 Say 'Y' here if you want your kernel to support the
27 Atheros AP81 reference board. 27 Atheros AP81 reference board.
28 28
29config ATH79_MACH_DB120
30 bool "Atheros DB120 reference board"
31 select SOC_AR934X
32 select ATH79_DEV_GPIO_BUTTONS
33 select ATH79_DEV_LEDS_GPIO
34 select ATH79_DEV_SPI
35 select ATH79_DEV_USB
36 select ATH79_DEV_WMAC
37 help
38 Say 'Y' here if you want your kernel to support the
39 Atheros DB120 reference board.
40
29config ATH79_MACH_PB44 41config ATH79_MACH_PB44
30 bool "Atheros PB44 reference board" 42 bool "Atheros PB44 reference board"
31 select SOC_AR71XX 43 select SOC_AR71XX
@@ -52,12 +64,14 @@ endmenu
52config SOC_AR71XX 64config SOC_AR71XX
53 select USB_ARCH_HAS_EHCI 65 select USB_ARCH_HAS_EHCI
54 select USB_ARCH_HAS_OHCI 66 select USB_ARCH_HAS_OHCI
67 select HW_HAS_PCI
55 def_bool n 68 def_bool n
56 69
57config SOC_AR724X 70config SOC_AR724X
58 select USB_ARCH_HAS_EHCI 71 select USB_ARCH_HAS_EHCI
59 select USB_ARCH_HAS_OHCI 72 select USB_ARCH_HAS_OHCI
60 select HW_HAS_PCI 73 select HW_HAS_PCI
74 select PCI_AR724X if PCI
61 def_bool n 75 def_bool n
62 76
63config SOC_AR913X 77config SOC_AR913X
@@ -68,6 +82,15 @@ config SOC_AR933X
68 select USB_ARCH_HAS_EHCI 82 select USB_ARCH_HAS_EHCI
69 def_bool n 83 def_bool n
70 84
85config SOC_AR934X
86 select USB_ARCH_HAS_EHCI
87 select HW_HAS_PCI
88 select PCI_AR724X if PCI
89 def_bool n
90
91config PCI_AR724X
92 def_bool n
93
71config ATH79_DEV_GPIO_BUTTONS 94config ATH79_DEV_GPIO_BUTTONS
72 def_bool n 95 def_bool n
73 96
@@ -81,7 +104,7 @@ config ATH79_DEV_USB
81 def_bool n 104 def_bool n
82 105
83config ATH79_DEV_WMAC 106config ATH79_DEV_WMAC
84 depends on (SOC_AR913X || SOC_AR933X) 107 depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X)
85 def_bool n 108 def_bool n
86 109
87endif 110endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 3b911e09dbe..2b54d98263f 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -11,6 +11,7 @@
11obj-y := prom.o setup.o irq.o common.o clock.o gpio.o 11obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
12 12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14obj-$(CONFIG_PCI) += pci.o
14 15
15# 16#
16# Devices 17# Devices
@@ -27,5 +28,6 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
27# 28#
28obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o 29obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
29obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o 30obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
31obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
30obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o 32obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
31obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o 33obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 54d0eb4db98..b91ad3efe29 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -1,8 +1,11 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X common routines 2 * Atheros AR71XX/AR724X/AR913X common routines
3 * 3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
4 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
5 * 6 *
7 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8 *
6 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published 10 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation. 11 * by the Free Software Foundation.
@@ -163,6 +166,82 @@ static void __init ar933x_clocks_init(void)
163 ath79_uart_clk.rate = ath79_ref_clk.rate; 166 ath79_uart_clk.rate = ath79_ref_clk.rate;
164} 167}
165 168
169static void __init ar934x_clocks_init(void)
170{
171 u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
172 u32 cpu_pll, ddr_pll;
173 u32 bootstrap;
174
175 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
176 if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40)
177 ath79_ref_clk.rate = 40 * 1000 * 1000;
178 else
179 ath79_ref_clk.rate = 25 * 1000 * 1000;
180
181 pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
182 out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
183 AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
184 ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
185 AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
186 nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
187 AR934X_PLL_CPU_CONFIG_NINT_MASK;
188 frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
189 AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
190
191 cpu_pll = nint * ath79_ref_clk.rate / ref_div;
192 cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
193 cpu_pll /= (1 << out_div);
194
195 pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
196 out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
197 AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
198 ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
199 AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
200 nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
201 AR934X_PLL_DDR_CONFIG_NINT_MASK;
202 frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
203 AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
204
205 ddr_pll = nint * ath79_ref_clk.rate / ref_div;
206 ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
207 ddr_pll /= (1 << out_div);
208
209 clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
210
211 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
212 AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
213
214 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
215 ath79_cpu_clk.rate = ath79_ref_clk.rate;
216 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
217 ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
218 else
219 ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
220
221 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
222 AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
223
224 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
225 ath79_ddr_clk.rate = ath79_ref_clk.rate;
226 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
227 ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
228 else
229 ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
230
231 postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
232 AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
233
234 if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
235 ath79_ahb_clk.rate = ath79_ref_clk.rate;
236 else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
237 ath79_ahb_clk.rate = ddr_pll / (postdiv + 1);
238 else
239 ath79_ahb_clk.rate = cpu_pll / (postdiv + 1);
240
241 ath79_wdt_clk.rate = ath79_ref_clk.rate;
242 ath79_uart_clk.rate = ath79_ref_clk.rate;
243}
244
166void __init ath79_clocks_init(void) 245void __init ath79_clocks_init(void)
167{ 246{
168 if (soc_is_ar71xx()) 247 if (soc_is_ar71xx())
@@ -173,6 +252,8 @@ void __init ath79_clocks_init(void)
173 ar913x_clocks_init(); 252 ar913x_clocks_init();
174 else if (soc_is_ar933x()) 253 else if (soc_is_ar933x())
175 ar933x_clocks_init(); 254 ar933x_clocks_init();
255 else if (soc_is_ar934x())
256 ar934x_clocks_init();
176 else 257 else
177 BUG(); 258 BUG();
178 259
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
index f0fda982b96..5a4adfc9d79 100644
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -1,9 +1,12 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X common routines 2 * Atheros AR71XX/AR724X/AR913X common routines
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
9 *
7 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation. 12 * by the Free Software Foundation.
@@ -67,6 +70,8 @@ void ath79_device_reset_set(u32 mask)
67 reg = AR913X_RESET_REG_RESET_MODULE; 70 reg = AR913X_RESET_REG_RESET_MODULE;
68 else if (soc_is_ar933x()) 71 else if (soc_is_ar933x())
69 reg = AR933X_RESET_REG_RESET_MODULE; 72 reg = AR933X_RESET_REG_RESET_MODULE;
73 else if (soc_is_ar934x())
74 reg = AR934X_RESET_REG_RESET_MODULE;
70 else 75 else
71 BUG(); 76 BUG();
72 77
@@ -91,6 +96,8 @@ void ath79_device_reset_clear(u32 mask)
91 reg = AR913X_RESET_REG_RESET_MODULE; 96 reg = AR913X_RESET_REG_RESET_MODULE;
92 else if (soc_is_ar933x()) 97 else if (soc_is_ar933x())
93 reg = AR933X_RESET_REG_RESET_MODULE; 98 reg = AR933X_RESET_REG_RESET_MODULE;
99 else if (soc_is_ar934x())
100 reg = AR934X_RESET_REG_RESET_MODULE;
94 else 101 else
95 BUG(); 102 BUG();
96 103
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index f4956f80907..45efc63b08b 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -89,7 +89,8 @@ void __init ath79_register_uart(void)
89 89
90 if (soc_is_ar71xx() || 90 if (soc_is_ar71xx() ||
91 soc_is_ar724x() || 91 soc_is_ar724x() ||
92 soc_is_ar913x()) { 92 soc_is_ar913x() ||
93 soc_is_ar934x()) {
93 ath79_uart_data[0].uartclk = clk_get_rate(clk); 94 ath79_uart_data[0].uartclk = clk_get_rate(clk);
94 platform_device_register(&ath79_uart_device); 95 platform_device_register(&ath79_uart_device);
95 } else if (soc_is_ar933x()) { 96 } else if (soc_is_ar933x()) {
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
index 4b0168a11c0..366b35fb164 100644
--- a/arch/mips/ath79/dev-gpio-buttons.c
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -25,12 +25,10 @@ void __init ath79_register_gpio_keys_polled(int id,
25 struct gpio_keys_button *p; 25 struct gpio_keys_button *p;
26 int err; 26 int err;
27 27
28 p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); 28 p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL);
29 if (!p) 29 if (!p)
30 return; 30 return;
31 31
32 memcpy(p, buttons, nbuttons * sizeof(*p));
33
34 pdev = platform_device_alloc("gpio-keys-polled", id); 32 pdev = platform_device_alloc("gpio-keys-polled", id);
35 if (!pdev) 33 if (!pdev)
36 goto err_free_buttons; 34 goto err_free_buttons;
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
index cdade68dcd1..dcb1debcefb 100644
--- a/arch/mips/ath79/dev-leds-gpio.c
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -24,12 +24,10 @@ void __init ath79_register_leds_gpio(int id,
24 struct gpio_led *p; 24 struct gpio_led *p;
25 int err; 25 int err;
26 26
27 p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); 27 p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL);
28 if (!p) 28 if (!p)
29 return; 29 return;
30 30
31 memcpy(p, leds, num_leds * sizeof(*p));
32
33 pdev = platform_device_alloc("leds-gpio", id); 31 pdev = platform_device_alloc("leds-gpio", id);
34 if (!pdev) 32 if (!pdev)
35 goto err_free_leds; 33 goto err_free_leds;
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
index 9c717bf98ff..d6d893c16ad 100644
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -1,9 +1,12 @@
1/* 1/*
2 * Atheros AR913X/AR933X SoC built-in WMAC device support 2 * Atheros AR913X/AR933X SoC built-in WMAC device support
3 * 3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
8 * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
9 *
7 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation. 12 * by the Free Software Foundation.
@@ -26,8 +29,7 @@ static struct resource ath79_wmac_resources[] = {
26 /* .start and .end fields are filled dynamically */ 29 /* .start and .end fields are filled dynamically */
27 .flags = IORESOURCE_MEM, 30 .flags = IORESOURCE_MEM,
28 }, { 31 }, {
29 .start = ATH79_CPU_IRQ_IP2, 32 /* .start and .end fields are filled dynamically */
30 .end = ATH79_CPU_IRQ_IP2,
31 .flags = IORESOURCE_IRQ, 33 .flags = IORESOURCE_IRQ,
32 }, 34 },
33}; 35};
@@ -53,6 +55,8 @@ static void __init ar913x_wmac_setup(void)
53 55
54 ath79_wmac_resources[0].start = AR913X_WMAC_BASE; 56 ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
55 ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; 57 ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
58 ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
59 ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
56} 60}
57 61
58 62
@@ -79,6 +83,8 @@ static void __init ar933x_wmac_setup(void)
79 83
80 ath79_wmac_resources[0].start = AR933X_WMAC_BASE; 84 ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
81 ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; 85 ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
86 ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
87 ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
82 88
83 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); 89 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
84 if (t & AR933X_BOOTSTRAP_REF_CLK_40) 90 if (t & AR933X_BOOTSTRAP_REF_CLK_40)
@@ -92,12 +98,32 @@ static void __init ar933x_wmac_setup(void)
92 ath79_wmac_data.external_reset = ar933x_wmac_reset; 98 ath79_wmac_data.external_reset = ar933x_wmac_reset;
93} 99}
94 100
101static void ar934x_wmac_setup(void)
102{
103 u32 t;
104
105 ath79_wmac_device.name = "ar934x_wmac";
106
107 ath79_wmac_resources[0].start = AR934X_WMAC_BASE;
108 ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
109 ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
110 ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
111
112 t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
113 if (t & AR934X_BOOTSTRAP_REF_CLK_40)
114 ath79_wmac_data.is_clk_25mhz = false;
115 else
116 ath79_wmac_data.is_clk_25mhz = true;
117}
118
95void __init ath79_register_wmac(u8 *cal_data) 119void __init ath79_register_wmac(u8 *cal_data)
96{ 120{
97 if (soc_is_ar913x()) 121 if (soc_is_ar913x())
98 ar913x_wmac_setup(); 122 ar913x_wmac_setup();
99 else if (soc_is_ar933x()) 123 else if (soc_is_ar933x())
100 ar933x_wmac_setup(); 124 ar933x_wmac_setup();
125 else if (soc_is_ar934x())
126 ar934x_wmac_setup();
101 else 127 else
102 BUG(); 128 BUG();
103 129
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
index 6a51ced7a29..dc938cb2ba5 100644
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -71,6 +71,9 @@ static void prom_putchar_init(void)
71 case REV_ID_MAJOR_AR7241: 71 case REV_ID_MAJOR_AR7241:
72 case REV_ID_MAJOR_AR7242: 72 case REV_ID_MAJOR_AR7242:
73 case REV_ID_MAJOR_AR913X: 73 case REV_ID_MAJOR_AR913X:
74 case REV_ID_MAJOR_AR9341:
75 case REV_ID_MAJOR_AR9342:
76 case REV_ID_MAJOR_AR9344:
74 _prom_putchar = prom_putchar_ar71xx; 77 _prom_putchar = prom_putchar_ar71xx;
75 break; 78 break;
76 79
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
index a2f8ca630ed..29054f21183 100644
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -1,9 +1,12 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X GPIO API support 2 * Atheros AR71XX/AR724X/AR913X GPIO API support
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
9 *
7 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation. 12 * by the Free Software Foundation.
@@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(struct gpio_chip *chip,
89 return 0; 92 return 0;
90} 93}
91 94
95static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
96{
97 void __iomem *base = ath79_gpio_base;
98 unsigned long flags;
99
100 spin_lock_irqsave(&ath79_gpio_lock, flags);
101
102 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
103 base + AR71XX_GPIO_REG_OE);
104
105 spin_unlock_irqrestore(&ath79_gpio_lock, flags);
106
107 return 0;
108}
109
110static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
111 int value)
112{
113 void __iomem *base = ath79_gpio_base;
114 unsigned long flags;
115
116 spin_lock_irqsave(&ath79_gpio_lock, flags);
117
118 if (value)
119 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
120 else
121 __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
122
123 __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
124 base + AR71XX_GPIO_REG_OE);
125
126 spin_unlock_irqrestore(&ath79_gpio_lock, flags);
127
128 return 0;
129}
130
92static struct gpio_chip ath79_gpio_chip = { 131static struct gpio_chip ath79_gpio_chip = {
93 .label = "ath79", 132 .label = "ath79",
94 .get = ath79_gpio_get_value, 133 .get = ath79_gpio_get_value,
@@ -155,11 +194,17 @@ void __init ath79_gpio_init(void)
155 ath79_gpio_count = AR913X_GPIO_COUNT; 194 ath79_gpio_count = AR913X_GPIO_COUNT;
156 else if (soc_is_ar933x()) 195 else if (soc_is_ar933x())
157 ath79_gpio_count = AR933X_GPIO_COUNT; 196 ath79_gpio_count = AR933X_GPIO_COUNT;
197 else if (soc_is_ar934x())
198 ath79_gpio_count = AR934X_GPIO_COUNT;
158 else 199 else
159 BUG(); 200 BUG();
160 201
161 ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); 202 ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
162 ath79_gpio_chip.ngpio = ath79_gpio_count; 203 ath79_gpio_chip.ngpio = ath79_gpio_count;
204 if (soc_is_ar934x()) {
205 ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
206 ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
207 }
163 208
164 err = gpiochip_add(&ath79_gpio_chip); 209 err = gpiochip_add(&ath79_gpio_chip);
165 if (err) 210 if (err)
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 1b073de4468..90d09fc1539 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling 2 * Atheros AR71xx/AR724x/AR913x specific interrupt handling
3 * 3 *
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP 8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
@@ -23,8 +24,8 @@
23#include <asm/mach-ath79/ar71xx_regs.h> 24#include <asm/mach-ath79/ar71xx_regs.h>
24#include "common.h" 25#include "common.h"
25 26
26static unsigned int ath79_ip2_flush_reg; 27static void (*ath79_ip2_handler)(void);
27static unsigned int ath79_ip3_flush_reg; 28static void (*ath79_ip3_handler)(void);
28 29
29static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) 30static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
30{ 31{
@@ -129,7 +130,7 @@ static void __init ath79_misc_irq_init(void)
129 130
130 if (soc_is_ar71xx() || soc_is_ar913x()) 131 if (soc_is_ar71xx() || soc_is_ar913x())
131 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; 132 ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
132 else if (soc_is_ar724x() || soc_is_ar933x()) 133 else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x())
133 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; 134 ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
134 else 135 else
135 BUG(); 136 BUG();
@@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(void)
143 irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); 144 irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
144} 145}
145 146
147static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
148{
149 u32 status;
150
151 disable_irq_nosync(irq);
152
153 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
154
155 if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
156 ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE);
157 generic_handle_irq(ATH79_IP2_IRQ(0));
158 } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
159 ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC);
160 generic_handle_irq(ATH79_IP2_IRQ(1));
161 } else {
162 spurious_interrupt();
163 }
164
165 enable_irq(irq);
166}
167
168static void ar934x_ip2_irq_init(void)
169{
170 int i;
171
172 for (i = ATH79_IP2_IRQ_BASE;
173 i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
174 irq_set_chip_and_handler(i, &dummy_irq_chip,
175 handle_level_irq);
176
177 irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch);
178}
179
146asmlinkage void plat_irq_dispatch(void) 180asmlinkage void plat_irq_dispatch(void)
147{ 181{
148 unsigned long pending; 182 unsigned long pending;
@@ -152,10 +186,8 @@ asmlinkage void plat_irq_dispatch(void)
152 if (pending & STATUSF_IP7) 186 if (pending & STATUSF_IP7)
153 do_IRQ(ATH79_CPU_IRQ_TIMER); 187 do_IRQ(ATH79_CPU_IRQ_TIMER);
154 188
155 else if (pending & STATUSF_IP2) { 189 else if (pending & STATUSF_IP2)
156 ath79_ddr_wb_flush(ath79_ip2_flush_reg); 190 ath79_ip2_handler();
157 do_IRQ(ATH79_CPU_IRQ_IP2);
158 }
159 191
160 else if (pending & STATUSF_IP4) 192 else if (pending & STATUSF_IP4)
161 do_IRQ(ATH79_CPU_IRQ_GE0); 193 do_IRQ(ATH79_CPU_IRQ_GE0);
@@ -163,10 +195,8 @@ asmlinkage void plat_irq_dispatch(void)
163 else if (pending & STATUSF_IP5) 195 else if (pending & STATUSF_IP5)
164 do_IRQ(ATH79_CPU_IRQ_GE1); 196 do_IRQ(ATH79_CPU_IRQ_GE1);
165 197
166 else if (pending & STATUSF_IP3) { 198 else if (pending & STATUSF_IP3)
167 ath79_ddr_wb_flush(ath79_ip3_flush_reg); 199 ath79_ip3_handler();
168 do_IRQ(ATH79_CPU_IRQ_USB);
169 }
170 200
171 else if (pending & STATUSF_IP6) 201 else if (pending & STATUSF_IP6)
172 do_IRQ(ATH79_CPU_IRQ_MISC); 202 do_IRQ(ATH79_CPU_IRQ_MISC);
@@ -175,24 +205,97 @@ asmlinkage void plat_irq_dispatch(void)
175 spurious_interrupt(); 205 spurious_interrupt();
176} 206}
177 207
208/*
209 * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
210 * these devices typically allocate coherent DMA memory, however the
211 * DMA controller may still have some unsynchronized data in the FIFO.
212 * Issue a flush in the handlers to ensure that the driver sees
213 * the update.
214 */
215static void ar71xx_ip2_handler(void)
216{
217 ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
218 do_IRQ(ATH79_CPU_IRQ_IP2);
219}
220
221static void ar724x_ip2_handler(void)
222{
223 ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
224 do_IRQ(ATH79_CPU_IRQ_IP2);
225}
226
227static void ar913x_ip2_handler(void)
228{
229 ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
230 do_IRQ(ATH79_CPU_IRQ_IP2);
231}
232
233static void ar933x_ip2_handler(void)
234{
235 ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
236 do_IRQ(ATH79_CPU_IRQ_IP2);
237}
238
239static void ar934x_ip2_handler(void)
240{
241 do_IRQ(ATH79_CPU_IRQ_IP2);
242}
243
244static void ar71xx_ip3_handler(void)
245{
246 ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
247 do_IRQ(ATH79_CPU_IRQ_USB);
248}
249
250static void ar724x_ip3_handler(void)
251{
252 ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
253 do_IRQ(ATH79_CPU_IRQ_USB);
254}
255
256static void ar913x_ip3_handler(void)
257{
258 ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
259 do_IRQ(ATH79_CPU_IRQ_USB);
260}
261
262static void ar933x_ip3_handler(void)
263{
264 ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
265 do_IRQ(ATH79_CPU_IRQ_USB);
266}
267
268static void ar934x_ip3_handler(void)
269{
270 ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB);
271 do_IRQ(ATH79_CPU_IRQ_USB);
272}
273
178void __init arch_init_irq(void) 274void __init arch_init_irq(void)
179{ 275{
180 if (soc_is_ar71xx()) { 276 if (soc_is_ar71xx()) {
181 ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; 277 ath79_ip2_handler = ar71xx_ip2_handler;
182 ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; 278 ath79_ip3_handler = ar71xx_ip3_handler;
183 } else if (soc_is_ar724x()) { 279 } else if (soc_is_ar724x()) {
184 ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; 280 ath79_ip2_handler = ar724x_ip2_handler;
185 ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; 281 ath79_ip3_handler = ar724x_ip3_handler;
186 } else if (soc_is_ar913x()) { 282 } else if (soc_is_ar913x()) {
187 ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; 283 ath79_ip2_handler = ar913x_ip2_handler;
188 ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; 284 ath79_ip3_handler = ar913x_ip3_handler;
189 } else if (soc_is_ar933x()) { 285 } else if (soc_is_ar933x()) {
190 ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC; 286 ath79_ip2_handler = ar933x_ip2_handler;
191 ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB; 287 ath79_ip3_handler = ar933x_ip3_handler;
192 } else 288 } else if (soc_is_ar934x()) {
289 ath79_ip2_handler = ar934x_ip2_handler;
290 ath79_ip3_handler = ar934x_ip3_handler;
291 } else {
193 BUG(); 292 BUG();
293 }
194 294
195 cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; 295 cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
196 mips_cpu_irq_init(); 296 mips_cpu_irq_init();
197 ath79_misc_irq_init(); 297 ath79_misc_irq_init();
298
299 if (soc_is_ar934x())
300 ar934x_ip2_irq_init();
198} 301}
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c
new file mode 100644
index 00000000000..1983e4d2af4
--- /dev/null
+++ b/arch/mips/ath79/mach-db120.c
@@ -0,0 +1,134 @@
1/*
2 * Atheros DB120 reference board support
3 *
4 * Copyright (c) 2011 Qualcomm Atheros
5 * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21#include <linux/pci.h>
22#include <linux/ath9k_platform.h>
23
24#include "machtypes.h"
25#include "dev-gpio-buttons.h"
26#include "dev-leds-gpio.h"
27#include "dev-spi.h"
28#include "dev-wmac.h"
29#include "pci.h"
30
31#define DB120_GPIO_LED_WLAN_5G 12
32#define DB120_GPIO_LED_WLAN_2G 13
33#define DB120_GPIO_LED_STATUS 14
34#define DB120_GPIO_LED_WPS 15
35
36#define DB120_GPIO_BTN_WPS 16
37
38#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
39#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
40
41#define DB120_WMAC_CALDATA_OFFSET 0x1000
42#define DB120_PCIE_CALDATA_OFFSET 0x5000
43
44static struct gpio_led db120_leds_gpio[] __initdata = {
45 {
46 .name = "db120:green:status",
47 .gpio = DB120_GPIO_LED_STATUS,
48 .active_low = 1,
49 },
50 {
51 .name = "db120:green:wps",
52 .gpio = DB120_GPIO_LED_WPS,
53 .active_low = 1,
54 },
55 {
56 .name = "db120:green:wlan-5g",
57 .gpio = DB120_GPIO_LED_WLAN_5G,
58 .active_low = 1,
59 },
60 {
61 .name = "db120:green:wlan-2g",
62 .gpio = DB120_GPIO_LED_WLAN_2G,
63 .active_low = 1,
64 },
65};
66
67static struct gpio_keys_button db120_gpio_keys[] __initdata = {
68 {
69 .desc = "WPS button",
70 .type = EV_KEY,
71 .code = KEY_WPS_BUTTON,
72 .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
73 .gpio = DB120_GPIO_BTN_WPS,
74 .active_low = 1,
75 },
76};
77
78static struct spi_board_info db120_spi_info[] = {
79 {
80 .bus_num = 0,
81 .chip_select = 0,
82 .max_speed_hz = 25000000,
83 .modalias = "s25sl064a",
84 }
85};
86
87static struct ath79_spi_platform_data db120_spi_data = {
88 .bus_num = 0,
89 .num_chipselect = 1,
90};
91
92#ifdef CONFIG_PCI
93static struct ath9k_platform_data db120_ath9k_data;
94
95static int db120_pci_plat_dev_init(struct pci_dev *dev)
96{
97 switch (PCI_SLOT(dev->devfn)) {
98 case 0:
99 dev->dev.platform_data = &db120_ath9k_data;
100 break;
101 }
102
103 return 0;
104}
105
106static void __init db120_pci_init(u8 *eeprom)
107{
108 memcpy(db120_ath9k_data.eeprom_data, eeprom,
109 sizeof(db120_ath9k_data.eeprom_data));
110
111 ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
112 ath79_register_pci();
113}
114#else
115static inline void db120_pci_init(void) {}
116#endif /* CONFIG_PCI */
117
118static void __init db120_setup(void)
119{
120 u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
121
122 ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
123 db120_leds_gpio);
124 ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
125 ARRAY_SIZE(db120_gpio_keys),
126 db120_gpio_keys);
127 ath79_register_spi(&db120_spi_data, db120_spi_info,
128 ARRAY_SIZE(db120_spi_info));
129 ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
130 db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
131}
132
133MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
134 db120_setup);
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index fe9701a3229..c5f0ea5e00c 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -19,6 +19,7 @@
19#include "dev-leds-gpio.h" 19#include "dev-leds-gpio.h"
20#include "dev-spi.h" 20#include "dev-spi.h"
21#include "dev-usb.h" 21#include "dev-usb.h"
22#include "pci.h"
22 23
23#define PB44_GPIO_I2C_SCL 0 24#define PB44_GPIO_I2C_SCL 0
24#define PB44_GPIO_I2C_SDA 1 25#define PB44_GPIO_I2C_SDA 1
@@ -114,6 +115,7 @@ static void __init pb44_init(void)
114 ath79_register_spi(&pb44_spi_data, pb44_spi_info, 115 ath79_register_spi(&pb44_spi_data, pb44_spi_info,
115 ARRAY_SIZE(pb44_spi_info)); 116 ARRAY_SIZE(pb44_spi_info));
116 ath79_register_usb(); 117 ath79_register_usb();
118 ath79_register_pci();
117} 119}
118 120
119MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", 121MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
index 3c311a53934..4a3c60694c7 100644
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -12,16 +12,15 @@
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15
16#ifdef CONFIG_PCI
17#include <linux/ath9k_platform.h> 15#include <linux/ath9k_platform.h>
18#include <asm/mach-ath79/pci-ath724x.h> 16
19#endif /* CONFIG_PCI */ 17#include <asm/mach-ath79/irq.h>
20 18
21#include "machtypes.h" 19#include "machtypes.h"
22#include "dev-gpio-buttons.h" 20#include "dev-gpio-buttons.h"
23#include "dev-leds-gpio.h" 21#include "dev-leds-gpio.h"
24#include "dev-spi.h" 22#include "dev-spi.h"
23#include "pci.h"
25 24
26#define UBNT_XM_GPIO_LED_L1 0 25#define UBNT_XM_GPIO_LED_L1 0
27#define UBNT_XM_GPIO_LED_L2 1 26#define UBNT_XM_GPIO_LED_L2 1
@@ -33,7 +32,6 @@
33#define UBNT_XM_KEYS_POLL_INTERVAL 20 32#define UBNT_XM_KEYS_POLL_INTERVAL 20
34#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) 33#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
35 34
36#define UBNT_XM_PCI_IRQ 48
37#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) 35#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
38 36
39static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { 37static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
@@ -84,12 +82,27 @@ static struct ath79_spi_platform_data ubnt_xm_spi_data = {
84#ifdef CONFIG_PCI 82#ifdef CONFIG_PCI
85static struct ath9k_platform_data ubnt_xm_eeprom_data; 83static struct ath9k_platform_data ubnt_xm_eeprom_data;
86 84
87static struct ath724x_pci_data ubnt_xm_pci_data[] = { 85static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
88 { 86{
89 .irq = UBNT_XM_PCI_IRQ, 87 switch (PCI_SLOT(dev->devfn)) {
90 .pdata = &ubnt_xm_eeprom_data, 88 case 0:
91 }, 89 dev->dev.platform_data = &ubnt_xm_eeprom_data;
92}; 90 break;
91 }
92
93 return 0;
94}
95
96static void __init ubnt_xm_pci_init(void)
97{
98 memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
99 sizeof(ubnt_xm_eeprom_data.eeprom_data));
100
101 ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
102 ath79_register_pci();
103}
104#else
105static inline void ubnt_xm_pci_init(void) {}
93#endif /* CONFIG_PCI */ 106#endif /* CONFIG_PCI */
94 107
95static void __init ubnt_xm_init(void) 108static void __init ubnt_xm_init(void)
@@ -104,13 +117,7 @@ static void __init ubnt_xm_init(void)
104 ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, 117 ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
105 ARRAY_SIZE(ubnt_xm_spi_info)); 118 ARRAY_SIZE(ubnt_xm_spi_info));
106 119
107#ifdef CONFIG_PCI 120 ubnt_xm_pci_init();
108 memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
109 sizeof(ubnt_xm_eeprom_data.eeprom_data));
110
111 ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
112#endif /* CONFIG_PCI */
113
114} 121}
115 122
116MIPS_MACHINE(ATH79_MACH_UBNT_XM, 123MIPS_MACHINE(ATH79_MACH_UBNT_XM,
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index 9a1f3826626..af92e5c30d6 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -18,6 +18,7 @@ enum ath79_mach_type {
18 ATH79_MACH_GENERIC = 0, 18 ATH79_MACH_GENERIC = 0,
19 ATH79_MACH_AP121, /* Atheros AP121 reference board */ 19 ATH79_MACH_AP121, /* Atheros AP121 reference board */
20 ATH79_MACH_AP81, /* Atheros AP81 reference board */ 20 ATH79_MACH_AP81, /* Atheros AP81 reference board */
21 ATH79_MACH_DB120, /* Atheros DB120 reference board */
21 ATH79_MACH_PB44, /* Atheros PB44 reference board */ 22 ATH79_MACH_PB44, /* Atheros PB44 reference board */
22 ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ 23 ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
23}; 24};
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
new file mode 100644
index 00000000000..ca83abd9d31
--- /dev/null
+++ b/arch/mips/ath79/pci.c
@@ -0,0 +1,130 @@
1/*
2 * Atheros AR71XX/AR724X specific PCI setup code
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * Parts of this file are based on Atheros' 2.6.15 BSP
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <asm/mach-ath79/ar71xx_regs.h>
18#include <asm/mach-ath79/ath79.h>
19#include <asm/mach-ath79/irq.h>
20#include <asm/mach-ath79/pci.h>
21#include "pci.h"
22
23static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
24static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
25static unsigned ath79_pci_nr_irqs __initdata;
26
27static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = {
28 {
29 .slot = 17,
30 .pin = 1,
31 .irq = ATH79_PCI_IRQ(0),
32 }, {
33 .slot = 18,
34 .pin = 1,
35 .irq = ATH79_PCI_IRQ(1),
36 }, {
37 .slot = 19,
38 .pin = 1,
39 .irq = ATH79_PCI_IRQ(2),
40 }
41};
42
43static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = {
44 {
45 .slot = 0,
46 .pin = 1,
47 .irq = ATH79_PCI_IRQ(0),
48 }
49};
50
51int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
52{
53 int irq = -1;
54 int i;
55
56 if (ath79_pci_nr_irqs == 0 ||
57 ath79_pci_irq_map == NULL) {
58 if (soc_is_ar71xx()) {
59 ath79_pci_irq_map = ar71xx_pci_irq_map;
60 ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
61 } else if (soc_is_ar724x() ||
62 soc_is_ar9342() ||
63 soc_is_ar9344()) {
64 ath79_pci_irq_map = ar724x_pci_irq_map;
65 ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
66 } else {
67 pr_crit("pci %s: invalid irq map\n",
68 pci_name((struct pci_dev *) dev));
69 return irq;
70 }
71 }
72
73 for (i = 0; i < ath79_pci_nr_irqs; i++) {
74 const struct ath79_pci_irq *entry;
75
76 entry = &ath79_pci_irq_map[i];
77 if (entry->slot == slot && entry->pin == pin) {
78 irq = entry->irq;
79 break;
80 }
81 }
82
83 if (irq < 0)
84 pr_crit("pci %s: no irq found for pin %u\n",
85 pci_name((struct pci_dev *) dev), pin);
86 else
87 pr_info("pci %s: using irq %d for pin %u\n",
88 pci_name((struct pci_dev *) dev), irq, pin);
89
90 return irq;
91}
92
93int pcibios_plat_dev_init(struct pci_dev *dev)
94{
95 if (ath79_pci_plat_dev_init)
96 return ath79_pci_plat_dev_init(dev);
97
98 return 0;
99}
100
101void __init ath79_pci_set_irq_map(unsigned nr_irqs,
102 const struct ath79_pci_irq *map)
103{
104 ath79_pci_nr_irqs = nr_irqs;
105 ath79_pci_irq_map = map;
106}
107
108void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
109{
110 ath79_pci_plat_dev_init = func;
111}
112
113int __init ath79_register_pci(void)
114{
115 if (soc_is_ar71xx())
116 return ar71xx_pcibios_init();
117
118 if (soc_is_ar724x())
119 return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
120
121 if (soc_is_ar9342() || soc_is_ar9344()) {
122 u32 bootstrap;
123
124 bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
125 if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC)
126 return ar724x_pcibios_init(ATH79_IP2_IRQ(0));
127 }
128
129 return -ENODEV;
130}
diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
new file mode 100644
index 00000000000..51c6625dcc6
--- /dev/null
+++ b/arch/mips/ath79/pci.h
@@ -0,0 +1,34 @@
1/*
2 * Atheros AR71XX/AR724X PCI support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#ifndef _ATH79_PCI_H
14#define _ATH79_PCI_H
15
16struct ath79_pci_irq {
17 u8 slot;
18 u8 pin;
19 int irq;
20};
21
22#ifdef CONFIG_PCI
23void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
24void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
25int ath79_register_pci(void);
26#else
27static inline void
28ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
29static inline void
30ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
31static inline int ath79_register_pci(void) { return 0; }
32#endif
33
34#endif /* _ATH79_PCI_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 80a7d4023d7..60d212ef862 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X specific setup 2 * Atheros AR71XX/AR724X/AR913X specific setup
3 * 3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP 8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
@@ -116,18 +117,6 @@ static void __init ath79_detect_sys_type(void)
116 rev = id & AR724X_REV_ID_REVISION_MASK; 117 rev = id & AR724X_REV_ID_REVISION_MASK;
117 break; 118 break;
118 119
119 case REV_ID_MAJOR_AR9330:
120 ath79_soc = ATH79_SOC_AR9330;
121 chip = "9330";
122 rev = id & AR933X_REV_ID_REVISION_MASK;
123 break;
124
125 case REV_ID_MAJOR_AR9331:
126 ath79_soc = ATH79_SOC_AR9331;
127 chip = "9331";
128 rev = id & AR933X_REV_ID_REVISION_MASK;
129 break;
130
131 case REV_ID_MAJOR_AR913X: 120 case REV_ID_MAJOR_AR913X:
132 minor = id & AR913X_REV_ID_MINOR_MASK; 121 minor = id & AR913X_REV_ID_MINOR_MASK;
133 rev = id >> AR913X_REV_ID_REVISION_SHIFT; 122 rev = id >> AR913X_REV_ID_REVISION_SHIFT;
@@ -145,6 +134,36 @@ static void __init ath79_detect_sys_type(void)
145 } 134 }
146 break; 135 break;
147 136
137 case REV_ID_MAJOR_AR9330:
138 ath79_soc = ATH79_SOC_AR9330;
139 chip = "9330";
140 rev = id & AR933X_REV_ID_REVISION_MASK;
141 break;
142
143 case REV_ID_MAJOR_AR9331:
144 ath79_soc = ATH79_SOC_AR9331;
145 chip = "9331";
146 rev = id & AR933X_REV_ID_REVISION_MASK;
147 break;
148
149 case REV_ID_MAJOR_AR9341:
150 ath79_soc = ATH79_SOC_AR9341;
151 chip = "9341";
152 rev = id & AR934X_REV_ID_REVISION_MASK;
153 break;
154
155 case REV_ID_MAJOR_AR9342:
156 ath79_soc = ATH79_SOC_AR9342;
157 chip = "9342";
158 rev = id & AR934X_REV_ID_REVISION_MASK;
159 break;
160
161 case REV_ID_MAJOR_AR9344:
162 ath79_soc = ATH79_SOC_AR9344;
163 chip = "9344";
164 rev = id & AR934X_REV_ID_REVISION_MASK;
165 break;
166
148 default: 167 default:
149 panic("ath79: unknown SoC, id:0x%08x", id); 168 panic("ath79: unknown SoC, id:0x%08x", id);
150 } 169 }
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
index 9f64fb41407..af07c1aa202 100644
--- a/arch/mips/bcm63xx/boards/Makefile
+++ b/arch/mips/bcm63xx/boards/Makefile
@@ -1,3 +1 @@
1obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
2
3ccflags-y := -Werror
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index d3a9f012aa0..260dc247c05 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -9,6 +9,7 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/console.h> 10#include <linux/console.h>
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/export.h>
12#include <linux/interrupt.h> 13#include <linux/interrupt.h>
13#include <linux/io.h> 14#include <linux/io.h>
14#include <linux/serial.h> 15#include <linux/serial.h>
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 97e7ce9b50e..4b93048044e 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -257,8 +257,6 @@ DEFINE_PER_CPU(int, cpu_state);
257 257
258extern void fixup_irqs(void); 258extern void fixup_irqs(void);
259 259
260static DEFINE_SPINLOCK(smp_reserve_lock);
261
262static int octeon_cpu_disable(void) 260static int octeon_cpu_disable(void)
263{ 261{
264 unsigned int cpu = smp_processor_id(); 262 unsigned int cpu = smp_processor_id();
@@ -266,8 +264,6 @@ static int octeon_cpu_disable(void)
266 if (cpu == 0) 264 if (cpu == 0)
267 return -EBUSY; 265 return -EBUSY;
268 266
269 spin_lock(&smp_reserve_lock);
270
271 set_cpu_online(cpu, false); 267 set_cpu_online(cpu, false);
272 cpu_clear(cpu, cpu_callin_map); 268 cpu_clear(cpu, cpu_callin_map);
273 local_irq_disable(); 269 local_irq_disable();
@@ -277,8 +273,6 @@ static int octeon_cpu_disable(void)
277 flush_cache_all(); 273 flush_cache_all();
278 local_flush_tlb_all(); 274 local_flush_tlb_all();
279 275
280 spin_unlock(&smp_reserve_lock);
281
282 return 0; 276 return 0;
283} 277}
284 278
diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile
index 5314b37aff2..4f349ec1ea2 100644
--- a/arch/mips/fw/arc/Makefile
+++ b/arch/mips/fw/arc/Makefile
@@ -8,5 +8,3 @@ lib-y += cmdline.o env.o file.o identify.o init.o \
8lib-$(CONFIG_ARC_MEMORY) += memory.o 8lib-$(CONFIG_ARC_MEMORY) += memory.o
9lib-$(CONFIG_ARC_CONSOLE) += arc_con.o 9lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
10lib-$(CONFIG_ARC_PROMLIB) += promlib.o 10lib-$(CONFIG_ARC_PROMLIB) += promlib.o
11
12ccflags-y := -Werror
diff --git a/arch/mips/include/asm/clkdev.h b/arch/mips/include/asm/clkdev.h
new file mode 100644
index 00000000000..262475414e5
--- /dev/null
+++ b/arch/mips/include/asm/clkdev.h
@@ -0,0 +1,25 @@
1/*
2 * based on arch/arm/include/asm/clkdev.h
3 *
4 * Copyright (C) 2008 Russell King.
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 * Helper for the clk API to assist looking up a struct clk.
11 */
12#ifndef __ASM_CLKDEV_H
13#define __ASM_CLKDEV_H
14
15#include <linux/slab.h>
16
17#define __clk_get(clk) ({ 1; })
18#define __clk_put(clk) do { } while (0)
19
20static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
21{
22 return kzalloc(size, GFP_KERNEL);
23}
24
25#endif
diff --git a/arch/mips/include/asm/kvm_para.h b/arch/mips/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/mips/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 2f0becb4ec8..1caa78ad06d 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -1,10 +1,11 @@
1/* 1/*
2 * Atheros AR71XX/AR724X/AR913X SoC register definitions 2 * Atheros AR71XX/AR724X/AR913X SoC register definitions
3 * 3 *
4 * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
4 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> 5 * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> 6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 * 7 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP 8 * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
8 * 9 *
9 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published 11 * under the terms of the GNU General Public License version 2 as published
@@ -60,6 +61,9 @@
60#define AR933X_EHCI_BASE 0x1b000000 61#define AR933X_EHCI_BASE 0x1b000000
61#define AR933X_EHCI_SIZE 0x1000 62#define AR933X_EHCI_SIZE 0x1000
62 63
64#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
65#define AR934X_WMAC_SIZE 0x20000
66
63/* 67/*
64 * DDR_CTRL block 68 * DDR_CTRL block
65 */ 69 */
@@ -91,6 +95,12 @@
91#define AR933X_DDR_REG_FLUSH_USB 0x84 95#define AR933X_DDR_REG_FLUSH_USB 0x84
92#define AR933X_DDR_REG_FLUSH_WMAC 0x88 96#define AR933X_DDR_REG_FLUSH_WMAC 0x88
93 97
98#define AR934X_DDR_REG_FLUSH_GE0 0x9c
99#define AR934X_DDR_REG_FLUSH_GE1 0xa0
100#define AR934X_DDR_REG_FLUSH_USB 0xa4
101#define AR934X_DDR_REG_FLUSH_PCIE 0xa8
102#define AR934X_DDR_REG_FLUSH_WMAC 0xac
103
94/* 104/*
95 * PLL block 105 * PLL block
96 */ 106 */
@@ -150,6 +160,41 @@
150#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 160#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
151#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 161#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
152 162
163#define AR934X_PLL_CPU_CONFIG_REG 0x00
164#define AR934X_PLL_DDR_CONFIG_REG 0x04
165#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
166
167#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
168#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
169#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6
170#define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f
171#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
172#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
173#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
174#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3
175
176#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
177#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
178#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10
179#define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f
180#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
181#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
182#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
183#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
184
185#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
186#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
187#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
188#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5
189#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
190#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10
191#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
192#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15
193#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
194#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
195#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
196#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
197
153/* 198/*
154 * USB_CONFIG block 199 * USB_CONFIG block
155 */ 200 */
@@ -185,6 +230,10 @@
185#define AR933X_RESET_REG_RESET_MODULE 0x1c 230#define AR933X_RESET_REG_RESET_MODULE 0x1c
186#define AR933X_RESET_REG_BOOTSTRAP 0xac 231#define AR933X_RESET_REG_BOOTSTRAP 0xac
187 232
233#define AR934X_RESET_REG_RESET_MODULE 0x1c
234#define AR934X_RESET_REG_BOOTSTRAP 0xb0
235#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac
236
188#define MISC_INT_ETHSW BIT(12) 237#define MISC_INT_ETHSW BIT(12)
189#define MISC_INT_TIMER4 BIT(10) 238#define MISC_INT_TIMER4 BIT(10)
190#define MISC_INT_TIMER3 BIT(9) 239#define MISC_INT_TIMER3 BIT(9)
@@ -241,6 +290,40 @@
241 290
242#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) 291#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
243 292
293#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23)
294#define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22)
295#define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21)
296#define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20)
297#define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19)
298#define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18)
299#define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17)
300#define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16)
301#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7)
302#define AR934X_BOOTSTRAP_PCIE_RC BIT(6)
303#define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5)
304#define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4)
305#define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2)
306#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
307#define AR934X_BOOTSTRAP_DDR1 BIT(0)
308
309#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0)
310#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1)
311#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2)
312#define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3)
313#define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4)
314#define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5)
315#define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6)
316#define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7)
317#define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8)
318#define AR934X_PCIE_WMAC_INT_WMAC_ALL \
319 (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \
320 AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP)
321
322#define AR934X_PCIE_WMAC_INT_PCIE_ALL \
323 (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \
324 AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
325 AR934X_PCIE_WMAC_INT_PCIE_RC3)
326
244#define REV_ID_MAJOR_MASK 0xfff0 327#define REV_ID_MAJOR_MASK 0xfff0
245#define REV_ID_MAJOR_AR71XX 0x00a0 328#define REV_ID_MAJOR_AR71XX 0x00a0
246#define REV_ID_MAJOR_AR913X 0x00b0 329#define REV_ID_MAJOR_AR913X 0x00b0
@@ -249,6 +332,9 @@
249#define REV_ID_MAJOR_AR7242 0x1100 332#define REV_ID_MAJOR_AR7242 0x1100
250#define REV_ID_MAJOR_AR9330 0x0110 333#define REV_ID_MAJOR_AR9330 0x0110
251#define REV_ID_MAJOR_AR9331 0x1110 334#define REV_ID_MAJOR_AR9331 0x1110
335#define REV_ID_MAJOR_AR9341 0x0120
336#define REV_ID_MAJOR_AR9342 0x1120
337#define REV_ID_MAJOR_AR9344 0x2120
252 338
253#define AR71XX_REV_ID_MINOR_MASK 0x3 339#define AR71XX_REV_ID_MINOR_MASK 0x3
254#define AR71XX_REV_ID_MINOR_AR7130 0x0 340#define AR71XX_REV_ID_MINOR_AR7130 0x0
@@ -267,6 +353,8 @@
267 353
268#define AR724X_REV_ID_REVISION_MASK 0x3 354#define AR724X_REV_ID_REVISION_MASK 0x3
269 355
356#define AR934X_REV_ID_REVISION_MASK 0xf
357
270/* 358/*
271 * SPI block 359 * SPI block
272 */ 360 */
@@ -308,5 +396,6 @@
308#define AR724X_GPIO_COUNT 18 396#define AR724X_GPIO_COUNT 18
309#define AR913X_GPIO_COUNT 22 397#define AR913X_GPIO_COUNT 22
310#define AR933X_GPIO_COUNT 30 398#define AR933X_GPIO_COUNT 30
399#define AR934X_GPIO_COUNT 23
311 400
312#endif /* __ASM_MACH_AR71XX_REGS_H */ 401#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 6d0c6c9d562..4f248c3d7b2 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -29,6 +29,9 @@ enum ath79_soc_type {
29 ATH79_SOC_AR9132, 29 ATH79_SOC_AR9132,
30 ATH79_SOC_AR9330, 30 ATH79_SOC_AR9330,
31 ATH79_SOC_AR9331, 31 ATH79_SOC_AR9331,
32 ATH79_SOC_AR9341,
33 ATH79_SOC_AR9342,
34 ATH79_SOC_AR9344,
32}; 35};
33 36
34extern enum ath79_soc_type ath79_soc; 37extern enum ath79_soc_type ath79_soc;
@@ -75,6 +78,26 @@ static inline int soc_is_ar933x(void)
75 ath79_soc == ATH79_SOC_AR9331); 78 ath79_soc == ATH79_SOC_AR9331);
76} 79}
77 80
81static inline int soc_is_ar9341(void)
82{
83 return (ath79_soc == ATH79_SOC_AR9341);
84}
85
86static inline int soc_is_ar9342(void)
87{
88 return (ath79_soc == ATH79_SOC_AR9342);
89}
90
91static inline int soc_is_ar9344(void)
92{
93 return (ath79_soc == ATH79_SOC_AR9344);
94}
95
96static inline int soc_is_ar934x(void)
97{
98 return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
99}
100
78extern void __iomem *ath79_ddr_base; 101extern void __iomem *ath79_ddr_base;
79extern void __iomem *ath79_pll_base; 102extern void __iomem *ath79_pll_base;
80extern void __iomem *ath79_reset_base; 103extern void __iomem *ath79_reset_base;
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
index 519958fe4e3..0968f69e201 100644
--- a/arch/mips/include/asm/mach-ath79/irq.h
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -10,11 +10,19 @@
10#define __ASM_MACH_ATH79_IRQ_H 10#define __ASM_MACH_ATH79_IRQ_H
11 11
12#define MIPS_CPU_IRQ_BASE 0 12#define MIPS_CPU_IRQ_BASE 0
13#define NR_IRQS 40 13#define NR_IRQS 48
14 14
15#define ATH79_MISC_IRQ_BASE 8 15#define ATH79_MISC_IRQ_BASE 8
16#define ATH79_MISC_IRQ_COUNT 32 16#define ATH79_MISC_IRQ_COUNT 32
17 17
18#define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
19#define ATH79_PCI_IRQ_COUNT 6
20#define ATH79_PCI_IRQ(_x) (ATH79_PCI_IRQ_BASE + (_x))
21
22#define ATH79_IP2_IRQ_BASE (ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT)
23#define ATH79_IP2_IRQ_COUNT 2
24#define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x))
25
18#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) 26#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
19#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) 27#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
20#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) 28#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4)
diff --git a/arch/mips/include/asm/mach-ath79/pci-ath724x.h b/arch/mips/include/asm/mach-ath79/pci-ath724x.h
deleted file mode 100644
index 454885fa30c..00000000000
--- a/arch/mips/include/asm/mach-ath79/pci-ath724x.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * Atheros 724x PCI support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
12#define __ASM_MACH_ATH79_PCI_ATH724X_H
13
14struct ath724x_pci_data {
15 int irq;
16 void *pdata;
17};
18
19void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
20
21#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
new file mode 100644
index 00000000000..7868f7fa028
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/pci.h
@@ -0,0 +1,28 @@
1/*
2 * Atheros AR71XX/AR724X PCI support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 as published
10 * by the Free Software Foundation.
11 */
12
13#ifndef __ASM_MACH_ATH79_PCI_H
14#define __ASM_MACH_ATH79_PCI_H
15
16#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX)
17int ar71xx_pcibios_init(void);
18#else
19static inline int ar71xx_pcibios_init(void) { return 0; }
20#endif
21
22#if defined(CONFIG_PCI_AR724X)
23int ar724x_pcibios_init(int irq);
24#else
25static inline int ar724x_pcibios_init(int irq) { return 0; }
26#endif
27
28#endif /* __ASM_MACH_ATH79_PCI_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
index 3d5de96d403..1d7dd96aa46 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -2,6 +2,7 @@
2#define BCM63XX_GPIO_H 2#define BCM63XX_GPIO_H
3 3
4#include <linux/init.h> 4#include <linux/init.h>
5#include <bcm63xx_cpu.h>
5 6
6int __init bcm63xx_gpio_init(void); 7int __init bcm63xx_gpio_init(void);
7 8
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
new file mode 100644
index 00000000000..318f982f04f
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
@@ -0,0 +1,23 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
7 */
8
9#ifndef _FALCON_IRQ__
10#define _FALCON_IRQ__
11
12#define INT_NUM_IRQ0 8
13#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
14#define INT_NUM_IM1_IRL0 (INT_NUM_IM0_IRL0 + 32)
15#define INT_NUM_IM2_IRL0 (INT_NUM_IM1_IRL0 + 32)
16#define INT_NUM_IM3_IRL0 (INT_NUM_IM2_IRL0 + 32)
17#define INT_NUM_IM4_IRL0 (INT_NUM_IM3_IRL0 + 32)
18#define INT_NUM_EXTRA_START (INT_NUM_IM4_IRL0 + 32)
19#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
20
21#define MIPS_CPU_TIMER_IRQ 7
22
23#endif /* _FALCON_IRQ__ */
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/irq.h b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
new file mode 100644
index 00000000000..2caccd9f9db
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/falcon/irq.h
@@ -0,0 +1,18 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
7 */
8
9#ifndef __FALCON_IRQ_H
10#define __FALCON_IRQ_H
11
12#include <falcon_irq.h>
13
14#define NR_IRQS 328
15
16#include_next <irq.h>
17
18#endif
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
new file mode 100644
index 00000000000..b385252584e
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -0,0 +1,67 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _LTQ_FALCON_H__
10#define _LTQ_FALCON_H__
11
12#ifdef CONFIG_SOC_FALCON
13
14#include <linux/pinctrl/pinctrl.h>
15#include <lantiq.h>
16
17/* Chip IDs */
18#define SOC_ID_FALCON 0x01B8
19
20/* SoC Types */
21#define SOC_TYPE_FALCON 0x01
22
23/*
24 * during early_printk no ioremap possible at this early stage
25 * lets use KSEG1 instead
26 */
27#define LTQ_ASC0_BASE_ADDR 0x1E100C00
28#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC0_BASE_ADDR)
29
30/* WDT */
31#define LTQ_RST_CAUSE_WDTRST 0x0002
32
33/* CHIP ID */
34#define LTQ_STATUS_BASE_ADDR 0x1E802000
35
36#define FALCON_CHIPID ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x0c))
37#define FALCON_CHIPTYPE ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x38))
38#define FALCON_CHIPCONF ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x40))
39
40/* SYSCTL - start/stop/restart/configure/... different parts of the Soc */
41#define SYSCTL_SYS1 0
42#define SYSCTL_SYSETH 1
43#define SYSCTL_SYSGPE 2
44
45/* BOOT_SEL - find what boot media we have */
46#define BS_FLASH 0x1
47#define BS_SPI 0x4
48
49/* global register ranges */
50extern __iomem void *ltq_ebu_membase;
51extern __iomem void *ltq_sys1_membase;
52#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
53#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
54
55#define ltq_sys1_w32(x, y) ltq_w32((x), ltq_sys1_membase + (y))
56#define ltq_sys1_r32(x) ltq_r32(ltq_sys1_membase + (x))
57#define ltq_sys1_w32_mask(clear, set, reg) \
58 ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
59
60/*
61 * to keep the irq code generic we need to define this to 0 as falcon
62 * has no EIU/EBU
63 */
64#define LTQ_EBU_PCC_ISTAT 0
65
66#endif /* CONFIG_SOC_FALCON */
67#endif /* _LTQ_XWAY_H__ */
diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h
new file mode 100644
index 00000000000..f79505b4360
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/gpio.h
@@ -0,0 +1,16 @@
1#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
2#define __ASM_MIPS_MACH_LANTIQ_GPIO_H
3
4static inline int gpio_to_irq(unsigned int gpio)
5{
6 return -1;
7}
8
9#define gpio_get_value __gpio_get_value
10#define gpio_set_value __gpio_set_value
11
12#define gpio_cansleep __gpio_cansleep
13
14#include <asm-generic/gpio.h>
15
16#endif
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
index ce2f02929d2..5e8a6e96575 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -9,6 +9,8 @@
9#define _LANTIQ_H__ 9#define _LANTIQ_H__
10 10
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/device.h>
13#include <linux/clk.h>
12 14
13/* generic reg access functions */ 15/* generic reg access functions */
14#define ltq_r32(reg) __raw_readl(reg) 16#define ltq_r32(reg) __raw_readl(reg)
@@ -21,25 +23,9 @@
21/* register access macros for EBU and CGU */ 23/* register access macros for EBU and CGU */
22#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) 24#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
23#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) 25#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
24#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y)) 26#define ltq_ebu_w32_mask(x, y, z) \
25#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x)) 27 ltq_w32_mask(x, y, ltq_ebu_membase + (z))
26
27extern __iomem void *ltq_ebu_membase; 28extern __iomem void *ltq_ebu_membase;
28extern __iomem void *ltq_cgu_membase;
29
30extern unsigned int ltq_get_cpu_ver(void);
31extern unsigned int ltq_get_soc_type(void);
32
33/* clock speeds */
34#define CLOCK_60M 60000000
35#define CLOCK_83M 83333333
36#define CLOCK_111M 111111111
37#define CLOCK_133M 133333333
38#define CLOCK_167M 166666667
39#define CLOCK_200M 200000000
40#define CLOCK_266M 266666666
41#define CLOCK_333M 333333333
42#define CLOCK_400M 400000000
43 29
44/* spinlock all ebu i/o */ 30/* spinlock all ebu i/o */
45extern spinlock_t ebu_lock; 31extern spinlock_t ebu_lock;
@@ -49,15 +35,21 @@ extern void ltq_disable_irq(struct irq_data *data);
49extern void ltq_mask_and_ack_irq(struct irq_data *data); 35extern void ltq_mask_and_ack_irq(struct irq_data *data);
50extern void ltq_enable_irq(struct irq_data *data); 36extern void ltq_enable_irq(struct irq_data *data);
51 37
38/* clock handling */
39extern int clk_activate(struct clk *clk);
40extern void clk_deactivate(struct clk *clk);
41extern struct clk *clk_get_cpu(void);
42extern struct clk *clk_get_fpi(void);
43extern struct clk *clk_get_io(void);
44
45/* find out what bootsource we have */
46extern unsigned char ltq_boot_select(void);
52/* find out what caused the last cpu reset */ 47/* find out what caused the last cpu reset */
53extern int ltq_reset_cause(void); 48extern int ltq_reset_cause(void);
54#define LTQ_RST_CAUSE_WDTRST 0x20
55 49
56#define IOPORT_RESOURCE_START 0x10000000 50#define IOPORT_RESOURCE_START 0x10000000
57#define IOPORT_RESOURCE_END 0xffffffff 51#define IOPORT_RESOURCE_END 0xffffffff
58#define IOMEM_RESOURCE_START 0x10000000 52#define IOMEM_RESOURCE_START 0x10000000
59#define IOMEM_RESOURCE_END 0xffffffff 53#define IOMEM_RESOURCE_END 0xffffffff
60#define LTQ_FLASH_START 0x10000000
61#define LTQ_FLASH_MAX 0x04000000
62 54
63#endif 55#endif
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
index a305f1d0259..e23bf7c9a2d 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
@@ -9,41 +9,8 @@
9#ifndef _LANTIQ_PLATFORM_H__ 9#ifndef _LANTIQ_PLATFORM_H__
10#define _LANTIQ_PLATFORM_H__ 10#define _LANTIQ_PLATFORM_H__
11 11
12#include <linux/mtd/partitions.h>
13#include <linux/socket.h> 12#include <linux/socket.h>
14 13
15/* struct used to pass info to the pci core */
16enum {
17 PCI_CLOCK_INT = 0,
18 PCI_CLOCK_EXT
19};
20
21#define PCI_EXIN0 0x0001
22#define PCI_EXIN1 0x0002
23#define PCI_EXIN2 0x0004
24#define PCI_EXIN3 0x0008
25#define PCI_EXIN4 0x0010
26#define PCI_EXIN5 0x0020
27#define PCI_EXIN_MAX 6
28
29#define PCI_GNT1 0x0040
30#define PCI_GNT2 0x0080
31#define PCI_GNT3 0x0100
32#define PCI_GNT4 0x0200
33
34#define PCI_REQ1 0x0400
35#define PCI_REQ2 0x0800
36#define PCI_REQ3 0x1000
37#define PCI_REQ4 0x2000
38#define PCI_REQ_SHIFT 10
39#define PCI_REQ_MASK 0xf
40
41struct ltq_pci_data {
42 int clock;
43 int gpio;
44 int irq[16];
45};
46
47/* struct used to pass info to network drivers */ 14/* struct used to pass info to network drivers */
48struct ltq_eth_data { 15struct ltq_eth_data {
49 struct sockaddr mac; 16 struct sockaddr mac;
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
index b4465a888e2..aa0b3b866f8 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -17,50 +17,8 @@
17#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) 17#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128)
18#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) 18#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
19 19
20#define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8))
21#define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1)
22#define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2)
23
24#define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0
25#define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2)
26#define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3)
27
28#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
29#define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
30#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
31
32#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
33#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
34
35#define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
36#define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
37#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
38
39#define MIPS_CPU_TIMER_IRQ 7
40
41#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) 20#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
42#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
43#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
44#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
45#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
46#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
47#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
48#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
49#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
50#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
51#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
52#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
53#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
54#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
55#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
56#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
57#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
58#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
59#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
60#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
61
62#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
63 21
64#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14) 22#define MIPS_CPU_TIMER_IRQ 7
65 23
66#endif 24#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
index 8a3c6be669d..6a2df709c57 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -17,38 +17,56 @@
17#define SOC_ID_DANUBE1 0x129 17#define SOC_ID_DANUBE1 0x129
18#define SOC_ID_DANUBE2 0x12B 18#define SOC_ID_DANUBE2 0x12B
19#define SOC_ID_TWINPASS 0x12D 19#define SOC_ID_TWINPASS 0x12D
20#define SOC_ID_AMAZON_SE 0x152 20#define SOC_ID_AMAZON_SE_1 0x152 /* 50601 */
21#define SOC_ID_AMAZON_SE_2 0x153 /* 50600 */
21#define SOC_ID_ARX188 0x16C 22#define SOC_ID_ARX188 0x16C
22#define SOC_ID_ARX168 0x16D 23#define SOC_ID_ARX168_1 0x16D
24#define SOC_ID_ARX168_2 0x16E
23#define SOC_ID_ARX182 0x16F 25#define SOC_ID_ARX182 0x16F
24 26#define SOC_ID_GRX188 0x170
25/* SoC Types */ 27#define SOC_ID_GRX168 0x171
28
29#define SOC_ID_VRX288 0x1C0 /* v1.1 */
30#define SOC_ID_VRX282 0x1C1 /* v1.1 */
31#define SOC_ID_VRX268 0x1C2 /* v1.1 */
32#define SOC_ID_GRX268 0x1C8 /* v1.1 */
33#define SOC_ID_GRX288 0x1C9 /* v1.1 */
34#define SOC_ID_VRX288_2 0x00B /* v1.2 */
35#define SOC_ID_VRX268_2 0x00C /* v1.2 */
36#define SOC_ID_GRX288_2 0x00D /* v1.2 */
37#define SOC_ID_GRX282_2 0x00E /* v1.2 */
38
39 /* SoC Types */
26#define SOC_TYPE_DANUBE 0x01 40#define SOC_TYPE_DANUBE 0x01
27#define SOC_TYPE_TWINPASS 0x02 41#define SOC_TYPE_TWINPASS 0x02
28#define SOC_TYPE_AR9 0x03 42#define SOC_TYPE_AR9 0x03
29#define SOC_TYPE_VR9 0x04 43#define SOC_TYPE_VR9 0x04 /* v1.1 */
30#define SOC_TYPE_AMAZON_SE 0x05 44#define SOC_TYPE_VR9_2 0x05 /* v1.2 */
45#define SOC_TYPE_AMAZON_SE 0x06
46
47/* BOOT_SEL - find what boot media we have */
48#define BS_EXT_ROM 0x0
49#define BS_FLASH 0x1
50#define BS_MII0 0x2
51#define BS_PCI 0x3
52#define BS_UART1 0x4
53#define BS_SPI 0x5
54#define BS_NAND 0x6
55#define BS_RMII0 0x7
56
57/* helpers used to access the cgu */
58#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
59#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
60extern __iomem void *ltq_cgu_membase;
31 61
32/* ASC0/1 - serial port */ 62/*
33#define LTQ_ASC0_BASE_ADDR 0x1E100400 63 * during early_printk no ioremap is possible
64 * lets use KSEG1 instead
65 */
34#define LTQ_ASC1_BASE_ADDR 0x1E100C00 66#define LTQ_ASC1_BASE_ADDR 0x1E100C00
35#define LTQ_ASC_SIZE 0x400 67#define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
36
37/* RCU - reset control unit */
38#define LTQ_RCU_BASE_ADDR 0x1F203000
39#define LTQ_RCU_SIZE 0x1000
40
41/* GPTU - general purpose timer unit */
42#define LTQ_GPTU_BASE_ADDR 0x18000300
43#define LTQ_GPTU_SIZE 0x100
44 68
45/* EBU - external bus unit */ 69/* EBU - external bus unit */
46#define LTQ_EBU_GPIO_START 0x14000000
47#define LTQ_EBU_GPIO_SIZE 0x1000
48
49#define LTQ_EBU_BASE_ADDR 0x1E105300
50#define LTQ_EBU_SIZE 0x100
51
52#define LTQ_EBU_BUSCON0 0x0060 70#define LTQ_EBU_BUSCON0 0x0060
53#define LTQ_EBU_PCC_CON 0x0090 71#define LTQ_EBU_PCC_CON 0x0090
54#define LTQ_EBU_PCC_IEN 0x00A4 72#define LTQ_EBU_PCC_IEN 0x00A4
@@ -57,85 +75,17 @@
57#define LTQ_EBU_ADDRSEL1 0x0024 75#define LTQ_EBU_ADDRSEL1 0x0024
58#define EBU_WRDIS 0x80000000 76#define EBU_WRDIS 0x80000000
59 77
60/* CGU - clock generation unit */
61#define LTQ_CGU_BASE_ADDR 0x1F103000
62#define LTQ_CGU_SIZE 0x1000
63
64/* ICU - interrupt control unit */
65#define LTQ_ICU_BASE_ADDR 0x1F880200
66#define LTQ_ICU_SIZE 0x100
67
68/* EIU - external interrupt unit */
69#define LTQ_EIU_BASE_ADDR 0x1F101000
70#define LTQ_EIU_SIZE 0x1000
71
72/* PMU - power management unit */
73#define LTQ_PMU_BASE_ADDR 0x1F102000
74#define LTQ_PMU_SIZE 0x1000
75
76#define PMU_DMA 0x0020
77#define PMU_USB 0x8041
78#define PMU_LED 0x0800
79#define PMU_GPT 0x1000
80#define PMU_PPE 0x2000
81#define PMU_FPI 0x4000
82#define PMU_SWITCH 0x10000000
83
84/* ETOP - ethernet */
85#define LTQ_ETOP_BASE_ADDR 0x1E180000
86#define LTQ_ETOP_SIZE 0x40000
87
88/* DMA */
89#define LTQ_DMA_BASE_ADDR 0x1E104100
90#define LTQ_DMA_SIZE 0x800
91
92/* PCI */
93#define PCI_CR_BASE_ADDR 0x1E105400
94#define PCI_CR_SIZE 0x400
95
96/* WDT */ 78/* WDT */
97#define LTQ_WDT_BASE_ADDR 0x1F8803F0 79#define LTQ_RST_CAUSE_WDTRST 0x20
98#define LTQ_WDT_SIZE 0x10
99
100/* STP - serial to parallel conversion unit */
101#define LTQ_STP_BASE_ADDR 0x1E100BB0
102#define LTQ_STP_SIZE 0x40
103
104/* GPIO */
105#define LTQ_GPIO0_BASE_ADDR 0x1E100B10
106#define LTQ_GPIO1_BASE_ADDR 0x1E100B40
107#define LTQ_GPIO2_BASE_ADDR 0x1E100B70
108#define LTQ_GPIO_SIZE 0x30
109
110/* SSC */
111#define LTQ_SSC_BASE_ADDR 0x1e100800
112#define LTQ_SSC_SIZE 0x100
113
114/* MEI - dsl core */
115#define LTQ_MEI_BASE_ADDR 0x1E116000
116
117/* DEU - data encryption unit */
118#define LTQ_DEU_BASE_ADDR 0x1E103100
119 80
120/* MPS - multi processor unit (voice) */ 81/* MPS - multi processor unit (voice) */
121#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) 82#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
122#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) 83#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
123 84
124/* request a non-gpio and set the PIO config */ 85/* request a non-gpio and set the PIO config */
125extern int ltq_gpio_request(unsigned int pin, unsigned int alt0, 86#define PMU_PPE BIT(13)
126 unsigned int alt1, unsigned int dir, const char *name);
127extern void ltq_pmu_enable(unsigned int module); 87extern void ltq_pmu_enable(unsigned int module);
128extern void ltq_pmu_disable(unsigned int module); 88extern void ltq_pmu_disable(unsigned int module);
129 89
130static inline int ltq_is_ar9(void)
131{
132 return (ltq_get_soc_type() == SOC_TYPE_AR9);
133}
134
135static inline int ltq_is_vr9(void)
136{
137 return (ltq_get_soc_type() == SOC_TYPE_VR9);
138}
139
140#endif /* CONFIG_SOC_TYPE_XWAY */ 90#endif /* CONFIG_SOC_TYPE_XWAY */
141#endif /* _LTQ_XWAY_H__ */ 91#endif /* _LTQ_XWAY_H__ */
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h
index 46c08563e53..6e23ceb0ba8 100644
--- a/arch/mips/include/asm/mips-boards/generic.h
+++ b/arch/mips/include/asm/mips-boards/generic.h
@@ -93,8 +93,4 @@ extern void mips_pcibios_init(void);
93#define mips_pcibios_init() do { } while (0) 93#define mips_pcibios_init() do { } while (0)
94#endif 94#endif
95 95
96#ifdef CONFIG_KGDB
97extern void kgdb_config(void);
98#endif
99
100#endif /* __ASM_MIPS_BOARDS_GENERIC_H */ 96#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 7467d1d933d..530008048c6 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -2,6 +2,7 @@
2#define _ASM_MODULE_H 2#define _ASM_MODULE_H
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/elf.h>
5#include <asm/uaccess.h> 6#include <asm/uaccess.h>
6 7
7struct mod_arch_specific { 8struct mod_arch_specific {
diff --git a/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
deleted file mode 100644
index d553f8e88df..00000000000
--- a/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
+++ /dev/null
@@ -1,1365 +0,0 @@
1/***********************license start***************
2 * Author: Cavium Networks
3 *
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
6 *
7 * Copyright (c) 2003-2008 Cavium Networks
8 *
9 * This file 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 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this file; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 * or visit http://www.gnu.org/licenses/.
23 *
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 ***********************license end**************************************/
27
28#ifndef __CVMX_PCIEEP_DEFS_H__
29#define __CVMX_PCIEEP_DEFS_H__
30
31#define CVMX_PCIEEP_CFG000 \
32 (0x0000000000000000ull)
33#define CVMX_PCIEEP_CFG001 \
34 (0x0000000000000004ull)
35#define CVMX_PCIEEP_CFG002 \
36 (0x0000000000000008ull)
37#define CVMX_PCIEEP_CFG003 \
38 (0x000000000000000Cull)
39#define CVMX_PCIEEP_CFG004 \
40 (0x0000000000000010ull)
41#define CVMX_PCIEEP_CFG004_MASK \
42 (0x0000000080000010ull)
43#define CVMX_PCIEEP_CFG005 \
44 (0x0000000000000014ull)
45#define CVMX_PCIEEP_CFG005_MASK \
46 (0x0000000080000014ull)
47#define CVMX_PCIEEP_CFG006 \
48 (0x0000000000000018ull)
49#define CVMX_PCIEEP_CFG006_MASK \
50 (0x0000000080000018ull)
51#define CVMX_PCIEEP_CFG007 \
52 (0x000000000000001Cull)
53#define CVMX_PCIEEP_CFG007_MASK \
54 (0x000000008000001Cull)
55#define CVMX_PCIEEP_CFG008 \
56 (0x0000000000000020ull)
57#define CVMX_PCIEEP_CFG008_MASK \
58 (0x0000000080000020ull)
59#define CVMX_PCIEEP_CFG009 \
60 (0x0000000000000024ull)
61#define CVMX_PCIEEP_CFG009_MASK \
62 (0x0000000080000024ull)
63#define CVMX_PCIEEP_CFG010 \
64 (0x0000000000000028ull)
65#define CVMX_PCIEEP_CFG011 \
66 (0x000000000000002Cull)
67#define CVMX_PCIEEP_CFG012 \
68 (0x0000000000000030ull)
69#define CVMX_PCIEEP_CFG012_MASK \
70 (0x0000000080000030ull)
71#define CVMX_PCIEEP_CFG013 \
72 (0x0000000000000034ull)
73#define CVMX_PCIEEP_CFG015 \
74 (0x000000000000003Cull)
75#define CVMX_PCIEEP_CFG016 \
76 (0x0000000000000040ull)
77#define CVMX_PCIEEP_CFG017 \
78 (0x0000000000000044ull)
79#define CVMX_PCIEEP_CFG020 \
80 (0x0000000000000050ull)
81#define CVMX_PCIEEP_CFG021 \
82 (0x0000000000000054ull)
83#define CVMX_PCIEEP_CFG022 \
84 (0x0000000000000058ull)
85#define CVMX_PCIEEP_CFG023 \
86 (0x000000000000005Cull)
87#define CVMX_PCIEEP_CFG028 \
88 (0x0000000000000070ull)
89#define CVMX_PCIEEP_CFG029 \
90 (0x0000000000000074ull)
91#define CVMX_PCIEEP_CFG030 \
92 (0x0000000000000078ull)
93#define CVMX_PCIEEP_CFG031 \
94 (0x000000000000007Cull)
95#define CVMX_PCIEEP_CFG032 \
96 (0x0000000000000080ull)
97#define CVMX_PCIEEP_CFG033 \
98 (0x0000000000000084ull)
99#define CVMX_PCIEEP_CFG034 \
100 (0x0000000000000088ull)
101#define CVMX_PCIEEP_CFG037 \
102 (0x0000000000000094ull)
103#define CVMX_PCIEEP_CFG038 \
104 (0x0000000000000098ull)
105#define CVMX_PCIEEP_CFG039 \
106 (0x000000000000009Cull)
107#define CVMX_PCIEEP_CFG040 \
108 (0x00000000000000A0ull)
109#define CVMX_PCIEEP_CFG041 \
110 (0x00000000000000A4ull)
111#define CVMX_PCIEEP_CFG042 \
112 (0x00000000000000A8ull)
113#define CVMX_PCIEEP_CFG064 \
114 (0x0000000000000100ull)
115#define CVMX_PCIEEP_CFG065 \
116 (0x0000000000000104ull)
117#define CVMX_PCIEEP_CFG066 \
118 (0x0000000000000108ull)
119#define CVMX_PCIEEP_CFG067 \
120 (0x000000000000010Cull)
121#define CVMX_PCIEEP_CFG068 \
122 (0x0000000000000110ull)
123#define CVMX_PCIEEP_CFG069 \
124 (0x0000000000000114ull)
125#define CVMX_PCIEEP_CFG070 \
126 (0x0000000000000118ull)
127#define CVMX_PCIEEP_CFG071 \
128 (0x000000000000011Cull)
129#define CVMX_PCIEEP_CFG072 \
130 (0x0000000000000120ull)
131#define CVMX_PCIEEP_CFG073 \
132 (0x0000000000000124ull)
133#define CVMX_PCIEEP_CFG074 \
134 (0x0000000000000128ull)
135#define CVMX_PCIEEP_CFG448 \
136 (0x0000000000000700ull)
137#define CVMX_PCIEEP_CFG449 \
138 (0x0000000000000704ull)
139#define CVMX_PCIEEP_CFG450 \
140 (0x0000000000000708ull)
141#define CVMX_PCIEEP_CFG451 \
142 (0x000000000000070Cull)
143#define CVMX_PCIEEP_CFG452 \
144 (0x0000000000000710ull)
145#define CVMX_PCIEEP_CFG453 \
146 (0x0000000000000714ull)
147#define CVMX_PCIEEP_CFG454 \
148 (0x0000000000000718ull)
149#define CVMX_PCIEEP_CFG455 \
150 (0x000000000000071Cull)
151#define CVMX_PCIEEP_CFG456 \
152 (0x0000000000000720ull)
153#define CVMX_PCIEEP_CFG458 \
154 (0x0000000000000728ull)
155#define CVMX_PCIEEP_CFG459 \
156 (0x000000000000072Cull)
157#define CVMX_PCIEEP_CFG460 \
158 (0x0000000000000730ull)
159#define CVMX_PCIEEP_CFG461 \
160 (0x0000000000000734ull)
161#define CVMX_PCIEEP_CFG462 \
162 (0x0000000000000738ull)
163#define CVMX_PCIEEP_CFG463 \
164 (0x000000000000073Cull)
165#define CVMX_PCIEEP_CFG464 \
166 (0x0000000000000740ull)
167#define CVMX_PCIEEP_CFG465 \
168 (0x0000000000000744ull)
169#define CVMX_PCIEEP_CFG466 \
170 (0x0000000000000748ull)
171#define CVMX_PCIEEP_CFG467 \
172 (0x000000000000074Cull)
173#define CVMX_PCIEEP_CFG468 \
174 (0x0000000000000750ull)
175#define CVMX_PCIEEP_CFG490 \
176 (0x00000000000007A8ull)
177#define CVMX_PCIEEP_CFG491 \
178 (0x00000000000007ACull)
179#define CVMX_PCIEEP_CFG492 \
180 (0x00000000000007B0ull)
181#define CVMX_PCIEEP_CFG516 \
182 (0x0000000000000810ull)
183#define CVMX_PCIEEP_CFG517 \
184 (0x0000000000000814ull)
185
186union cvmx_pcieep_cfg000 {
187 uint32_t u32;
188 struct cvmx_pcieep_cfg000_s {
189 uint32_t devid:16;
190 uint32_t vendid:16;
191 } s;
192 struct cvmx_pcieep_cfg000_s cn52xx;
193 struct cvmx_pcieep_cfg000_s cn52xxp1;
194 struct cvmx_pcieep_cfg000_s cn56xx;
195 struct cvmx_pcieep_cfg000_s cn56xxp1;
196};
197
198union cvmx_pcieep_cfg001 {
199 uint32_t u32;
200 struct cvmx_pcieep_cfg001_s {
201 uint32_t dpe:1;
202 uint32_t sse:1;
203 uint32_t rma:1;
204 uint32_t rta:1;
205 uint32_t sta:1;
206 uint32_t devt:2;
207 uint32_t mdpe:1;
208 uint32_t fbb:1;
209 uint32_t reserved_22_22:1;
210 uint32_t m66:1;
211 uint32_t cl:1;
212 uint32_t i_stat:1;
213 uint32_t reserved_11_18:8;
214 uint32_t i_dis:1;
215 uint32_t fbbe:1;
216 uint32_t see:1;
217 uint32_t ids_wcc:1;
218 uint32_t per:1;
219 uint32_t vps:1;
220 uint32_t mwice:1;
221 uint32_t scse:1;
222 uint32_t me:1;
223 uint32_t msae:1;
224 uint32_t isae:1;
225 } s;
226 struct cvmx_pcieep_cfg001_s cn52xx;
227 struct cvmx_pcieep_cfg001_s cn52xxp1;
228 struct cvmx_pcieep_cfg001_s cn56xx;
229 struct cvmx_pcieep_cfg001_s cn56xxp1;
230};
231
232union cvmx_pcieep_cfg002 {
233 uint32_t u32;
234 struct cvmx_pcieep_cfg002_s {
235 uint32_t bcc:8;
236 uint32_t sc:8;
237 uint32_t pi:8;
238 uint32_t rid:8;
239 } s;
240 struct cvmx_pcieep_cfg002_s cn52xx;
241 struct cvmx_pcieep_cfg002_s cn52xxp1;
242 struct cvmx_pcieep_cfg002_s cn56xx;
243 struct cvmx_pcieep_cfg002_s cn56xxp1;
244};
245
246union cvmx_pcieep_cfg003 {
247 uint32_t u32;
248 struct cvmx_pcieep_cfg003_s {
249 uint32_t bist:8;
250 uint32_t mfd:1;
251 uint32_t chf:7;
252 uint32_t lt:8;
253 uint32_t cls:8;
254 } s;
255 struct cvmx_pcieep_cfg003_s cn52xx;
256 struct cvmx_pcieep_cfg003_s cn52xxp1;
257 struct cvmx_pcieep_cfg003_s cn56xx;
258 struct cvmx_pcieep_cfg003_s cn56xxp1;
259};
260
261union cvmx_pcieep_cfg004 {
262 uint32_t u32;
263 struct cvmx_pcieep_cfg004_s {
264 uint32_t lbab:18;
265 uint32_t reserved_4_13:10;
266 uint32_t pf:1;
267 uint32_t typ:2;
268 uint32_t mspc:1;
269 } s;
270 struct cvmx_pcieep_cfg004_s cn52xx;
271 struct cvmx_pcieep_cfg004_s cn52xxp1;
272 struct cvmx_pcieep_cfg004_s cn56xx;
273 struct cvmx_pcieep_cfg004_s cn56xxp1;
274};
275
276union cvmx_pcieep_cfg004_mask {
277 uint32_t u32;
278 struct cvmx_pcieep_cfg004_mask_s {
279 uint32_t lmask:31;
280 uint32_t enb:1;
281 } s;
282 struct cvmx_pcieep_cfg004_mask_s cn52xx;
283 struct cvmx_pcieep_cfg004_mask_s cn52xxp1;
284 struct cvmx_pcieep_cfg004_mask_s cn56xx;
285 struct cvmx_pcieep_cfg004_mask_s cn56xxp1;
286};
287
288union cvmx_pcieep_cfg005 {
289 uint32_t u32;
290 struct cvmx_pcieep_cfg005_s {
291 uint32_t ubab:32;
292 } s;
293 struct cvmx_pcieep_cfg005_s cn52xx;
294 struct cvmx_pcieep_cfg005_s cn52xxp1;
295 struct cvmx_pcieep_cfg005_s cn56xx;
296 struct cvmx_pcieep_cfg005_s cn56xxp1;
297};
298
299union cvmx_pcieep_cfg005_mask {
300 uint32_t u32;
301 struct cvmx_pcieep_cfg005_mask_s {
302 uint32_t umask:32;
303 } s;
304 struct cvmx_pcieep_cfg005_mask_s cn52xx;
305 struct cvmx_pcieep_cfg005_mask_s cn52xxp1;
306 struct cvmx_pcieep_cfg005_mask_s cn56xx;
307 struct cvmx_pcieep_cfg005_mask_s cn56xxp1;
308};
309
310union cvmx_pcieep_cfg006 {
311 uint32_t u32;
312 struct cvmx_pcieep_cfg006_s {
313 uint32_t lbab:6;
314 uint32_t reserved_4_25:22;
315 uint32_t pf:1;
316 uint32_t typ:2;
317 uint32_t mspc:1;
318 } s;
319 struct cvmx_pcieep_cfg006_s cn52xx;
320 struct cvmx_pcieep_cfg006_s cn52xxp1;
321 struct cvmx_pcieep_cfg006_s cn56xx;
322 struct cvmx_pcieep_cfg006_s cn56xxp1;
323};
324
325union cvmx_pcieep_cfg006_mask {
326 uint32_t u32;
327 struct cvmx_pcieep_cfg006_mask_s {
328 uint32_t lmask:31;
329 uint32_t enb:1;
330 } s;
331 struct cvmx_pcieep_cfg006_mask_s cn52xx;
332 struct cvmx_pcieep_cfg006_mask_s cn52xxp1;
333 struct cvmx_pcieep_cfg006_mask_s cn56xx;
334 struct cvmx_pcieep_cfg006_mask_s cn56xxp1;
335};
336
337union cvmx_pcieep_cfg007 {
338 uint32_t u32;
339 struct cvmx_pcieep_cfg007_s {
340 uint32_t ubab:32;
341 } s;
342 struct cvmx_pcieep_cfg007_s cn52xx;
343 struct cvmx_pcieep_cfg007_s cn52xxp1;
344 struct cvmx_pcieep_cfg007_s cn56xx;
345 struct cvmx_pcieep_cfg007_s cn56xxp1;
346};
347
348union cvmx_pcieep_cfg007_mask {
349 uint32_t u32;
350 struct cvmx_pcieep_cfg007_mask_s {
351 uint32_t umask:32;
352 } s;
353 struct cvmx_pcieep_cfg007_mask_s cn52xx;
354 struct cvmx_pcieep_cfg007_mask_s cn52xxp1;
355 struct cvmx_pcieep_cfg007_mask_s cn56xx;
356 struct cvmx_pcieep_cfg007_mask_s cn56xxp1;
357};
358
359union cvmx_pcieep_cfg008 {
360 uint32_t u32;
361 struct cvmx_pcieep_cfg008_s {
362 uint32_t reserved_4_31:28;
363 uint32_t pf:1;
364 uint32_t typ:2;
365 uint32_t mspc:1;
366 } s;
367 struct cvmx_pcieep_cfg008_s cn52xx;
368 struct cvmx_pcieep_cfg008_s cn52xxp1;
369 struct cvmx_pcieep_cfg008_s cn56xx;
370 struct cvmx_pcieep_cfg008_s cn56xxp1;
371};
372
373union cvmx_pcieep_cfg008_mask {
374 uint32_t u32;
375 struct cvmx_pcieep_cfg008_mask_s {
376 uint32_t lmask:31;
377 uint32_t enb:1;
378 } s;
379 struct cvmx_pcieep_cfg008_mask_s cn52xx;
380 struct cvmx_pcieep_cfg008_mask_s cn52xxp1;
381 struct cvmx_pcieep_cfg008_mask_s cn56xx;
382 struct cvmx_pcieep_cfg008_mask_s cn56xxp1;
383};
384
385union cvmx_pcieep_cfg009 {
386 uint32_t u32;
387 struct cvmx_pcieep_cfg009_s {
388 uint32_t ubab:25;
389 uint32_t reserved_0_6:7;
390 } s;
391 struct cvmx_pcieep_cfg009_s cn52xx;
392 struct cvmx_pcieep_cfg009_s cn52xxp1;
393 struct cvmx_pcieep_cfg009_s cn56xx;
394 struct cvmx_pcieep_cfg009_s cn56xxp1;
395};
396
397union cvmx_pcieep_cfg009_mask {
398 uint32_t u32;
399 struct cvmx_pcieep_cfg009_mask_s {
400 uint32_t umask:32;
401 } s;
402 struct cvmx_pcieep_cfg009_mask_s cn52xx;
403 struct cvmx_pcieep_cfg009_mask_s cn52xxp1;
404 struct cvmx_pcieep_cfg009_mask_s cn56xx;
405 struct cvmx_pcieep_cfg009_mask_s cn56xxp1;
406};
407
408union cvmx_pcieep_cfg010 {
409 uint32_t u32;
410 struct cvmx_pcieep_cfg010_s {
411 uint32_t cisp:32;
412 } s;
413 struct cvmx_pcieep_cfg010_s cn52xx;
414 struct cvmx_pcieep_cfg010_s cn52xxp1;
415 struct cvmx_pcieep_cfg010_s cn56xx;
416 struct cvmx_pcieep_cfg010_s cn56xxp1;
417};
418
419union cvmx_pcieep_cfg011 {
420 uint32_t u32;
421 struct cvmx_pcieep_cfg011_s {
422 uint32_t ssid:16;
423 uint32_t ssvid:16;
424 } s;
425 struct cvmx_pcieep_cfg011_s cn52xx;
426 struct cvmx_pcieep_cfg011_s cn52xxp1;
427 struct cvmx_pcieep_cfg011_s cn56xx;
428 struct cvmx_pcieep_cfg011_s cn56xxp1;
429};
430
431union cvmx_pcieep_cfg012 {
432 uint32_t u32;
433 struct cvmx_pcieep_cfg012_s {
434 uint32_t eraddr:16;
435 uint32_t reserved_1_15:15;
436 uint32_t er_en:1;
437 } s;
438 struct cvmx_pcieep_cfg012_s cn52xx;
439 struct cvmx_pcieep_cfg012_s cn52xxp1;
440 struct cvmx_pcieep_cfg012_s cn56xx;
441 struct cvmx_pcieep_cfg012_s cn56xxp1;
442};
443
444union cvmx_pcieep_cfg012_mask {
445 uint32_t u32;
446 struct cvmx_pcieep_cfg012_mask_s {
447 uint32_t mask:31;
448 uint32_t enb:1;
449 } s;
450 struct cvmx_pcieep_cfg012_mask_s cn52xx;
451 struct cvmx_pcieep_cfg012_mask_s cn52xxp1;
452 struct cvmx_pcieep_cfg012_mask_s cn56xx;
453 struct cvmx_pcieep_cfg012_mask_s cn56xxp1;
454};
455
456union cvmx_pcieep_cfg013 {
457 uint32_t u32;
458 struct cvmx_pcieep_cfg013_s {
459 uint32_t reserved_8_31:24;
460 uint32_t cp:8;
461 } s;
462 struct cvmx_pcieep_cfg013_s cn52xx;
463 struct cvmx_pcieep_cfg013_s cn52xxp1;
464 struct cvmx_pcieep_cfg013_s cn56xx;
465 struct cvmx_pcieep_cfg013_s cn56xxp1;
466};
467
468union cvmx_pcieep_cfg015 {
469 uint32_t u32;
470 struct cvmx_pcieep_cfg015_s {
471 uint32_t ml:8;
472 uint32_t mg:8;
473 uint32_t inta:8;
474 uint32_t il:8;
475 } s;
476 struct cvmx_pcieep_cfg015_s cn52xx;
477 struct cvmx_pcieep_cfg015_s cn52xxp1;
478 struct cvmx_pcieep_cfg015_s cn56xx;
479 struct cvmx_pcieep_cfg015_s cn56xxp1;
480};
481
482union cvmx_pcieep_cfg016 {
483 uint32_t u32;
484 struct cvmx_pcieep_cfg016_s {
485 uint32_t pmes:5;
486 uint32_t d2s:1;
487 uint32_t d1s:1;
488 uint32_t auxc:3;
489 uint32_t dsi:1;
490 uint32_t reserved_20_20:1;
491 uint32_t pme_clock:1;
492 uint32_t pmsv:3;
493 uint32_t ncp:8;
494 uint32_t pmcid:8;
495 } s;
496 struct cvmx_pcieep_cfg016_s cn52xx;
497 struct cvmx_pcieep_cfg016_s cn52xxp1;
498 struct cvmx_pcieep_cfg016_s cn56xx;
499 struct cvmx_pcieep_cfg016_s cn56xxp1;
500};
501
502union cvmx_pcieep_cfg017 {
503 uint32_t u32;
504 struct cvmx_pcieep_cfg017_s {
505 uint32_t pmdia:8;
506 uint32_t bpccee:1;
507 uint32_t bd3h:1;
508 uint32_t reserved_16_21:6;
509 uint32_t pmess:1;
510 uint32_t pmedsia:2;
511 uint32_t pmds:4;
512 uint32_t pmeens:1;
513 uint32_t reserved_4_7:4;
514 uint32_t nsr:1;
515 uint32_t reserved_2_2:1;
516 uint32_t ps:2;
517 } s;
518 struct cvmx_pcieep_cfg017_s cn52xx;
519 struct cvmx_pcieep_cfg017_s cn52xxp1;
520 struct cvmx_pcieep_cfg017_s cn56xx;
521 struct cvmx_pcieep_cfg017_s cn56xxp1;
522};
523
524union cvmx_pcieep_cfg020 {
525 uint32_t u32;
526 struct cvmx_pcieep_cfg020_s {
527 uint32_t reserved_24_31:8;
528 uint32_t m64:1;
529 uint32_t mme:3;
530 uint32_t mmc:3;
531 uint32_t msien:1;
532 uint32_t ncp:8;
533 uint32_t msicid:8;
534 } s;
535 struct cvmx_pcieep_cfg020_s cn52xx;
536 struct cvmx_pcieep_cfg020_s cn52xxp1;
537 struct cvmx_pcieep_cfg020_s cn56xx;
538 struct cvmx_pcieep_cfg020_s cn56xxp1;
539};
540
541union cvmx_pcieep_cfg021 {
542 uint32_t u32;
543 struct cvmx_pcieep_cfg021_s {
544 uint32_t lmsi:30;
545 uint32_t reserved_0_1:2;
546 } s;
547 struct cvmx_pcieep_cfg021_s cn52xx;
548 struct cvmx_pcieep_cfg021_s cn52xxp1;
549 struct cvmx_pcieep_cfg021_s cn56xx;
550 struct cvmx_pcieep_cfg021_s cn56xxp1;
551};
552
553union cvmx_pcieep_cfg022 {
554 uint32_t u32;
555 struct cvmx_pcieep_cfg022_s {
556 uint32_t umsi:32;
557 } s;
558 struct cvmx_pcieep_cfg022_s cn52xx;
559 struct cvmx_pcieep_cfg022_s cn52xxp1;
560 struct cvmx_pcieep_cfg022_s cn56xx;
561 struct cvmx_pcieep_cfg022_s cn56xxp1;
562};
563
564union cvmx_pcieep_cfg023 {
565 uint32_t u32;
566 struct cvmx_pcieep_cfg023_s {
567 uint32_t reserved_16_31:16;
568 uint32_t msimd:16;
569 } s;
570 struct cvmx_pcieep_cfg023_s cn52xx;
571 struct cvmx_pcieep_cfg023_s cn52xxp1;
572 struct cvmx_pcieep_cfg023_s cn56xx;
573 struct cvmx_pcieep_cfg023_s cn56xxp1;
574};
575
576union cvmx_pcieep_cfg028 {
577 uint32_t u32;
578 struct cvmx_pcieep_cfg028_s {
579 uint32_t reserved_30_31:2;
580 uint32_t imn:5;
581 uint32_t si:1;
582 uint32_t dpt:4;
583 uint32_t pciecv:4;
584 uint32_t ncp:8;
585 uint32_t pcieid:8;
586 } s;
587 struct cvmx_pcieep_cfg028_s cn52xx;
588 struct cvmx_pcieep_cfg028_s cn52xxp1;
589 struct cvmx_pcieep_cfg028_s cn56xx;
590 struct cvmx_pcieep_cfg028_s cn56xxp1;
591};
592
593union cvmx_pcieep_cfg029 {
594 uint32_t u32;
595 struct cvmx_pcieep_cfg029_s {
596 uint32_t reserved_28_31:4;
597 uint32_t cspls:2;
598 uint32_t csplv:8;
599 uint32_t reserved_16_17:2;
600 uint32_t rber:1;
601 uint32_t reserved_12_14:3;
602 uint32_t el1al:3;
603 uint32_t el0al:3;
604 uint32_t etfs:1;
605 uint32_t pfs:2;
606 uint32_t mpss:3;
607 } s;
608 struct cvmx_pcieep_cfg029_s cn52xx;
609 struct cvmx_pcieep_cfg029_s cn52xxp1;
610 struct cvmx_pcieep_cfg029_s cn56xx;
611 struct cvmx_pcieep_cfg029_s cn56xxp1;
612};
613
614union cvmx_pcieep_cfg030 {
615 uint32_t u32;
616 struct cvmx_pcieep_cfg030_s {
617 uint32_t reserved_22_31:10;
618 uint32_t tp:1;
619 uint32_t ap_d:1;
620 uint32_t ur_d:1;
621 uint32_t fe_d:1;
622 uint32_t nfe_d:1;
623 uint32_t ce_d:1;
624 uint32_t reserved_15_15:1;
625 uint32_t mrrs:3;
626 uint32_t ns_en:1;
627 uint32_t ap_en:1;
628 uint32_t pf_en:1;
629 uint32_t etf_en:1;
630 uint32_t mps:3;
631 uint32_t ro_en:1;
632 uint32_t ur_en:1;
633 uint32_t fe_en:1;
634 uint32_t nfe_en:1;
635 uint32_t ce_en:1;
636 } s;
637 struct cvmx_pcieep_cfg030_s cn52xx;
638 struct cvmx_pcieep_cfg030_s cn52xxp1;
639 struct cvmx_pcieep_cfg030_s cn56xx;
640 struct cvmx_pcieep_cfg030_s cn56xxp1;
641};
642
643union cvmx_pcieep_cfg031 {
644 uint32_t u32;
645 struct cvmx_pcieep_cfg031_s {
646 uint32_t pnum:8;
647 uint32_t reserved_22_23:2;
648 uint32_t lbnc:1;
649 uint32_t dllarc:1;
650 uint32_t sderc:1;
651 uint32_t cpm:1;
652 uint32_t l1el:3;
653 uint32_t l0el:3;
654 uint32_t aslpms:2;
655 uint32_t mlw:6;
656 uint32_t mls:4;
657 } s;
658 struct cvmx_pcieep_cfg031_s cn52xx;
659 struct cvmx_pcieep_cfg031_s cn52xxp1;
660 struct cvmx_pcieep_cfg031_s cn56xx;
661 struct cvmx_pcieep_cfg031_s cn56xxp1;
662};
663
664union cvmx_pcieep_cfg032 {
665 uint32_t u32;
666 struct cvmx_pcieep_cfg032_s {
667 uint32_t reserved_30_31:2;
668 uint32_t dlla:1;
669 uint32_t scc:1;
670 uint32_t lt:1;
671 uint32_t reserved_26_26:1;
672 uint32_t nlw:6;
673 uint32_t ls:4;
674 uint32_t reserved_10_15:6;
675 uint32_t hawd:1;
676 uint32_t ecpm:1;
677 uint32_t es:1;
678 uint32_t ccc:1;
679 uint32_t rl:1;
680 uint32_t ld:1;
681 uint32_t rcb:1;
682 uint32_t reserved_2_2:1;
683 uint32_t aslpc:2;
684 } s;
685 struct cvmx_pcieep_cfg032_s cn52xx;
686 struct cvmx_pcieep_cfg032_s cn52xxp1;
687 struct cvmx_pcieep_cfg032_s cn56xx;
688 struct cvmx_pcieep_cfg032_s cn56xxp1;
689};
690
691union cvmx_pcieep_cfg033 {
692 uint32_t u32;
693 struct cvmx_pcieep_cfg033_s {
694 uint32_t ps_num:13;
695 uint32_t nccs:1;
696 uint32_t emip:1;
697 uint32_t sp_ls:2;
698 uint32_t sp_lv:8;
699 uint32_t hp_c:1;
700 uint32_t hp_s:1;
701 uint32_t pip:1;
702 uint32_t aip:1;
703 uint32_t mrlsp:1;
704 uint32_t pcp:1;
705 uint32_t abp:1;
706 } s;
707 struct cvmx_pcieep_cfg033_s cn52xx;
708 struct cvmx_pcieep_cfg033_s cn52xxp1;
709 struct cvmx_pcieep_cfg033_s cn56xx;
710 struct cvmx_pcieep_cfg033_s cn56xxp1;
711};
712
713union cvmx_pcieep_cfg034 {
714 uint32_t u32;
715 struct cvmx_pcieep_cfg034_s {
716 uint32_t reserved_25_31:7;
717 uint32_t dlls_c:1;
718 uint32_t emis:1;
719 uint32_t pds:1;
720 uint32_t mrlss:1;
721 uint32_t ccint_d:1;
722 uint32_t pd_c:1;
723 uint32_t mrls_c:1;
724 uint32_t pf_d:1;
725 uint32_t abp_d:1;
726 uint32_t reserved_13_15:3;
727 uint32_t dlls_en:1;
728 uint32_t emic:1;
729 uint32_t pcc:1;
730 uint32_t pic:2;
731 uint32_t aic:2;
732 uint32_t hpint_en:1;
733 uint32_t ccint_en:1;
734 uint32_t pd_en:1;
735 uint32_t mrls_en:1;
736 uint32_t pf_en:1;
737 uint32_t abp_en:1;
738 } s;
739 struct cvmx_pcieep_cfg034_s cn52xx;
740 struct cvmx_pcieep_cfg034_s cn52xxp1;
741 struct cvmx_pcieep_cfg034_s cn56xx;
742 struct cvmx_pcieep_cfg034_s cn56xxp1;
743};
744
745union cvmx_pcieep_cfg037 {
746 uint32_t u32;
747 struct cvmx_pcieep_cfg037_s {
748 uint32_t reserved_5_31:27;
749 uint32_t ctds:1;
750 uint32_t ctrs:4;
751 } s;
752 struct cvmx_pcieep_cfg037_s cn52xx;
753 struct cvmx_pcieep_cfg037_s cn52xxp1;
754 struct cvmx_pcieep_cfg037_s cn56xx;
755 struct cvmx_pcieep_cfg037_s cn56xxp1;
756};
757
758union cvmx_pcieep_cfg038 {
759 uint32_t u32;
760 struct cvmx_pcieep_cfg038_s {
761 uint32_t reserved_5_31:27;
762 uint32_t ctd:1;
763 uint32_t ctv:4;
764 } s;
765 struct cvmx_pcieep_cfg038_s cn52xx;
766 struct cvmx_pcieep_cfg038_s cn52xxp1;
767 struct cvmx_pcieep_cfg038_s cn56xx;
768 struct cvmx_pcieep_cfg038_s cn56xxp1;
769};
770
771union cvmx_pcieep_cfg039 {
772 uint32_t u32;
773 struct cvmx_pcieep_cfg039_s {
774 uint32_t reserved_0_31:32;
775 } s;
776 struct cvmx_pcieep_cfg039_s cn52xx;
777 struct cvmx_pcieep_cfg039_s cn52xxp1;
778 struct cvmx_pcieep_cfg039_s cn56xx;
779 struct cvmx_pcieep_cfg039_s cn56xxp1;
780};
781
782union cvmx_pcieep_cfg040 {
783 uint32_t u32;
784 struct cvmx_pcieep_cfg040_s {
785 uint32_t reserved_0_31:32;
786 } s;
787 struct cvmx_pcieep_cfg040_s cn52xx;
788 struct cvmx_pcieep_cfg040_s cn52xxp1;
789 struct cvmx_pcieep_cfg040_s cn56xx;
790 struct cvmx_pcieep_cfg040_s cn56xxp1;
791};
792
793union cvmx_pcieep_cfg041 {
794 uint32_t u32;
795 struct cvmx_pcieep_cfg041_s {
796 uint32_t reserved_0_31:32;
797 } s;
798 struct cvmx_pcieep_cfg041_s cn52xx;
799 struct cvmx_pcieep_cfg041_s cn52xxp1;
800 struct cvmx_pcieep_cfg041_s cn56xx;
801 struct cvmx_pcieep_cfg041_s cn56xxp1;
802};
803
804union cvmx_pcieep_cfg042 {
805 uint32_t u32;
806 struct cvmx_pcieep_cfg042_s {
807 uint32_t reserved_0_31:32;
808 } s;
809 struct cvmx_pcieep_cfg042_s cn52xx;
810 struct cvmx_pcieep_cfg042_s cn52xxp1;
811 struct cvmx_pcieep_cfg042_s cn56xx;
812 struct cvmx_pcieep_cfg042_s cn56xxp1;
813};
814
815union cvmx_pcieep_cfg064 {
816 uint32_t u32;
817 struct cvmx_pcieep_cfg064_s {
818 uint32_t nco:12;
819 uint32_t cv:4;
820 uint32_t pcieec:16;
821 } s;
822 struct cvmx_pcieep_cfg064_s cn52xx;
823 struct cvmx_pcieep_cfg064_s cn52xxp1;
824 struct cvmx_pcieep_cfg064_s cn56xx;
825 struct cvmx_pcieep_cfg064_s cn56xxp1;
826};
827
828union cvmx_pcieep_cfg065 {
829 uint32_t u32;
830 struct cvmx_pcieep_cfg065_s {
831 uint32_t reserved_21_31:11;
832 uint32_t ures:1;
833 uint32_t ecrces:1;
834 uint32_t mtlps:1;
835 uint32_t ros:1;
836 uint32_t ucs:1;
837 uint32_t cas:1;
838 uint32_t cts:1;
839 uint32_t fcpes:1;
840 uint32_t ptlps:1;
841 uint32_t reserved_6_11:6;
842 uint32_t sdes:1;
843 uint32_t dlpes:1;
844 uint32_t reserved_0_3:4;
845 } s;
846 struct cvmx_pcieep_cfg065_s cn52xx;
847 struct cvmx_pcieep_cfg065_s cn52xxp1;
848 struct cvmx_pcieep_cfg065_s cn56xx;
849 struct cvmx_pcieep_cfg065_s cn56xxp1;
850};
851
852union cvmx_pcieep_cfg066 {
853 uint32_t u32;
854 struct cvmx_pcieep_cfg066_s {
855 uint32_t reserved_21_31:11;
856 uint32_t urem:1;
857 uint32_t ecrcem:1;
858 uint32_t mtlpm:1;
859 uint32_t rom:1;
860 uint32_t ucm:1;
861 uint32_t cam:1;
862 uint32_t ctm:1;
863 uint32_t fcpem:1;
864 uint32_t ptlpm:1;
865 uint32_t reserved_6_11:6;
866 uint32_t sdem:1;
867 uint32_t dlpem:1;
868 uint32_t reserved_0_3:4;
869 } s;
870 struct cvmx_pcieep_cfg066_s cn52xx;
871 struct cvmx_pcieep_cfg066_s cn52xxp1;
872 struct cvmx_pcieep_cfg066_s cn56xx;
873 struct cvmx_pcieep_cfg066_s cn56xxp1;
874};
875
876union cvmx_pcieep_cfg067 {
877 uint32_t u32;
878 struct cvmx_pcieep_cfg067_s {
879 uint32_t reserved_21_31:11;
880 uint32_t ures:1;
881 uint32_t ecrces:1;
882 uint32_t mtlps:1;
883 uint32_t ros:1;
884 uint32_t ucs:1;
885 uint32_t cas:1;
886 uint32_t cts:1;
887 uint32_t fcpes:1;
888 uint32_t ptlps:1;
889 uint32_t reserved_6_11:6;
890 uint32_t sdes:1;
891 uint32_t dlpes:1;
892 uint32_t reserved_0_3:4;
893 } s;
894 struct cvmx_pcieep_cfg067_s cn52xx;
895 struct cvmx_pcieep_cfg067_s cn52xxp1;
896 struct cvmx_pcieep_cfg067_s cn56xx;
897 struct cvmx_pcieep_cfg067_s cn56xxp1;
898};
899
900union cvmx_pcieep_cfg068 {
901 uint32_t u32;
902 struct cvmx_pcieep_cfg068_s {
903 uint32_t reserved_14_31:18;
904 uint32_t anfes:1;
905 uint32_t rtts:1;
906 uint32_t reserved_9_11:3;
907 uint32_t rnrs:1;
908 uint32_t bdllps:1;
909 uint32_t btlps:1;
910 uint32_t reserved_1_5:5;
911 uint32_t res:1;
912 } s;
913 struct cvmx_pcieep_cfg068_s cn52xx;
914 struct cvmx_pcieep_cfg068_s cn52xxp1;
915 struct cvmx_pcieep_cfg068_s cn56xx;
916 struct cvmx_pcieep_cfg068_s cn56xxp1;
917};
918
919union cvmx_pcieep_cfg069 {
920 uint32_t u32;
921 struct cvmx_pcieep_cfg069_s {
922 uint32_t reserved_14_31:18;
923 uint32_t anfem:1;
924 uint32_t rttm:1;
925 uint32_t reserved_9_11:3;
926 uint32_t rnrm:1;
927 uint32_t bdllpm:1;
928 uint32_t btlpm:1;
929 uint32_t reserved_1_5:5;
930 uint32_t rem:1;
931 } s;
932 struct cvmx_pcieep_cfg069_s cn52xx;
933 struct cvmx_pcieep_cfg069_s cn52xxp1;
934 struct cvmx_pcieep_cfg069_s cn56xx;
935 struct cvmx_pcieep_cfg069_s cn56xxp1;
936};
937
938union cvmx_pcieep_cfg070 {
939 uint32_t u32;
940 struct cvmx_pcieep_cfg070_s {
941 uint32_t reserved_9_31:23;
942 uint32_t ce:1;
943 uint32_t cc:1;
944 uint32_t ge:1;
945 uint32_t gc:1;
946 uint32_t fep:5;
947 } s;
948 struct cvmx_pcieep_cfg070_s cn52xx;
949 struct cvmx_pcieep_cfg070_s cn52xxp1;
950 struct cvmx_pcieep_cfg070_s cn56xx;
951 struct cvmx_pcieep_cfg070_s cn56xxp1;
952};
953
954union cvmx_pcieep_cfg071 {
955 uint32_t u32;
956 struct cvmx_pcieep_cfg071_s {
957 uint32_t dword1:32;
958 } s;
959 struct cvmx_pcieep_cfg071_s cn52xx;
960 struct cvmx_pcieep_cfg071_s cn52xxp1;
961 struct cvmx_pcieep_cfg071_s cn56xx;
962 struct cvmx_pcieep_cfg071_s cn56xxp1;
963};
964
965union cvmx_pcieep_cfg072 {
966 uint32_t u32;
967 struct cvmx_pcieep_cfg072_s {
968 uint32_t dword2:32;
969 } s;
970 struct cvmx_pcieep_cfg072_s cn52xx;
971 struct cvmx_pcieep_cfg072_s cn52xxp1;
972 struct cvmx_pcieep_cfg072_s cn56xx;
973 struct cvmx_pcieep_cfg072_s cn56xxp1;
974};
975
976union cvmx_pcieep_cfg073 {
977 uint32_t u32;
978 struct cvmx_pcieep_cfg073_s {
979 uint32_t dword3:32;
980 } s;
981 struct cvmx_pcieep_cfg073_s cn52xx;
982 struct cvmx_pcieep_cfg073_s cn52xxp1;
983 struct cvmx_pcieep_cfg073_s cn56xx;
984 struct cvmx_pcieep_cfg073_s cn56xxp1;
985};
986
987union cvmx_pcieep_cfg074 {
988 uint32_t u32;
989 struct cvmx_pcieep_cfg074_s {
990 uint32_t dword4:32;
991 } s;
992 struct cvmx_pcieep_cfg074_s cn52xx;
993 struct cvmx_pcieep_cfg074_s cn52xxp1;
994 struct cvmx_pcieep_cfg074_s cn56xx;
995 struct cvmx_pcieep_cfg074_s cn56xxp1;
996};
997
998union cvmx_pcieep_cfg448 {
999 uint32_t u32;
1000 struct cvmx_pcieep_cfg448_s {
1001 uint32_t rtl:16;
1002 uint32_t rtltl:16;
1003 } s;
1004 struct cvmx_pcieep_cfg448_s cn52xx;
1005 struct cvmx_pcieep_cfg448_s cn52xxp1;
1006 struct cvmx_pcieep_cfg448_s cn56xx;
1007 struct cvmx_pcieep_cfg448_s cn56xxp1;
1008};
1009
1010union cvmx_pcieep_cfg449 {
1011 uint32_t u32;
1012 struct cvmx_pcieep_cfg449_s {
1013 uint32_t omr:32;
1014 } s;
1015 struct cvmx_pcieep_cfg449_s cn52xx;
1016 struct cvmx_pcieep_cfg449_s cn52xxp1;
1017 struct cvmx_pcieep_cfg449_s cn56xx;
1018 struct cvmx_pcieep_cfg449_s cn56xxp1;
1019};
1020
1021union cvmx_pcieep_cfg450 {
1022 uint32_t u32;
1023 struct cvmx_pcieep_cfg450_s {
1024 uint32_t lpec:8;
1025 uint32_t reserved_22_23:2;
1026 uint32_t link_state:6;
1027 uint32_t force_link:1;
1028 uint32_t reserved_8_14:7;
1029 uint32_t link_num:8;
1030 } s;
1031 struct cvmx_pcieep_cfg450_s cn52xx;
1032 struct cvmx_pcieep_cfg450_s cn52xxp1;
1033 struct cvmx_pcieep_cfg450_s cn56xx;
1034 struct cvmx_pcieep_cfg450_s cn56xxp1;
1035};
1036
1037union cvmx_pcieep_cfg451 {
1038 uint32_t u32;
1039 struct cvmx_pcieep_cfg451_s {
1040 uint32_t reserved_30_31:2;
1041 uint32_t l1el:3;
1042 uint32_t l0el:3;
1043 uint32_t n_fts_cc:8;
1044 uint32_t n_fts:8;
1045 uint32_t ack_freq:8;
1046 } s;
1047 struct cvmx_pcieep_cfg451_s cn52xx;
1048 struct cvmx_pcieep_cfg451_s cn52xxp1;
1049 struct cvmx_pcieep_cfg451_s cn56xx;
1050 struct cvmx_pcieep_cfg451_s cn56xxp1;
1051};
1052
1053union cvmx_pcieep_cfg452 {
1054 uint32_t u32;
1055 struct cvmx_pcieep_cfg452_s {
1056 uint32_t reserved_26_31:6;
1057 uint32_t eccrc:1;
1058 uint32_t reserved_22_24:3;
1059 uint32_t lme:6;
1060 uint32_t reserved_8_15:8;
1061 uint32_t flm:1;
1062 uint32_t reserved_6_6:1;
1063 uint32_t dllle:1;
1064 uint32_t reserved_4_4:1;
1065 uint32_t ra:1;
1066 uint32_t le:1;
1067 uint32_t sd:1;
1068 uint32_t omr:1;
1069 } s;
1070 struct cvmx_pcieep_cfg452_s cn52xx;
1071 struct cvmx_pcieep_cfg452_s cn52xxp1;
1072 struct cvmx_pcieep_cfg452_s cn56xx;
1073 struct cvmx_pcieep_cfg452_s cn56xxp1;
1074};
1075
1076union cvmx_pcieep_cfg453 {
1077 uint32_t u32;
1078 struct cvmx_pcieep_cfg453_s {
1079 uint32_t dlld:1;
1080 uint32_t reserved_26_30:5;
1081 uint32_t ack_nak:1;
1082 uint32_t fcd:1;
1083 uint32_t ilst:24;
1084 } s;
1085 struct cvmx_pcieep_cfg453_s cn52xx;
1086 struct cvmx_pcieep_cfg453_s cn52xxp1;
1087 struct cvmx_pcieep_cfg453_s cn56xx;
1088 struct cvmx_pcieep_cfg453_s cn56xxp1;
1089};
1090
1091union cvmx_pcieep_cfg454 {
1092 uint32_t u32;
1093 struct cvmx_pcieep_cfg454_s {
1094 uint32_t reserved_29_31:3;
1095 uint32_t tmfcwt:5;
1096 uint32_t tmanlt:5;
1097 uint32_t tmrt:5;
1098 uint32_t reserved_11_13:3;
1099 uint32_t nskps:3;
1100 uint32_t reserved_4_7:4;
1101 uint32_t ntss:4;
1102 } s;
1103 struct cvmx_pcieep_cfg454_s cn52xx;
1104 struct cvmx_pcieep_cfg454_s cn52xxp1;
1105 struct cvmx_pcieep_cfg454_s cn56xx;
1106 struct cvmx_pcieep_cfg454_s cn56xxp1;
1107};
1108
1109union cvmx_pcieep_cfg455 {
1110 uint32_t u32;
1111 struct cvmx_pcieep_cfg455_s {
1112 uint32_t m_cfg0_filt:1;
1113 uint32_t m_io_filt:1;
1114 uint32_t msg_ctrl:1;
1115 uint32_t m_cpl_ecrc_filt:1;
1116 uint32_t m_ecrc_filt:1;
1117 uint32_t m_cpl_len_err:1;
1118 uint32_t m_cpl_attr_err:1;
1119 uint32_t m_cpl_tc_err:1;
1120 uint32_t m_cpl_fun_err:1;
1121 uint32_t m_cpl_rid_err:1;
1122 uint32_t m_cpl_tag_err:1;
1123 uint32_t m_lk_filt:1;
1124 uint32_t m_cfg1_filt:1;
1125 uint32_t m_bar_match:1;
1126 uint32_t m_pois_filt:1;
1127 uint32_t m_fun:1;
1128 uint32_t dfcwt:1;
1129 uint32_t reserved_11_14:4;
1130 uint32_t skpiv:11;
1131 } s;
1132 struct cvmx_pcieep_cfg455_s cn52xx;
1133 struct cvmx_pcieep_cfg455_s cn52xxp1;
1134 struct cvmx_pcieep_cfg455_s cn56xx;
1135 struct cvmx_pcieep_cfg455_s cn56xxp1;
1136};
1137
1138union cvmx_pcieep_cfg456 {
1139 uint32_t u32;
1140 struct cvmx_pcieep_cfg456_s {
1141 uint32_t reserved_2_31:30;
1142 uint32_t m_vend1_drp:1;
1143 uint32_t m_vend0_drp:1;
1144 } s;
1145 struct cvmx_pcieep_cfg456_s cn52xx;
1146 struct cvmx_pcieep_cfg456_s cn52xxp1;
1147 struct cvmx_pcieep_cfg456_s cn56xx;
1148 struct cvmx_pcieep_cfg456_s cn56xxp1;
1149};
1150
1151union cvmx_pcieep_cfg458 {
1152 uint32_t u32;
1153 struct cvmx_pcieep_cfg458_s {
1154 uint32_t dbg_info_l32:32;
1155 } s;
1156 struct cvmx_pcieep_cfg458_s cn52xx;
1157 struct cvmx_pcieep_cfg458_s cn52xxp1;
1158 struct cvmx_pcieep_cfg458_s cn56xx;
1159 struct cvmx_pcieep_cfg458_s cn56xxp1;
1160};
1161
1162union cvmx_pcieep_cfg459 {
1163 uint32_t u32;
1164 struct cvmx_pcieep_cfg459_s {
1165 uint32_t dbg_info_u32:32;
1166 } s;
1167 struct cvmx_pcieep_cfg459_s cn52xx;
1168 struct cvmx_pcieep_cfg459_s cn52xxp1;
1169 struct cvmx_pcieep_cfg459_s cn56xx;
1170 struct cvmx_pcieep_cfg459_s cn56xxp1;
1171};
1172
1173union cvmx_pcieep_cfg460 {
1174 uint32_t u32;
1175 struct cvmx_pcieep_cfg460_s {
1176 uint32_t reserved_20_31:12;
1177 uint32_t tphfcc:8;
1178 uint32_t tpdfcc:12;
1179 } s;
1180 struct cvmx_pcieep_cfg460_s cn52xx;
1181 struct cvmx_pcieep_cfg460_s cn52xxp1;
1182 struct cvmx_pcieep_cfg460_s cn56xx;
1183 struct cvmx_pcieep_cfg460_s cn56xxp1;
1184};
1185
1186union cvmx_pcieep_cfg461 {
1187 uint32_t u32;
1188 struct cvmx_pcieep_cfg461_s {
1189 uint32_t reserved_20_31:12;
1190 uint32_t tchfcc:8;
1191 uint32_t tcdfcc:12;
1192 } s;
1193 struct cvmx_pcieep_cfg461_s cn52xx;
1194 struct cvmx_pcieep_cfg461_s cn52xxp1;
1195 struct cvmx_pcieep_cfg461_s cn56xx;
1196 struct cvmx_pcieep_cfg461_s cn56xxp1;
1197};
1198
1199union cvmx_pcieep_cfg462 {
1200 uint32_t u32;
1201 struct cvmx_pcieep_cfg462_s {
1202 uint32_t reserved_20_31:12;
1203 uint32_t tchfcc:8;
1204 uint32_t tcdfcc:12;
1205 } s;
1206 struct cvmx_pcieep_cfg462_s cn52xx;
1207 struct cvmx_pcieep_cfg462_s cn52xxp1;
1208 struct cvmx_pcieep_cfg462_s cn56xx;
1209 struct cvmx_pcieep_cfg462_s cn56xxp1;
1210};
1211
1212union cvmx_pcieep_cfg463 {
1213 uint32_t u32;
1214 struct cvmx_pcieep_cfg463_s {
1215 uint32_t reserved_3_31:29;
1216 uint32_t rqne:1;
1217 uint32_t trbne:1;
1218 uint32_t rtlpfccnr:1;
1219 } s;
1220 struct cvmx_pcieep_cfg463_s cn52xx;
1221 struct cvmx_pcieep_cfg463_s cn52xxp1;
1222 struct cvmx_pcieep_cfg463_s cn56xx;
1223 struct cvmx_pcieep_cfg463_s cn56xxp1;
1224};
1225
1226union cvmx_pcieep_cfg464 {
1227 uint32_t u32;
1228 struct cvmx_pcieep_cfg464_s {
1229 uint32_t wrr_vc3:8;
1230 uint32_t wrr_vc2:8;
1231 uint32_t wrr_vc1:8;
1232 uint32_t wrr_vc0:8;
1233 } s;
1234 struct cvmx_pcieep_cfg464_s cn52xx;
1235 struct cvmx_pcieep_cfg464_s cn52xxp1;
1236 struct cvmx_pcieep_cfg464_s cn56xx;
1237 struct cvmx_pcieep_cfg464_s cn56xxp1;
1238};
1239
1240union cvmx_pcieep_cfg465 {
1241 uint32_t u32;
1242 struct cvmx_pcieep_cfg465_s {
1243 uint32_t wrr_vc7:8;
1244 uint32_t wrr_vc6:8;
1245 uint32_t wrr_vc5:8;
1246 uint32_t wrr_vc4:8;
1247 } s;
1248 struct cvmx_pcieep_cfg465_s cn52xx;
1249 struct cvmx_pcieep_cfg465_s cn52xxp1;
1250 struct cvmx_pcieep_cfg465_s cn56xx;
1251 struct cvmx_pcieep_cfg465_s cn56xxp1;
1252};
1253
1254union cvmx_pcieep_cfg466 {
1255 uint32_t u32;
1256 struct cvmx_pcieep_cfg466_s {
1257 uint32_t rx_queue_order:1;
1258 uint32_t type_ordering:1;
1259 uint32_t reserved_24_29:6;
1260 uint32_t queue_mode:3;
1261 uint32_t reserved_20_20:1;
1262 uint32_t header_credits:8;
1263 uint32_t data_credits:12;
1264 } s;
1265 struct cvmx_pcieep_cfg466_s cn52xx;
1266 struct cvmx_pcieep_cfg466_s cn52xxp1;
1267 struct cvmx_pcieep_cfg466_s cn56xx;
1268 struct cvmx_pcieep_cfg466_s cn56xxp1;
1269};
1270
1271union cvmx_pcieep_cfg467 {
1272 uint32_t u32;
1273 struct cvmx_pcieep_cfg467_s {
1274 uint32_t reserved_24_31:8;
1275 uint32_t queue_mode:3;
1276 uint32_t reserved_20_20:1;
1277 uint32_t header_credits:8;
1278 uint32_t data_credits:12;
1279 } s;
1280 struct cvmx_pcieep_cfg467_s cn52xx;
1281 struct cvmx_pcieep_cfg467_s cn52xxp1;
1282 struct cvmx_pcieep_cfg467_s cn56xx;
1283 struct cvmx_pcieep_cfg467_s cn56xxp1;
1284};
1285
1286union cvmx_pcieep_cfg468 {
1287 uint32_t u32;
1288 struct cvmx_pcieep_cfg468_s {
1289 uint32_t reserved_24_31:8;
1290 uint32_t queue_mode:3;
1291 uint32_t reserved_20_20:1;
1292 uint32_t header_credits:8;
1293 uint32_t data_credits:12;
1294 } s;
1295 struct cvmx_pcieep_cfg468_s cn52xx;
1296 struct cvmx_pcieep_cfg468_s cn52xxp1;
1297 struct cvmx_pcieep_cfg468_s cn56xx;
1298 struct cvmx_pcieep_cfg468_s cn56xxp1;
1299};
1300
1301union cvmx_pcieep_cfg490 {
1302 uint32_t u32;
1303 struct cvmx_pcieep_cfg490_s {
1304 uint32_t reserved_26_31:6;
1305 uint32_t header_depth:10;
1306 uint32_t reserved_14_15:2;
1307 uint32_t data_depth:14;
1308 } s;
1309 struct cvmx_pcieep_cfg490_s cn52xx;
1310 struct cvmx_pcieep_cfg490_s cn52xxp1;
1311 struct cvmx_pcieep_cfg490_s cn56xx;
1312 struct cvmx_pcieep_cfg490_s cn56xxp1;
1313};
1314
1315union cvmx_pcieep_cfg491 {
1316 uint32_t u32;
1317 struct cvmx_pcieep_cfg491_s {
1318 uint32_t reserved_26_31:6;
1319 uint32_t header_depth:10;
1320 uint32_t reserved_14_15:2;
1321 uint32_t data_depth:14;
1322 } s;
1323 struct cvmx_pcieep_cfg491_s cn52xx;
1324 struct cvmx_pcieep_cfg491_s cn52xxp1;
1325 struct cvmx_pcieep_cfg491_s cn56xx;
1326 struct cvmx_pcieep_cfg491_s cn56xxp1;
1327};
1328
1329union cvmx_pcieep_cfg492 {
1330 uint32_t u32;
1331 struct cvmx_pcieep_cfg492_s {
1332 uint32_t reserved_26_31:6;
1333 uint32_t header_depth:10;
1334 uint32_t reserved_14_15:2;
1335 uint32_t data_depth:14;
1336 } s;
1337 struct cvmx_pcieep_cfg492_s cn52xx;
1338 struct cvmx_pcieep_cfg492_s cn52xxp1;
1339 struct cvmx_pcieep_cfg492_s cn56xx;
1340 struct cvmx_pcieep_cfg492_s cn56xxp1;
1341};
1342
1343union cvmx_pcieep_cfg516 {
1344 uint32_t u32;
1345 struct cvmx_pcieep_cfg516_s {
1346 uint32_t phy_stat:32;
1347 } s;
1348 struct cvmx_pcieep_cfg516_s cn52xx;
1349 struct cvmx_pcieep_cfg516_s cn52xxp1;
1350 struct cvmx_pcieep_cfg516_s cn56xx;
1351 struct cvmx_pcieep_cfg516_s cn56xxp1;
1352};
1353
1354union cvmx_pcieep_cfg517 {
1355 uint32_t u32;
1356 struct cvmx_pcieep_cfg517_s {
1357 uint32_t phy_ctrl:32;
1358 } s;
1359 struct cvmx_pcieep_cfg517_s cn52xx;
1360 struct cvmx_pcieep_cfg517_s cn52xxp1;
1361 struct cvmx_pcieep_cfg517_s cn56xx;
1362 struct cvmx_pcieep_cfg517_s cn56xxp1;
1363};
1364
1365#endif
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index fcd4060f642..90bf3b3fce1 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/ioport.h> 19#include <linux/ioport.h>
20#include <linux/of.h>
20 21
21/* 22/*
22 * Each pci channel is a top-level PCI bus seem by CPU. A machine with 23 * Each pci channel is a top-level PCI bus seem by CPU. A machine with
@@ -26,6 +27,7 @@
26struct pci_controller { 27struct pci_controller {
27 struct pci_controller *next; 28 struct pci_controller *next;
28 struct pci_bus *bus; 29 struct pci_bus *bus;
30 struct device_node *of_node;
29 31
30 struct pci_ops *pci_ops; 32 struct pci_ops *pci_ops;
31 struct resource *mem_resource; 33 struct resource *mem_resource;
@@ -142,4 +144,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
142 144
143extern char * (*pcibios_plat_setup)(char *str); 145extern char * (*pcibios_plat_setup)(char *str);
144 146
147/* this function parses memory ranges from a device node */
148extern void __devinit pci_load_of_ranges(struct pci_controller *hose,
149 struct device_node *node);
150
145#endif /* _ASM_PCI_H */ 151#endif /* _ASM_PCI_H */
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index 7a6e82ef449..7206d445bab 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -12,6 +12,9 @@
12#define __ASM_PROM_H 12#define __ASM_PROM_H
13 13
14#ifdef CONFIG_OF 14#ifdef CONFIG_OF
15#include <linux/bug.h>
16#include <linux/io.h>
17#include <linux/types.h>
15#include <asm/bootinfo.h> 18#include <asm/bootinfo.h>
16 19
17extern int early_init_dt_scan_memory_arch(unsigned long node, 20extern int early_init_dt_scan_memory_arch(unsigned long node,
@@ -21,6 +24,29 @@ extern int reserve_mem_mach(unsigned long addr, unsigned long size);
21extern void free_mem_mach(unsigned long addr, unsigned long size); 24extern void free_mem_mach(unsigned long addr, unsigned long size);
22 25
23extern void device_tree_init(void); 26extern void device_tree_init(void);
27
28static inline unsigned long pci_address_to_pio(phys_addr_t address)
29{
30 /*
31 * The ioport address can be directly used by inX() / outX()
32 */
33 BUG_ON(address > IO_SPACE_LIMIT);
34
35 return (unsigned long) address;
36}
37#define pci_address_to_pio pci_address_to_pio
38
39struct boot_param_header;
40
41extern void __dt_setup_arch(struct boot_param_header *bph);
42
43#define dt_setup_arch(sym) \
44({ \
45 extern struct boot_param_header __dtb_##sym##_begin; \
46 \
47 __dt_setup_arch(&__dtb_##sym##_begin); \
48})
49
24#else /* CONFIG_OF */ 50#else /* CONFIG_OF */
25static inline void device_tree_init(void) { } 51static inline void device_tree_init(void) { }
26#endif /* CONFIG_OF */ 52#endif /* CONFIG_OF */
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
index 6dce6d8d09a..2560b6b6a7d 100644
--- a/arch/mips/include/asm/setup.h
+++ b/arch/mips/include/asm/setup.h
@@ -14,7 +14,8 @@ extern void *set_vi_handler(int n, vi_handler_t addr);
14 14
15extern void *set_except_vector(int n, void *addr); 15extern void *set_except_vector(int n, void *addr);
16extern unsigned long ebase; 16extern unsigned long ebase;
17extern void per_cpu_trap_init(void); 17extern void per_cpu_trap_init(bool);
18extern void cpu_cache_init(void);
18 19
19#endif /* __KERNEL__ */ 20#endif /* __KERNEL__ */
20 21
diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h
index 7165333ad04..4461198361c 100644
--- a/arch/mips/include/asm/sparsemem.h
+++ b/arch/mips/include/asm/sparsemem.h
@@ -6,7 +6,11 @@
6 * SECTION_SIZE_BITS 2^N: how big each section will be 6 * SECTION_SIZE_BITS 2^N: how big each section will be
7 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space 7 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
8 */ 8 */
9#define SECTION_SIZE_BITS 28 9#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PAGE_SIZE_64KB)
10# define SECTION_SIZE_BITS 29
11#else
12# define SECTION_SIZE_BITS 28
13#endif
10#define MAX_PHYSMEM_BITS 35 14#define MAX_PHYSMEM_BITS 35
11 15
12#endif /* CONFIG_SPARSEMEM */ 16#endif /* CONFIG_SPARSEMEM */
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
index 8f77f774a2a..abdd87aaf60 100644
--- a/arch/mips/include/asm/termios.h
+++ b/arch/mips/include/asm/termios.h
@@ -60,7 +60,7 @@ struct termio {
60}; 60};
61 61
62#ifdef __KERNEL__ 62#ifdef __KERNEL__
63#include <linux/module.h> 63#include <asm/uaccess.h>
64 64
65/* 65/*
66 * intr=^C quit=^\ erase=del kill=^U 66 * intr=^C quit=^\ erase=del kill=^U
diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h
index ff74aec3561..420ca06b2f4 100644
--- a/arch/mips/include/asm/traps.h
+++ b/arch/mips/include/asm/traps.h
@@ -25,6 +25,7 @@ extern void (*board_nmi_handler_setup)(void);
25extern void (*board_ejtag_handler_setup)(void); 25extern void (*board_ejtag_handler_setup)(void);
26extern void (*board_bind_eic_interrupt)(int irq, int regset); 26extern void (*board_bind_eic_interrupt)(int irq, int regset);
27extern void (*board_ebase_setup)(void); 27extern void (*board_ebase_setup)(void);
28extern void (*board_cache_error_setup)(void);
28 29
29extern int register_nmi_notifier(struct notifier_block *nb); 30extern int register_nmi_notifier(struct notifier_block *nb);
30 31
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 504d40aedfa..440a21dab57 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -11,7 +11,7 @@
11#include <linux/types.h> 11#include <linux/types.h>
12 12
13#ifdef CONFIG_EXPORT_UASM 13#ifdef CONFIG_EXPORT_UASM
14#include <linux/module.h> 14#include <linux/export.h>
15#define __uasminit 15#define __uasminit
16#define __uasminitdata 16#define __uasminitdata
17#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym) 17#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index a9dff332125..e44abea9c20 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -16,5 +16,3 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
16# PM support 16# PM support
17 17
18obj-$(CONFIG_PM) += pm.o 18obj-$(CONFIG_PM) += pm.o
19
20ccflags-y := -Werror -Wall
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 5099201fb7b..6ae7ce4ac63 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -340,7 +340,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
340 __cpu_name[cpu] = "R2000"; 340 __cpu_name[cpu] = "R2000";
341 c->isa_level = MIPS_CPU_ISA_I; 341 c->isa_level = MIPS_CPU_ISA_I;
342 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | 342 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
343 MIPS_CPU_NOFPUEX; 343 MIPS_CPU_NOFPUEX;
344 if (__cpu_has_fpu()) 344 if (__cpu_has_fpu())
345 c->options |= MIPS_CPU_FPU; 345 c->options |= MIPS_CPU_FPU;
346 c->tlbsize = 64; 346 c->tlbsize = 64;
@@ -361,7 +361,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
361 } 361 }
362 c->isa_level = MIPS_CPU_ISA_I; 362 c->isa_level = MIPS_CPU_ISA_I;
363 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | 363 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
364 MIPS_CPU_NOFPUEX; 364 MIPS_CPU_NOFPUEX;
365 if (__cpu_has_fpu()) 365 if (__cpu_has_fpu())
366 c->options |= MIPS_CPU_FPU; 366 c->options |= MIPS_CPU_FPU;
367 c->tlbsize = 64; 367 c->tlbsize = 64;
@@ -387,8 +387,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
387 387
388 c->isa_level = MIPS_CPU_ISA_III; 388 c->isa_level = MIPS_CPU_ISA_III;
389 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 389 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
390 MIPS_CPU_WATCH | MIPS_CPU_VCE | 390 MIPS_CPU_WATCH | MIPS_CPU_VCE |
391 MIPS_CPU_LLSC; 391 MIPS_CPU_LLSC;
392 c->tlbsize = 48; 392 c->tlbsize = 48;
393 break; 393 break;
394 case PRID_IMP_VR41XX: 394 case PRID_IMP_VR41XX:
@@ -434,7 +434,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
434 __cpu_name[cpu] = "R4300"; 434 __cpu_name[cpu] = "R4300";
435 c->isa_level = MIPS_CPU_ISA_III; 435 c->isa_level = MIPS_CPU_ISA_III;
436 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 436 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
437 MIPS_CPU_LLSC; 437 MIPS_CPU_LLSC;
438 c->tlbsize = 32; 438 c->tlbsize = 32;
439 break; 439 break;
440 case PRID_IMP_R4600: 440 case PRID_IMP_R4600:
@@ -446,7 +446,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
446 c->tlbsize = 48; 446 c->tlbsize = 48;
447 break; 447 break;
448 #if 0 448 #if 0
449 case PRID_IMP_R4650: 449 case PRID_IMP_R4650:
450 /* 450 /*
451 * This processor doesn't have an MMU, so it's not 451 * This processor doesn't have an MMU, so it's not
452 * "real easy" to run Linux on it. It is left purely 452 * "real easy" to run Linux on it. It is left purely
@@ -455,9 +455,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
455 */ 455 */
456 c->cputype = CPU_R4650; 456 c->cputype = CPU_R4650;
457 __cpu_name[cpu] = "R4650"; 457 __cpu_name[cpu] = "R4650";
458 c->isa_level = MIPS_CPU_ISA_III; 458 c->isa_level = MIPS_CPU_ISA_III;
459 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; 459 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
460 c->tlbsize = 48; 460 c->tlbsize = 48;
461 break; 461 break;
462 #endif 462 #endif
463 case PRID_IMP_TX39: 463 case PRID_IMP_TX39:
@@ -488,7 +488,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
488 __cpu_name[cpu] = "R4700"; 488 __cpu_name[cpu] = "R4700";
489 c->isa_level = MIPS_CPU_ISA_III; 489 c->isa_level = MIPS_CPU_ISA_III;
490 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 490 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
491 MIPS_CPU_LLSC; 491 MIPS_CPU_LLSC;
492 c->tlbsize = 48; 492 c->tlbsize = 48;
493 break; 493 break;
494 case PRID_IMP_TX49: 494 case PRID_IMP_TX49:
@@ -505,7 +505,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
505 __cpu_name[cpu] = "R5000"; 505 __cpu_name[cpu] = "R5000";
506 c->isa_level = MIPS_CPU_ISA_IV; 506 c->isa_level = MIPS_CPU_ISA_IV;
507 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 507 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
508 MIPS_CPU_LLSC; 508 MIPS_CPU_LLSC;
509 c->tlbsize = 48; 509 c->tlbsize = 48;
510 break; 510 break;
511 case PRID_IMP_R5432: 511 case PRID_IMP_R5432:
@@ -513,7 +513,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
513 __cpu_name[cpu] = "R5432"; 513 __cpu_name[cpu] = "R5432";
514 c->isa_level = MIPS_CPU_ISA_IV; 514 c->isa_level = MIPS_CPU_ISA_IV;
515 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 515 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
516 MIPS_CPU_WATCH | MIPS_CPU_LLSC; 516 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
517 c->tlbsize = 48; 517 c->tlbsize = 48;
518 break; 518 break;
519 case PRID_IMP_R5500: 519 case PRID_IMP_R5500:
@@ -521,7 +521,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
521 __cpu_name[cpu] = "R5500"; 521 __cpu_name[cpu] = "R5500";
522 c->isa_level = MIPS_CPU_ISA_IV; 522 c->isa_level = MIPS_CPU_ISA_IV;
523 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 523 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
524 MIPS_CPU_WATCH | MIPS_CPU_LLSC; 524 MIPS_CPU_WATCH | MIPS_CPU_LLSC;
525 c->tlbsize = 48; 525 c->tlbsize = 48;
526 break; 526 break;
527 case PRID_IMP_NEVADA: 527 case PRID_IMP_NEVADA:
@@ -529,7 +529,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
529 __cpu_name[cpu] = "Nevada"; 529 __cpu_name[cpu] = "Nevada";
530 c->isa_level = MIPS_CPU_ISA_IV; 530 c->isa_level = MIPS_CPU_ISA_IV;
531 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 531 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
532 MIPS_CPU_DIVEC | MIPS_CPU_LLSC; 532 MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
533 c->tlbsize = 48; 533 c->tlbsize = 48;
534 break; 534 break;
535 case PRID_IMP_R6000: 535 case PRID_IMP_R6000:
@@ -537,7 +537,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
537 __cpu_name[cpu] = "R6000"; 537 __cpu_name[cpu] = "R6000";
538 c->isa_level = MIPS_CPU_ISA_II; 538 c->isa_level = MIPS_CPU_ISA_II;
539 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | 539 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
540 MIPS_CPU_LLSC; 540 MIPS_CPU_LLSC;
541 c->tlbsize = 32; 541 c->tlbsize = 32;
542 break; 542 break;
543 case PRID_IMP_R6000A: 543 case PRID_IMP_R6000A:
@@ -545,7 +545,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
545 __cpu_name[cpu] = "R6000A"; 545 __cpu_name[cpu] = "R6000A";
546 c->isa_level = MIPS_CPU_ISA_II; 546 c->isa_level = MIPS_CPU_ISA_II;
547 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | 547 c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
548 MIPS_CPU_LLSC; 548 MIPS_CPU_LLSC;
549 c->tlbsize = 32; 549 c->tlbsize = 32;
550 break; 550 break;
551 case PRID_IMP_RM7000: 551 case PRID_IMP_RM7000:
@@ -553,7 +553,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
553 __cpu_name[cpu] = "RM7000"; 553 __cpu_name[cpu] = "RM7000";
554 c->isa_level = MIPS_CPU_ISA_IV; 554 c->isa_level = MIPS_CPU_ISA_IV;
555 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 555 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
556 MIPS_CPU_LLSC; 556 MIPS_CPU_LLSC;
557 /* 557 /*
558 * Undocumented RM7000: Bit 29 in the info register of 558 * Undocumented RM7000: Bit 29 in the info register of
559 * the RM7000 v2.0 indicates if the TLB has 48 or 64 559 * the RM7000 v2.0 indicates if the TLB has 48 or 64
@@ -569,7 +569,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
569 __cpu_name[cpu] = "RM9000"; 569 __cpu_name[cpu] = "RM9000";
570 c->isa_level = MIPS_CPU_ISA_IV; 570 c->isa_level = MIPS_CPU_ISA_IV;
571 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 571 c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
572 MIPS_CPU_LLSC; 572 MIPS_CPU_LLSC;
573 /* 573 /*
574 * Bit 29 in the info register of the RM9000 574 * Bit 29 in the info register of the RM9000
575 * indicates if the TLB has 48 or 64 entries. 575 * indicates if the TLB has 48 or 64 entries.
@@ -584,8 +584,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
584 __cpu_name[cpu] = "RM8000"; 584 __cpu_name[cpu] = "RM8000";
585 c->isa_level = MIPS_CPU_ISA_IV; 585 c->isa_level = MIPS_CPU_ISA_IV;
586 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 586 c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
587 MIPS_CPU_FPU | MIPS_CPU_32FPR | 587 MIPS_CPU_FPU | MIPS_CPU_32FPR |
588 MIPS_CPU_LLSC; 588 MIPS_CPU_LLSC;
589 c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ 589 c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
590 break; 590 break;
591 case PRID_IMP_R10000: 591 case PRID_IMP_R10000:
@@ -593,9 +593,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
593 __cpu_name[cpu] = "R10000"; 593 __cpu_name[cpu] = "R10000";
594 c->isa_level = MIPS_CPU_ISA_IV; 594 c->isa_level = MIPS_CPU_ISA_IV;
595 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | 595 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
596 MIPS_CPU_FPU | MIPS_CPU_32FPR | 596 MIPS_CPU_FPU | MIPS_CPU_32FPR |
597 MIPS_CPU_COUNTER | MIPS_CPU_WATCH | 597 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
598 MIPS_CPU_LLSC; 598 MIPS_CPU_LLSC;
599 c->tlbsize = 64; 599 c->tlbsize = 64;
600 break; 600 break;
601 case PRID_IMP_R12000: 601 case PRID_IMP_R12000:
@@ -603,9 +603,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
603 __cpu_name[cpu] = "R12000"; 603 __cpu_name[cpu] = "R12000";
604 c->isa_level = MIPS_CPU_ISA_IV; 604 c->isa_level = MIPS_CPU_ISA_IV;
605 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | 605 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
606 MIPS_CPU_FPU | MIPS_CPU_32FPR | 606 MIPS_CPU_FPU | MIPS_CPU_32FPR |
607 MIPS_CPU_COUNTER | MIPS_CPU_WATCH | 607 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
608 MIPS_CPU_LLSC; 608 MIPS_CPU_LLSC;
609 c->tlbsize = 64; 609 c->tlbsize = 64;
610 break; 610 break;
611 case PRID_IMP_R14000: 611 case PRID_IMP_R14000:
@@ -613,9 +613,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
613 __cpu_name[cpu] = "R14000"; 613 __cpu_name[cpu] = "R14000";
614 c->isa_level = MIPS_CPU_ISA_IV; 614 c->isa_level = MIPS_CPU_ISA_IV;
615 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | 615 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
616 MIPS_CPU_FPU | MIPS_CPU_32FPR | 616 MIPS_CPU_FPU | MIPS_CPU_32FPR |
617 MIPS_CPU_COUNTER | MIPS_CPU_WATCH | 617 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
618 MIPS_CPU_LLSC; 618 MIPS_CPU_LLSC;
619 c->tlbsize = 64; 619 c->tlbsize = 64;
620 break; 620 break;
621 case PRID_IMP_LOONGSON2: 621 case PRID_IMP_LOONGSON2:
@@ -739,7 +739,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
739 if (config3 & MIPS_CONF3_VEIC) 739 if (config3 & MIPS_CONF3_VEIC)
740 c->options |= MIPS_CPU_VEIC; 740 c->options |= MIPS_CPU_VEIC;
741 if (config3 & MIPS_CONF3_MT) 741 if (config3 & MIPS_CONF3_MT)
742 c->ases |= MIPS_ASE_MIPSMT; 742 c->ases |= MIPS_ASE_MIPSMT;
743 if (config3 & MIPS_CONF3_ULRI) 743 if (config3 & MIPS_CONF3_ULRI)
744 c->options |= MIPS_CPU_ULRI; 744 c->options |= MIPS_CPU_ULRI;
745 745
@@ -767,7 +767,7 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c)
767 767
768 /* MIPS32 or MIPS64 compliant CPU. */ 768 /* MIPS32 or MIPS64 compliant CPU. */
769 c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | 769 c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
770 MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; 770 MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
771 771
772 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 772 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
773 773
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index ab73fa2fb9b..f29099b104c 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -1532,7 +1532,8 @@ init_hw_perf_events(void)
1532 irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 1532 irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
1533 } else { 1533 } else {
1534#endif 1534#endif
1535 if (cp0_perfcount_irq >= 0) 1535 if ((cp0_perfcount_irq >= 0) &&
1536 (cp0_compare_irq != cp0_perfcount_irq))
1536 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 1537 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
1537 else 1538 else
1538 irq = -1; 1539 irq = -1;
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index f8b2c592514..5542817c1b4 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -41,27 +41,27 @@ static int show_cpuinfo(struct seq_file *m, void *v)
41 41
42 seq_printf(m, "processor\t\t: %ld\n", n); 42 seq_printf(m, "processor\t\t: %ld\n", n);
43 sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", 43 sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
44 cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); 44 cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
45 seq_printf(m, fmt, __cpu_name[n], 45 seq_printf(m, fmt, __cpu_name[n],
46 (version >> 4) & 0x0f, version & 0x0f, 46 (version >> 4) & 0x0f, version & 0x0f,
47 (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); 47 (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
48 seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", 48 seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
49 cpu_data[n].udelay_val / (500000/HZ), 49 cpu_data[n].udelay_val / (500000/HZ),
50 (cpu_data[n].udelay_val / (5000/HZ)) % 100); 50 (cpu_data[n].udelay_val / (5000/HZ)) % 100);
51 seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); 51 seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
52 seq_printf(m, "microsecond timers\t: %s\n", 52 seq_printf(m, "microsecond timers\t: %s\n",
53 cpu_has_counter ? "yes" : "no"); 53 cpu_has_counter ? "yes" : "no");
54 seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize); 54 seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
55 seq_printf(m, "extra interrupt vector\t: %s\n", 55 seq_printf(m, "extra interrupt vector\t: %s\n",
56 cpu_has_divec ? "yes" : "no"); 56 cpu_has_divec ? "yes" : "no");
57 seq_printf(m, "hardware watchpoint\t: %s", 57 seq_printf(m, "hardware watchpoint\t: %s",
58 cpu_has_watch ? "yes, " : "no\n"); 58 cpu_has_watch ? "yes, " : "no\n");
59 if (cpu_has_watch) { 59 if (cpu_has_watch) {
60 seq_printf(m, "count: %d, address/irw mask: [", 60 seq_printf(m, "count: %d, address/irw mask: [",
61 cpu_data[n].watch_reg_count); 61 cpu_data[n].watch_reg_count);
62 for (i = 0; i < cpu_data[n].watch_reg_count; i++) 62 for (i = 0; i < cpu_data[n].watch_reg_count; i++)
63 seq_printf(m, "%s0x%04x", i ? ", " : "" , 63 seq_printf(m, "%s0x%04x", i ? ", " : "" ,
64 cpu_data[n].watch_reg_masks[i]); 64 cpu_data[n].watch_reg_masks[i]);
65 seq_printf(m, "]\n"); 65 seq_printf(m, "]\n");
66 } 66 }
67 seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n", 67 seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
@@ -73,13 +73,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
73 cpu_has_mipsmt ? " mt" : "" 73 cpu_has_mipsmt ? " mt" : ""
74 ); 74 );
75 seq_printf(m, "shadow register sets\t: %d\n", 75 seq_printf(m, "shadow register sets\t: %d\n",
76 cpu_data[n].srsets); 76 cpu_data[n].srsets);
77 seq_printf(m, "kscratch registers\t: %d\n", 77 seq_printf(m, "kscratch registers\t: %d\n",
78 hweight8(cpu_data[n].kscratch_mask)); 78 hweight8(cpu_data[n].kscratch_mask));
79 seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); 79 seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
80 80
81 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", 81 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
82 cpu_has_vce ? "%u" : "not available"); 82 cpu_has_vce ? "%u" : "not available");
83 seq_printf(m, fmt, 'D', vced_count); 83 seq_printf(m, fmt, 'D', vced_count);
84 seq_printf(m, fmt, 'I', vcei_count); 84 seq_printf(m, fmt, 'I', vcei_count);
85 seq_printf(m, "\n"); 85 seq_printf(m, "\n");
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 558b5395795..f11b2bbb826 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -95,3 +95,16 @@ void __init device_tree_init(void)
95 /* free the space reserved for the dt blob */ 95 /* free the space reserved for the dt blob */
96 free_mem_mach(base, size); 96 free_mem_mach(base, size);
97} 97}
98
99void __init __dt_setup_arch(struct boot_param_header *bph)
100{
101 if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
102 pr_err("DTB has bad magic, ignoring builtin OF DTB\n");
103
104 return;
105 }
106
107 initial_boot_params = bph;
108
109 early_init_devtree(initial_boot_params);
110}
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c504b212f8f..a53f8ec37aa 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -605,6 +605,8 @@ void __init setup_arch(char **cmdline_p)
605 605
606 resource_init(); 606 resource_init();
607 plat_smp_setup(); 607 plat_smp_setup();
608
609 cpu_cache_init();
608} 610}
609 611
610unsigned long kernelsp[NR_CPUS]; 612unsigned long kernelsp[NR_CPUS];
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 71a95f55a64..48650c81804 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -106,7 +106,7 @@ asmlinkage __cpuinit void start_secondary(void)
106#endif /* CONFIG_MIPS_MT_SMTC */ 106#endif /* CONFIG_MIPS_MT_SMTC */
107 cpu_probe(); 107 cpu_probe();
108 cpu_report(); 108 cpu_report();
109 per_cpu_trap_init(); 109 per_cpu_trap_init(false);
110 mips_clockevent_init(); 110 mips_clockevent_init();
111 mp_ops->init_secondary(); 111 mp_ops->init_secondary();
112 112
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cfdaaa4cffc..2d0c2a277f5 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -15,6 +15,7 @@
15#include <linux/compiler.h> 15#include <linux/compiler.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h>
18#include <linux/mm.h> 19#include <linux/mm.h>
19#include <linux/sched.h> 20#include <linux/sched.h>
20#include <linux/smp.h> 21#include <linux/smp.h>
@@ -91,7 +92,7 @@ void (*board_nmi_handler_setup)(void);
91void (*board_ejtag_handler_setup)(void); 92void (*board_ejtag_handler_setup)(void);
92void (*board_bind_eic_interrupt)(int irq, int regset); 93void (*board_bind_eic_interrupt)(int irq, int regset);
93void (*board_ebase_setup)(void); 94void (*board_ebase_setup)(void);
94 95void __cpuinitdata(*board_cache_error_setup)(void);
95 96
96static void show_raw_backtrace(unsigned long reg29) 97static void show_raw_backtrace(unsigned long reg29)
97{ 98{
@@ -1490,7 +1491,6 @@ void *set_vi_handler(int n, vi_handler_t addr)
1490 return set_vi_srs_handler(n, addr, 0); 1491 return set_vi_srs_handler(n, addr, 0);
1491} 1492}
1492 1493
1493extern void cpu_cache_init(void);
1494extern void tlb_init(void); 1494extern void tlb_init(void);
1495extern void flush_tlb_handlers(void); 1495extern void flush_tlb_handlers(void);
1496 1496
@@ -1517,7 +1517,7 @@ static int __init ulri_disable(char *s)
1517} 1517}
1518__setup("noulri", ulri_disable); 1518__setup("noulri", ulri_disable);
1519 1519
1520void __cpuinit per_cpu_trap_init(void) 1520void __cpuinit per_cpu_trap_init(bool is_boot_cpu)
1521{ 1521{
1522 unsigned int cpu = smp_processor_id(); 1522 unsigned int cpu = smp_processor_id();
1523 unsigned int status_set = ST0_CU0; 1523 unsigned int status_set = ST0_CU0;
@@ -1616,7 +1616,9 @@ void __cpuinit per_cpu_trap_init(void)
1616#ifdef CONFIG_MIPS_MT_SMTC 1616#ifdef CONFIG_MIPS_MT_SMTC
1617 if (bootTC) { 1617 if (bootTC) {
1618#endif /* CONFIG_MIPS_MT_SMTC */ 1618#endif /* CONFIG_MIPS_MT_SMTC */
1619 cpu_cache_init(); 1619 /* Boot CPU's cache setup in setup_arch(). */
1620 if (!is_boot_cpu)
1621 cpu_cache_init();
1620 tlb_init(); 1622 tlb_init();
1621#ifdef CONFIG_MIPS_MT_SMTC 1623#ifdef CONFIG_MIPS_MT_SMTC
1622 } else if (!secondaryTC) { 1624 } else if (!secondaryTC) {
@@ -1632,7 +1634,7 @@ void __cpuinit per_cpu_trap_init(void)
1632} 1634}
1633 1635
1634/* Install CPU exception handler */ 1636/* Install CPU exception handler */
1635void __init set_handler(unsigned long offset, void *addr, unsigned long size) 1637void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size)
1636{ 1638{
1637 memcpy((void *)(ebase + offset), addr, size); 1639 memcpy((void *)(ebase + offset), addr, size);
1638 local_flush_icache_range(ebase + offset, ebase + offset + size); 1640 local_flush_icache_range(ebase + offset, ebase + offset + size);
@@ -1693,7 +1695,7 @@ void __init trap_init(void)
1693 1695
1694 if (board_ebase_setup) 1696 if (board_ebase_setup)
1695 board_ebase_setup(); 1697 board_ebase_setup();
1696 per_cpu_trap_init(); 1698 per_cpu_trap_init(true);
1697 1699
1698 /* 1700 /*
1699 * Copy the generic exception handlers to their final destination. 1701 * Copy the generic exception handlers to their final destination.
@@ -1797,6 +1799,9 @@ void __init trap_init(void)
1797 1799
1798 set_except_vector(26, handle_dsp); 1800 set_except_vector(26, handle_dsp);
1799 1801
1802 if (board_cache_error_setup)
1803 board_cache_error_setup();
1804
1800 if (cpu_has_vce) 1805 if (cpu_has_vce)
1801 /* Special exception: R4[04]00 uses also the divec space. */ 1806 /* Special exception: R4[04]00 uses also the divec space. */
1802 memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100); 1807 memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100);
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 3fccf210451..20bdf40b3ef 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -16,8 +16,22 @@ config SOC_XWAY
16 bool "XWAY" 16 bool "XWAY"
17 select SOC_TYPE_XWAY 17 select SOC_TYPE_XWAY
18 select HW_HAS_PCI 18 select HW_HAS_PCI
19
20config SOC_FALCON
21 bool "FALCON"
22
23endchoice
24
25choice
26 prompt "Devicetree"
27
28config DT_EASY50712
29 bool "Easy50712"
30 depends on SOC_XWAY
19endchoice 31endchoice
20 32
21source "arch/mips/lantiq/xway/Kconfig" 33config PCI_LANTIQ
34 bool "PCI Support"
35 depends on SOC_XWAY && PCI
22 36
23endif 37endif
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
index e5dae0e24b0..d6bdc579419 100644
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -4,8 +4,11 @@
4# under the terms of the GNU General Public License version 2 as published 4# under the terms of the GNU General Public License version 2 as published
5# by the Free Software Foundation. 5# by the Free Software Foundation.
6 6
7obj-y := irq.o setup.o clk.o prom.o devices.o 7obj-y := irq.o clk.o prom.o
8
9obj-y += dts/
8 10
9obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 11obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
10 12
11obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ 13obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
14obj-$(CONFIG_SOC_FALCON) += falcon/
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
index f3dff05722d..b3ec49838fd 100644
--- a/arch/mips/lantiq/Platform
+++ b/arch/mips/lantiq/Platform
@@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ) += lantiq/
6cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq 6cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
7load-$(CONFIG_LANTIQ) = 0xffffffff80002000 7load-$(CONFIG_LANTIQ) = 0xffffffff80002000
8cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway 8cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
9cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
index 412814fdd3e..d3bcc33f469 100644
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -12,6 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/clkdev.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/list.h> 17#include <linux/list.h>
17 18
@@ -22,44 +23,32 @@
22#include <lantiq_soc.h> 23#include <lantiq_soc.h>
23 24
24#include "clk.h" 25#include "clk.h"
26#include "prom.h"
25 27
26struct clk { 28/* lantiq socs have 3 static clocks */
27 const char *name; 29static struct clk cpu_clk_generic[3];
28 unsigned long rate;
29 unsigned long (*get_rate) (void);
30};
31 30
32static struct clk *cpu_clk; 31void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io)
33static int cpu_clk_cnt; 32{
33 cpu_clk_generic[0].rate = cpu;
34 cpu_clk_generic[1].rate = fpi;
35 cpu_clk_generic[2].rate = io;
36}
34 37
35/* lantiq socs have 3 static clocks */ 38struct clk *clk_get_cpu(void)
36static struct clk cpu_clk_generic[] = { 39{
37 { 40 return &cpu_clk_generic[0];
38 .name = "cpu", 41}
39 .get_rate = ltq_get_cpu_hz, 42
40 }, { 43struct clk *clk_get_fpi(void)
41 .name = "fpi", 44{
42 .get_rate = ltq_get_fpi_hz, 45 return &cpu_clk_generic[1];
43 }, { 46}
44 .name = "io", 47EXPORT_SYMBOL_GPL(clk_get_fpi);
45 .get_rate = ltq_get_io_region_clock, 48
46 }, 49struct clk *clk_get_io(void)
47};
48
49static struct resource ltq_cgu_resource = {
50 .name = "cgu",
51 .start = LTQ_CGU_BASE_ADDR,
52 .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
53 .flags = IORESOURCE_MEM,
54};
55
56/* remapped clock register range */
57void __iomem *ltq_cgu_membase;
58
59void clk_init(void)
60{ 50{
61 cpu_clk = cpu_clk_generic; 51 return &cpu_clk_generic[2];
62 cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
63} 52}
64 53
65static inline int clk_good(struct clk *clk) 54static inline int clk_good(struct clk *clk)
@@ -82,38 +71,71 @@ unsigned long clk_get_rate(struct clk *clk)
82} 71}
83EXPORT_SYMBOL(clk_get_rate); 72EXPORT_SYMBOL(clk_get_rate);
84 73
85struct clk *clk_get(struct device *dev, const char *id) 74int clk_set_rate(struct clk *clk, unsigned long rate)
86{ 75{
87 int i; 76 if (unlikely(!clk_good(clk)))
88 77 return 0;
89 for (i = 0; i < cpu_clk_cnt; i++) 78 if (clk->rates && *clk->rates) {
90 if (!strcmp(id, cpu_clk[i].name)) 79 unsigned long *r = clk->rates;
91 return &cpu_clk[i]; 80
92 BUG(); 81 while (*r && (*r != rate))
93 return ERR_PTR(-ENOENT); 82 r++;
94} 83 if (!*r) {
95EXPORT_SYMBOL(clk_get); 84 pr_err("clk %s.%s: trying to set invalid rate %ld\n",
96 85 clk->cl.dev_id, clk->cl.con_id, rate);
97void clk_put(struct clk *clk) 86 return -1;
98{ 87 }
99 /* not used */ 88 }
89 clk->rate = rate;
90 return 0;
100} 91}
101EXPORT_SYMBOL(clk_put); 92EXPORT_SYMBOL(clk_set_rate);
102 93
103int clk_enable(struct clk *clk) 94int clk_enable(struct clk *clk)
104{ 95{
105 /* not used */ 96 if (unlikely(!clk_good(clk)))
106 return 0; 97 return -1;
98
99 if (clk->enable)
100 return clk->enable(clk);
101
102 return -1;
107} 103}
108EXPORT_SYMBOL(clk_enable); 104EXPORT_SYMBOL(clk_enable);
109 105
110void clk_disable(struct clk *clk) 106void clk_disable(struct clk *clk)
111{ 107{
112 /* not used */ 108 if (unlikely(!clk_good(clk)))
109 return;
110
111 if (clk->disable)
112 clk->disable(clk);
113} 113}
114EXPORT_SYMBOL(clk_disable); 114EXPORT_SYMBOL(clk_disable);
115 115
116static inline u32 ltq_get_counter_resolution(void) 116int clk_activate(struct clk *clk)
117{
118 if (unlikely(!clk_good(clk)))
119 return -1;
120
121 if (clk->activate)
122 return clk->activate(clk);
123
124 return -1;
125}
126EXPORT_SYMBOL(clk_activate);
127
128void clk_deactivate(struct clk *clk)
129{
130 if (unlikely(!clk_good(clk)))
131 return;
132
133 if (clk->deactivate)
134 clk->deactivate(clk);
135}
136EXPORT_SYMBOL(clk_deactivate);
137
138static inline u32 get_counter_resolution(void)
117{ 139{
118 u32 res; 140 u32 res;
119 141
@@ -133,21 +155,11 @@ void __init plat_time_init(void)
133{ 155{
134 struct clk *clk; 156 struct clk *clk;
135 157
136 if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0) 158 ltq_soc_init();
137 panic("Failed to insert cgu memory");
138 159
139 if (request_mem_region(ltq_cgu_resource.start, 160 clk = clk_get_cpu();
140 resource_size(&ltq_cgu_resource), "cgu") < 0) 161 mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
141 panic("Failed to request cgu memory");
142
143 ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
144 resource_size(&ltq_cgu_resource));
145 if (!ltq_cgu_membase) {
146 pr_err("Failed to remap cgu memory\n");
147 unreachable();
148 }
149 clk = clk_get(0, "cpu");
150 mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
151 write_c0_compare(read_c0_count()); 162 write_c0_compare(read_c0_count());
163 pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
152 clk_put(clk); 164 clk_put(clk);
153} 165}
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
index 3328925f2c3..fa670602b91 100644
--- a/arch/mips/lantiq/clk.h
+++ b/arch/mips/lantiq/clk.h
@@ -9,10 +9,70 @@
9#ifndef _LTQ_CLK_H__ 9#ifndef _LTQ_CLK_H__
10#define _LTQ_CLK_H__ 10#define _LTQ_CLK_H__
11 11
12extern void clk_init(void); 12#include <linux/clkdev.h>
13 13
14extern unsigned long ltq_get_cpu_hz(void); 14/* clock speeds */
15extern unsigned long ltq_get_fpi_hz(void); 15#define CLOCK_33M 33333333
16extern unsigned long ltq_get_io_region_clock(void); 16#define CLOCK_60M 60000000
17#define CLOCK_62_5M 62500000
18#define CLOCK_83M 83333333
19#define CLOCK_83_5M 83500000
20#define CLOCK_98_304M 98304000
21#define CLOCK_100M 100000000
22#define CLOCK_111M 111111111
23#define CLOCK_125M 125000000
24#define CLOCK_133M 133333333
25#define CLOCK_150M 150000000
26#define CLOCK_166M 166666666
27#define CLOCK_167M 166666667
28#define CLOCK_196_608M 196608000
29#define CLOCK_200M 200000000
30#define CLOCK_250M 250000000
31#define CLOCK_266M 266666666
32#define CLOCK_300M 300000000
33#define CLOCK_333M 333333333
34#define CLOCK_393M 393215332
35#define CLOCK_400M 400000000
36#define CLOCK_500M 500000000
37#define CLOCK_600M 600000000
38
39/* clock out speeds */
40#define CLOCK_32_768K 32768
41#define CLOCK_1_536M 1536000
42#define CLOCK_2_5M 2500000
43#define CLOCK_12M 12000000
44#define CLOCK_24M 24000000
45#define CLOCK_25M 25000000
46#define CLOCK_30M 30000000
47#define CLOCK_40M 40000000
48#define CLOCK_48M 48000000
49#define CLOCK_50M 50000000
50#define CLOCK_60M 60000000
51
52struct clk {
53 struct clk_lookup cl;
54 unsigned long rate;
55 unsigned long *rates;
56 unsigned int module;
57 unsigned int bits;
58 unsigned long (*get_rate) (void);
59 int (*enable) (struct clk *clk);
60 void (*disable) (struct clk *clk);
61 int (*activate) (struct clk *clk);
62 void (*deactivate) (struct clk *clk);
63 void (*reboot) (struct clk *clk);
64};
65
66extern void clkdev_add_static(unsigned long cpu, unsigned long fpi,
67 unsigned long io);
68
69extern unsigned long ltq_danube_cpu_hz(void);
70extern unsigned long ltq_danube_fpi_hz(void);
71
72extern unsigned long ltq_ar9_cpu_hz(void);
73extern unsigned long ltq_ar9_fpi_hz(void);
74
75extern unsigned long ltq_vr9_cpu_hz(void);
76extern unsigned long ltq_vr9_fpi_hz(void);
17 77
18#endif 78#endif
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
deleted file mode 100644
index de1cb2bcd79..00000000000
--- a/arch/mips/lantiq/devices.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/export.h>
11#include <linux/types.h>
12#include <linux/string.h>
13#include <linux/kernel.h>
14#include <linux/reboot.h>
15#include <linux/platform_device.h>
16#include <linux/leds.h>
17#include <linux/etherdevice.h>
18#include <linux/time.h>
19#include <linux/io.h>
20#include <linux/gpio.h>
21
22#include <asm/bootinfo.h>
23#include <asm/irq.h>
24
25#include <lantiq_soc.h>
26
27#include "devices.h"
28
29/* nor flash */
30static struct resource ltq_nor_resource = {
31 .name = "nor",
32 .start = LTQ_FLASH_START,
33 .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
34 .flags = IORESOURCE_MEM,
35};
36
37static struct platform_device ltq_nor = {
38 .name = "ltq_nor",
39 .resource = &ltq_nor_resource,
40 .num_resources = 1,
41};
42
43void __init ltq_register_nor(struct physmap_flash_data *data)
44{
45 ltq_nor.dev.platform_data = data;
46 platform_device_register(&ltq_nor);
47}
48
49/* watchdog */
50static struct resource ltq_wdt_resource = {
51 .name = "watchdog",
52 .start = LTQ_WDT_BASE_ADDR,
53 .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
54 .flags = IORESOURCE_MEM,
55};
56
57void __init ltq_register_wdt(void)
58{
59 platform_device_register_simple("ltq_wdt", 0, &ltq_wdt_resource, 1);
60}
61
62/* asc ports */
63static struct resource ltq_asc0_resources[] = {
64 {
65 .name = "asc0",
66 .start = LTQ_ASC0_BASE_ADDR,
67 .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
68 .flags = IORESOURCE_MEM,
69 },
70 IRQ_RES(tx, LTQ_ASC_TIR(0)),
71 IRQ_RES(rx, LTQ_ASC_RIR(0)),
72 IRQ_RES(err, LTQ_ASC_EIR(0)),
73};
74
75static struct resource ltq_asc1_resources[] = {
76 {
77 .name = "asc1",
78 .start = LTQ_ASC1_BASE_ADDR,
79 .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
80 .flags = IORESOURCE_MEM,
81 },
82 IRQ_RES(tx, LTQ_ASC_TIR(1)),
83 IRQ_RES(rx, LTQ_ASC_RIR(1)),
84 IRQ_RES(err, LTQ_ASC_EIR(1)),
85};
86
87void __init ltq_register_asc(int port)
88{
89 switch (port) {
90 case 0:
91 platform_device_register_simple("ltq_asc", 0,
92 ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
93 break;
94 case 1:
95 platform_device_register_simple("ltq_asc", 1,
96 ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
97 break;
98 default:
99 break;
100 }
101}
102
103#ifdef CONFIG_PCI
104/* pci */
105static struct platform_device ltq_pci = {
106 .name = "ltq_pci",
107 .num_resources = 0,
108};
109
110void __init ltq_register_pci(struct ltq_pci_data *data)
111{
112 ltq_pci.dev.platform_data = data;
113 platform_device_register(&ltq_pci);
114}
115#else
116void __init ltq_register_pci(struct ltq_pci_data *data)
117{
118 pr_err("kernel is compiled without PCI support\n");
119}
120#endif
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
deleted file mode 100644
index 2947bb19a52..00000000000
--- a/arch/mips/lantiq/devices.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _LTQ_DEVICES_H__
10#define _LTQ_DEVICES_H__
11
12#include <lantiq_platform.h>
13#include <linux/mtd/physmap.h>
14
15#define IRQ_RES(resname, irq) \
16 {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
17
18extern void ltq_register_nor(struct physmap_flash_data *data);
19extern void ltq_register_wdt(void);
20extern void ltq_register_asc(int port);
21extern void ltq_register_pci(struct ltq_pci_data *data);
22
23#endif
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile
new file mode 100644
index 00000000000..674fca45f72
--- /dev/null
+++ b/arch/mips/lantiq/dts/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o
2
3$(obj)/%.dtb: $(obj)/%.dts
4 $(call if_changed,dtc)
diff --git a/arch/mips/lantiq/dts/danube.dtsi b/arch/mips/lantiq/dts/danube.dtsi
new file mode 100644
index 00000000000..3a4520f009c
--- /dev/null
+++ b/arch/mips/lantiq/dts/danube.dtsi
@@ -0,0 +1,105 @@
1/ {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "lantiq,xway", "lantiq,danube";
5
6 cpus {
7 cpu@0 {
8 compatible = "mips,mips24Kc";
9 };
10 };
11
12 biu@1F800000 {
13 #address-cells = <1>;
14 #size-cells = <1>;
15 compatible = "lantiq,biu", "simple-bus";
16 reg = <0x1F800000 0x800000>;
17 ranges = <0x0 0x1F800000 0x7FFFFF>;
18
19 icu0: icu@80200 {
20 #interrupt-cells = <1>;
21 interrupt-controller;
22 compatible = "lantiq,icu";
23 reg = <0x80200 0x120>;
24 };
25
26 watchdog@803F0 {
27 compatible = "lantiq,wdt";
28 reg = <0x803F0 0x10>;
29 };
30 };
31
32 sram@1F000000 {
33 #address-cells = <1>;
34 #size-cells = <1>;
35 compatible = "lantiq,sram";
36 reg = <0x1F000000 0x800000>;
37 ranges = <0x0 0x1F000000 0x7FFFFF>;
38
39 eiu0: eiu@101000 {
40 #interrupt-cells = <1>;
41 interrupt-controller;
42 interrupt-parent;
43 compatible = "lantiq,eiu-xway";
44 reg = <0x101000 0x1000>;
45 };
46
47 pmu0: pmu@102000 {
48 compatible = "lantiq,pmu-xway";
49 reg = <0x102000 0x1000>;
50 };
51
52 cgu0: cgu@103000 {
53 compatible = "lantiq,cgu-xway";
54 reg = <0x103000 0x1000>;
55 #clock-cells = <1>;
56 };
57
58 rcu0: rcu@203000 {
59 compatible = "lantiq,rcu-xway";
60 reg = <0x203000 0x1000>;
61 };
62 };
63
64 fpi@10000000 {
65 #address-cells = <1>;
66 #size-cells = <1>;
67 compatible = "lantiq,fpi", "simple-bus";
68 ranges = <0x0 0x10000000 0xEEFFFFF>;
69 reg = <0x10000000 0xEF00000>;
70
71 gptu@E100A00 {
72 compatible = "lantiq,gptu-xway";
73 reg = <0xE100A00 0x100>;
74 };
75
76 serial@E100C00 {
77 compatible = "lantiq,asc";
78 reg = <0xE100C00 0x400>;
79 interrupt-parent = <&icu0>;
80 interrupts = <112 113 114>;
81 };
82
83 dma0: dma@E104100 {
84 compatible = "lantiq,dma-xway";
85 reg = <0xE104100 0x800>;
86 };
87
88 ebu0: ebu@E105300 {
89 compatible = "lantiq,ebu-xway";
90 reg = <0xE105300 0x100>;
91 };
92
93 pci0: pci@E105400 {
94 #address-cells = <3>;
95 #size-cells = <2>;
96 #interrupt-cells = <1>;
97 compatible = "lantiq,pci-xway";
98 bus-range = <0x0 0x0>;
99 ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */
100 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */
101 reg = <0x7000000 0x8000 /* config space */
102 0xE105400 0x400>; /* pci bridge */
103 };
104 };
105};
diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/lantiq/dts/easy50712.dts
new file mode 100644
index 00000000000..68c17310bc8
--- /dev/null
+++ b/arch/mips/lantiq/dts/easy50712.dts
@@ -0,0 +1,113 @@
1/dts-v1/;
2
3/include/ "danube.dtsi"
4
5/ {
6 chosen {
7 bootargs = "console=ttyLTQ0,115200 init=/etc/preinit";
8 };
9
10 memory@0 {
11 reg = <0x0 0x2000000>;
12 };
13
14 fpi@10000000 {
15 #address-cells = <1>;
16 #size-cells = <1>;
17 localbus@0 {
18 #address-cells = <2>;
19 #size-cells = <1>;
20 ranges = <0 0 0x0 0x3ffffff /* addrsel0 */
21 1 0 0x4000000 0x4000010>; /* addsel1 */
22 compatible = "lantiq,localbus", "simple-bus";
23
24 nor-boot@0 {
25 compatible = "lantiq,nor";
26 bank-width = <2>;
27 reg = <0 0x0 0x2000000>;
28 #address-cells = <1>;
29 #size-cells = <1>;
30
31 partition@0 {
32 label = "uboot";
33 reg = <0x00000 0x10000>; /* 64 KB */
34 };
35
36 partition@10000 {
37 label = "uboot_env";
38 reg = <0x10000 0x10000>; /* 64 KB */
39 };
40
41 partition@20000 {
42 label = "linux";
43 reg = <0x20000 0x3d0000>;
44 };
45
46 partition@400000 {
47 label = "rootfs";
48 reg = <0x400000 0x400000>;
49 };
50 };
51 };
52
53 gpio: pinmux@E100B10 {
54 compatible = "lantiq,pinctrl-xway";
55 pinctrl-names = "default";
56 pinctrl-0 = <&state_default>;
57
58 #gpio-cells = <2>;
59 gpio-controller;
60 reg = <0xE100B10 0xA0>;
61
62 state_default: pinmux {
63 stp {
64 lantiq,groups = "stp";
65 lantiq,function = "stp";
66 };
67 exin {
68 lantiq,groups = "exin1";
69 lantiq,function = "exin";
70 };
71 pci {
72 lantiq,groups = "gnt1";
73 lantiq,function = "pci";
74 };
75 conf_out {
76 lantiq,pins = "io4", "io5", "io6"; /* stp */
77 lantiq,open-drain;
78 lantiq,pull = <0>;
79 };
80 };
81 };
82
83 etop@E180000 {
84 compatible = "lantiq,etop-xway";
85 reg = <0xE180000 0x40000>;
86 interrupt-parent = <&icu0>;
87 interrupts = <73 78>;
88 phy-mode = "rmii";
89 mac-address = [ 00 11 22 33 44 55 ];
90 };
91
92 stp0: stp@E100BB0 {
93 #gpio-cells = <2>;
94 compatible = "lantiq,gpio-stp-xway";
95 gpio-controller;
96 reg = <0xE100BB0 0x40>;
97
98 lantiq,shadow = <0xfff>;
99 lantiq,groups = <0x3>;
100 };
101
102 pci@E105400 {
103 lantiq,bus-clock = <33333333>;
104 interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
105 interrupt-map = <
106 0x7000 0 0 1 &icu0 29 1 // slot 14, irq 29
107 >;
108 gpios-reset = <&gpio 21 0>;
109 req-mask = <0x1>; /* GNT1 */
110 };
111
112 };
113};
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
index 972e05f8763..9b28d0940ef 100644
--- a/arch/mips/lantiq/early_printk.c
+++ b/arch/mips/lantiq/early_printk.c
@@ -6,17 +6,16 @@
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */ 7 */
8 8
9#include <linux/init.h>
10#include <linux/cpu.h> 9#include <linux/cpu.h>
11
12#include <lantiq.h>
13#include <lantiq_soc.h> 10#include <lantiq_soc.h>
14 11
15/* no ioremap possible at this early stage, lets use KSEG1 instead */
16#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
17#define ASC_BUF 1024 12#define ASC_BUF 1024
18#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048)) 13#define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048))
19#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020)) 14#ifdef __BIG_ENDIAN
15#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3))
16#else
17#define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020))
18#endif
20#define TXMASK 0x3F00 19#define TXMASK 0x3F00
21#define TXOFFSET 8 20#define TXOFFSET 8
22 21
@@ -27,7 +26,7 @@ void prom_putchar(char c)
27 local_irq_save(flags); 26 local_irq_save(flags);
28 do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); 27 do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
29 if (c == '\n') 28 if (c == '\n')
30 ltq_w32('\r', LTQ_ASC_TBUF); 29 ltq_w8('\r', LTQ_ASC_TBUF);
31 ltq_w32(c, LTQ_ASC_TBUF); 30 ltq_w8(c, LTQ_ASC_TBUF);
32 local_irq_restore(flags); 31 local_irq_restore(flags);
33} 32}
diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile
new file mode 100644
index 00000000000..ff220f97693
--- /dev/null
+++ b/arch/mips/lantiq/falcon/Makefile
@@ -0,0 +1 @@
obj-y := prom.o reset.o sysctrl.o
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
new file mode 100644
index 00000000000..c1d278f05a3
--- /dev/null
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -0,0 +1,87 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
7 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/kernel.h>
11#include <asm/io.h>
12
13#include <lantiq_soc.h>
14
15#include "../prom.h"
16
17#define SOC_FALCON "Falcon"
18#define SOC_FALCON_D "Falcon-D"
19#define SOC_FALCON_V "Falcon-V"
20#define SOC_FALCON_M "Falcon-M"
21
22#define COMP_FALCON "lantiq,falcon"
23
24#define PART_SHIFT 12
25#define PART_MASK 0x0FFFF000
26#define REV_SHIFT 28
27#define REV_MASK 0xF0000000
28#define SREV_SHIFT 22
29#define SREV_MASK 0x03C00000
30#define TYPE_SHIFT 26
31#define TYPE_MASK 0x3C000000
32
33/* reset, nmi and ejtag exception vectors */
34#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
35#define BOOT_RVEC (BOOT_REG_BASE | 0x00)
36#define BOOT_NVEC (BOOT_REG_BASE | 0x04)
37#define BOOT_EVEC (BOOT_REG_BASE | 0x08)
38
39void __init ltq_soc_nmi_setup(void)
40{
41 extern void (*nmi_handler)(void);
42
43 ltq_w32((unsigned long)&nmi_handler, (void *)BOOT_NVEC);
44}
45
46void __init ltq_soc_ejtag_setup(void)
47{
48 extern void (*ejtag_debug_handler)(void);
49
50 ltq_w32((unsigned long)&ejtag_debug_handler, (void *)BOOT_EVEC);
51}
52
53void __init ltq_soc_detect(struct ltq_soc_info *i)
54{
55 u32 type;
56 i->partnum = (ltq_r32(FALCON_CHIPID) & PART_MASK) >> PART_SHIFT;
57 i->rev = (ltq_r32(FALCON_CHIPID) & REV_MASK) >> REV_SHIFT;
58 i->srev = ((ltq_r32(FALCON_CHIPCONF) & SREV_MASK) >> SREV_SHIFT);
59 i->compatible = COMP_FALCON;
60 i->type = SOC_TYPE_FALCON;
61 sprintf(i->rev_type, "%c%d%d", (i->srev & 0x4) ? ('B') : ('A'),
62 i->rev & 0x7, (i->srev & 0x3) + 1);
63
64 switch (i->partnum) {
65 case SOC_ID_FALCON:
66 type = (ltq_r32(FALCON_CHIPTYPE) & TYPE_MASK) >> TYPE_SHIFT;
67 switch (type) {
68 case 0:
69 i->name = SOC_FALCON_D;
70 break;
71 case 1:
72 i->name = SOC_FALCON_V;
73 break;
74 case 2:
75 i->name = SOC_FALCON_M;
76 break;
77 default:
78 i->name = SOC_FALCON;
79 break;
80 }
81 break;
82
83 default:
84 unreachable();
85 break;
86 }
87}
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c
new file mode 100644
index 00000000000..56824825342
--- /dev/null
+++ b/arch/mips/lantiq/falcon/reset.c
@@ -0,0 +1,90 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
7 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/init.h>
11#include <linux/io.h>
12#include <linux/pm.h>
13#include <asm/reboot.h>
14#include <linux/export.h>
15
16#include <lantiq_soc.h>
17
18/* CPU0 Reset Source Register */
19#define SYS1_CPU0RS 0x0040
20/* reset cause mask */
21#define CPU0RS_MASK 0x0003
22/* CPU0 Boot Mode Register */
23#define SYS1_BM 0x00a0
24/* boot mode mask */
25#define BM_MASK 0x0005
26
27/* allow platform code to find out what surce we booted from */
28unsigned char ltq_boot_select(void)
29{
30 return ltq_sys1_r32(SYS1_BM) & BM_MASK;
31}
32
33/* allow the watchdog driver to find out what the boot reason was */
34int ltq_reset_cause(void)
35{
36 return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK;
37}
38EXPORT_SYMBOL_GPL(ltq_reset_cause);
39
40#define BOOT_REG_BASE (KSEG1 | 0x1F200000)
41#define BOOT_PW1_REG (BOOT_REG_BASE | 0x20)
42#define BOOT_PW2_REG (BOOT_REG_BASE | 0x24)
43#define BOOT_PW1 0x4C545100
44#define BOOT_PW2 0x0051544C
45
46#define WDT_REG_BASE (KSEG1 | 0x1F8803F0)
47#define WDT_PW1 0x00BE0000
48#define WDT_PW2 0x00DC0000
49
50static void machine_restart(char *command)
51{
52 local_irq_disable();
53
54 /* reboot magic */
55 ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */
56 ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */
57 ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */
58
59 /* watchdog magic */
60 ltq_w32(WDT_PW1, (void *)WDT_REG_BASE);
61 ltq_w32(WDT_PW2 |
62 (0x3 << 26) | /* PWL */
63 (0x2 << 24) | /* CLKDIV */
64 (0x1 << 31) | /* enable */
65 (1), /* reload */
66 (void *)WDT_REG_BASE);
67 unreachable();
68}
69
70static void machine_halt(void)
71{
72 local_irq_disable();
73 unreachable();
74}
75
76static void machine_power_off(void)
77{
78 local_irq_disable();
79 unreachable();
80}
81
82static int __init mips_reboot_setup(void)
83{
84 _machine_restart = machine_restart;
85 _machine_halt = machine_halt;
86 pm_power_off = machine_power_off;
87 return 0;
88}
89
90arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
new file mode 100644
index 00000000000..ba0123d13d4
--- /dev/null
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -0,0 +1,260 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
7 * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
8 */
9
10#include <linux/ioport.h>
11#include <linux/export.h>
12#include <linux/clkdev.h>
13#include <linux/of_address.h>
14#include <asm/delay.h>
15
16#include <lantiq_soc.h>
17
18#include "../clk.h"
19
20/* infrastructure control register */
21#define SYS1_INFRAC 0x00bc
22/* Configuration fuses for drivers and pll */
23#define STATUS_CONFIG 0x0040
24
25/* GPE frequency selection */
26#define GPPC_OFFSET 24
27#define GPEFREQ_MASK 0x00000C0
28#define GPEFREQ_OFFSET 10
29/* Clock status register */
30#define SYSCTL_CLKS 0x0000
31/* Clock enable register */
32#define SYSCTL_CLKEN 0x0004
33/* Clock clear register */
34#define SYSCTL_CLKCLR 0x0008
35/* Activation Status Register */
36#define SYSCTL_ACTS 0x0020
37/* Activation Register */
38#define SYSCTL_ACT 0x0024
39/* Deactivation Register */
40#define SYSCTL_DEACT 0x0028
41/* reboot Register */
42#define SYSCTL_RBT 0x002c
43/* CPU0 Clock Control Register */
44#define SYS1_CPU0CC 0x0040
45/* HRST_OUT_N Control Register */
46#define SYS1_HRSTOUTC 0x00c0
47/* clock divider bit */
48#define CPU0CC_CPUDIV 0x0001
49
50/* Activation Status Register */
51#define ACTS_ASC1_ACT 0x00000800
52#define ACTS_I2C_ACT 0x00004000
53#define ACTS_P0 0x00010000
54#define ACTS_P1 0x00010000
55#define ACTS_P2 0x00020000
56#define ACTS_P3 0x00020000
57#define ACTS_P4 0x00040000
58#define ACTS_PADCTRL0 0x00100000
59#define ACTS_PADCTRL1 0x00100000
60#define ACTS_PADCTRL2 0x00200000
61#define ACTS_PADCTRL3 0x00200000
62#define ACTS_PADCTRL4 0x00400000
63
64#define sysctl_w32(m, x, y) ltq_w32((x), sysctl_membase[m] + (y))
65#define sysctl_r32(m, x) ltq_r32(sysctl_membase[m] + (x))
66#define sysctl_w32_mask(m, clear, set, reg) \
67 sysctl_w32(m, (sysctl_r32(m, reg) & ~(clear)) | (set), reg)
68
69#define status_w32(x, y) ltq_w32((x), status_membase + (y))
70#define status_r32(x) ltq_r32(status_membase + (x))
71
72static void __iomem *sysctl_membase[3], *status_membase;
73void __iomem *ltq_sys1_membase, *ltq_ebu_membase;
74
75void falcon_trigger_hrst(int level)
76{
77 sysctl_w32(SYSCTL_SYS1, level & 1, SYS1_HRSTOUTC);
78}
79
80static inline void sysctl_wait(struct clk *clk,
81 unsigned int test, unsigned int reg)
82{
83 int err = 1000000;
84
85 do {} while (--err && ((sysctl_r32(clk->module, reg)
86 & clk->bits) != test));
87 if (!err)
88 pr_err("module de/activation failed %d %08X %08X %08X\n",
89 clk->module, clk->bits, test,
90 sysctl_r32(clk->module, reg) & clk->bits);
91}
92
93static int sysctl_activate(struct clk *clk)
94{
95 sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
96 sysctl_w32(clk->module, clk->bits, SYSCTL_ACT);
97 sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
98 return 0;
99}
100
101static void sysctl_deactivate(struct clk *clk)
102{
103 sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
104 sysctl_w32(clk->module, clk->bits, SYSCTL_DEACT);
105 sysctl_wait(clk, 0, SYSCTL_ACTS);
106}
107
108static int sysctl_clken(struct clk *clk)
109{
110 sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
111 sysctl_wait(clk, clk->bits, SYSCTL_CLKS);
112 return 0;
113}
114
115static void sysctl_clkdis(struct clk *clk)
116{
117 sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
118 sysctl_wait(clk, 0, SYSCTL_CLKS);
119}
120
121static void sysctl_reboot(struct clk *clk)
122{
123 unsigned int act;
124 unsigned int bits;
125
126 act = sysctl_r32(clk->module, SYSCTL_ACT);
127 bits = ~act & clk->bits;
128 if (bits != 0) {
129 sysctl_w32(clk->module, bits, SYSCTL_CLKEN);
130 sysctl_w32(clk->module, bits, SYSCTL_ACT);
131 sysctl_wait(clk, bits, SYSCTL_ACTS);
132 }
133 sysctl_w32(clk->module, act & clk->bits, SYSCTL_RBT);
134 sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
135}
136
137/* enable the ONU core */
138static void falcon_gpe_enable(void)
139{
140 unsigned int freq;
141 unsigned int status;
142
143 /* if if the clock is already enabled */
144 status = sysctl_r32(SYSCTL_SYS1, SYS1_INFRAC);
145 if (status & (1 << (GPPC_OFFSET + 1)))
146 return;
147
148 if (status_r32(STATUS_CONFIG) == 0)
149 freq = 1; /* use 625MHz on unfused chip */
150 else
151 freq = (status_r32(STATUS_CONFIG) &
152 GPEFREQ_MASK) >>
153 GPEFREQ_OFFSET;
154
155 /* apply new frequency */
156 sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
157 freq << (GPPC_OFFSET + 2) , SYS1_INFRAC);
158 udelay(1);
159
160 /* enable new frequency */
161 sysctl_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC);
162 udelay(1);
163}
164
165static inline void clkdev_add_sys(const char *dev, unsigned int module,
166 unsigned int bits)
167{
168 struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
169
170 clk->cl.dev_id = dev;
171 clk->cl.con_id = NULL;
172 clk->cl.clk = clk;
173 clk->module = module;
174 clk->activate = sysctl_activate;
175 clk->deactivate = sysctl_deactivate;
176 clk->enable = sysctl_clken;
177 clk->disable = sysctl_clkdis;
178 clk->reboot = sysctl_reboot;
179 clkdev_add(&clk->cl);
180}
181
182void __init ltq_soc_init(void)
183{
184 struct device_node *np_status =
185 of_find_compatible_node(NULL, NULL, "lantiq,status-falcon");
186 struct device_node *np_ebu =
187 of_find_compatible_node(NULL, NULL, "lantiq,ebu-falcon");
188 struct device_node *np_sys1 =
189 of_find_compatible_node(NULL, NULL, "lantiq,sys1-falcon");
190 struct device_node *np_syseth =
191 of_find_compatible_node(NULL, NULL, "lantiq,syseth-falcon");
192 struct device_node *np_sysgpe =
193 of_find_compatible_node(NULL, NULL, "lantiq,sysgpe-falcon");
194 struct resource res_status, res_ebu, res_sys[3];
195 int i;
196
197 /* check if all the core register ranges are available */
198 if (!np_status || !np_ebu || !np_sys1 || !np_syseth || !np_sysgpe)
199 panic("Failed to load core nodes from devicetree");
200
201 if (of_address_to_resource(np_status, 0, &res_status) ||
202 of_address_to_resource(np_ebu, 0, &res_ebu) ||
203 of_address_to_resource(np_sys1, 0, &res_sys[0]) ||
204 of_address_to_resource(np_syseth, 0, &res_sys[1]) ||
205 of_address_to_resource(np_sysgpe, 0, &res_sys[2]))
206 panic("Failed to get core resources");
207
208 if ((request_mem_region(res_status.start, resource_size(&res_status),
209 res_status.name) < 0) ||
210 (request_mem_region(res_ebu.start, resource_size(&res_ebu),
211 res_ebu.name) < 0) ||
212 (request_mem_region(res_sys[0].start,
213 resource_size(&res_sys[0]),
214 res_sys[0].name) < 0) ||
215 (request_mem_region(res_sys[1].start,
216 resource_size(&res_sys[1]),
217 res_sys[1].name) < 0) ||
218 (request_mem_region(res_sys[2].start,
219 resource_size(&res_sys[2]),
220 res_sys[2].name) < 0))
221 pr_err("Failed to request core reources");
222
223 status_membase = ioremap_nocache(res_status.start,
224 resource_size(&res_status));
225 ltq_ebu_membase = ioremap_nocache(res_ebu.start,
226 resource_size(&res_ebu));
227
228 if (!status_membase || !ltq_ebu_membase)
229 panic("Failed to remap core resources");
230
231 for (i = 0; i < 3; i++) {
232 sysctl_membase[i] = ioremap_nocache(res_sys[i].start,
233 resource_size(&res_sys[i]));
234 if (!sysctl_membase[i])
235 panic("Failed to remap sysctrl resources");
236 }
237 ltq_sys1_membase = sysctl_membase[0];
238
239 falcon_gpe_enable();
240
241 /* get our 3 static rates for cpu, fpi and io clocks */
242 if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV)
243 clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M);
244 else
245 clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M);
246
247 /* add our clock domains */
248 clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0);
249 clkdev_add_sys("1d810100.gpio", SYSCTL_SYSETH, ACTS_P2);
250 clkdev_add_sys("1e800100.gpio", SYSCTL_SYS1, ACTS_P1);
251 clkdev_add_sys("1e800200.gpio", SYSCTL_SYS1, ACTS_P3);
252 clkdev_add_sys("1e800300.gpio", SYSCTL_SYS1, ACTS_P4);
253 clkdev_add_sys("1db01000.pad", SYSCTL_SYSETH, ACTS_PADCTRL0);
254 clkdev_add_sys("1db02000.pad", SYSCTL_SYSETH, ACTS_PADCTRL2);
255 clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1);
256 clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3);
257 clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4);
258 clkdev_add_sys("1e100C00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
259 clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
260}
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index d673731c538..57c1a4e5140 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -9,6 +9,11 @@
9 9
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/ioport.h> 11#include <linux/ioport.h>
12#include <linux/sched.h>
13#include <linux/irqdomain.h>
14#include <linux/of_platform.h>
15#include <linux/of_address.h>
16#include <linux/of_irq.h>
12 17
13#include <asm/bootinfo.h> 18#include <asm/bootinfo.h>
14#include <asm/irq_cpu.h> 19#include <asm/irq_cpu.h>
@@ -16,7 +21,7 @@
16#include <lantiq_soc.h> 21#include <lantiq_soc.h>
17#include <irq.h> 22#include <irq.h>
18 23
19/* register definitions */ 24/* register definitions - internal irqs */
20#define LTQ_ICU_IM0_ISR 0x0000 25#define LTQ_ICU_IM0_ISR 0x0000
21#define LTQ_ICU_IM0_IER 0x0008 26#define LTQ_ICU_IM0_IER 0x0008
22#define LTQ_ICU_IM0_IOSR 0x0010 27#define LTQ_ICU_IM0_IOSR 0x0010
@@ -25,6 +30,7 @@
25#define LTQ_ICU_IM1_ISR 0x0028 30#define LTQ_ICU_IM1_ISR 0x0028
26#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) 31#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
27 32
33/* register definitions - external irqs */
28#define LTQ_EIU_EXIN_C 0x0000 34#define LTQ_EIU_EXIN_C 0x0000
29#define LTQ_EIU_EXIN_INIC 0x0004 35#define LTQ_EIU_EXIN_INIC 0x0004
30#define LTQ_EIU_EXIN_INEN 0x000C 36#define LTQ_EIU_EXIN_INEN 0x000C
@@ -37,10 +43,14 @@
37#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) 43#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
38#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) 44#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
39#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) 45#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
40 46#define XWAY_EXIN_COUNT 3
41#define MAX_EIU 6 47#define MAX_EIU 6
42 48
43/* irqs generated by device attached to the EBU need to be acked in 49/* the performance counter */
50#define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31)
51
52/*
53 * irqs generated by devices attached to the EBU need to be acked in
44 * a special manner 54 * a special manner
45 */ 55 */
46#define LTQ_ICU_EBU_IRQ 22 56#define LTQ_ICU_EBU_IRQ 22
@@ -51,6 +61,17 @@
51#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) 61#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
52#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) 62#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
53 63
64/* our 2 ipi interrupts for VSMP */
65#define MIPS_CPU_IPI_RESCHED_IRQ 0
66#define MIPS_CPU_IPI_CALL_IRQ 1
67
68/* we have a cascade of 8 irqs */
69#define MIPS_CPU_IRQ_CASCADE 8
70
71#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
72int gic_present;
73#endif
74
54static unsigned short ltq_eiu_irq[MAX_EIU] = { 75static unsigned short ltq_eiu_irq[MAX_EIU] = {
55 LTQ_EIU_IR0, 76 LTQ_EIU_IR0,
56 LTQ_EIU_IR1, 77 LTQ_EIU_IR1,
@@ -60,64 +81,51 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = {
60 LTQ_EIU_IR5, 81 LTQ_EIU_IR5,
61}; 82};
62 83
63static struct resource ltq_icu_resource = { 84static int exin_avail;
64 .name = "icu",
65 .start = LTQ_ICU_BASE_ADDR,
66 .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
67 .flags = IORESOURCE_MEM,
68};
69
70static struct resource ltq_eiu_resource = {
71 .name = "eiu",
72 .start = LTQ_EIU_BASE_ADDR,
73 .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
74 .flags = IORESOURCE_MEM,
75};
76
77static void __iomem *ltq_icu_membase; 85static void __iomem *ltq_icu_membase;
78static void __iomem *ltq_eiu_membase; 86static void __iomem *ltq_eiu_membase;
79 87
80void ltq_disable_irq(struct irq_data *d) 88void ltq_disable_irq(struct irq_data *d)
81{ 89{
82 u32 ier = LTQ_ICU_IM0_IER; 90 u32 ier = LTQ_ICU_IM0_IER;
83 int irq_nr = d->irq - INT_NUM_IRQ0; 91 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
84 92
85 ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 93 ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
86 irq_nr %= INT_NUM_IM_OFFSET; 94 offset %= INT_NUM_IM_OFFSET;
87 ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); 95 ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
88} 96}
89 97
90void ltq_mask_and_ack_irq(struct irq_data *d) 98void ltq_mask_and_ack_irq(struct irq_data *d)
91{ 99{
92 u32 ier = LTQ_ICU_IM0_IER; 100 u32 ier = LTQ_ICU_IM0_IER;
93 u32 isr = LTQ_ICU_IM0_ISR; 101 u32 isr = LTQ_ICU_IM0_ISR;
94 int irq_nr = d->irq - INT_NUM_IRQ0; 102 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
95 103
96 ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 104 ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
97 isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 105 isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
98 irq_nr %= INT_NUM_IM_OFFSET; 106 offset %= INT_NUM_IM_OFFSET;
99 ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); 107 ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
100 ltq_icu_w32((1 << irq_nr), isr); 108 ltq_icu_w32(BIT(offset), isr);
101} 109}
102 110
103static void ltq_ack_irq(struct irq_data *d) 111static void ltq_ack_irq(struct irq_data *d)
104{ 112{
105 u32 isr = LTQ_ICU_IM0_ISR; 113 u32 isr = LTQ_ICU_IM0_ISR;
106 int irq_nr = d->irq - INT_NUM_IRQ0; 114 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
107 115
108 isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 116 isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
109 irq_nr %= INT_NUM_IM_OFFSET; 117 offset %= INT_NUM_IM_OFFSET;
110 ltq_icu_w32((1 << irq_nr), isr); 118 ltq_icu_w32(BIT(offset), isr);
111} 119}
112 120
113void ltq_enable_irq(struct irq_data *d) 121void ltq_enable_irq(struct irq_data *d)
114{ 122{
115 u32 ier = LTQ_ICU_IM0_IER; 123 u32 ier = LTQ_ICU_IM0_IER;
116 int irq_nr = d->irq - INT_NUM_IRQ0; 124 int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
117 125
118 ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); 126 ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
119 irq_nr %= INT_NUM_IM_OFFSET; 127 offset %= INT_NUM_IM_OFFSET;
120 ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier); 128 ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
121} 129}
122 130
123static unsigned int ltq_startup_eiu_irq(struct irq_data *d) 131static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
@@ -126,15 +134,15 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
126 134
127 ltq_enable_irq(d); 135 ltq_enable_irq(d);
128 for (i = 0; i < MAX_EIU; i++) { 136 for (i = 0; i < MAX_EIU; i++) {
129 if (d->irq == ltq_eiu_irq[i]) { 137 if (d->hwirq == ltq_eiu_irq[i]) {
130 /* low level - we should really handle set_type */ 138 /* low level - we should really handle set_type */
131 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | 139 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
132 (0x6 << (i * 4)), LTQ_EIU_EXIN_C); 140 (0x6 << (i * 4)), LTQ_EIU_EXIN_C);
133 /* clear all pending */ 141 /* clear all pending */
134 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i), 142 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i),
135 LTQ_EIU_EXIN_INIC); 143 LTQ_EIU_EXIN_INIC);
136 /* enable */ 144 /* enable */
137 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i), 145 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i),
138 LTQ_EIU_EXIN_INEN); 146 LTQ_EIU_EXIN_INEN);
139 break; 147 break;
140 } 148 }
@@ -149,9 +157,9 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d)
149 157
150 ltq_disable_irq(d); 158 ltq_disable_irq(d);
151 for (i = 0; i < MAX_EIU; i++) { 159 for (i = 0; i < MAX_EIU; i++) {
152 if (d->irq == ltq_eiu_irq[i]) { 160 if (d->hwirq == ltq_eiu_irq[i]) {
153 /* disable */ 161 /* disable */
154 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), 162 ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i),
155 LTQ_EIU_EXIN_INEN); 163 LTQ_EIU_EXIN_INEN);
156 break; 164 break;
157 } 165 }
@@ -188,14 +196,15 @@ static void ltq_hw_irqdispatch(int module)
188 if (irq == 0) 196 if (irq == 0)
189 return; 197 return;
190 198
191 /* silicon bug causes only the msb set to 1 to be valid. all 199 /*
200 * silicon bug causes only the msb set to 1 to be valid. all
192 * other bits might be bogus 201 * other bits might be bogus
193 */ 202 */
194 irq = __fls(irq); 203 irq = __fls(irq);
195 do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module)); 204 do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module));
196 205
197 /* if this is a EBU irq, we need to ack it or get a deadlock */ 206 /* if this is a EBU irq, we need to ack it or get a deadlock */
198 if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0)) 207 if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT)
199 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, 208 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
200 LTQ_EBU_PCC_ISTAT); 209 LTQ_EBU_PCC_ISTAT);
201} 210}
@@ -216,6 +225,47 @@ static void ltq_hw5_irqdispatch(void)
216 do_IRQ(MIPS_CPU_TIMER_IRQ); 225 do_IRQ(MIPS_CPU_TIMER_IRQ);
217} 226}
218 227
228#ifdef CONFIG_MIPS_MT_SMP
229void __init arch_init_ipiirq(int irq, struct irqaction *action)
230{
231 setup_irq(irq, action);
232 irq_set_handler(irq, handle_percpu_irq);
233}
234
235static void ltq_sw0_irqdispatch(void)
236{
237 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
238}
239
240static void ltq_sw1_irqdispatch(void)
241{
242 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
243}
244static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
245{
246 scheduler_ipi();
247 return IRQ_HANDLED;
248}
249
250static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
251{
252 smp_call_function_interrupt();
253 return IRQ_HANDLED;
254}
255
256static struct irqaction irq_resched = {
257 .handler = ipi_resched_interrupt,
258 .flags = IRQF_PERCPU,
259 .name = "IPI_resched"
260};
261
262static struct irqaction irq_call = {
263 .handler = ipi_call_interrupt,
264 .flags = IRQF_PERCPU,
265 .name = "IPI_call"
266};
267#endif
268
219asmlinkage void plat_irq_dispatch(void) 269asmlinkage void plat_irq_dispatch(void)
220{ 270{
221 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; 271 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
@@ -238,45 +288,75 @@ out:
238 return; 288 return;
239} 289}
240 290
291static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
292{
293 struct irq_chip *chip = &ltq_irq_type;
294 int i;
295
296 for (i = 0; i < exin_avail; i++)
297 if (hw == ltq_eiu_irq[i])
298 chip = &ltq_eiu_type;
299
300 irq_set_chip_and_handler(hw, chip, handle_level_irq);
301
302 return 0;
303}
304
305static const struct irq_domain_ops irq_domain_ops = {
306 .xlate = irq_domain_xlate_onetwocell,
307 .map = icu_map,
308};
309
241static struct irqaction cascade = { 310static struct irqaction cascade = {
242 .handler = no_action, 311 .handler = no_action,
243 .name = "cascade", 312 .name = "cascade",
244}; 313};
245 314
246void __init arch_init_irq(void) 315int __init icu_of_init(struct device_node *node, struct device_node *parent)
247{ 316{
317 struct device_node *eiu_node;
318 struct resource res;
248 int i; 319 int i;
249 320
250 if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0) 321 if (of_address_to_resource(node, 0, &res))
251 panic("Failed to insert icu memory"); 322 panic("Failed to get icu memory range");
252 323
253 if (request_mem_region(ltq_icu_resource.start, 324 if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
254 resource_size(&ltq_icu_resource), "icu") < 0) 325 pr_err("Failed to request icu memory");
255 panic("Failed to request icu memory");
256 326
257 ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start, 327 ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
258 resource_size(&ltq_icu_resource));
259 if (!ltq_icu_membase) 328 if (!ltq_icu_membase)
260 panic("Failed to remap icu memory"); 329 panic("Failed to remap icu memory");
261 330
262 if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0) 331 /* the external interrupts are optional and xway only */
263 panic("Failed to insert eiu memory"); 332 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
264 333 if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) {
265 if (request_mem_region(ltq_eiu_resource.start, 334 /* find out how many external irq sources we have */
266 resource_size(&ltq_eiu_resource), "eiu") < 0) 335 const __be32 *count = of_get_property(node,
267 panic("Failed to request eiu memory"); 336 "lantiq,count", NULL);
268 337
269 ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start, 338 if (count)
270 resource_size(&ltq_eiu_resource)); 339 exin_avail = *count;
271 if (!ltq_eiu_membase) 340 if (exin_avail > MAX_EIU)
272 panic("Failed to remap eiu memory"); 341 exin_avail = MAX_EIU;
342
343 if (request_mem_region(res.start, resource_size(&res),
344 res.name) < 0)
345 pr_err("Failed to request eiu memory");
346
347 ltq_eiu_membase = ioremap_nocache(res.start,
348 resource_size(&res));
349 if (!ltq_eiu_membase)
350 panic("Failed to remap eiu memory");
351 }
273 352
274 /* make sure all irqs are turned off by default */ 353 /* turn off all irqs by default */
275 for (i = 0; i < 5; i++) 354 for (i = 0; i < 5; i++) {
355 /* make sure all irqs are turned off by default */
276 ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); 356 ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
277 357 /* clear all possibly pending interrupts */
278 /* clear all possibly pending interrupts */ 358 ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
279 ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); 359 }
280 360
281 mips_cpu_irq_init(); 361 mips_cpu_irq_init();
282 362
@@ -293,20 +373,19 @@ void __init arch_init_irq(void)
293 set_vi_handler(7, ltq_hw5_irqdispatch); 373 set_vi_handler(7, ltq_hw5_irqdispatch);
294 } 374 }
295 375
296 for (i = INT_NUM_IRQ0; 376 irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
297 i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++) 377 &irq_domain_ops, 0);
298 if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || 378
299 (i == LTQ_EIU_IR2)) 379#if defined(CONFIG_MIPS_MT_SMP)
300 irq_set_chip_and_handler(i, &ltq_eiu_type, 380 if (cpu_has_vint) {
301 handle_level_irq); 381 pr_info("Setting up IPI vectored interrupts\n");
302 /* EIU3-5 only exist on ar9 and vr9 */ 382 set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch);
303 else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) || 383 set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch);
304 (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9())) 384 }
305 irq_set_chip_and_handler(i, &ltq_eiu_type, 385 arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ,
306 handle_level_irq); 386 &irq_resched);
307 else 387 arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call);
308 irq_set_chip_and_handler(i, &ltq_irq_type, 388#endif
309 handle_level_irq);
310 389
311#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) 390#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
312 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | 391 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
@@ -315,9 +394,23 @@ void __init arch_init_irq(void)
315 set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | 394 set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
316 IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); 395 IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
317#endif 396#endif
397
398 /* tell oprofile which irq to use */
399 cp0_perfcount_irq = LTQ_PERF_IRQ;
400 return 0;
318} 401}
319 402
320unsigned int __cpuinit get_c0_compare_int(void) 403unsigned int __cpuinit get_c0_compare_int(void)
321{ 404{
322 return CP0_LEGACY_COMPARE_IRQ; 405 return CP0_LEGACY_COMPARE_IRQ;
323} 406}
407
408static struct of_device_id __initdata of_irq_ids[] = {
409 { .compatible = "lantiq,icu", .data = icu_of_init },
410 {},
411};
412
413void __init arch_init_irq(void)
414{
415 of_irq_init(of_irq_ids);
416}
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
deleted file mode 100644
index 7e01b8c484e..00000000000
--- a/arch/mips/lantiq/machtypes.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _LANTIQ_MACH_H__
10#define _LANTIQ_MACH_H__
11
12#include <asm/mips_machine.h>
13
14enum lantiq_mach_type {
15 LTQ_MACH_GENERIC = 0,
16 LTQ_MACH_EASY50712, /* Danube evaluation board */
17 LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
18};
19
20#endif
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index e34fcfd0d5c..d185e8477fd 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/export.h> 9#include <linux/export.h>
10#include <linux/clk.h> 10#include <linux/clk.h>
11#include <linux/of_platform.h>
11#include <asm/bootinfo.h> 12#include <asm/bootinfo.h>
12#include <asm/time.h> 13#include <asm/time.h>
13 14
@@ -16,19 +17,15 @@
16#include "prom.h" 17#include "prom.h"
17#include "clk.h" 18#include "clk.h"
18 19
19static struct ltq_soc_info soc_info; 20/* access to the ebu needs to be locked between different drivers */
20 21DEFINE_SPINLOCK(ebu_lock);
21unsigned int ltq_get_cpu_ver(void) 22EXPORT_SYMBOL_GPL(ebu_lock);
22{
23 return soc_info.rev;
24}
25EXPORT_SYMBOL(ltq_get_cpu_ver);
26 23
27unsigned int ltq_get_soc_type(void) 24/*
28{ 25 * this struct is filled by the soc specific detection code and holds
29 return soc_info.type; 26 * information about the specific soc type, revision and name
30} 27 */
31EXPORT_SYMBOL(ltq_get_soc_type); 28static struct ltq_soc_info soc_info;
32 29
33const char *get_system_type(void) 30const char *get_system_type(void)
34{ 31{
@@ -45,27 +42,62 @@ static void __init prom_init_cmdline(void)
45 char **argv = (char **) KSEG1ADDR(fw_arg1); 42 char **argv = (char **) KSEG1ADDR(fw_arg1);
46 int i; 43 int i;
47 44
45 arcs_cmdline[0] = '\0';
46
48 for (i = 0; i < argc; i++) { 47 for (i = 0; i < argc; i++) {
49 char *p = (char *) KSEG1ADDR(argv[i]); 48 char *p = (char *) KSEG1ADDR(argv[i]);
50 49
51 if (p && *p) { 50 if (CPHYSADDR(p) && *p) {
52 strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); 51 strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
53 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); 52 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
54 } 53 }
55 } 54 }
56} 55}
57 56
58void __init prom_init(void) 57void __init plat_mem_setup(void)
59{ 58{
60 struct clk *clk; 59 ioport_resource.start = IOPORT_RESOURCE_START;
60 ioport_resource.end = IOPORT_RESOURCE_END;
61 iomem_resource.start = IOMEM_RESOURCE_START;
62 iomem_resource.end = IOMEM_RESOURCE_END;
63
64 set_io_port_base((unsigned long) KSEG1);
61 65
66 /*
67 * Load the builtin devicetree. This causes the chosen node to be
68 * parsed resulting in our memory appearing
69 */
70 __dt_setup_arch(&__dtb_start);
71}
72
73void __init prom_init(void)
74{
75 /* call the soc specific detetcion code and get it to fill soc_info */
62 ltq_soc_detect(&soc_info); 76 ltq_soc_detect(&soc_info);
63 clk_init(); 77 snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s",
64 clk = clk_get(0, "cpu"); 78 soc_info.name, soc_info.rev_type);
65 snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
66 soc_info.name, soc_info.rev);
67 clk_put(clk);
68 soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; 79 soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
69 pr_info("SoC: %s\n", soc_info.sys_type); 80 pr_info("SoC: %s\n", soc_info.sys_type);
70 prom_init_cmdline(); 81 prom_init_cmdline();
82
83#if defined(CONFIG_MIPS_MT_SMP)
84 if (register_vsmp_smp_ops())
85 panic("failed to register_vsmp_smp_ops()");
86#endif
71} 87}
88
89int __init plat_of_setup(void)
90{
91 static struct of_device_id of_ids[3];
92
93 if (!of_have_populated_dt())
94 panic("device tree not present");
95
96 strncpy(of_ids[0].compatible, soc_info.compatible,
97 sizeof(of_ids[0].compatible));
98 strncpy(of_ids[1].compatible, "simple-bus",
99 sizeof(of_ids[1].compatible));
100 return of_platform_bus_probe(NULL, of_ids, NULL);
101}
102
103arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
index b4229d94280..a3fa1a2bfaa 100644
--- a/arch/mips/lantiq/prom.h
+++ b/arch/mips/lantiq/prom.h
@@ -10,16 +10,22 @@
10#define _LTQ_PROM_H__ 10#define _LTQ_PROM_H__
11 11
12#define LTQ_SYS_TYPE_LEN 0x100 12#define LTQ_SYS_TYPE_LEN 0x100
13#define LTQ_SYS_REV_LEN 0x10
13 14
14struct ltq_soc_info { 15struct ltq_soc_info {
15 unsigned char *name; 16 unsigned char *name;
16 unsigned int rev; 17 unsigned int rev;
18 unsigned char rev_type[LTQ_SYS_REV_LEN];
19 unsigned int srev;
17 unsigned int partnum; 20 unsigned int partnum;
18 unsigned int type; 21 unsigned int type;
19 unsigned char sys_type[LTQ_SYS_TYPE_LEN]; 22 unsigned char sys_type[LTQ_SYS_TYPE_LEN];
23 unsigned char *compatible;
20}; 24};
21 25
22extern void ltq_soc_detect(struct ltq_soc_info *i); 26extern void ltq_soc_detect(struct ltq_soc_info *i);
23extern void ltq_soc_setup(void); 27extern void ltq_soc_init(void);
28
29extern struct boot_param_header __dtb_start;
24 30
25#endif 31#endif
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
deleted file mode 100644
index 1ff6c9d6cb9..00000000000
--- a/arch/mips/lantiq/setup.c
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/kernel.h>
10#include <linux/export.h>
11#include <linux/io.h>
12#include <linux/ioport.h>
13#include <asm/bootinfo.h>
14
15#include <lantiq_soc.h>
16
17#include "machtypes.h"
18#include "devices.h"
19#include "prom.h"
20
21void __init plat_mem_setup(void)
22{
23 /* assume 16M as default incase uboot fails to pass proper ramsize */
24 unsigned long memsize = 16;
25 char **envp = (char **) KSEG1ADDR(fw_arg2);
26
27 ioport_resource.start = IOPORT_RESOURCE_START;
28 ioport_resource.end = IOPORT_RESOURCE_END;
29 iomem_resource.start = IOMEM_RESOURCE_START;
30 iomem_resource.end = IOMEM_RESOURCE_END;
31
32 set_io_port_base((unsigned long) KSEG1);
33
34 while (*envp) {
35 char *e = (char *)KSEG1ADDR(*envp);
36 if (!strncmp(e, "memsize=", 8)) {
37 e += 8;
38 if (strict_strtoul(e, 0, &memsize))
39 pr_warn("bad memsize specified\n");
40 }
41 envp++;
42 }
43 memsize *= 1024 * 1024;
44 add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
45}
46
47static int __init
48lantiq_setup(void)
49{
50 ltq_soc_setup();
51 mips_machine_setup();
52 return 0;
53}
54
55arch_initcall(lantiq_setup);
56
57static void __init
58lantiq_generic_init(void)
59{
60 /* Nothing to do */
61}
62
63MIPS_MACHINE(LTQ_MACH_GENERIC,
64 "Generic",
65 "Generic Lantiq based board",
66 lantiq_generic_init);
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig
deleted file mode 100644
index 2b857de3662..00000000000
--- a/arch/mips/lantiq/xway/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
1if SOC_XWAY
2
3menu "MIPS Machine"
4
5config LANTIQ_MACH_EASY50712
6 bool "Easy50712 - Danube"
7 default y
8
9endmenu
10
11endif
12
13if SOC_AMAZON_SE
14
15menu "MIPS Machine"
16
17config LANTIQ_MACH_EASY50601
18 bool "Easy50601 - Amazon SE"
19 default y
20
21endmenu
22
23endif
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index c517f2e7756..dc3194f6ee4 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,7 +1 @@
1obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o
2
3obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
4obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
5
6obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
7obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c
deleted file mode 100644
index 652258309c9..00000000000
--- a/arch/mips/lantiq/xway/clk-ase.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/io.h>
10#include <linux/export.h>
11#include <linux/init.h>
12#include <linux/clk.h>
13
14#include <asm/time.h>
15#include <asm/irq.h>
16#include <asm/div64.h>
17
18#include <lantiq_soc.h>
19
20/* cgu registers */
21#define LTQ_CGU_SYS 0x0010
22
23unsigned int ltq_get_io_region_clock(void)
24{
25 return CLOCK_133M;
26}
27EXPORT_SYMBOL(ltq_get_io_region_clock);
28
29unsigned int ltq_get_fpi_bus_clock(int fpi)
30{
31 return CLOCK_133M;
32}
33EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
34
35unsigned int ltq_get_cpu_hz(void)
36{
37 if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
38 return CLOCK_266M;
39 else
40 return CLOCK_133M;
41}
42EXPORT_SYMBOL(ltq_get_cpu_hz);
43
44unsigned int ltq_get_fpi_hz(void)
45{
46 return CLOCK_133M;
47}
48EXPORT_SYMBOL(ltq_get_fpi_hz);
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c
deleted file mode 100644
index 696b1a3e064..00000000000
--- a/arch/mips/lantiq/xway/clk-xway.c
+++ /dev/null
@@ -1,223 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/io.h>
10#include <linux/export.h>
11#include <linux/init.h>
12#include <linux/clk.h>
13
14#include <asm/time.h>
15#include <asm/irq.h>
16#include <asm/div64.h>
17
18#include <lantiq_soc.h>
19
20static unsigned int ltq_ram_clocks[] = {
21 CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
22#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
23
24#define BASIC_FREQUENCY_1 35328000
25#define BASIC_FREQUENCY_2 36000000
26#define BASIS_REQUENCY_USB 12000000
27
28#define GET_BITS(x, msb, lsb) \
29 (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
30
31#define LTQ_CGU_PLL0_CFG 0x0004
32#define LTQ_CGU_PLL1_CFG 0x0008
33#define LTQ_CGU_PLL2_CFG 0x000C
34#define LTQ_CGU_SYS 0x0010
35#define LTQ_CGU_UPDATE 0x0014
36#define LTQ_CGU_IF_CLK 0x0018
37#define LTQ_CGU_OSC_CON 0x001C
38#define LTQ_CGU_SMD 0x0020
39#define LTQ_CGU_CT1SR 0x0028
40#define LTQ_CGU_CT2SR 0x002C
41#define LTQ_CGU_PCMCR 0x0030
42#define LTQ_CGU_PCI_CR 0x0034
43#define LTQ_CGU_PD_PC 0x0038
44#define LTQ_CGU_FMR 0x003C
45
46#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
47 (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
48#define CGU_PLL0_BYPASS \
49 (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
50#define CGU_PLL0_CFG_DSMSEL \
51 (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
52#define CGU_PLL0_CFG_FRAC_EN \
53 (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
54#define CGU_PLL1_SRC \
55 (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
56#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
57 (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
58#define CGU_SYS_FPI_SEL (1 << 6)
59#define CGU_SYS_DDR_SEL 0x3
60#define CGU_PLL0_SRC (1 << 29)
61
62#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
63#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
64#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
65#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
66#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
67
68static unsigned int ltq_get_pll0_fdiv(void);
69
70static inline unsigned int get_input_clock(int pll)
71{
72 switch (pll) {
73 case 0:
74 if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
75 return BASIS_REQUENCY_USB;
76 else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
77 return BASIC_FREQUENCY_1;
78 else
79 return BASIC_FREQUENCY_2;
80 case 1:
81 if (CGU_PLL1_SRC)
82 return BASIS_REQUENCY_USB;
83 else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
84 return BASIC_FREQUENCY_1;
85 else
86 return BASIC_FREQUENCY_2;
87 case 2:
88 switch (CGU_PLL2_SRC) {
89 case 0:
90 return ltq_get_pll0_fdiv();
91 case 1:
92 return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
93 BASIC_FREQUENCY_1 :
94 BASIC_FREQUENCY_2;
95 case 2:
96 return BASIS_REQUENCY_USB;
97 }
98 default:
99 return 0;
100 }
101}
102
103static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
104{
105 u64 res, clock = get_input_clock(pll);
106
107 res = num * clock;
108 do_div(res, den);
109 return res;
110}
111
112static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
113 unsigned int K)
114{
115 unsigned int num = ((N + 1) << 10) + K;
116 unsigned int den = (M + 1) << 10;
117
118 return cal_dsm(pll, num, den);
119}
120
121static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
122 unsigned int K)
123{
124 unsigned int num = ((N + 1) << 11) + K + 512;
125 unsigned int den = (M + 1) << 11;
126
127 return cal_dsm(pll, num, den);
128}
129
130static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
131 unsigned int K)
132{
133 unsigned int num = K >= 512 ?
134 ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
135 unsigned int den = (M + 1) << 12;
136
137 return cal_dsm(pll, num, den);
138}
139
140static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
141 unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
142{
143 if (!dsmsel)
144 return mash_dsm(pll, M, N, K);
145 else if (!phase_div_en)
146 return mash_dsm(pll, M, N, K);
147 else
148 return ssff_dsm_2(pll, M, N, K);
149}
150
151static inline unsigned int ltq_get_pll0_fosc(void)
152{
153 if (CGU_PLL0_BYPASS)
154 return get_input_clock(0);
155 else
156 return !CGU_PLL0_CFG_FRAC_EN
157 ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
158 CGU_PLL0_CFG_DSMSEL,
159 CGU_PLL0_PHASE_DIVIDER_ENABLE)
160 : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
161 CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
162 CGU_PLL0_PHASE_DIVIDER_ENABLE);
163}
164
165static unsigned int ltq_get_pll0_fdiv(void)
166{
167 unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
168
169 return (ltq_get_pll0_fosc() + (div >> 1)) / div;
170}
171
172unsigned int ltq_get_io_region_clock(void)
173{
174 unsigned int ret = ltq_get_pll0_fosc();
175
176 switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
177 default:
178 case 0:
179 return (ret + 1) / 2;
180 case 1:
181 return (ret * 2 + 2) / 5;
182 case 2:
183 return (ret + 1) / 3;
184 case 3:
185 return (ret + 2) / 4;
186 }
187}
188EXPORT_SYMBOL(ltq_get_io_region_clock);
189
190unsigned int ltq_get_fpi_bus_clock(int fpi)
191{
192 unsigned int ret = ltq_get_io_region_clock();
193
194 if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
195 ret >>= 1;
196 return ret;
197}
198EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
199
200unsigned int ltq_get_cpu_hz(void)
201{
202 switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
203 case 0:
204 return CLOCK_333M;
205 case 4:
206 return DDR_HZ;
207 case 8:
208 return DDR_HZ << 1;
209 default:
210 return DDR_HZ >> 1;
211 }
212}
213EXPORT_SYMBOL(ltq_get_cpu_hz);
214
215unsigned int ltq_get_fpi_hz(void)
216{
217 unsigned int ddr_clock = DDR_HZ;
218
219 if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
220 return ddr_clock >> 1;
221 return ddr_clock;
222}
223EXPORT_SYMBOL(ltq_get_fpi_hz);
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c
new file mode 100644
index 00000000000..9aa17f79a74
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk.c
@@ -0,0 +1,151 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/io.h>
10#include <linux/export.h>
11#include <linux/init.h>
12#include <linux/clk.h>
13
14#include <asm/time.h>
15#include <asm/irq.h>
16#include <asm/div64.h>
17
18#include <lantiq_soc.h>
19
20#include "../clk.h"
21
22static unsigned int ram_clocks[] = {
23 CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
24#define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3]
25
26/* legacy xway clock */
27#define CGU_SYS 0x10
28
29/* vr9 clock */
30#define CGU_SYS_VR9 0x0c
31#define CGU_IF_CLK_VR9 0x24
32
33unsigned long ltq_danube_fpi_hz(void)
34{
35 unsigned long ddr_clock = DDR_HZ;
36
37 if (ltq_cgu_r32(CGU_SYS) & 0x40)
38 return ddr_clock >> 1;
39 return ddr_clock;
40}
41
42unsigned long ltq_danube_cpu_hz(void)
43{
44 switch (ltq_cgu_r32(CGU_SYS) & 0xc) {
45 case 0:
46 return CLOCK_333M;
47 case 4:
48 return DDR_HZ;
49 case 8:
50 return DDR_HZ << 1;
51 default:
52 return DDR_HZ >> 1;
53 }
54}
55
56unsigned long ltq_ar9_sys_hz(void)
57{
58 if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2)
59 return CLOCK_393M;
60 return CLOCK_333M;
61}
62
63unsigned long ltq_ar9_fpi_hz(void)
64{
65 unsigned long sys = ltq_ar9_sys_hz();
66
67 if (ltq_cgu_r32(CGU_SYS) & BIT(0))
68 return sys;
69 return sys >> 1;
70}
71
72unsigned long ltq_ar9_cpu_hz(void)
73{
74 if (ltq_cgu_r32(CGU_SYS) & BIT(2))
75 return ltq_ar9_fpi_hz();
76 else
77 return ltq_ar9_sys_hz();
78}
79
80unsigned long ltq_vr9_cpu_hz(void)
81{
82 unsigned int cpu_sel;
83 unsigned long clk;
84
85 cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf;
86
87 switch (cpu_sel) {
88 case 0:
89 clk = CLOCK_600M;
90 break;
91 case 1:
92 clk = CLOCK_500M;
93 break;
94 case 2:
95 clk = CLOCK_393M;
96 break;
97 case 3:
98 clk = CLOCK_333M;
99 break;
100 case 5:
101 case 6:
102 clk = CLOCK_196_608M;
103 break;
104 case 7:
105 clk = CLOCK_167M;
106 break;
107 case 4:
108 case 8:
109 case 9:
110 clk = CLOCK_125M;
111 break;
112 default:
113 clk = 0;
114 break;
115 }
116
117 return clk;
118}
119
120unsigned long ltq_vr9_fpi_hz(void)
121{
122 unsigned int ocp_sel, cpu_clk;
123 unsigned long clk;
124
125 cpu_clk = ltq_vr9_cpu_hz();
126 ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3;
127
128 switch (ocp_sel) {
129 case 0:
130 /* OCP ratio 1 */
131 clk = cpu_clk;
132 break;
133 case 2:
134 /* OCP ratio 2 */
135 clk = cpu_clk / 2;
136 break;
137 case 3:
138 /* OCP ratio 2.5 */
139 clk = (cpu_clk * 2) / 5;
140 break;
141 case 4:
142 /* OCP ratio 3 */
143 clk = cpu_clk / 3;
144 break;
145 default:
146 clk = 0;
147 break;
148 }
149
150 return clk;
151}
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
deleted file mode 100644
index d614aa7ff07..00000000000
--- a/arch/mips/lantiq/xway/devices.c
+++ /dev/null
@@ -1,119 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/export.h>
11#include <linux/types.h>
12#include <linux/string.h>
13#include <linux/mtd/physmap.h>
14#include <linux/kernel.h>
15#include <linux/reboot.h>
16#include <linux/platform_device.h>
17#include <linux/leds.h>
18#include <linux/etherdevice.h>
19#include <linux/time.h>
20#include <linux/io.h>
21#include <linux/gpio.h>
22
23#include <asm/bootinfo.h>
24#include <asm/irq.h>
25
26#include <lantiq_soc.h>
27#include <lantiq_irq.h>
28#include <lantiq_platform.h>
29
30#include "devices.h"
31
32/* gpio */
33static struct resource ltq_gpio_resource[] = {
34 {
35 .name = "gpio0",
36 .start = LTQ_GPIO0_BASE_ADDR,
37 .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
38 .flags = IORESOURCE_MEM,
39 }, {
40 .name = "gpio1",
41 .start = LTQ_GPIO1_BASE_ADDR,
42 .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
43 .flags = IORESOURCE_MEM,
44 }, {
45 .name = "gpio2",
46 .start = LTQ_GPIO2_BASE_ADDR,
47 .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
48 .flags = IORESOURCE_MEM,
49 }
50};
51
52void __init ltq_register_gpio(void)
53{
54 platform_device_register_simple("ltq_gpio", 0,
55 &ltq_gpio_resource[0], 1);
56 platform_device_register_simple("ltq_gpio", 1,
57 &ltq_gpio_resource[1], 1);
58
59 /* AR9 and VR9 have an extra gpio block */
60 if (ltq_is_ar9() || ltq_is_vr9()) {
61 platform_device_register_simple("ltq_gpio", 2,
62 &ltq_gpio_resource[2], 1);
63 }
64}
65
66/* serial to parallel conversion */
67static struct resource ltq_stp_resource = {
68 .name = "stp",
69 .start = LTQ_STP_BASE_ADDR,
70 .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
71 .flags = IORESOURCE_MEM,
72};
73
74void __init ltq_register_gpio_stp(void)
75{
76 platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
77}
78
79/* asc ports - amazon se has its own serial mapping */
80static struct resource ltq_ase_asc_resources[] = {
81 {
82 .name = "asc0",
83 .start = LTQ_ASC1_BASE_ADDR,
84 .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
85 .flags = IORESOURCE_MEM,
86 },
87 IRQ_RES(tx, LTQ_ASC_ASE_TIR),
88 IRQ_RES(rx, LTQ_ASC_ASE_RIR),
89 IRQ_RES(err, LTQ_ASC_ASE_EIR),
90};
91
92void __init ltq_register_ase_asc(void)
93{
94 platform_device_register_simple("ltq_asc", 0,
95 ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
96}
97
98/* ethernet */
99static struct resource ltq_etop_resources = {
100 .name = "etop",
101 .start = LTQ_ETOP_BASE_ADDR,
102 .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
103 .flags = IORESOURCE_MEM,
104};
105
106static struct platform_device ltq_etop = {
107 .name = "ltq_etop",
108 .resource = &ltq_etop_resources,
109 .num_resources = 1,
110};
111
112void __init
113ltq_register_etop(struct ltq_eth_data *eth)
114{
115 if (eth) {
116 ltq_etop.dev.platform_data = eth;
117 platform_device_register(&ltq_etop);
118 }
119}
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h
deleted file mode 100644
index e90493471bc..00000000000
--- a/arch/mips/lantiq/xway/devices.h
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _LTQ_DEVICES_XWAY_H__
10#define _LTQ_DEVICES_XWAY_H__
11
12#include "../devices.h"
13#include <linux/phy.h>
14
15extern void ltq_register_gpio(void);
16extern void ltq_register_gpio_stp(void);
17extern void ltq_register_ase_asc(void);
18extern void ltq_register_etop(struct ltq_eth_data *eth);
19
20#endif
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
index b210e936c7c..55d2c4fa471 100644
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -19,7 +19,8 @@
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
22#include <linux/export.h> 22#include <linux/module.h>
23#include <linux/clk.h>
23 24
24#include <lantiq_soc.h> 25#include <lantiq_soc.h>
25#include <xway_dma.h> 26#include <xway_dma.h>
@@ -55,13 +56,6 @@
55#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ 56#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \
56 ltq_dma_membase + (z)) 57 ltq_dma_membase + (z))
57 58
58static struct resource ltq_dma_resource = {
59 .name = "dma",
60 .start = LTQ_DMA_BASE_ADDR,
61 .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
62 .flags = IORESOURCE_MEM,
63};
64
65static void __iomem *ltq_dma_membase; 59static void __iomem *ltq_dma_membase;
66 60
67void 61void
@@ -215,27 +209,28 @@ ltq_dma_init_port(int p)
215} 209}
216EXPORT_SYMBOL_GPL(ltq_dma_init_port); 210EXPORT_SYMBOL_GPL(ltq_dma_init_port);
217 211
218int __init 212static int __devinit
219ltq_dma_init(void) 213ltq_dma_init(struct platform_device *pdev)
220{ 214{
215 struct clk *clk;
216 struct resource *res;
221 int i; 217 int i;
222 218
223 /* insert and request the memory region */ 219 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
224 if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0) 220 if (!res)
225 panic("Failed to insert dma memory"); 221 panic("Failed to get dma resource");
226
227 if (request_mem_region(ltq_dma_resource.start,
228 resource_size(&ltq_dma_resource), "dma") < 0)
229 panic("Failed to request dma memory");
230 222
231 /* remap dma register range */ 223 /* remap dma register range */
232 ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, 224 ltq_dma_membase = devm_request_and_ioremap(&pdev->dev, res);
233 resource_size(&ltq_dma_resource));
234 if (!ltq_dma_membase) 225 if (!ltq_dma_membase)
235 panic("Failed to remap dma memory"); 226 panic("Failed to remap dma resource");
236 227
237 /* power up and reset the dma engine */ 228 /* power up and reset the dma engine */
238 ltq_pmu_enable(PMU_DMA); 229 clk = clk_get(&pdev->dev, NULL);
230 if (IS_ERR(clk))
231 panic("Failed to get dma clock");
232
233 clk_enable(clk);
239 ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); 234 ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
240 235
241 /* disable all interrupts */ 236 /* disable all interrupts */
@@ -248,7 +243,29 @@ ltq_dma_init(void)
248 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); 243 ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
249 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); 244 ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
250 } 245 }
246 dev_info(&pdev->dev, "init done\n");
251 return 0; 247 return 0;
252} 248}
253 249
254postcore_initcall(ltq_dma_init); 250static const struct of_device_id dma_match[] = {
251 { .compatible = "lantiq,dma-xway" },
252 {},
253};
254MODULE_DEVICE_TABLE(of, dma_match);
255
256static struct platform_driver dma_driver = {
257 .probe = ltq_dma_init,
258 .driver = {
259 .name = "dma-xway",
260 .owner = THIS_MODULE,
261 .of_match_table = dma_match,
262 },
263};
264
265int __init
266dma_init(void)
267{
268 return platform_driver_register(&dma_driver);
269}
270
271postcore_initcall(dma_init);
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
deleted file mode 100644
index 862e3e83068..00000000000
--- a/arch/mips/lantiq/xway/ebu.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * EBU - the external bus unit attaches PCI, NOR and NAND
7 *
8 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/ioport.h>
14
15#include <lantiq_soc.h>
16
17/* all access to the ebu must be locked */
18DEFINE_SPINLOCK(ebu_lock);
19EXPORT_SYMBOL_GPL(ebu_lock);
20
21static struct resource ltq_ebu_resource = {
22 .name = "ebu",
23 .start = LTQ_EBU_BASE_ADDR,
24 .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
25 .flags = IORESOURCE_MEM,
26};
27
28/* remapped base addr of the clock unit and external bus unit */
29void __iomem *ltq_ebu_membase;
30
31static int __init lantiq_ebu_init(void)
32{
33 /* insert and request the memory region */
34 if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
35 panic("Failed to insert ebu memory");
36
37 if (request_mem_region(ltq_ebu_resource.start,
38 resource_size(&ltq_ebu_resource), "ebu") < 0)
39 panic("Failed to request ebu memory");
40
41 /* remap ebu register range */
42 ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
43 resource_size(&ltq_ebu_resource));
44 if (!ltq_ebu_membase)
45 panic("Failed to remap ebu memory");
46
47 /* make sure to unprotect the memory region where flash is located */
48 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
49 return 0;
50}
51
52postcore_initcall(lantiq_ebu_init);
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
index c429a5bc080..2ab39e93d9b 100644
--- a/arch/mips/lantiq/xway/gpio.c
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -36,18 +36,6 @@ struct ltq_gpio {
36 36
37static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; 37static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
38 38
39int gpio_to_irq(unsigned int gpio)
40{
41 return -EINVAL;
42}
43EXPORT_SYMBOL(gpio_to_irq);
44
45int irq_to_gpio(unsigned int gpio)
46{
47 return -EINVAL;
48}
49EXPORT_SYMBOL(irq_to_gpio);
50
51int ltq_gpio_request(unsigned int pin, unsigned int alt0, 39int ltq_gpio_request(unsigned int pin, unsigned int alt0,
52 unsigned int alt1, unsigned int dir, const char *name) 40 unsigned int alt1, unsigned int dir, const char *name)
53{ 41{
diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
deleted file mode 100644
index aae17170472..00000000000
--- a/arch/mips/lantiq/xway/gpio_ebu.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/export.h>
11#include <linux/types.h>
12#include <linux/platform_device.h>
13#include <linux/mutex.h>
14#include <linux/gpio.h>
15#include <linux/io.h>
16
17#include <lantiq_soc.h>
18
19/*
20 * By attaching hardware latches to the EBU it is possible to create output
21 * only gpios. This driver configures a special memory address, which when
22 * written to outputs 16 bit to the latches.
23 */
24
25#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */
26#define LTQ_EBU_WP 0x80000000 /* write protect bit */
27
28/* we keep a shadow value of the last value written to the ebu */
29static int ltq_ebu_gpio_shadow = 0x0;
30static void __iomem *ltq_ebu_gpio_membase;
31
32static void ltq_ebu_apply(void)
33{
34 unsigned long flags;
35
36 spin_lock_irqsave(&ebu_lock, flags);
37 ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
38 *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
39 ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
40 spin_unlock_irqrestore(&ebu_lock, flags);
41}
42
43static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
44{
45 if (value)
46 ltq_ebu_gpio_shadow |= (1 << offset);
47 else
48 ltq_ebu_gpio_shadow &= ~(1 << offset);
49 ltq_ebu_apply();
50}
51
52static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
53 int value)
54{
55 ltq_ebu_set(chip, offset, value);
56
57 return 0;
58}
59
60static struct gpio_chip ltq_ebu_chip = {
61 .label = "ltq_ebu",
62 .direction_output = ltq_ebu_direction_output,
63 .set = ltq_ebu_set,
64 .base = 72,
65 .ngpio = 16,
66 .can_sleep = 1,
67 .owner = THIS_MODULE,
68};
69
70static int ltq_ebu_probe(struct platform_device *pdev)
71{
72 int ret = 0;
73 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
74
75 if (!res) {
76 dev_err(&pdev->dev, "failed to get memory resource\n");
77 return -ENOENT;
78 }
79
80 res = devm_request_mem_region(&pdev->dev, res->start,
81 resource_size(res), dev_name(&pdev->dev));
82 if (!res) {
83 dev_err(&pdev->dev, "failed to request memory resource\n");
84 return -EBUSY;
85 }
86
87 ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
88 resource_size(res));
89 if (!ltq_ebu_gpio_membase) {
90 dev_err(&pdev->dev, "Failed to ioremap mem region\n");
91 return -ENOMEM;
92 }
93
94 /* grab the default shadow value passed form the platform code */
95 ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
96
97 /* tell the ebu controller which memory address we will be using */
98 ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
99
100 /* write protect the region */
101 ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
102
103 ret = gpiochip_add(&ltq_ebu_chip);
104 if (!ret)
105 ltq_ebu_apply();
106 return ret;
107}
108
109static struct platform_driver ltq_ebu_driver = {
110 .probe = ltq_ebu_probe,
111 .driver = {
112 .name = "ltq_ebu",
113 .owner = THIS_MODULE,
114 },
115};
116
117static int __init ltq_ebu_init(void)
118{
119 int ret = platform_driver_register(&ltq_ebu_driver);
120
121 if (ret)
122 pr_info("ltq_ebu : Error registering platform driver!");
123 return ret;
124}
125
126postcore_initcall(ltq_ebu_init);
diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
deleted file mode 100644
index fd07d87adaa..00000000000
--- a/arch/mips/lantiq/xway/gpio_stp.c
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
7 *
8 */
9
10#include <linux/slab.h>
11#include <linux/init.h>
12#include <linux/export.h>
13#include <linux/types.h>
14#include <linux/platform_device.h>
15#include <linux/mutex.h>
16#include <linux/io.h>
17#include <linux/gpio.h>
18
19#include <lantiq_soc.h>
20
21#define LTQ_STP_CON0 0x00
22#define LTQ_STP_CON1 0x04
23#define LTQ_STP_CPU0 0x08
24#define LTQ_STP_CPU1 0x0C
25#define LTQ_STP_AR 0x10
26
27#define LTQ_STP_CON_SWU (1 << 31)
28#define LTQ_STP_2HZ 0
29#define LTQ_STP_4HZ (1 << 23)
30#define LTQ_STP_8HZ (2 << 23)
31#define LTQ_STP_10HZ (3 << 23)
32#define LTQ_STP_SPEED_MASK (0xf << 23)
33#define LTQ_STP_UPD_FPI (1 << 31)
34#define LTQ_STP_UPD_MASK (3 << 30)
35#define LTQ_STP_ADSL_SRC (3 << 24)
36
37#define LTQ_STP_GROUP0 (1 << 0)
38
39#define LTQ_STP_RISING 0
40#define LTQ_STP_FALLING (1 << 26)
41#define LTQ_STP_EDGE_MASK (1 << 26)
42
43#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg)
44#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg)
45#define ltq_stp_w32_mask(clear, set, reg) \
46 ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
47 ltq_stp_membase + (reg))
48
49static int ltq_stp_shadow = 0xffff;
50static void __iomem *ltq_stp_membase;
51
52static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
53{
54 if (value)
55 ltq_stp_shadow |= (1 << offset);
56 else
57 ltq_stp_shadow &= ~(1 << offset);
58 ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
59}
60
61static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
62 int value)
63{
64 ltq_stp_set(chip, offset, value);
65
66 return 0;
67}
68
69static struct gpio_chip ltq_stp_chip = {
70 .label = "ltq_stp",
71 .direction_output = ltq_stp_direction_output,
72 .set = ltq_stp_set,
73 .base = 48,
74 .ngpio = 24,
75 .can_sleep = 1,
76 .owner = THIS_MODULE,
77};
78
79static int ltq_stp_hw_init(void)
80{
81 /* the 3 pins used to control the external stp */
82 ltq_gpio_request(4, 1, 0, 1, "stp-st");
83 ltq_gpio_request(5, 1, 0, 1, "stp-d");
84 ltq_gpio_request(6, 1, 0, 1, "stp-sh");
85
86 /* sane defaults */
87 ltq_stp_w32(0, LTQ_STP_AR);
88 ltq_stp_w32(0, LTQ_STP_CPU0);
89 ltq_stp_w32(0, LTQ_STP_CPU1);
90 ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
91 ltq_stp_w32(0, LTQ_STP_CON1);
92
93 /* rising or falling edge */
94 ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
95
96 /* per default stp 15-0 are set */
97 ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
98
99 /* stp are update periodically by the FPI bus */
100 ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
101
102 /* set stp update speed */
103 ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
104
105 /* tell the hardware that pin (led) 0 and 1 are controlled
106 * by the dsl arc
107 */
108 ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
109
110 ltq_pmu_enable(PMU_LED);
111 return 0;
112}
113
114static int __devinit ltq_stp_probe(struct platform_device *pdev)
115{
116 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
117 int ret = 0;
118
119 if (!res)
120 return -ENOENT;
121 res = devm_request_mem_region(&pdev->dev, res->start,
122 resource_size(res), dev_name(&pdev->dev));
123 if (!res) {
124 dev_err(&pdev->dev, "failed to request STP memory\n");
125 return -EBUSY;
126 }
127 ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
128 resource_size(res));
129 if (!ltq_stp_membase) {
130 dev_err(&pdev->dev, "failed to remap STP memory\n");
131 return -ENOMEM;
132 }
133 ret = gpiochip_add(&ltq_stp_chip);
134 if (!ret)
135 ret = ltq_stp_hw_init();
136
137 return ret;
138}
139
140static struct platform_driver ltq_stp_driver = {
141 .probe = ltq_stp_probe,
142 .driver = {
143 .name = "ltq_stp",
144 .owner = THIS_MODULE,
145 },
146};
147
148int __init ltq_stp_init(void)
149{
150 int ret = platform_driver_register(&ltq_stp_driver);
151
152 if (ret)
153 pr_info("ltq_stp: error registering platform driver");
154 return ret;
155}
156
157postcore_initcall(ltq_stp_init);
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c
deleted file mode 100644
index d5aaf637ab1..00000000000
--- a/arch/mips/lantiq/xway/mach-easy50601.c
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/platform_device.h>
11#include <linux/mtd/mtd.h>
12#include <linux/mtd/partitions.h>
13#include <linux/mtd/physmap.h>
14#include <linux/input.h>
15
16#include <lantiq.h>
17
18#include "../machtypes.h"
19#include "devices.h"
20
21static struct mtd_partition easy50601_partitions[] = {
22 {
23 .name = "uboot",
24 .offset = 0x0,
25 .size = 0x10000,
26 },
27 {
28 .name = "uboot_env",
29 .offset = 0x10000,
30 .size = 0x10000,
31 },
32 {
33 .name = "linux",
34 .offset = 0x20000,
35 .size = 0xE0000,
36 },
37 {
38 .name = "rootfs",
39 .offset = 0x100000,
40 .size = 0x300000,
41 },
42};
43
44static struct physmap_flash_data easy50601_flash_data = {
45 .nr_parts = ARRAY_SIZE(easy50601_partitions),
46 .parts = easy50601_partitions,
47};
48
49static void __init easy50601_init(void)
50{
51 ltq_register_nor(&easy50601_flash_data);
52}
53
54MIPS_MACHINE(LTQ_MACH_EASY50601,
55 "EASY50601",
56 "EASY50601 Eval Board",
57 easy50601_init);
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c
deleted file mode 100644
index ea5027b3239..00000000000
--- a/arch/mips/lantiq/xway/mach-easy50712.c
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/init.h>
10#include <linux/platform_device.h>
11#include <linux/mtd/mtd.h>
12#include <linux/mtd/partitions.h>
13#include <linux/mtd/physmap.h>
14#include <linux/input.h>
15#include <linux/phy.h>
16
17#include <lantiq_soc.h>
18#include <irq.h>
19
20#include "../machtypes.h"
21#include "devices.h"
22
23static struct mtd_partition easy50712_partitions[] = {
24 {
25 .name = "uboot",
26 .offset = 0x0,
27 .size = 0x10000,
28 },
29 {
30 .name = "uboot_env",
31 .offset = 0x10000,
32 .size = 0x10000,
33 },
34 {
35 .name = "linux",
36 .offset = 0x20000,
37 .size = 0xe0000,
38 },
39 {
40 .name = "rootfs",
41 .offset = 0x100000,
42 .size = 0x300000,
43 },
44};
45
46static struct physmap_flash_data easy50712_flash_data = {
47 .nr_parts = ARRAY_SIZE(easy50712_partitions),
48 .parts = easy50712_partitions,
49};
50
51static struct ltq_pci_data ltq_pci_data = {
52 .clock = PCI_CLOCK_INT,
53 .gpio = PCI_GNT1 | PCI_REQ1,
54 .irq = {
55 [14] = INT_NUM_IM0_IRL0 + 22,
56 },
57};
58
59static struct ltq_eth_data ltq_eth_data = {
60 .mii_mode = PHY_INTERFACE_MODE_MII,
61};
62
63static void __init easy50712_init(void)
64{
65 ltq_register_gpio_stp();
66 ltq_register_nor(&easy50712_flash_data);
67 ltq_register_pci(&ltq_pci_data);
68 ltq_register_etop(&ltq_eth_data);
69}
70
71MIPS_MACHINE(LTQ_MACH_EASY50712,
72 "EASY50712",
73 "EASY50712 Eval Board",
74 easy50712_init);
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
deleted file mode 100644
index fe85361e032..00000000000
--- a/arch/mips/lantiq/xway/pmu.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/ioport.h>
12
13#include <lantiq_soc.h>
14
15/* PMU - the power management unit allows us to turn part of the core
16 * on and off
17 */
18
19/* the enable / disable registers */
20#define LTQ_PMU_PWDCR 0x1C
21#define LTQ_PMU_PWDSR 0x20
22
23#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
24#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
25
26static struct resource ltq_pmu_resource = {
27 .name = "pmu",
28 .start = LTQ_PMU_BASE_ADDR,
29 .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
30 .flags = IORESOURCE_MEM,
31};
32
33static void __iomem *ltq_pmu_membase;
34
35void ltq_pmu_enable(unsigned int module)
36{
37 int err = 1000000;
38
39 ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
40 do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
41
42 if (!err)
43 panic("activating PMU module failed!");
44}
45EXPORT_SYMBOL(ltq_pmu_enable);
46
47void ltq_pmu_disable(unsigned int module)
48{
49 ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
50}
51EXPORT_SYMBOL(ltq_pmu_disable);
52
53int __init ltq_pmu_init(void)
54{
55 if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
56 panic("Failed to insert pmu memory");
57
58 if (request_mem_region(ltq_pmu_resource.start,
59 resource_size(&ltq_pmu_resource), "pmu") < 0)
60 panic("Failed to request pmu memory");
61
62 ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
63 resource_size(&ltq_pmu_resource));
64 if (!ltq_pmu_membase)
65 panic("Failed to remap pmu memory");
66 return 0;
67}
68
69core_initcall(ltq_pmu_init);
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c
deleted file mode 100644
index ae4959ae865..00000000000
--- a/arch/mips/lantiq/xway/prom-ase.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/export.h>
10#include <linux/clk.h>
11#include <asm/bootinfo.h>
12#include <asm/time.h>
13
14#include <lantiq_soc.h>
15
16#include "../prom.h"
17
18#define SOC_AMAZON_SE "Amazon_SE"
19
20#define PART_SHIFT 12
21#define PART_MASK 0x0FFFFFFF
22#define REV_SHIFT 28
23#define REV_MASK 0xF0000000
24
25void __init ltq_soc_detect(struct ltq_soc_info *i)
26{
27 i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
28 i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
29 switch (i->partnum) {
30 case SOC_ID_AMAZON_SE:
31 i->name = SOC_AMAZON_SE;
32 i->type = SOC_TYPE_AMAZON_SE;
33 break;
34
35 default:
36 unreachable();
37 break;
38 }
39}
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c
deleted file mode 100644
index 2228133ca35..00000000000
--- a/arch/mips/lantiq/xway/prom-xway.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/export.h>
10#include <linux/clk.h>
11#include <asm/bootinfo.h>
12#include <asm/time.h>
13
14#include <lantiq_soc.h>
15
16#include "../prom.h"
17
18#define SOC_DANUBE "Danube"
19#define SOC_TWINPASS "Twinpass"
20#define SOC_AR9 "AR9"
21
22#define PART_SHIFT 12
23#define PART_MASK 0x0FFFFFFF
24#define REV_SHIFT 28
25#define REV_MASK 0xF0000000
26
27void __init ltq_soc_detect(struct ltq_soc_info *i)
28{
29 i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
30 i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
31 switch (i->partnum) {
32 case SOC_ID_DANUBE1:
33 case SOC_ID_DANUBE2:
34 i->name = SOC_DANUBE;
35 i->type = SOC_TYPE_DANUBE;
36 break;
37
38 case SOC_ID_TWINPASS:
39 i->name = SOC_TWINPASS;
40 i->type = SOC_TYPE_DANUBE;
41 break;
42
43 case SOC_ID_ARX188:
44 case SOC_ID_ARX168:
45 case SOC_ID_ARX182:
46 i->name = SOC_AR9;
47 i->type = SOC_TYPE_AR9;
48 break;
49
50 default:
51 unreachable();
52 break;
53 }
54}
diff --git a/arch/mips/lantiq/xway/prom.c b/arch/mips/lantiq/xway/prom.c
new file mode 100644
index 00000000000..248429ab262
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom.c
@@ -0,0 +1,115 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/export.h>
10#include <linux/clk.h>
11#include <asm/bootinfo.h>
12#include <asm/time.h>
13
14#include <lantiq_soc.h>
15
16#include "../prom.h"
17
18#define SOC_DANUBE "Danube"
19#define SOC_TWINPASS "Twinpass"
20#define SOC_AMAZON_SE "Amazon_SE"
21#define SOC_AR9 "AR9"
22#define SOC_GR9 "GR9"
23#define SOC_VR9 "VR9"
24
25#define COMP_DANUBE "lantiq,danube"
26#define COMP_TWINPASS "lantiq,twinpass"
27#define COMP_AMAZON_SE "lantiq,ase"
28#define COMP_AR9 "lantiq,ar9"
29#define COMP_GR9 "lantiq,gr9"
30#define COMP_VR9 "lantiq,vr9"
31
32#define PART_SHIFT 12
33#define PART_MASK 0x0FFFFFFF
34#define REV_SHIFT 28
35#define REV_MASK 0xF0000000
36
37void __init ltq_soc_detect(struct ltq_soc_info *i)
38{
39 i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
40 i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
41 sprintf(i->rev_type, "1.%d", i->rev);
42 switch (i->partnum) {
43 case SOC_ID_DANUBE1:
44 case SOC_ID_DANUBE2:
45 i->name = SOC_DANUBE;
46 i->type = SOC_TYPE_DANUBE;
47 i->compatible = COMP_DANUBE;
48 break;
49
50 case SOC_ID_TWINPASS:
51 i->name = SOC_TWINPASS;
52 i->type = SOC_TYPE_DANUBE;
53 i->compatible = COMP_TWINPASS;
54 break;
55
56 case SOC_ID_ARX188:
57 case SOC_ID_ARX168_1:
58 case SOC_ID_ARX168_2:
59 case SOC_ID_ARX182:
60 i->name = SOC_AR9;
61 i->type = SOC_TYPE_AR9;
62 i->compatible = COMP_AR9;
63 break;
64
65 case SOC_ID_GRX188:
66 case SOC_ID_GRX168:
67 i->name = SOC_GR9;
68 i->type = SOC_TYPE_AR9;
69 i->compatible = COMP_GR9;
70 break;
71
72 case SOC_ID_AMAZON_SE_1:
73 case SOC_ID_AMAZON_SE_2:
74#ifdef CONFIG_PCI
75 panic("ase is only supported for non pci kernels");
76#endif
77 i->name = SOC_AMAZON_SE;
78 i->type = SOC_TYPE_AMAZON_SE;
79 i->compatible = COMP_AMAZON_SE;
80 break;
81
82 case SOC_ID_VRX282:
83 case SOC_ID_VRX268:
84 case SOC_ID_VRX288:
85 i->name = SOC_VR9;
86 i->type = SOC_TYPE_VR9;
87 i->compatible = COMP_VR9;
88 break;
89
90 case SOC_ID_GRX268:
91 case SOC_ID_GRX288:
92 i->name = SOC_GR9;
93 i->type = SOC_TYPE_VR9;
94 i->compatible = COMP_GR9;
95 break;
96
97 case SOC_ID_VRX268_2:
98 case SOC_ID_VRX288_2:
99 i->name = SOC_VR9;
100 i->type = SOC_TYPE_VR9_2;
101 i->compatible = COMP_VR9;
102 break;
103
104 case SOC_ID_GRX282_2:
105 case SOC_ID_GRX288_2:
106 i->name = SOC_GR9;
107 i->type = SOC_TYPE_VR9_2;
108 i->compatible = COMP_GR9;
109 break;
110
111 default:
112 unreachable();
113 break;
114 }
115}
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 8b66bd87f0c..22c55f73aa9 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -11,26 +11,31 @@
11#include <linux/ioport.h> 11#include <linux/ioport.h>
12#include <linux/pm.h> 12#include <linux/pm.h>
13#include <linux/export.h> 13#include <linux/export.h>
14#include <linux/delay.h>
15#include <linux/of_address.h>
16#include <linux/of_platform.h>
17
14#include <asm/reboot.h> 18#include <asm/reboot.h>
15 19
16#include <lantiq_soc.h> 20#include <lantiq_soc.h>
17 21
22#include "../prom.h"
23
18#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) 24#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
19#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) 25#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
20 26
21/* register definitions */ 27/* reset request register */
22#define LTQ_RCU_RST 0x0010 28#define RCU_RST_REQ 0x0010
23#define LTQ_RCU_RST_ALL 0x40000000 29/* reset status register */
24 30#define RCU_RST_STAT 0x0014
25#define LTQ_RCU_RST_STAT 0x0014
26#define LTQ_RCU_STAT_SHIFT 26
27 31
28static struct resource ltq_rcu_resource = { 32/* reboot bit */
29 .name = "rcu", 33#define RCU_RD_SRST BIT(30)
30 .start = LTQ_RCU_BASE_ADDR, 34/* reset cause */
31 .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1, 35#define RCU_STAT_SHIFT 26
32 .flags = IORESOURCE_MEM, 36/* boot selection */
33}; 37#define RCU_BOOT_SEL_SHIFT 26
38#define RCU_BOOT_SEL_MASK 0x7
34 39
35/* remapped base addr of the reset control unit */ 40/* remapped base addr of the reset control unit */
36static void __iomem *ltq_rcu_membase; 41static void __iomem *ltq_rcu_membase;
@@ -38,48 +43,64 @@ static void __iomem *ltq_rcu_membase;
38/* This function is used by the watchdog driver */ 43/* This function is used by the watchdog driver */
39int ltq_reset_cause(void) 44int ltq_reset_cause(void)
40{ 45{
41 u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT); 46 u32 val = ltq_rcu_r32(RCU_RST_STAT);
42 return val >> LTQ_RCU_STAT_SHIFT; 47 return val >> RCU_STAT_SHIFT;
43} 48}
44EXPORT_SYMBOL_GPL(ltq_reset_cause); 49EXPORT_SYMBOL_GPL(ltq_reset_cause);
45 50
51/* allow platform code to find out what source we booted from */
52unsigned char ltq_boot_select(void)
53{
54 u32 val = ltq_rcu_r32(RCU_RST_STAT);
55 return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK;
56}
57
58/* reset a io domain for u micro seconds */
59void ltq_reset_once(unsigned int module, ulong u)
60{
61 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ);
62 udelay(u);
63 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
64}
65
46static void ltq_machine_restart(char *command) 66static void ltq_machine_restart(char *command)
47{ 67{
48 pr_notice("System restart\n");
49 local_irq_disable(); 68 local_irq_disable();
50 ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST); 69 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ);
51 unreachable(); 70 unreachable();
52} 71}
53 72
54static void ltq_machine_halt(void) 73static void ltq_machine_halt(void)
55{ 74{
56 pr_notice("System halted.\n");
57 local_irq_disable(); 75 local_irq_disable();
58 unreachable(); 76 unreachable();
59} 77}
60 78
61static void ltq_machine_power_off(void) 79static void ltq_machine_power_off(void)
62{ 80{
63 pr_notice("Please turn off the power now.\n");
64 local_irq_disable(); 81 local_irq_disable();
65 unreachable(); 82 unreachable();
66} 83}
67 84
68static int __init mips_reboot_setup(void) 85static int __init mips_reboot_setup(void)
69{ 86{
70 /* insert and request the memory region */ 87 struct resource res;
71 if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0) 88 struct device_node *np =
72 panic("Failed to insert rcu memory"); 89 of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway");
90
91 /* check if all the reset register range is available */
92 if (!np)
93 panic("Failed to load reset resources from devicetree");
94
95 if (of_address_to_resource(np, 0, &res))
96 panic("Failed to get rcu memory range");
73 97
74 if (request_mem_region(ltq_rcu_resource.start, 98 if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
75 resource_size(&ltq_rcu_resource), "rcu") < 0) 99 pr_err("Failed to request rcu memory");
76 panic("Failed to request rcu memory");
77 100
78 /* remap rcu register range */ 101 ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res));
79 ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
80 resource_size(&ltq_rcu_resource));
81 if (!ltq_rcu_membase) 102 if (!ltq_rcu_membase)
82 panic("Failed to remap rcu memory"); 103 panic("Failed to remap core memory");
83 104
84 _machine_restart = ltq_machine_restart; 105 _machine_restart = ltq_machine_restart;
85 _machine_halt = ltq_machine_halt; 106 _machine_halt = ltq_machine_halt;
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c
deleted file mode 100644
index f6f326798a3..00000000000
--- a/arch/mips/lantiq/xway/setup-ase.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
7 */
8
9#include <lantiq_soc.h>
10
11#include "../prom.h"
12#include "devices.h"
13
14void __init ltq_soc_setup(void)
15{
16 ltq_register_ase_asc();
17 ltq_register_gpio();
18 ltq_register_wdt();
19}
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c
deleted file mode 100644
index c292f643a85..00000000000
--- a/arch/mips/lantiq/xway/setup-xway.c
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
7 */
8
9#include <lantiq_soc.h>
10
11#include "../prom.h"
12#include "devices.h"
13
14void __init ltq_soc_setup(void)
15{
16 ltq_register_asc(0);
17 ltq_register_asc(1);
18 ltq_register_gpio();
19 ltq_register_wdt();
20}
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
new file mode 100644
index 00000000000..83780f7c842
--- /dev/null
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -0,0 +1,371 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/ioport.h>
10#include <linux/export.h>
11#include <linux/clkdev.h>
12#include <linux/of.h>
13#include <linux/of_platform.h>
14#include <linux/of_address.h>
15
16#include <lantiq_soc.h>
17
18#include "../clk.h"
19#include "../prom.h"
20
21/* clock control register */
22#define CGU_IFCCR 0x0018
23/* system clock register */
24#define CGU_SYS 0x0010
25/* pci control register */
26#define CGU_PCICR 0x0034
27/* ephy configuration register */
28#define CGU_EPHY 0x10
29/* power control register */
30#define PMU_PWDCR 0x1C
31/* power status register */
32#define PMU_PWDSR 0x20
33/* power control register */
34#define PMU_PWDCR1 0x24
35/* power status register */
36#define PMU_PWDSR1 0x28
37/* power control register */
38#define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR))
39/* power status register */
40#define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR))
41
42/* clock gates that we can en/disable */
43#define PMU_USB0_P BIT(0)
44#define PMU_PCI BIT(4)
45#define PMU_DMA BIT(5)
46#define PMU_USB0 BIT(6)
47#define PMU_ASC0 BIT(7)
48#define PMU_EPHY BIT(7) /* ase */
49#define PMU_SPI BIT(8)
50#define PMU_DFE BIT(9)
51#define PMU_EBU BIT(10)
52#define PMU_STP BIT(11)
53#define PMU_GPT BIT(12)
54#define PMU_AHBS BIT(13) /* vr9 */
55#define PMU_FPI BIT(14)
56#define PMU_AHBM BIT(15)
57#define PMU_ASC1 BIT(17)
58#define PMU_PPE_QSB BIT(18)
59#define PMU_PPE_SLL01 BIT(19)
60#define PMU_PPE_TC BIT(21)
61#define PMU_PPE_EMA BIT(22)
62#define PMU_PPE_DPLUM BIT(23)
63#define PMU_PPE_DPLUS BIT(24)
64#define PMU_USB1_P BIT(26)
65#define PMU_USB1 BIT(27)
66#define PMU_SWITCH BIT(28)
67#define PMU_PPE_TOP BIT(29)
68#define PMU_GPHY BIT(30)
69#define PMU_PCIE_CLK BIT(31)
70
71#define PMU1_PCIE_PHY BIT(0)
72#define PMU1_PCIE_CTL BIT(1)
73#define PMU1_PCIE_PDI BIT(4)
74#define PMU1_PCIE_MSI BIT(5)
75
76#define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y))
77#define pmu_r32(x) ltq_r32(pmu_membase + (x))
78
79static void __iomem *pmu_membase;
80void __iomem *ltq_cgu_membase;
81void __iomem *ltq_ebu_membase;
82
83/* legacy function kept alive to ease clkdev transition */
84void ltq_pmu_enable(unsigned int module)
85{
86 int err = 1000000;
87
88 pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR);
89 do {} while (--err && (pmu_r32(PMU_PWDSR) & module));
90
91 if (!err)
92 panic("activating PMU module failed!");
93}
94EXPORT_SYMBOL(ltq_pmu_enable);
95
96/* legacy function kept alive to ease clkdev transition */
97void ltq_pmu_disable(unsigned int module)
98{
99 pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR);
100}
101EXPORT_SYMBOL(ltq_pmu_disable);
102
103/* enable a hw clock */
104static int cgu_enable(struct clk *clk)
105{
106 ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR);
107 return 0;
108}
109
110/* disable a hw clock */
111static void cgu_disable(struct clk *clk)
112{
113 ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR);
114}
115
116/* enable a clock gate */
117static int pmu_enable(struct clk *clk)
118{
119 int retry = 1000000;
120
121 pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits,
122 PWDCR(clk->module));
123 do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits));
124
125 if (!retry)
126 panic("activating PMU module failed!\n");
127
128 return 0;
129}
130
131/* disable a clock gate */
132static void pmu_disable(struct clk *clk)
133{
134 pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits,
135 PWDCR(clk->module));
136}
137
138/* the pci enable helper */
139static int pci_enable(struct clk *clk)
140{
141 unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
142 /* set bus clock speed */
143 if (of_machine_is_compatible("lantiq,ar9")) {
144 ifccr &= ~0x1f00000;
145 if (clk->rate == CLOCK_33M)
146 ifccr |= 0xe00000;
147 else
148 ifccr |= 0x700000; /* 62.5M */
149 } else {
150 ifccr &= ~0xf00000;
151 if (clk->rate == CLOCK_33M)
152 ifccr |= 0x800000;
153 else
154 ifccr |= 0x400000; /* 62.5M */
155 }
156 ltq_cgu_w32(ifccr, CGU_IFCCR);
157 pmu_enable(clk);
158 return 0;
159}
160
161/* enable the external clock as a source */
162static int pci_ext_enable(struct clk *clk)
163{
164 ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16),
165 CGU_IFCCR);
166 ltq_cgu_w32((1 << 30), CGU_PCICR);
167 return 0;
168}
169
170/* disable the external clock as a source */
171static void pci_ext_disable(struct clk *clk)
172{
173 ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
174 CGU_IFCCR);
175 ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
176}
177
178/* enable a clockout source */
179static int clkout_enable(struct clk *clk)
180{
181 int i;
182
183 /* get the correct rate */
184 for (i = 0; i < 4; i++) {
185 if (clk->rates[i] == clk->rate) {
186 int shift = 14 - (2 * clk->module);
187 unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
188
189 ifccr &= ~(3 << shift);
190 ifccr |= i << shift;
191 ltq_cgu_w32(ifccr, CGU_IFCCR);
192 return 0;
193 }
194 }
195 return -1;
196}
197
198/* manage the clock gates via PMU */
199static void clkdev_add_pmu(const char *dev, const char *con,
200 unsigned int module, unsigned int bits)
201{
202 struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
203
204 clk->cl.dev_id = dev;
205 clk->cl.con_id = con;
206 clk->cl.clk = clk;
207 clk->enable = pmu_enable;
208 clk->disable = pmu_disable;
209 clk->module = module;
210 clk->bits = bits;
211 clkdev_add(&clk->cl);
212}
213
214/* manage the clock generator */
215static void clkdev_add_cgu(const char *dev, const char *con,
216 unsigned int bits)
217{
218 struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
219
220 clk->cl.dev_id = dev;
221 clk->cl.con_id = con;
222 clk->cl.clk = clk;
223 clk->enable = cgu_enable;
224 clk->disable = cgu_disable;
225 clk->bits = bits;
226 clkdev_add(&clk->cl);
227}
228
229/* pci needs its own enable function as the setup is a bit more complex */
230static unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0};
231
232static void clkdev_add_pci(void)
233{
234 struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
235 struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL);
236
237 /* main pci clock */
238 clk->cl.dev_id = "17000000.pci";
239 clk->cl.con_id = NULL;
240 clk->cl.clk = clk;
241 clk->rate = CLOCK_33M;
242 clk->rates = valid_pci_rates;
243 clk->enable = pci_enable;
244 clk->disable = pmu_disable;
245 clk->module = 0;
246 clk->bits = PMU_PCI;
247 clkdev_add(&clk->cl);
248
249 /* use internal/external bus clock */
250 clk_ext->cl.dev_id = "17000000.pci";
251 clk_ext->cl.con_id = "external";
252 clk_ext->cl.clk = clk_ext;
253 clk_ext->enable = pci_ext_enable;
254 clk_ext->disable = pci_ext_disable;
255 clkdev_add(&clk_ext->cl);
256}
257
258/* xway socs can generate clocks on gpio pins */
259static unsigned long valid_clkout_rates[4][5] = {
260 {CLOCK_32_768K, CLOCK_1_536M, CLOCK_2_5M, CLOCK_12M, 0},
261 {CLOCK_40M, CLOCK_12M, CLOCK_24M, CLOCK_48M, 0},
262 {CLOCK_25M, CLOCK_40M, CLOCK_30M, CLOCK_60M, 0},
263 {CLOCK_12M, CLOCK_50M, CLOCK_32_768K, CLOCK_25M, 0},
264};
265
266static void clkdev_add_clkout(void)
267{
268 int i;
269
270 for (i = 0; i < 4; i++) {
271 struct clk *clk;
272 char *name;
273
274 name = kzalloc(sizeof("clkout0"), GFP_KERNEL);
275 sprintf(name, "clkout%d", i);
276
277 clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
278 clk->cl.dev_id = "1f103000.cgu";
279 clk->cl.con_id = name;
280 clk->cl.clk = clk;
281 clk->rate = 0;
282 clk->rates = valid_clkout_rates[i];
283 clk->enable = clkout_enable;
284 clk->module = i;
285 clkdev_add(&clk->cl);
286 }
287}
288
289/* bring up all register ranges that we need for basic system control */
290void __init ltq_soc_init(void)
291{
292 struct resource res_pmu, res_cgu, res_ebu;
293 struct device_node *np_pmu =
294 of_find_compatible_node(NULL, NULL, "lantiq,pmu-xway");
295 struct device_node *np_cgu =
296 of_find_compatible_node(NULL, NULL, "lantiq,cgu-xway");
297 struct device_node *np_ebu =
298 of_find_compatible_node(NULL, NULL, "lantiq,ebu-xway");
299
300 /* check if all the core register ranges are available */
301 if (!np_pmu || !np_cgu || !np_ebu)
302 panic("Failed to load core nodess from devicetree");
303
304 if (of_address_to_resource(np_pmu, 0, &res_pmu) ||
305 of_address_to_resource(np_cgu, 0, &res_cgu) ||
306 of_address_to_resource(np_ebu, 0, &res_ebu))
307 panic("Failed to get core resources");
308
309 if ((request_mem_region(res_pmu.start, resource_size(&res_pmu),
310 res_pmu.name) < 0) ||
311 (request_mem_region(res_cgu.start, resource_size(&res_cgu),
312 res_cgu.name) < 0) ||
313 (request_mem_region(res_ebu.start, resource_size(&res_ebu),
314 res_ebu.name) < 0))
315 pr_err("Failed to request core reources");
316
317 pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu));
318 ltq_cgu_membase = ioremap_nocache(res_cgu.start,
319 resource_size(&res_cgu));
320 ltq_ebu_membase = ioremap_nocache(res_ebu.start,
321 resource_size(&res_ebu));
322 if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
323 panic("Failed to remap core resources");
324
325 /* make sure to unprotect the memory region where flash is located */
326 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
327
328 /* add our generic xway clocks */
329 clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI);
330 clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0);
331 clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT);
332 clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP);
333 clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA);
334 clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI);
335 clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU);
336 clkdev_add_clkout();
337
338 /* add the soc dependent clocks */
339 if (!of_machine_is_compatible("lantiq,vr9"))
340 clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE);
341
342 if (!of_machine_is_compatible("lantiq,ase")) {
343 clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1);
344 clkdev_add_pci();
345 }
346
347 if (of_machine_is_compatible("lantiq,ase")) {
348 if (ltq_cgu_r32(CGU_SYS) & (1 << 5))
349 clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M);
350 else
351 clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M);
352 clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY),
353 clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY);
354 } else if (of_machine_is_compatible("lantiq,vr9")) {
355 clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
356 ltq_vr9_fpi_hz());
357 clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY);
358 clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK);
359 clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI);
360 clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI);
361 clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL);
362 clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS);
363 } else if (of_machine_is_compatible("lantiq,ar9")) {
364 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
365 ltq_ar9_fpi_hz());
366 clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH);
367 } else {
368 clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
369 ltq_danube_fpi_hz());
370 }
371}
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
index 47037ec5589..44e69e7a451 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -21,6 +21,7 @@
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/pgtable.h> 22#include <asm/pgtable.h>
23#include <asm/r4kcache.h> 23#include <asm/r4kcache.h>
24#include <asm/traps.h>
24#include <asm/mmu_context.h> 25#include <asm/mmu_context.h>
25#include <asm/war.h> 26#include <asm/war.h>
26 27
@@ -248,6 +249,11 @@ static void __cpuinit probe_octeon(void)
248 } 249 }
249} 250}
250 251
252static void __cpuinit octeon_cache_error_setup(void)
253{
254 extern char except_vec2_octeon;
255 set_handler(0x100, &except_vec2_octeon, 0x80);
256}
251 257
252/** 258/**
253 * Setup the Octeon cache flush routines 259 * Setup the Octeon cache flush routines
@@ -255,12 +261,6 @@ static void __cpuinit probe_octeon(void)
255 */ 261 */
256void __cpuinit octeon_cache_init(void) 262void __cpuinit octeon_cache_init(void)
257{ 263{
258 extern unsigned long ebase;
259 extern char except_vec2_octeon;
260
261 memcpy((void *)(ebase + 0x100), &except_vec2_octeon, 0x80);
262 octeon_flush_cache_sigtramp(ebase + 0x100);
263
264 probe_octeon(); 264 probe_octeon();
265 265
266 shm_align_mask = PAGE_SIZE - 1; 266 shm_align_mask = PAGE_SIZE - 1;
@@ -280,6 +280,8 @@ void __cpuinit octeon_cache_init(void)
280 280
281 build_clear_page(); 281 build_clear_page();
282 build_copy_page(); 282 build_copy_page();
283
284 board_cache_error_setup = octeon_cache_error_setup;
283} 285}
284 286
285/** 287/**
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index bda8eb26ece..5109be96d98 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -32,7 +32,7 @@
32#include <asm/mmu_context.h> 32#include <asm/mmu_context.h>
33#include <asm/war.h> 33#include <asm/war.h>
34#include <asm/cacheflush.h> /* for run_uncached() */ 34#include <asm/cacheflush.h> /* for run_uncached() */
35 35#include <asm/traps.h>
36 36
37/* 37/*
38 * Special Variant of smp_call_function for use by cache functions: 38 * Special Variant of smp_call_function for use by cache functions:
@@ -1385,10 +1385,8 @@ static int __init setcoherentio(char *str)
1385__setup("coherentio", setcoherentio); 1385__setup("coherentio", setcoherentio);
1386#endif 1386#endif
1387 1387
1388void __cpuinit r4k_cache_init(void) 1388static void __cpuinit r4k_cache_error_setup(void)
1389{ 1389{
1390 extern void build_clear_page(void);
1391 extern void build_copy_page(void);
1392 extern char __weak except_vec2_generic; 1390 extern char __weak except_vec2_generic;
1393 extern char __weak except_vec2_sb1; 1391 extern char __weak except_vec2_sb1;
1394 struct cpuinfo_mips *c = &current_cpu_data; 1392 struct cpuinfo_mips *c = &current_cpu_data;
@@ -1403,6 +1401,13 @@ void __cpuinit r4k_cache_init(void)
1403 set_uncached_handler(0x100, &except_vec2_generic, 0x80); 1401 set_uncached_handler(0x100, &except_vec2_generic, 0x80);
1404 break; 1402 break;
1405 } 1403 }
1404}
1405
1406void __cpuinit r4k_cache_init(void)
1407{
1408 extern void build_clear_page(void);
1409 extern void build_copy_page(void);
1410 struct cpuinfo_mips *c = &current_cpu_data;
1406 1411
1407 probe_pcache(); 1412 probe_pcache();
1408 setup_scache(); 1413 setup_scache();
@@ -1465,4 +1470,5 @@ void __cpuinit r4k_cache_init(void)
1465 local_r4k___flush_cache_all(NULL); 1470 local_r4k___flush_cache_all(NULL);
1466#endif 1471#endif
1467 coherency_setup(); 1472 coherency_setup();
1473 board_cache_error_setup = r4k_cache_error_setup;
1468} 1474}
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 29f2f13eb31..1208c280f77 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -1,5 +1,3 @@
1ccflags-y := -Werror
2
3obj-$(CONFIG_OPROFILE) += oprofile.o 1obj-$(CONFIG_OPROFILE) += oprofile.o
4 2
5DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ 3DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 54759f1669d..baba3bcaa3c 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -298,6 +298,11 @@ static void reset_counters(void *arg)
298 } 298 }
299} 299}
300 300
301static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id)
302{
303 return mipsxx_perfcount_handler();
304}
305
301static int __init mipsxx_init(void) 306static int __init mipsxx_init(void)
302{ 307{
303 int counters; 308 int counters;
@@ -374,6 +379,10 @@ static int __init mipsxx_init(void)
374 save_perf_irq = perf_irq; 379 save_perf_irq = perf_irq;
375 perf_irq = mipsxx_perfcount_handler; 380 perf_irq = mipsxx_perfcount_handler;
376 381
382 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq))
383 return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
384 0, "Perfcounter", save_perf_irq);
385
377 return 0; 386 return 0;
378} 387}
379 388
@@ -381,6 +390,9 @@ static void mipsxx_exit(void)
381{ 390{
382 int counters = op_model_mipsxx_ops.num_counters; 391 int counters = op_model_mipsxx_ops.num_counters;
383 392
393 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq))
394 free_irq(cp0_perfcount_irq, save_perf_irq);
395
384 counters = counters_per_cpu_to_total(counters); 396 counters = counters_per_cpu_to_total(counters);
385 on_each_cpu(reset_counters, (void *)(long)counters, 1); 397 on_each_cpu(reset_counters, (void *)(long)counters, 1);
386 398
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c3ac4b086eb..c703f43a991 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -19,7 +19,8 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ 19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
20 ops-bcm63xx.o 20 ops-bcm63xx.o
21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o 21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
22obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o 22obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
23obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
23 24
24# 25#
25# These are still pretty much in the old state, watch, go blind. 26# These are still pretty much in the old state, watch, go blind.
@@ -41,7 +42,8 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
41obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o 42obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
42obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o 43obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
43obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o 44obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
44obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o 45obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
46obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
45obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o 47obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
46obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o 48obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
47obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o 49obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
new file mode 100644
index 00000000000..6c829df28dc
--- /dev/null
+++ b/arch/mips/pci/fixup-lantiq.c
@@ -0,0 +1,40 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/of_irq.h>
10#include <linux/of_pci.h>
11
12int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
13int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
14
15int pcibios_plat_dev_init(struct pci_dev *dev)
16{
17 if (ltq_pci_plat_arch_init)
18 return ltq_pci_plat_arch_init(dev);
19
20 if (ltq_pci_plat_dev_init)
21 return ltq_pci_plat_dev_init(dev);
22
23 return 0;
24}
25
26int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
27{
28 struct of_irq dev_irq;
29 int irq;
30
31 if (of_irq_map_pci(dev, &dev_irq)) {
32 dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n",
33 slot, pin);
34 return 0;
35 }
36 irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier,
37 dev_irq.size);
38 dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq);
39 return irq;
40}
diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c
index d657ee0bc13..afd221122d2 100644
--- a/arch/mips/pci/ops-loongson2.c
+++ b/arch/mips/pci/ops-loongson2.c
@@ -15,6 +15,7 @@
15#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/export.h>
18 19
19#include <loongson.h> 20#include <loongson.h>
20 21
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c
new file mode 100644
index 00000000000..1552522b871
--- /dev/null
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -0,0 +1,375 @@
1/*
2 * Atheros AR71xx PCI host controller driver
3 *
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6 *
7 * Parts of this file are based on Atheros' 2.6.15 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/resource.h>
15#include <linux/types.h>
16#include <linux/delay.h>
17#include <linux/bitops.h>
18#include <linux/pci.h>
19#include <linux/pci_regs.h>
20#include <linux/interrupt.h>
21
22#include <asm/mach-ath79/ar71xx_regs.h>
23#include <asm/mach-ath79/ath79.h>
24#include <asm/mach-ath79/pci.h>
25
26#define AR71XX_PCI_MEM_BASE 0x10000000
27#define AR71XX_PCI_MEM_SIZE 0x08000000
28
29#define AR71XX_PCI_WIN0_OFFS 0x10000000
30#define AR71XX_PCI_WIN1_OFFS 0x11000000
31#define AR71XX_PCI_WIN2_OFFS 0x12000000
32#define AR71XX_PCI_WIN3_OFFS 0x13000000
33#define AR71XX_PCI_WIN4_OFFS 0x14000000
34#define AR71XX_PCI_WIN5_OFFS 0x15000000
35#define AR71XX_PCI_WIN6_OFFS 0x16000000
36#define AR71XX_PCI_WIN7_OFFS 0x07000000
37
38#define AR71XX_PCI_CFG_BASE \
39 (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
40#define AR71XX_PCI_CFG_SIZE 0x100
41
42#define AR71XX_PCI_REG_CRP_AD_CBE 0x00
43#define AR71XX_PCI_REG_CRP_WRDATA 0x04
44#define AR71XX_PCI_REG_CRP_RDDATA 0x08
45#define AR71XX_PCI_REG_CFG_AD 0x0c
46#define AR71XX_PCI_REG_CFG_CBE 0x10
47#define AR71XX_PCI_REG_CFG_WRDATA 0x14
48#define AR71XX_PCI_REG_CFG_RDDATA 0x18
49#define AR71XX_PCI_REG_PCI_ERR 0x1c
50#define AR71XX_PCI_REG_PCI_ERR_ADDR 0x20
51#define AR71XX_PCI_REG_AHB_ERR 0x24
52#define AR71XX_PCI_REG_AHB_ERR_ADDR 0x28
53
54#define AR71XX_PCI_CRP_CMD_WRITE 0x00010000
55#define AR71XX_PCI_CRP_CMD_READ 0x00000000
56#define AR71XX_PCI_CFG_CMD_READ 0x0000000a
57#define AR71XX_PCI_CFG_CMD_WRITE 0x0000000b
58
59#define AR71XX_PCI_INT_CORE BIT(4)
60#define AR71XX_PCI_INT_DEV2 BIT(2)
61#define AR71XX_PCI_INT_DEV1 BIT(1)
62#define AR71XX_PCI_INT_DEV0 BIT(0)
63
64#define AR71XX_PCI_IRQ_COUNT 5
65
66static DEFINE_SPINLOCK(ar71xx_pci_lock);
67static void __iomem *ar71xx_pcicfg_base;
68
69/* Byte lane enable bits */
70static const u8 ar71xx_pci_ble_table[4][4] = {
71 {0x0, 0xf, 0xf, 0xf},
72 {0xe, 0xd, 0xb, 0x7},
73 {0xc, 0xf, 0x3, 0xf},
74 {0xf, 0xf, 0xf, 0xf},
75};
76
77static const u32 ar71xx_pci_read_mask[8] = {
78 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0
79};
80
81static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
82{
83 u32 t;
84
85 t = ar71xx_pci_ble_table[size & 3][where & 3];
86 BUG_ON(t == 0xf);
87 t <<= (local) ? 20 : 4;
88
89 return t;
90}
91
92static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
93 int where)
94{
95 u32 ret;
96
97 if (!bus->number) {
98 /* type 0 */
99 ret = (1 << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
100 (where & ~3);
101 } else {
102 /* type 1 */
103 ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) |
104 (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
105 }
106
107 return ret;
108}
109
110static int ar71xx_pci_check_error(int quiet)
111{
112 void __iomem *base = ar71xx_pcicfg_base;
113 u32 pci_err;
114 u32 ahb_err;
115
116 pci_err = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR) & 3;
117 if (pci_err) {
118 if (!quiet) {
119 u32 addr;
120
121 addr = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR_ADDR);
122 pr_crit("ar71xx: %s bus error %d at addr 0x%x\n",
123 "PCI", pci_err, addr);
124 }
125
126 /* clear PCI error status */
127 __raw_writel(pci_err, base + AR71XX_PCI_REG_PCI_ERR);
128 }
129
130 ahb_err = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR) & 1;
131 if (ahb_err) {
132 if (!quiet) {
133 u32 addr;
134
135 addr = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR_ADDR);
136 pr_crit("ar71xx: %s bus error %d at addr 0x%x\n",
137 "AHB", ahb_err, addr);
138 }
139
140 /* clear AHB error status */
141 __raw_writel(ahb_err, base + AR71XX_PCI_REG_AHB_ERR);
142 }
143
144 return !!(ahb_err | pci_err);
145}
146
147static inline void ar71xx_pci_local_write(int where, int size, u32 value)
148{
149 void __iomem *base = ar71xx_pcicfg_base;
150 u32 ad_cbe;
151
152 value = value << (8 * (where & 3));
153
154 ad_cbe = AR71XX_PCI_CRP_CMD_WRITE | (where & ~3);
155 ad_cbe |= ar71xx_pci_get_ble(where, size, 1);
156
157 __raw_writel(ad_cbe, base + AR71XX_PCI_REG_CRP_AD_CBE);
158 __raw_writel(value, base + AR71XX_PCI_REG_CRP_WRDATA);
159}
160
161static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
162 unsigned int devfn,
163 int where, int size, u32 cmd)
164{
165 void __iomem *base = ar71xx_pcicfg_base;
166 u32 addr;
167
168 addr = ar71xx_pci_bus_addr(bus, devfn, where);
169
170 __raw_writel(addr, base + AR71XX_PCI_REG_CFG_AD);
171 __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
172 base + AR71XX_PCI_REG_CFG_CBE);
173
174 return ar71xx_pci_check_error(1);
175}
176
177static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
178 int where, int size, u32 *value)
179{
180 void __iomem *base = ar71xx_pcicfg_base;
181 unsigned long flags;
182 u32 data;
183 int err;
184 int ret;
185
186 ret = PCIBIOS_SUCCESSFUL;
187 data = ~0;
188
189 spin_lock_irqsave(&ar71xx_pci_lock, flags);
190
191 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
192 AR71XX_PCI_CFG_CMD_READ);
193 if (err)
194 ret = PCIBIOS_DEVICE_NOT_FOUND;
195 else
196 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
197
198 spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
199
200 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
201
202 return ret;
203}
204
205static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
206 int where, int size, u32 value)
207{
208 void __iomem *base = ar71xx_pcicfg_base;
209 unsigned long flags;
210 int err;
211 int ret;
212
213 value = value << (8 * (where & 3));
214 ret = PCIBIOS_SUCCESSFUL;
215
216 spin_lock_irqsave(&ar71xx_pci_lock, flags);
217
218 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
219 AR71XX_PCI_CFG_CMD_WRITE);
220 if (err)
221 ret = PCIBIOS_DEVICE_NOT_FOUND;
222 else
223 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
224
225 spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
226
227 return ret;
228}
229
230static struct pci_ops ar71xx_pci_ops = {
231 .read = ar71xx_pci_read_config,
232 .write = ar71xx_pci_write_config,
233};
234
235static struct resource ar71xx_pci_io_resource = {
236 .name = "PCI IO space",
237 .start = 0,
238 .end = 0,
239 .flags = IORESOURCE_IO,
240};
241
242static struct resource ar71xx_pci_mem_resource = {
243 .name = "PCI memory space",
244 .start = AR71XX_PCI_MEM_BASE,
245 .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
246 .flags = IORESOURCE_MEM
247};
248
249static struct pci_controller ar71xx_pci_controller = {
250 .pci_ops = &ar71xx_pci_ops,
251 .mem_resource = &ar71xx_pci_mem_resource,
252 .io_resource = &ar71xx_pci_io_resource,
253};
254
255static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
256{
257 void __iomem *base = ath79_reset_base;
258 u32 pending;
259
260 pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
261 __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
262
263 if (pending & AR71XX_PCI_INT_DEV0)
264 generic_handle_irq(ATH79_PCI_IRQ(0));
265
266 else if (pending & AR71XX_PCI_INT_DEV1)
267 generic_handle_irq(ATH79_PCI_IRQ(1));
268
269 else if (pending & AR71XX_PCI_INT_DEV2)
270 generic_handle_irq(ATH79_PCI_IRQ(2));
271
272 else if (pending & AR71XX_PCI_INT_CORE)
273 generic_handle_irq(ATH79_PCI_IRQ(4));
274
275 else
276 spurious_interrupt();
277}
278
279static void ar71xx_pci_irq_unmask(struct irq_data *d)
280{
281 unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
282 void __iomem *base = ath79_reset_base;
283 u32 t;
284
285 t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
286 __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
287
288 /* flush write */
289 __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
290}
291
292static void ar71xx_pci_irq_mask(struct irq_data *d)
293{
294 unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
295 void __iomem *base = ath79_reset_base;
296 u32 t;
297
298 t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
299 __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
300
301 /* flush write */
302 __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
303}
304
305static struct irq_chip ar71xx_pci_irq_chip = {
306 .name = "AR71XX PCI",
307 .irq_mask = ar71xx_pci_irq_mask,
308 .irq_unmask = ar71xx_pci_irq_unmask,
309 .irq_mask_ack = ar71xx_pci_irq_mask,
310};
311
312static __init void ar71xx_pci_irq_init(void)
313{
314 void __iomem *base = ath79_reset_base;
315 int i;
316
317 __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
318 __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
319
320 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
321
322 for (i = ATH79_PCI_IRQ_BASE;
323 i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++)
324 irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
325 handle_level_irq);
326
327 irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
328}
329
330static __init void ar71xx_pci_reset(void)
331{
332 void __iomem *ddr_base = ath79_ddr_base;
333
334 ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
335 mdelay(100);
336
337 ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
338 mdelay(100);
339
340 __raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
341 __raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
342 __raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
343 __raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
344 __raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
345 __raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
346 __raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
347 __raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
348
349 mdelay(100);
350}
351
352__init int ar71xx_pcibios_init(void)
353{
354 u32 t;
355
356 ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE);
357 if (ar71xx_pcicfg_base == NULL)
358 return -ENOMEM;
359
360 ar71xx_pci_reset();
361
362 /* setup COMMAND register */
363 t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
364 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
365 ar71xx_pci_local_write(PCI_COMMAND, 4, t);
366
367 /* clear bus errors */
368 ar71xx_pci_check_error(1);
369
370 ar71xx_pci_irq_init();
371
372 register_pci_controller(&ar71xx_pci_controller);
373
374 return 0;
375}
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
new file mode 100644
index 00000000000..414a7459858
--- /dev/null
+++ b/arch/mips/pci/pci-ar724x.c
@@ -0,0 +1,292 @@
1/*
2 * Atheros AR724X PCI host controller driver
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
10 */
11
12#include <linux/irq.h>
13#include <linux/pci.h>
14#include <asm/mach-ath79/ath79.h>
15#include <asm/mach-ath79/ar71xx_regs.h>
16#include <asm/mach-ath79/pci.h>
17
18#define AR724X_PCI_CFG_BASE 0x14000000
19#define AR724X_PCI_CFG_SIZE 0x1000
20#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000)
21#define AR724X_PCI_CTRL_SIZE 0x100
22
23#define AR724X_PCI_MEM_BASE 0x10000000
24#define AR724X_PCI_MEM_SIZE 0x08000000
25
26#define AR724X_PCI_REG_INT_STATUS 0x4c
27#define AR724X_PCI_REG_INT_MASK 0x50
28
29#define AR724X_PCI_INT_DEV0 BIT(14)
30
31#define AR724X_PCI_IRQ_COUNT 1
32
33#define AR7240_BAR0_WAR_VALUE 0xffff
34
35static DEFINE_SPINLOCK(ar724x_pci_lock);
36static void __iomem *ar724x_pci_devcfg_base;
37static void __iomem *ar724x_pci_ctrl_base;
38
39static u32 ar724x_pci_bar0_value;
40static bool ar724x_pci_bar0_is_cached;
41
42static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
43 int size, uint32_t *value)
44{
45 unsigned long flags;
46 void __iomem *base;
47 u32 data;
48
49 if (devfn)
50 return PCIBIOS_DEVICE_NOT_FOUND;
51
52 base = ar724x_pci_devcfg_base;
53
54 spin_lock_irqsave(&ar724x_pci_lock, flags);
55 data = __raw_readl(base + (where & ~3));
56
57 switch (size) {
58 case 1:
59 if (where & 1)
60 data >>= 8;
61 if (where & 2)
62 data >>= 16;
63 data &= 0xff;
64 break;
65 case 2:
66 if (where & 2)
67 data >>= 16;
68 data &= 0xffff;
69 break;
70 case 4:
71 break;
72 default:
73 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
74
75 return PCIBIOS_BAD_REGISTER_NUMBER;
76 }
77
78 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
79
80 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
81 ar724x_pci_bar0_is_cached) {
82 /* use the cached value */
83 *value = ar724x_pci_bar0_value;
84 } else {
85 *value = data;
86 }
87
88 return PCIBIOS_SUCCESSFUL;
89}
90
91static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
92 int size, uint32_t value)
93{
94 unsigned long flags;
95 void __iomem *base;
96 u32 data;
97 int s;
98
99 if (devfn)
100 return PCIBIOS_DEVICE_NOT_FOUND;
101
102 if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
103 if (value != 0xffffffff) {
104 /*
105 * WAR for a hw issue. If the BAR0 register of the
106 * device is set to the proper base address, the
107 * memory space of the device is not accessible.
108 *
109 * Cache the intended value so it can be read back,
110 * and write a SoC specific constant value to the
111 * BAR0 register in order to make the device memory
112 * accessible.
113 */
114 ar724x_pci_bar0_is_cached = true;
115 ar724x_pci_bar0_value = value;
116
117 value = AR7240_BAR0_WAR_VALUE;
118 } else {
119 ar724x_pci_bar0_is_cached = false;
120 }
121 }
122
123 base = ar724x_pci_devcfg_base;
124
125 spin_lock_irqsave(&ar724x_pci_lock, flags);
126 data = __raw_readl(base + (where & ~3));
127
128 switch (size) {
129 case 1:
130 s = ((where & 3) * 8);
131 data &= ~(0xff << s);
132 data |= ((value & 0xff) << s);
133 break;
134 case 2:
135 s = ((where & 2) * 8);
136 data &= ~(0xffff << s);
137 data |= ((value & 0xffff) << s);
138 break;
139 case 4:
140 data = value;
141 break;
142 default:
143 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
144
145 return PCIBIOS_BAD_REGISTER_NUMBER;
146 }
147
148 __raw_writel(data, base + (where & ~3));
149 /* flush write */
150 __raw_readl(base + (where & ~3));
151 spin_unlock_irqrestore(&ar724x_pci_lock, flags);
152
153 return PCIBIOS_SUCCESSFUL;
154}
155
156static struct pci_ops ar724x_pci_ops = {
157 .read = ar724x_pci_read,
158 .write = ar724x_pci_write,
159};
160
161static struct resource ar724x_io_resource = {
162 .name = "PCI IO space",
163 .start = 0,
164 .end = 0,
165 .flags = IORESOURCE_IO,
166};
167
168static struct resource ar724x_mem_resource = {
169 .name = "PCI memory space",
170 .start = AR724X_PCI_MEM_BASE,
171 .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
172 .flags = IORESOURCE_MEM,
173};
174
175static struct pci_controller ar724x_pci_controller = {
176 .pci_ops = &ar724x_pci_ops,
177 .io_resource = &ar724x_io_resource,
178 .mem_resource = &ar724x_mem_resource,
179};
180
181static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
182{
183 void __iomem *base;
184 u32 pending;
185
186 base = ar724x_pci_ctrl_base;
187
188 pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
189 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
190
191 if (pending & AR724X_PCI_INT_DEV0)
192 generic_handle_irq(ATH79_PCI_IRQ(0));
193
194 else
195 spurious_interrupt();
196}
197
198static void ar724x_pci_irq_unmask(struct irq_data *d)
199{
200 void __iomem *base;
201 u32 t;
202
203 base = ar724x_pci_ctrl_base;
204
205 switch (d->irq) {
206 case ATH79_PCI_IRQ(0):
207 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
208 __raw_writel(t | AR724X_PCI_INT_DEV0,
209 base + AR724X_PCI_REG_INT_MASK);
210 /* flush write */
211 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
212 }
213}
214
215static void ar724x_pci_irq_mask(struct irq_data *d)
216{
217 void __iomem *base;
218 u32 t;
219
220 base = ar724x_pci_ctrl_base;
221
222 switch (d->irq) {
223 case ATH79_PCI_IRQ(0):
224 t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
225 __raw_writel(t & ~AR724X_PCI_INT_DEV0,
226 base + AR724X_PCI_REG_INT_MASK);
227
228 /* flush write */
229 __raw_readl(base + AR724X_PCI_REG_INT_MASK);
230
231 t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
232 __raw_writel(t | AR724X_PCI_INT_DEV0,
233 base + AR724X_PCI_REG_INT_STATUS);
234
235 /* flush write */
236 __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
237 }
238}
239
240static struct irq_chip ar724x_pci_irq_chip = {
241 .name = "AR724X PCI ",
242 .irq_mask = ar724x_pci_irq_mask,
243 .irq_unmask = ar724x_pci_irq_unmask,
244 .irq_mask_ack = ar724x_pci_irq_mask,
245};
246
247static void __init ar724x_pci_irq_init(int irq)
248{
249 void __iomem *base;
250 int i;
251
252 base = ar724x_pci_ctrl_base;
253
254 __raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
255 __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
256
257 BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
258
259 for (i = ATH79_PCI_IRQ_BASE;
260 i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
261 irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
262 handle_level_irq);
263
264 irq_set_chained_handler(irq, ar724x_pci_irq_handler);
265}
266
267int __init ar724x_pcibios_init(int irq)
268{
269 int ret;
270
271 ret = -ENOMEM;
272
273 ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
274 AR724X_PCI_CFG_SIZE);
275 if (ar724x_pci_devcfg_base == NULL)
276 goto err;
277
278 ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
279 AR724X_PCI_CTRL_SIZE);
280 if (ar724x_pci_ctrl_base == NULL)
281 goto err_unmap_devcfg;
282
283 ar724x_pci_irq_init(irq);
284 register_pci_controller(&ar724x_pci_controller);
285
286 return PCIBIOS_SUCCESSFUL;
287
288err_unmap_devcfg:
289 iounmap(ar724x_pci_devcfg_base);
290err:
291 return ret;
292}
diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
deleted file mode 100644
index a4dd24a4130..00000000000
--- a/arch/mips/pci/pci-ath724x.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * Atheros 724x PCI support
3 *
4 * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation.
9 */
10
11#include <linux/pci.h>
12#include <asm/mach-ath79/pci-ath724x.h>
13
14#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys))
15#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
16
17#define ATH724X_PCI_DEV_BASE 0x14000000
18#define ATH724X_PCI_MEM_BASE 0x10000000
19#define ATH724X_PCI_MEM_SIZE 0x08000000
20
21static DEFINE_SPINLOCK(ath724x_pci_lock);
22static struct ath724x_pci_data *pci_data;
23static int pci_data_size;
24
25static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
26 int size, uint32_t *value)
27{
28 unsigned long flags, addr, tval, mask;
29
30 if (devfn)
31 return PCIBIOS_DEVICE_NOT_FOUND;
32
33 if (where & (size - 1))
34 return PCIBIOS_BAD_REGISTER_NUMBER;
35
36 spin_lock_irqsave(&ath724x_pci_lock, flags);
37
38 switch (size) {
39 case 1:
40 addr = where & ~3;
41 mask = 0xff000000 >> ((where % 4) * 8);
42 tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
43 tval = tval & ~mask;
44 *value = (tval >> ((4 - (where % 4))*8));
45 break;
46 case 2:
47 addr = where & ~3;
48 mask = 0xffff0000 >> ((where % 4)*8);
49 tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
50 tval = tval & ~mask;
51 *value = (tval >> ((4 - (where % 4))*8));
52 break;
53 case 4:
54 *value = reg_read(ATH724X_PCI_DEV_BASE + where);
55 break;
56 default:
57 spin_unlock_irqrestore(&ath724x_pci_lock, flags);
58
59 return PCIBIOS_BAD_REGISTER_NUMBER;
60 }
61
62 spin_unlock_irqrestore(&ath724x_pci_lock, flags);
63
64 return PCIBIOS_SUCCESSFUL;
65}
66
67static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
68 int size, uint32_t value)
69{
70 unsigned long flags, tval, addr, mask;
71
72 if (devfn)
73 return PCIBIOS_DEVICE_NOT_FOUND;
74
75 if (where & (size - 1))
76 return PCIBIOS_BAD_REGISTER_NUMBER;
77
78 spin_lock_irqsave(&ath724x_pci_lock, flags);
79
80 switch (size) {
81 case 1:
82 addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
83 mask = 0xff000000 >> ((where % 4)*8);
84 tval = reg_read(addr);
85 tval = tval & ~mask;
86 tval |= (value << ((4 - (where % 4))*8)) & mask;
87 reg_write(addr, tval);
88 break;
89 case 2:
90 addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
91 mask = 0xffff0000 >> ((where % 4)*8);
92 tval = reg_read(addr);
93 tval = tval & ~mask;
94 tval |= (value << ((4 - (where % 4))*8)) & mask;
95 reg_write(addr, tval);
96 break;
97 case 4:
98 reg_write((ATH724X_PCI_DEV_BASE + where), value);
99 break;
100 default:
101 spin_unlock_irqrestore(&ath724x_pci_lock, flags);
102
103 return PCIBIOS_BAD_REGISTER_NUMBER;
104 }
105
106 spin_unlock_irqrestore(&ath724x_pci_lock, flags);
107
108 return PCIBIOS_SUCCESSFUL;
109}
110
111static struct pci_ops ath724x_pci_ops = {
112 .read = ath724x_pci_read,
113 .write = ath724x_pci_write,
114};
115
116static struct resource ath724x_io_resource = {
117 .name = "PCI IO space",
118 .start = 0,
119 .end = 0,
120 .flags = IORESOURCE_IO,
121};
122
123static struct resource ath724x_mem_resource = {
124 .name = "PCI memory space",
125 .start = ATH724X_PCI_MEM_BASE,
126 .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
127 .flags = IORESOURCE_MEM,
128};
129
130static struct pci_controller ath724x_pci_controller = {
131 .pci_ops = &ath724x_pci_ops,
132 .io_resource = &ath724x_io_resource,
133 .mem_resource = &ath724x_mem_resource,
134};
135
136void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
137{
138 pci_data = data;
139 pci_data_size = size;
140}
141
142int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
143{
144 unsigned int devfn = dev->devfn;
145 int irq = -1;
146
147 if (devfn > pci_data_size - 1)
148 return irq;
149
150 irq = pci_data[devfn].irq;
151
152 return irq;
153}
154
155int pcibios_plat_dev_init(struct pci_dev *dev)
156{
157 unsigned int devfn = dev->devfn;
158
159 if (devfn > pci_data_size - 1)
160 return PCIBIOS_DEVICE_NOT_FOUND;
161
162 dev->dev.platform_data = pci_data[devfn].pdata;
163
164 return PCIBIOS_SUCCESSFUL;
165}
166
167static int __init ath724x_pcibios_init(void)
168{
169 register_pci_controller(&ath724x_pci_controller);
170
171 return PCIBIOS_SUCCESSFUL;
172}
173
174arch_initcall(ath724x_pcibios_init);
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
index 030c77e7926..ea453532a33 100644
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -13,8 +13,12 @@
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
16#include <linux/export.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/clk.h>
18#include <linux/of_platform.h>
19#include <linux/of_gpio.h>
20#include <linux/of_irq.h>
21#include <linux/of_pci.h>
18 22
19#include <asm/pci.h> 23#include <asm/pci.h>
20#include <asm/gpio.h> 24#include <asm/gpio.h>
@@ -22,17 +26,9 @@
22 26
23#include <lantiq_soc.h> 27#include <lantiq_soc.h>
24#include <lantiq_irq.h> 28#include <lantiq_irq.h>
25#include <lantiq_platform.h>
26 29
27#include "pci-lantiq.h" 30#include "pci-lantiq.h"
28 31
29#define LTQ_PCI_CFG_BASE 0x17000000
30#define LTQ_PCI_CFG_SIZE 0x00008000
31#define LTQ_PCI_MEM_BASE 0x18000000
32#define LTQ_PCI_MEM_SIZE 0x02000000
33#define LTQ_PCI_IO_BASE 0x1AE00000
34#define LTQ_PCI_IO_SIZE 0x00200000
35
36#define PCI_CR_FCI_ADDR_MAP0 0x00C0 32#define PCI_CR_FCI_ADDR_MAP0 0x00C0
37#define PCI_CR_FCI_ADDR_MAP1 0x00C4 33#define PCI_CR_FCI_ADDR_MAP1 0x00C4
38#define PCI_CR_FCI_ADDR_MAP2 0x00C8 34#define PCI_CR_FCI_ADDR_MAP2 0x00C8
@@ -68,79 +64,27 @@
68#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y)) 64#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
69#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x)) 65#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
70 66
71struct ltq_pci_gpio_map {
72 int pin;
73 int alt0;
74 int alt1;
75 int dir;
76 char *name;
77};
78
79/* the pci core can make use of the following gpios */
80static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = {
81 { 0, 1, 0, 0, "pci-exin0" },
82 { 1, 1, 0, 0, "pci-exin1" },
83 { 2, 1, 0, 0, "pci-exin2" },
84 { 39, 1, 0, 0, "pci-exin3" },
85 { 10, 1, 0, 0, "pci-exin4" },
86 { 9, 1, 0, 0, "pci-exin5" },
87 { 30, 1, 0, 1, "pci-gnt1" },
88 { 23, 1, 0, 1, "pci-gnt2" },
89 { 19, 1, 0, 1, "pci-gnt3" },
90 { 38, 1, 0, 1, "pci-gnt4" },
91 { 29, 1, 0, 0, "pci-req1" },
92 { 31, 1, 0, 0, "pci-req2" },
93 { 3, 1, 0, 0, "pci-req3" },
94 { 37, 1, 0, 0, "pci-req4" },
95};
96
97__iomem void *ltq_pci_mapped_cfg; 67__iomem void *ltq_pci_mapped_cfg;
98static __iomem void *ltq_pci_membase; 68static __iomem void *ltq_pci_membase;
99 69
100int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL; 70static int reset_gpio;
101 71static struct clk *clk_pci, *clk_external;
102/* Since the PCI REQ pins can be reused for other functionality, make it 72static struct resource pci_io_resource;
103 possible to exclude those from interpretation by the PCI controller */ 73static struct resource pci_mem_resource;
104static int ltq_pci_req_mask = 0xf; 74static struct pci_ops pci_ops = {
105
106static int *ltq_pci_irq_map;
107
108struct pci_ops ltq_pci_ops = {
109 .read = ltq_pci_read_config_dword, 75 .read = ltq_pci_read_config_dword,
110 .write = ltq_pci_write_config_dword 76 .write = ltq_pci_write_config_dword
111}; 77};
112 78
113static struct resource pci_io_resource = { 79static struct pci_controller pci_controller = {
114 .name = "pci io space", 80 .pci_ops = &pci_ops,
115 .start = LTQ_PCI_IO_BASE,
116 .end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1,
117 .flags = IORESOURCE_IO
118};
119
120static struct resource pci_mem_resource = {
121 .name = "pci memory space",
122 .start = LTQ_PCI_MEM_BASE,
123 .end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1,
124 .flags = IORESOURCE_MEM
125};
126
127static struct pci_controller ltq_pci_controller = {
128 .pci_ops = &ltq_pci_ops,
129 .mem_resource = &pci_mem_resource, 81 .mem_resource = &pci_mem_resource,
130 .mem_offset = 0x00000000UL, 82 .mem_offset = 0x00000000UL,
131 .io_resource = &pci_io_resource, 83 .io_resource = &pci_io_resource,
132 .io_offset = 0x00000000UL, 84 .io_offset = 0x00000000UL,
133}; 85};
134 86
135int pcibios_plat_dev_init(struct pci_dev *dev) 87static inline u32 ltq_calc_bar11mask(void)
136{
137 if (ltqpci_plat_dev_init)
138 return ltqpci_plat_dev_init(dev);
139
140 return 0;
141}
142
143static u32 ltq_calc_bar11mask(void)
144{ 88{
145 u32 mem, bar11mask; 89 u32 mem, bar11mask;
146 90
@@ -151,48 +95,42 @@ static u32 ltq_calc_bar11mask(void)
151 return bar11mask; 95 return bar11mask;
152} 96}
153 97
154static void ltq_pci_setup_gpio(int gpio) 98static int __devinit ltq_pci_startup(struct platform_device *pdev)
155{
156 int i;
157 for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
158 if (gpio & (1 << i)) {
159 ltq_gpio_request(ltq_pci_gpio_map[i].pin,
160 ltq_pci_gpio_map[i].alt0,
161 ltq_pci_gpio_map[i].alt1,
162 ltq_pci_gpio_map[i].dir,
163 ltq_pci_gpio_map[i].name);
164 }
165 }
166 ltq_gpio_request(21, 0, 0, 1, "pci-reset");
167 ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
168}
169
170static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
171{ 99{
100 struct device_node *node = pdev->dev.of_node;
101 const __be32 *req_mask, *bus_clk;
172 u32 temp_buffer; 102 u32 temp_buffer;
173 103
174 /* set clock to 33Mhz */ 104 /* get our clocks */
175 if (ltq_is_ar9()) { 105 clk_pci = clk_get(&pdev->dev, NULL);
176 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR); 106 if (IS_ERR(clk_pci)) {
177 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR); 107 dev_err(&pdev->dev, "failed to get pci clock\n");
178 } else { 108 return PTR_ERR(clk_pci);
179 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
180 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
181 } 109 }
182 110
183 /* external or internal clock ? */ 111 clk_external = clk_get(&pdev->dev, "external");
184 if (conf->clock) { 112 if (IS_ERR(clk_external)) {
185 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16), 113 clk_put(clk_pci);
186 LTQ_CGU_IFCCR); 114 dev_err(&pdev->dev, "failed to get external pci clock\n");
187 ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR); 115 return PTR_ERR(clk_external);
188 } else {
189 ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16),
190 LTQ_CGU_IFCCR);
191 ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR);
192 } 116 }
193 117
194 /* setup pci clock and gpis used by pci */ 118 /* read the bus speed that we want */
195 ltq_pci_setup_gpio(conf->gpio); 119 bus_clk = of_get_property(node, "lantiq,bus-clock", NULL);
120 if (bus_clk)
121 clk_set_rate(clk_pci, *bus_clk);
122
123 /* and enable the clocks */
124 clk_enable(clk_pci);
125 if (of_find_property(node, "lantiq,external-clock", NULL))
126 clk_enable(clk_external);
127 else
128 clk_disable(clk_external);
129
130 /* setup reset gpio used by pci */
131 reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
132 if (reset_gpio > 0)
133 devm_gpio_request(&pdev->dev, reset_gpio, "pci-reset");
196 134
197 /* enable auto-switching between PCI and EBU */ 135 /* enable auto-switching between PCI and EBU */
198 ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); 136 ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
@@ -205,7 +143,12 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
205 143
206 /* enable external 2 PCI masters */ 144 /* enable external 2 PCI masters */
207 temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB); 145 temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB);
208 temp_buffer &= (~(ltq_pci_req_mask << 16)); 146 /* setup the request mask */
147 req_mask = of_get_property(node, "req-mask", NULL);
148 if (req_mask)
149 temp_buffer &= ~((*req_mask & 0xf) << 16);
150 else
151 temp_buffer &= ~0xf0000;
209 /* enable internal arbiter */ 152 /* enable internal arbiter */
210 temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT); 153 temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
211 /* enable internal PCI master reqest */ 154 /* enable internal PCI master reqest */
@@ -249,47 +192,55 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
249 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); 192 ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN);
250 193
251 /* toggle reset pin */ 194 /* toggle reset pin */
252 __gpio_set_value(21, 0); 195 if (reset_gpio > 0) {
253 wmb(); 196 __gpio_set_value(reset_gpio, 0);
254 mdelay(1); 197 wmb();
255 __gpio_set_value(21, 1); 198 mdelay(1);
256 return 0; 199 __gpio_set_value(reset_gpio, 1);
257} 200 }
258
259int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
260{
261 if (ltq_pci_irq_map[slot])
262 return ltq_pci_irq_map[slot];
263 printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
264 slot);
265
266 return 0; 201 return 0;
267} 202}
268 203
269static int __devinit ltq_pci_probe(struct platform_device *pdev) 204static int __devinit ltq_pci_probe(struct platform_device *pdev)
270{ 205{
271 struct ltq_pci_data *ltq_pci_data = 206 struct resource *res_cfg, *res_bridge;
272 (struct ltq_pci_data *) pdev->dev.platform_data;
273 207
274 pci_clear_flags(PCI_PROBE_ONLY); 208 pci_clear_flags(PCI_PROBE_ONLY);
275 ltq_pci_irq_map = ltq_pci_data->irq;
276 ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
277 ltq_pci_mapped_cfg =
278 ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
279 ltq_pci_controller.io_map_base =
280 (unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
281 ltq_pci_startup(ltq_pci_data);
282 register_pci_controller(&ltq_pci_controller);
283 209
210 res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
211 res_bridge = platform_get_resource(pdev, IORESOURCE_MEM, 1);
212 if (!res_cfg || !res_bridge) {
213 dev_err(&pdev->dev, "missing memory reources\n");
214 return -EINVAL;
215 }
216
217 ltq_pci_membase = devm_request_and_ioremap(&pdev->dev, res_bridge);
218 ltq_pci_mapped_cfg = devm_request_and_ioremap(&pdev->dev, res_cfg);
219
220 if (!ltq_pci_membase || !ltq_pci_mapped_cfg) {
221 dev_err(&pdev->dev, "failed to remap resources\n");
222 return -ENOMEM;
223 }
224
225 ltq_pci_startup(pdev);
226
227 pci_load_of_ranges(&pci_controller, pdev->dev.of_node);
228 register_pci_controller(&pci_controller);
284 return 0; 229 return 0;
285} 230}
286 231
287static struct platform_driver 232static const struct of_device_id ltq_pci_match[] = {
288ltq_pci_driver = { 233 { .compatible = "lantiq,pci-xway" },
234 {},
235};
236MODULE_DEVICE_TABLE(of, ltq_pci_match);
237
238static struct platform_driver ltq_pci_driver = {
289 .probe = ltq_pci_probe, 239 .probe = ltq_pci_probe,
290 .driver = { 240 .driver = {
291 .name = "ltq_pci", 241 .name = "pci-xway",
292 .owner = THIS_MODULE, 242 .owner = THIS_MODULE,
243 .of_match_table = ltq_pci_match,
293 }, 244 },
294}; 245};
295 246
@@ -297,7 +248,7 @@ int __init pcibios_init(void)
297{ 248{
298 int ret = platform_driver_register(&ltq_pci_driver); 249 int ret = platform_driver_register(&ltq_pci_driver);
299 if (ret) 250 if (ret)
300 printk(KERN_INFO "ltq_pci: Error registering platfom driver!"); 251 pr_info("pci-xway: Error registering platform driver!");
301 return ret; 252 return ret;
302} 253}
303 254
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 0514866fa92..271e8c4a54c 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/of_address.h>
19 20
20#include <asm/cpu-info.h> 21#include <asm/cpu-info.h>
21 22
@@ -114,9 +115,63 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
114 pci_bus_assign_resources(bus); 115 pci_bus_assign_resources(bus);
115 pci_enable_bridges(bus); 116 pci_enable_bridges(bus);
116 } 117 }
118 bus->dev.of_node = hose->of_node;
117 } 119 }
118} 120}
119 121
122#ifdef CONFIG_OF
123void __devinit pci_load_of_ranges(struct pci_controller *hose,
124 struct device_node *node)
125{
126 const __be32 *ranges;
127 int rlen;
128 int pna = of_n_addr_cells(node);
129 int np = pna + 5;
130
131 pr_info("PCI host bridge %s ranges:\n", node->full_name);
132 ranges = of_get_property(node, "ranges", &rlen);
133 if (ranges == NULL)
134 return;
135 hose->of_node = node;
136
137 while ((rlen -= np * 4) >= 0) {
138 u32 pci_space;
139 struct resource *res = NULL;
140 u64 addr, size;
141
142 pci_space = be32_to_cpup(&ranges[0]);
143 addr = of_translate_address(node, ranges + 3);
144 size = of_read_number(ranges + pna + 3, 2);
145 ranges += np;
146 switch ((pci_space >> 24) & 0x3) {
147 case 1: /* PCI IO space */
148 pr_info(" IO 0x%016llx..0x%016llx\n",
149 addr, addr + size - 1);
150 hose->io_map_base =
151 (unsigned long)ioremap(addr, size);
152 res = hose->io_resource;
153 res->flags = IORESOURCE_IO;
154 break;
155 case 2: /* PCI Memory space */
156 case 3: /* PCI 64 bits Memory space */
157 pr_info(" MEM 0x%016llx..0x%016llx\n",
158 addr, addr + size - 1);
159 res = hose->mem_resource;
160 res->flags = IORESOURCE_MEM;
161 break;
162 }
163 if (res != NULL) {
164 res->start = addr;
165 res->name = node->full_name;
166 res->end = res->start + size - 1;
167 res->parent = NULL;
168 res->sibling = NULL;
169 res->child = NULL;
170 }
171 }
172}
173#endif
174
120static DEFINE_MUTEX(pci_scan_mutex); 175static DEFINE_MUTEX(pci_scan_mutex);
121 176
122void __devinit register_pci_controller(struct pci_controller *hose) 177void __devinit register_pci_controller(struct pci_controller *hose)
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
index 02f5fb94ea2..5af95ec3319 100644
--- a/arch/mips/pmc-sierra/yosemite/Makefile
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -5,5 +5,3 @@
5obj-y += irq.o prom.o py-console.o setup.o 5obj-y += irq.o prom.o py-console.o setup.o
6 6
7obj-$(CONFIG_SMP) += smp.o 7obj-$(CONFIG_SMP) += smp.o
8
9ccflags-y := -Werror
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 3498ac9c35a..b6472fc88a9 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -27,6 +27,7 @@
27#include <linux/bcd.h> 27#include <linux/bcd.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/export.h>
30#include <linux/types.h> 31#include <linux/types.h>
31#include <linux/mm.h> 32#include <linux/mm.h>
32#include <linux/bootmem.h> 33#include <linux/bootmem.h>
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
index 348d2e850ef..39ca9f8d63a 100644
--- a/arch/mips/powertv/Makefile
+++ b/arch/mips/powertv/Makefile
@@ -27,5 +27,3 @@ obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \
27 asic/ pci/ 27 asic/ pci/
28 28
29obj-$(CONFIG_USB) += powertv-usb.o 29obj-$(CONFIG_USB) += powertv-usb.o
30
31ccflags-y := -Wall
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
index d810a33182a..35dcc53eb25 100644
--- a/arch/mips/powertv/asic/Makefile
+++ b/arch/mips/powertv/asic/Makefile
@@ -19,5 +19,3 @@
19obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \ 19obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \
20 asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \ 20 asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \
21 prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o 21 prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o
22
23ccflags-y := -Wall -Werror
diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile
index 5783201cd2c..2610a6af5b2 100644
--- a/arch/mips/powertv/pci/Makefile
+++ b/arch/mips/powertv/pci/Makefile
@@ -17,5 +17,3 @@
17# 17#
18 18
19obj-$(CONFIG_PCI) += fixup-powertv.o 19obj-$(CONFIG_PCI) += fixup-powertv.o
20
21ccflags-y := -Wall -Werror
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index a969eb82663..ea774285e6c 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -15,6 +15,7 @@
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 */ 16 */
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/export.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/ctype.h> 20#include <linux/ctype.h>
20#include <linux/string.h> 21#include <linux/string.h>
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
index d16b462154c..413f17f8e89 100644
--- a/arch/mips/sni/setup.c
+++ b/arch/mips/sni/setup.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/eisa.h> 11#include <linux/eisa.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/export.h>
13#include <linux/console.h> 14#include <linux/console.h>
14#include <linux/fb.h> 15#include <linux/fb.h>
15#include <linux/screen_info.h> 16#include <linux/screen_info.h>
diff --git a/arch/mn10300/include/asm/kvm_para.h b/arch/mn10300/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/mn10300/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 4932247d078..49765b53f63 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -19,6 +19,8 @@ config OPENRISC
19 select GENERIC_CPU_DEVICES 19 select GENERIC_CPU_DEVICES
20 select GENERIC_ATOMIC64 20 select GENERIC_ATOMIC64
21 select GENERIC_CLOCKEVENTS 21 select GENERIC_CLOCKEVENTS
22 select GENERIC_STRNCPY_FROM_USER
23 select GENERIC_STRNLEN_USER
22 24
23config MMU 25config MMU
24 def_bool y 26 def_bool y
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index c936483bc8e..3f35c38d7b6 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -66,3 +66,4 @@ generic-y += topology.h
66generic-y += types.h 66generic-y += types.h
67generic-y += ucontext.h 67generic-y += ucontext.h
68generic-y += user.h 68generic-y += user.h
69generic-y += word-at-a-time.h
diff --git a/arch/openrisc/include/asm/kvm_para.h b/arch/openrisc/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/openrisc/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index f5abaa0ffc3..ab2e7a198a4 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -313,42 +313,12 @@ clear_user(void *addr, unsigned long size)
313 return size; 313 return size;
314} 314}
315 315
316extern int __strncpy_from_user(char *dst, const char *src, long count); 316#define user_addr_max() \
317 (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
317 318
318static inline long strncpy_from_user(char *dst, const char *src, long count) 319extern long strncpy_from_user(char *dest, const char __user *src, long count);
319{
320 if (access_ok(VERIFY_READ, src, 1))
321 return __strncpy_from_user(dst, src, count);
322 return -EFAULT;
323}
324
325/*
326 * Return the size of a string (including the ending 0)
327 *
328 * Return 0 for error
329 */
330
331extern int __strnlen_user(const char *str, long len, unsigned long top);
332
333/*
334 * Returns the length of the string at str (including the null byte),
335 * or 0 if we hit a page we can't access,
336 * or something > len if we didn't find a null byte.
337 *
338 * The `top' parameter to __strnlen_user is to make sure that
339 * we can never overflow from the user area into kernel space.
340 */
341static inline long strnlen_user(const char __user *str, long len)
342{
343 unsigned long top = (unsigned long)get_fs();
344 unsigned long res = 0;
345
346 if (__addr_ok(str))
347 res = __strnlen_user(str, len, top);
348
349 return res;
350}
351 320
352#define strlen_user(str) strnlen_user(str, TASK_SIZE-1) 321extern __must_check long strlen_user(const char __user *str);
322extern __must_check long strnlen_user(const char __user *str, long n);
353 323
354#endif /* __ASM_OPENRISC_UACCESS_H */ 324#endif /* __ASM_OPENRISC_UACCESS_H */
diff --git a/arch/openrisc/lib/string.S b/arch/openrisc/lib/string.S
index 465f04bc7de..c09fee7dec1 100644
--- a/arch/openrisc/lib/string.S
+++ b/arch/openrisc/lib/string.S
@@ -103,102 +103,3 @@ __clear_user:
103 .section __ex_table, "a" 103 .section __ex_table, "a"
104 .long 9b, 99b // write fault 104 .long 9b, 99b // write fault
105 .previous 105 .previous
106
107/*
108 * long strncpy_from_user(char *dst, const char *src, long count)
109 *
110 *
111 */
112 .global __strncpy_from_user
113__strncpy_from_user:
114 l.addi r1,r1,-16
115 l.sw 0(r1),r6
116 l.sw 4(r1),r5
117 l.sw 8(r1),r4
118 l.sw 12(r1),r3
119
120 l.addi r11,r5,0
1212: l.sfeq r5,r0
122 l.bf 1f
123 l.addi r5,r5,-1
1248: l.lbz r6,0(r4)
125 l.sfeq r6,r0
126 l.bf 1f
1279: l.sb 0(r3),r6
128 l.addi r3,r3,1
129 l.j 2b
130 l.addi r4,r4,1
1311:
132 l.lwz r6,0(r1)
133 l.addi r5,r5,1
134 l.sub r11,r11,r5 // r11 holds the return value
135
136 l.lwz r6,0(r1)
137 l.lwz r5,4(r1)
138 l.lwz r4,8(r1)
139 l.lwz r3,12(r1)
140 l.jr r9
141 l.addi r1,r1,16
142
143 .section .fixup, "ax"
14499:
145 l.movhi r11,hi(-EFAULT)
146 l.ori r11,r11,lo(-EFAULT)
147
148 l.lwz r6,0(r1)
149 l.lwz r5,4(r1)
150 l.lwz r4,8(r1)
151 l.lwz r3,12(r1)
152 l.jr r9
153 l.addi r1,r1,16
154 .previous
155
156 .section __ex_table, "a"
157 .long 8b, 99b // read fault
158 .previous
159
160/*
161 * extern int __strnlen_user(const char *str, long len, unsigned long top);
162 *
163 *
164 * RTRN: - length of a string including NUL termination character
165 * - on page fault 0
166 */
167
168 .global __strnlen_user
169__strnlen_user:
170 l.addi r1,r1,-8
171 l.sw 0(r1),r6
172 l.sw 4(r1),r3
173
174 l.addi r11,r0,0
1752: l.sfeq r11,r4
176 l.bf 1f
177 l.addi r11,r11,1
1788: l.lbz r6,0(r3)
179 l.sfeq r6,r0
180 l.bf 1f
181 l.sfgeu r3,r5 // are we over the top ?
182 l.bf 99f
183 l.j 2b
184 l.addi r3,r3,1
185
1861:
187 l.lwz r6,0(r1)
188 l.lwz r3,4(r1)
189 l.jr r9
190 l.addi r1,r1,8
191
192 .section .fixup, "ax"
19399:
194 l.addi r11,r0,0
195
196 l.lwz r6,0(r1)
197 l.lwz r3,4(r1)
198 l.jr r9
199 l.addi r1,r1,8
200 .previous
201
202 .section __ex_table, "a"
203 .long 8b, 99b // read fault
204 .previous
diff --git a/arch/parisc/include/asm/kvm_para.h b/arch/parisc/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/parisc/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 00b9874e224..050cb371a69 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,8 @@ config PPC
135 select GENERIC_CMOS_UPDATE 135 select GENERIC_CMOS_UPDATE
136 select GENERIC_TIME_VSYSCALL 136 select GENERIC_TIME_VSYSCALL
137 select GENERIC_CLOCKEVENTS 137 select GENERIC_CLOCKEVENTS
138 select GENERIC_STRNCPY_FROM_USER
139 select GENERIC_STRNLEN_USER
138 140
139config EARLY_PRINTK 141config EARLY_PRINTK
140 bool 142 bool
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index 7e283c891b7..fe0d60935e9 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -119,6 +119,7 @@
119 sdhc@2e000 { 119 sdhc@2e000 {
120 status = "disabled"; 120 status = "disabled";
121 sdhci,1-bit-only; 121 sdhci,1-bit-only;
122 bus-width = <1>;
122 }; 123 };
123 124
124 par_io@e0100 { 125 par_io@e0100 {
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index b9219e99bd2..50d82c8a037 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -168,6 +168,7 @@ extern const char *powerpc_base_platform;
168#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000) 168#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000)
169#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000) 169#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000)
170#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000) 170#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000)
171#define CPU_FTR_EMB_HV ASM_CONST(0x0000000040000000)
171 172
172/* 173/*
173 * Add the 64-bit processor unique features in the top half of the word; 174 * Add the 64-bit processor unique features in the top half of the word;
@@ -376,7 +377,8 @@ extern const char *powerpc_base_platform;
376#define CPU_FTRS_47X (CPU_FTRS_440x6) 377#define CPU_FTRS_47X (CPU_FTRS_440x6)
377#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \ 378#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
378 CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ 379 CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
379 CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE) 380 CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE | \
381 CPU_FTR_DEBUG_LVL_EXC)
380#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \ 382#define CPU_FTRS_E500 (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
381 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \ 383 CPU_FTR_SPE_COMP | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
382 CPU_FTR_NOEXECUTE) 384 CPU_FTR_NOEXECUTE)
@@ -385,15 +387,15 @@ extern const char *powerpc_base_platform;
385 CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) 387 CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
386#define CPU_FTRS_E500MC (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 388#define CPU_FTRS_E500MC (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
387 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 389 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
388 CPU_FTR_DBELL) 390 CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
389#define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 391#define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
390 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 392 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
391 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 393 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
392 CPU_FTR_DEBUG_LVL_EXC) 394 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
393#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 395#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
394 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 396 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
395 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 397 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
396 CPU_FTR_DEBUG_LVL_EXC) 398 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
397#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 399#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
398 400
399/* 64-bit CPUs */ 401/* 64-bit CPUs */
@@ -486,8 +488,10 @@ enum {
486 CPU_FTRS_E200 | 488 CPU_FTRS_E200 |
487#endif 489#endif
488#ifdef CONFIG_E500 490#ifdef CONFIG_E500
489 CPU_FTRS_E500 | CPU_FTRS_E500_2 | CPU_FTRS_E500MC | 491 CPU_FTRS_E500 | CPU_FTRS_E500_2 |
490 CPU_FTRS_E5500 | CPU_FTRS_E6500 | 492#endif
493#ifdef CONFIG_PPC_E500MC
494 CPU_FTRS_E500MC | CPU_FTRS_E5500 | CPU_FTRS_E6500 |
491#endif 495#endif
492 0, 496 0,
493}; 497};
@@ -531,9 +535,12 @@ enum {
531 CPU_FTRS_E200 & 535 CPU_FTRS_E200 &
532#endif 536#endif
533#ifdef CONFIG_E500 537#ifdef CONFIG_E500
534 CPU_FTRS_E500 & CPU_FTRS_E500_2 & CPU_FTRS_E500MC & 538 CPU_FTRS_E500 & CPU_FTRS_E500_2 &
535 CPU_FTRS_E5500 & CPU_FTRS_E6500 & 539#endif
540#ifdef CONFIG_PPC_E500MC
541 CPU_FTRS_E500MC & CPU_FTRS_E5500 & CPU_FTRS_E6500 &
536#endif 542#endif
543 ~CPU_FTR_EMB_HV & /* can be removed at runtime */
537 CPU_FTRS_POSSIBLE, 544 CPU_FTRS_POSSIBLE,
538}; 545};
539#endif /* __powerpc64__ */ 546#endif /* __powerpc64__ */
diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
index efa74ac44a3..154c067761b 100644
--- a/arch/powerpc/include/asm/dbell.h
+++ b/arch/powerpc/include/asm/dbell.h
@@ -19,6 +19,9 @@
19 19
20#define PPC_DBELL_MSG_BRDCAST (0x04000000) 20#define PPC_DBELL_MSG_BRDCAST (0x04000000)
21#define PPC_DBELL_TYPE(x) (((x) & 0xf) << (63-36)) 21#define PPC_DBELL_TYPE(x) (((x) & 0xf) << (63-36))
22#define PPC_DBELL_TYPE_MASK PPC_DBELL_TYPE(0xf)
23#define PPC_DBELL_LPID(x) ((x) << (63 - 49))
24#define PPC_DBELL_PIR_MASK 0x3fff
22enum ppc_dbell { 25enum ppc_dbell {
23 PPC_DBELL = 0, /* doorbell */ 26 PPC_DBELL = 0, /* doorbell */
24 PPC_DBELL_CRIT = 1, /* critical doorbell */ 27 PPC_DBELL_CRIT = 1, /* critical doorbell */
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 61225238819..423cf9eaf4a 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -133,6 +133,16 @@
133#define H_PP1 (1UL<<(63-62)) 133#define H_PP1 (1UL<<(63-62))
134#define H_PP2 (1UL<<(63-63)) 134#define H_PP2 (1UL<<(63-63))
135 135
136/* Flags for H_REGISTER_VPA subfunction field */
137#define H_VPA_FUNC_SHIFT (63-18) /* Bit posn of subfunction code */
138#define H_VPA_FUNC_MASK 7UL
139#define H_VPA_REG_VPA 1UL /* Register Virtual Processor Area */
140#define H_VPA_REG_DTL 2UL /* Register Dispatch Trace Log */
141#define H_VPA_REG_SLB 3UL /* Register SLB shadow buffer */
142#define H_VPA_DEREG_VPA 5UL /* Deregister Virtual Processor Area */
143#define H_VPA_DEREG_DTL 6UL /* Deregister Dispatch Trace Log */
144#define H_VPA_DEREG_SLB 7UL /* Deregister SLB shadow buffer */
145
136/* VASI States */ 146/* VASI States */
137#define H_VASI_INVALID 0 147#define H_VASI_INVALID 0
138#define H_VASI_ENABLED 1 148#define H_VASI_ENABLED 1
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 51010bfc792..c9aac24b02e 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -33,6 +33,7 @@
33extern void __replay_interrupt(unsigned int vector); 33extern void __replay_interrupt(unsigned int vector);
34 34
35extern void timer_interrupt(struct pt_regs *); 35extern void timer_interrupt(struct pt_regs *);
36extern void performance_monitor_exception(struct pt_regs *regs);
36 37
37#ifdef CONFIG_PPC64 38#ifdef CONFIG_PPC64
38#include <asm/paca.h> 39#include <asm/paca.h>
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index b921c3f4892..1bea4d8ea6f 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -277,6 +277,7 @@ struct kvm_sync_regs {
277#define KVM_CPU_E500V2 2 277#define KVM_CPU_E500V2 2
278#define KVM_CPU_3S_32 3 278#define KVM_CPU_3S_32 3
279#define KVM_CPU_3S_64 4 279#define KVM_CPU_3S_64 4
280#define KVM_CPU_E500MC 5
280 281
281/* for KVM_CAP_SPAPR_TCE */ 282/* for KVM_CAP_SPAPR_TCE */
282struct kvm_create_spapr_tce { 283struct kvm_create_spapr_tce {
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 7b1f0e0fc65..76fdcfef088 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -20,6 +20,16 @@
20#ifndef __POWERPC_KVM_ASM_H__ 20#ifndef __POWERPC_KVM_ASM_H__
21#define __POWERPC_KVM_ASM_H__ 21#define __POWERPC_KVM_ASM_H__
22 22
23#ifdef __ASSEMBLY__
24#ifdef CONFIG_64BIT
25#define PPC_STD(sreg, offset, areg) std sreg, (offset)(areg)
26#define PPC_LD(treg, offset, areg) ld treg, (offset)(areg)
27#else
28#define PPC_STD(sreg, offset, areg) stw sreg, (offset+4)(areg)
29#define PPC_LD(treg, offset, areg) lwz treg, (offset+4)(areg)
30#endif
31#endif
32
23/* IVPR must be 64KiB-aligned. */ 33/* IVPR must be 64KiB-aligned. */
24#define VCPU_SIZE_ORDER 4 34#define VCPU_SIZE_ORDER 4
25#define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12) 35#define VCPU_SIZE_LOG (VCPU_SIZE_ORDER + 12)
@@ -48,6 +58,14 @@
48#define BOOKE_INTERRUPT_SPE_FP_DATA 33 58#define BOOKE_INTERRUPT_SPE_FP_DATA 33
49#define BOOKE_INTERRUPT_SPE_FP_ROUND 34 59#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
50#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35 60#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
61#define BOOKE_INTERRUPT_DOORBELL 36
62#define BOOKE_INTERRUPT_DOORBELL_CRITICAL 37
63
64/* booke_hv */
65#define BOOKE_INTERRUPT_GUEST_DBELL 38
66#define BOOKE_INTERRUPT_GUEST_DBELL_CRIT 39
67#define BOOKE_INTERRUPT_HV_SYSCALL 40
68#define BOOKE_INTERRUPT_HV_PRIV 41
51 69
52/* book3s */ 70/* book3s */
53 71
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index fd07f43d662..f0e0c6a66d9 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -453,4 +453,7 @@ static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu)
453 453
454#define INS_DCBZ 0x7c0007ec 454#define INS_DCBZ 0x7c0007ec
455 455
456/* LPIDs we support with this build -- runtime limit may be lower */
457#define KVMPPC_NR_LPIDS (LPID_RSVD + 1)
458
456#endif /* __ASM_KVM_BOOK3S_H__ */ 459#endif /* __ASM_KVM_BOOK3S_H__ */
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 1f2f5b6156b..88609b23b77 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -79,6 +79,9 @@ struct kvmppc_host_state {
79 u8 napping; 79 u8 napping;
80 80
81#ifdef CONFIG_KVM_BOOK3S_64_HV 81#ifdef CONFIG_KVM_BOOK3S_64_HV
82 u8 hwthread_req;
83 u8 hwthread_state;
84
82 struct kvm_vcpu *kvm_vcpu; 85 struct kvm_vcpu *kvm_vcpu;
83 struct kvmppc_vcore *kvm_vcore; 86 struct kvmppc_vcore *kvm_vcore;
84 unsigned long xics_phys; 87 unsigned long xics_phys;
@@ -122,4 +125,9 @@ struct kvmppc_book3s_shadow_vcpu {
122 125
123#endif /*__ASSEMBLY__ */ 126#endif /*__ASSEMBLY__ */
124 127
128/* Values for kvm_state */
129#define KVM_HWTHREAD_IN_KERNEL 0
130#define KVM_HWTHREAD_IN_NAP 1
131#define KVM_HWTHREAD_IN_KVM 2
132
125#endif /* __ASM_KVM_BOOK3S_ASM_H__ */ 133#endif /* __ASM_KVM_BOOK3S_ASM_H__ */
diff --git a/arch/powerpc/include/asm/kvm_booke.h b/arch/powerpc/include/asm/kvm_booke.h
index a90e0918877..b7cd3356a53 100644
--- a/arch/powerpc/include/asm/kvm_booke.h
+++ b/arch/powerpc/include/asm/kvm_booke.h
@@ -23,6 +23,9 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/kvm_host.h> 24#include <linux/kvm_host.h>
25 25
26/* LPIDs we support with this build -- runtime limit may be lower */
27#define KVMPPC_NR_LPIDS 64
28
26static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) 29static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val)
27{ 30{
28 vcpu->arch.gpr[num] = val; 31 vcpu->arch.gpr[num] = val;
diff --git a/arch/powerpc/include/asm/kvm_booke_hv_asm.h b/arch/powerpc/include/asm/kvm_booke_hv_asm.h
new file mode 100644
index 00000000000..30a600fa1b6
--- /dev/null
+++ b/arch/powerpc/include/asm/kvm_booke_hv_asm.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2010-2011 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, version 2, as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef ASM_KVM_BOOKE_HV_ASM_H
10#define ASM_KVM_BOOKE_HV_ASM_H
11
12#ifdef __ASSEMBLY__
13
14/*
15 * All exceptions from guest state must go through KVM
16 * (except for those which are delivered directly to the guest) --
17 * there are no exceptions for which we fall through directly to
18 * the normal host handler.
19 *
20 * Expected inputs (normal exceptions):
21 * SCRATCH0 = saved r10
22 * r10 = thread struct
23 * r11 = appropriate SRR1 variant (currently used as scratch)
24 * r13 = saved CR
25 * *(r10 + THREAD_NORMSAVE(0)) = saved r11
26 * *(r10 + THREAD_NORMSAVE(2)) = saved r13
27 *
28 * Expected inputs (crit/mcheck/debug exceptions):
29 * appropriate SCRATCH = saved r8
30 * r8 = exception level stack frame
31 * r9 = *(r8 + _CCR) = saved CR
32 * r11 = appropriate SRR1 variant (currently used as scratch)
33 * *(r8 + GPR9) = saved r9
34 * *(r8 + GPR10) = saved r10 (r10 not yet clobbered)
35 * *(r8 + GPR11) = saved r11
36 */
37.macro DO_KVM intno srr1
38#ifdef CONFIG_KVM_BOOKE_HV
39BEGIN_FTR_SECTION
40 mtocrf 0x80, r11 /* check MSR[GS] without clobbering reg */
41 bf 3, kvmppc_resume_\intno\()_\srr1
42 b kvmppc_handler_\intno\()_\srr1
43kvmppc_resume_\intno\()_\srr1:
44END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
45#endif
46.endm
47
48#endif /*__ASSEMBLY__ */
49#endif /* ASM_KVM_BOOKE_HV_ASM_H */
diff --git a/arch/powerpc/include/asm/kvm_e500.h b/arch/powerpc/include/asm/kvm_e500.h
deleted file mode 100644
index 8cd50a51427..00000000000
--- a/arch/powerpc/include/asm/kvm_e500.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Yu Liu, <yu.liu@freescale.com>
5 *
6 * Description:
7 * This file is derived from arch/powerpc/include/asm/kvm_44x.h,
8 * by Hollis Blanchard <hollisb@us.ibm.com>.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __ASM_KVM_E500_H__
16#define __ASM_KVM_E500_H__
17
18#include <linux/kvm_host.h>
19
20#define BOOKE_INTERRUPT_SIZE 36
21
22#define E500_PID_NUM 3
23#define E500_TLB_NUM 2
24
25#define E500_TLB_VALID 1
26#define E500_TLB_DIRTY 2
27
28struct tlbe_ref {
29 pfn_t pfn;
30 unsigned int flags; /* E500_TLB_* */
31};
32
33struct tlbe_priv {
34 struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */
35};
36
37struct vcpu_id_table;
38
39struct kvmppc_e500_tlb_params {
40 int entries, ways, sets;
41};
42
43struct kvmppc_vcpu_e500 {
44 /* Unmodified copy of the guest's TLB -- shared with host userspace. */
45 struct kvm_book3e_206_tlb_entry *gtlb_arch;
46
47 /* Starting entry number in gtlb_arch[] */
48 int gtlb_offset[E500_TLB_NUM];
49
50 /* KVM internal information associated with each guest TLB entry */
51 struct tlbe_priv *gtlb_priv[E500_TLB_NUM];
52
53 struct kvmppc_e500_tlb_params gtlb_params[E500_TLB_NUM];
54
55 unsigned int gtlb_nv[E500_TLB_NUM];
56
57 /*
58 * information associated with each host TLB entry --
59 * TLB1 only for now. If/when guest TLB1 entries can be
60 * mapped with host TLB0, this will be used for that too.
61 *
62 * We don't want to use this for guest TLB0 because then we'd
63 * have the overhead of doing the translation again even if
64 * the entry is still in the guest TLB (e.g. we swapped out
65 * and back, and our host TLB entries got evicted).
66 */
67 struct tlbe_ref *tlb_refs[E500_TLB_NUM];
68 unsigned int host_tlb1_nv;
69
70 u32 host_pid[E500_PID_NUM];
71 u32 pid[E500_PID_NUM];
72 u32 svr;
73
74 /* vcpu id table */
75 struct vcpu_id_table *idt;
76
77 u32 l1csr0;
78 u32 l1csr1;
79 u32 hid0;
80 u32 hid1;
81 u32 tlb0cfg;
82 u32 tlb1cfg;
83 u64 mcar;
84
85 struct page **shared_tlb_pages;
86 int num_shared_tlb_pages;
87
88 struct kvm_vcpu vcpu;
89};
90
91static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
92{
93 return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
94}
95
96#endif /* __ASM_KVM_E500_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 52eb9c1f4fe..d848cdc4971 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -82,7 +82,7 @@ struct kvm_vcpu;
82 82
83struct lppaca; 83struct lppaca;
84struct slb_shadow; 84struct slb_shadow;
85struct dtl; 85struct dtl_entry;
86 86
87struct kvm_vm_stat { 87struct kvm_vm_stat {
88 u32 remote_tlb_flush; 88 u32 remote_tlb_flush;
@@ -106,6 +106,8 @@ struct kvm_vcpu_stat {
106 u32 dec_exits; 106 u32 dec_exits;
107 u32 ext_intr_exits; 107 u32 ext_intr_exits;
108 u32 halt_wakeup; 108 u32 halt_wakeup;
109 u32 dbell_exits;
110 u32 gdbell_exits;
109#ifdef CONFIG_PPC_BOOK3S 111#ifdef CONFIG_PPC_BOOK3S
110 u32 pf_storage; 112 u32 pf_storage;
111 u32 pf_instruc; 113 u32 pf_instruc;
@@ -140,6 +142,7 @@ enum kvm_exit_types {
140 EMULATED_TLBSX_EXITS, 142 EMULATED_TLBSX_EXITS,
141 EMULATED_TLBWE_EXITS, 143 EMULATED_TLBWE_EXITS,
142 EMULATED_RFI_EXITS, 144 EMULATED_RFI_EXITS,
145 EMULATED_RFCI_EXITS,
143 DEC_EXITS, 146 DEC_EXITS,
144 EXT_INTR_EXITS, 147 EXT_INTR_EXITS,
145 HALT_WAKEUP, 148 HALT_WAKEUP,
@@ -147,6 +150,8 @@ enum kvm_exit_types {
147 FP_UNAVAIL, 150 FP_UNAVAIL,
148 DEBUG_EXITS, 151 DEBUG_EXITS,
149 TIMEINGUEST, 152 TIMEINGUEST,
153 DBELL_EXITS,
154 GDBELL_EXITS,
150 __NUMBER_OF_KVM_EXIT_TYPES 155 __NUMBER_OF_KVM_EXIT_TYPES
151}; 156};
152 157
@@ -217,10 +222,10 @@ struct kvm_arch_memory_slot {
217}; 222};
218 223
219struct kvm_arch { 224struct kvm_arch {
225 unsigned int lpid;
220#ifdef CONFIG_KVM_BOOK3S_64_HV 226#ifdef CONFIG_KVM_BOOK3S_64_HV
221 unsigned long hpt_virt; 227 unsigned long hpt_virt;
222 struct revmap_entry *revmap; 228 struct revmap_entry *revmap;
223 unsigned int lpid;
224 unsigned int host_lpid; 229 unsigned int host_lpid;
225 unsigned long host_lpcr; 230 unsigned long host_lpcr;
226 unsigned long sdr1; 231 unsigned long sdr1;
@@ -232,7 +237,6 @@ struct kvm_arch {
232 unsigned long vrma_slb_v; 237 unsigned long vrma_slb_v;
233 int rma_setup_done; 238 int rma_setup_done;
234 int using_mmu_notifiers; 239 int using_mmu_notifiers;
235 struct list_head spapr_tce_tables;
236 spinlock_t slot_phys_lock; 240 spinlock_t slot_phys_lock;
237 unsigned long *slot_phys[KVM_MEM_SLOTS_NUM]; 241 unsigned long *slot_phys[KVM_MEM_SLOTS_NUM];
238 int slot_npages[KVM_MEM_SLOTS_NUM]; 242 int slot_npages[KVM_MEM_SLOTS_NUM];
@@ -240,6 +244,9 @@ struct kvm_arch {
240 struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; 244 struct kvmppc_vcore *vcores[KVM_MAX_VCORES];
241 struct kvmppc_linear_info *hpt_li; 245 struct kvmppc_linear_info *hpt_li;
242#endif /* CONFIG_KVM_BOOK3S_64_HV */ 246#endif /* CONFIG_KVM_BOOK3S_64_HV */
247#ifdef CONFIG_PPC_BOOK3S_64
248 struct list_head spapr_tce_tables;
249#endif
243}; 250};
244 251
245/* 252/*
@@ -263,6 +270,9 @@ struct kvmppc_vcore {
263 struct list_head runnable_threads; 270 struct list_head runnable_threads;
264 spinlock_t lock; 271 spinlock_t lock;
265 wait_queue_head_t wq; 272 wait_queue_head_t wq;
273 u64 stolen_tb;
274 u64 preempt_tb;
275 struct kvm_vcpu *runner;
266}; 276};
267 277
268#define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff) 278#define VCORE_ENTRY_COUNT(vc) ((vc)->entry_exit_count & 0xff)
@@ -274,6 +284,19 @@ struct kvmppc_vcore {
274#define VCORE_EXITING 2 284#define VCORE_EXITING 2
275#define VCORE_SLEEPING 3 285#define VCORE_SLEEPING 3
276 286
287/*
288 * Struct used to manage memory for a virtual processor area
289 * registered by a PAPR guest. There are three types of area
290 * that a guest can register.
291 */
292struct kvmppc_vpa {
293 void *pinned_addr; /* Address in kernel linear mapping */
294 void *pinned_end; /* End of region */
295 unsigned long next_gpa; /* Guest phys addr for update */
296 unsigned long len; /* Number of bytes required */
297 u8 update_pending; /* 1 => update pinned_addr from next_gpa */
298};
299
277struct kvmppc_pte { 300struct kvmppc_pte {
278 ulong eaddr; 301 ulong eaddr;
279 u64 vpage; 302 u64 vpage;
@@ -345,6 +368,17 @@ struct kvm_vcpu_arch {
345 u64 vsr[64]; 368 u64 vsr[64];
346#endif 369#endif
347 370
371#ifdef CONFIG_KVM_BOOKE_HV
372 u32 host_mas4;
373 u32 host_mas6;
374 u32 shadow_epcr;
375 u32 epcr;
376 u32 shadow_msrp;
377 u32 eplc;
378 u32 epsc;
379 u32 oldpir;
380#endif
381
348#ifdef CONFIG_PPC_BOOK3S 382#ifdef CONFIG_PPC_BOOK3S
349 /* For Gekko paired singles */ 383 /* For Gekko paired singles */
350 u32 qpr[32]; 384 u32 qpr[32];
@@ -370,6 +404,7 @@ struct kvm_vcpu_arch {
370#endif 404#endif
371 u32 vrsave; /* also USPRG0 */ 405 u32 vrsave; /* also USPRG0 */
372 u32 mmucr; 406 u32 mmucr;
407 /* shadow_msr is unused for BookE HV */
373 ulong shadow_msr; 408 ulong shadow_msr;
374 ulong csrr0; 409 ulong csrr0;
375 ulong csrr1; 410 ulong csrr1;
@@ -426,8 +461,12 @@ struct kvm_vcpu_arch {
426 ulong fault_esr; 461 ulong fault_esr;
427 ulong queued_dear; 462 ulong queued_dear;
428 ulong queued_esr; 463 ulong queued_esr;
464 u32 tlbcfg[4];
465 u32 mmucfg;
466 u32 epr;
429#endif 467#endif
430 gpa_t paddr_accessed; 468 gpa_t paddr_accessed;
469 gva_t vaddr_accessed;
431 470
432 u8 io_gpr; /* GPR used as IO source/target */ 471 u8 io_gpr; /* GPR used as IO source/target */
433 u8 mmio_is_bigendian; 472 u8 mmio_is_bigendian;
@@ -453,11 +492,6 @@ struct kvm_vcpu_arch {
453 u8 prodded; 492 u8 prodded;
454 u32 last_inst; 493 u32 last_inst;
455 494
456 struct lppaca *vpa;
457 struct slb_shadow *slb_shadow;
458 struct dtl *dtl;
459 struct dtl *dtl_end;
460
461 wait_queue_head_t *wqp; 495 wait_queue_head_t *wqp;
462 struct kvmppc_vcore *vcore; 496 struct kvmppc_vcore *vcore;
463 int ret; 497 int ret;
@@ -482,6 +516,14 @@ struct kvm_vcpu_arch {
482 struct task_struct *run_task; 516 struct task_struct *run_task;
483 struct kvm_run *kvm_run; 517 struct kvm_run *kvm_run;
484 pgd_t *pgdir; 518 pgd_t *pgdir;
519
520 spinlock_t vpa_update_lock;
521 struct kvmppc_vpa vpa;
522 struct kvmppc_vpa dtl;
523 struct dtl_entry *dtl_ptr;
524 unsigned long dtl_index;
525 u64 stolen_logged;
526 struct kvmppc_vpa slb_shadow;
485#endif 527#endif
486}; 528};
487 529
@@ -498,4 +540,6 @@ struct kvm_vcpu_arch {
498#define KVM_MMIO_REG_QPR 0x0040 540#define KVM_MMIO_REG_QPR 0x0040
499#define KVM_MMIO_REG_FQPR 0x0060 541#define KVM_MMIO_REG_FQPR 0x0060
500 542
543#define __KVM_HAVE_ARCH_WQP
544
501#endif /* __POWERPC_KVM_HOST_H__ */ 545#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index 7b754e74300..c18916bff68 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -206,6 +206,11 @@ static inline unsigned int kvm_arch_para_features(void)
206 return r; 206 return r;
207} 207}
208 208
209static inline bool kvm_check_and_clear_guest_paused(void)
210{
211 return false;
212}
213
209#endif /* __KERNEL__ */ 214#endif /* __KERNEL__ */
210 215
211#endif /* __POWERPC_KVM_PARA_H__ */ 216#endif /* __POWERPC_KVM_PARA_H__ */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 9d6dee0f7d4..f68c22fa2fc 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -95,7 +95,7 @@ extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
95extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu); 95extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
96extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); 96extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
97 97
98extern void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu); 98extern int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu);
99extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu); 99extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
100extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags); 100extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
101extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); 101extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
@@ -107,8 +107,10 @@ extern void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
107 107
108extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 108extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
109 unsigned int op, int *advance); 109 unsigned int op, int *advance);
110extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs); 110extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn,
111extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt); 111 ulong val);
112extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn,
113 ulong *val);
112 114
113extern int kvmppc_booke_init(void); 115extern int kvmppc_booke_init(void);
114extern void kvmppc_booke_exit(void); 116extern void kvmppc_booke_exit(void);
@@ -126,6 +128,8 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
126extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); 128extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
127extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, 129extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
128 struct kvm_create_spapr_tce *args); 130 struct kvm_create_spapr_tce *args);
131extern long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
132 unsigned long ioba, unsigned long tce);
129extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, 133extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm,
130 struct kvm_allocate_rma *rma); 134 struct kvm_allocate_rma *rma);
131extern struct kvmppc_linear_info *kvm_alloc_rma(void); 135extern struct kvmppc_linear_info *kvm_alloc_rma(void);
@@ -138,6 +142,11 @@ extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
138 struct kvm_userspace_memory_region *mem); 142 struct kvm_userspace_memory_region *mem);
139extern void kvmppc_core_commit_memory_region(struct kvm *kvm, 143extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
140 struct kvm_userspace_memory_region *mem); 144 struct kvm_userspace_memory_region *mem);
145extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
146 struct kvm_ppc_smmu_info *info);
147
148extern int kvmppc_bookehv_init(void);
149extern void kvmppc_bookehv_exit(void);
141 150
142/* 151/*
143 * Cuts out inst bits with ordering according to spec. 152 * Cuts out inst bits with ordering according to spec.
@@ -204,4 +213,9 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
204int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu, 213int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
205 struct kvm_dirty_tlb *cfg); 214 struct kvm_dirty_tlb *cfg);
206 215
216long kvmppc_alloc_lpid(void);
217void kvmppc_claim_lpid(long lpid);
218void kvmppc_free_lpid(long lpid);
219void kvmppc_init_lpid(unsigned long nr_lpids);
220
207#endif /* __POWERPC_KVM_PPC_H__ */ 221#endif /* __POWERPC_KVM_PPC_H__ */
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index cdb5421877e..eeabcdbc30f 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -104,6 +104,8 @@
104#define MAS4_TSIZED_MASK 0x00000f80 /* Default TSIZE */ 104#define MAS4_TSIZED_MASK 0x00000f80 /* Default TSIZE */
105#define MAS4_TSIZED_SHIFT 7 105#define MAS4_TSIZED_SHIFT 7
106 106
107#define MAS5_SGS 0x80000000
108
107#define MAS6_SPID0 0x3FFF0000 109#define MAS6_SPID0 0x3FFF0000
108#define MAS6_SPID1 0x00007FFE 110#define MAS6_SPID1 0x00007FFE
109#define MAS6_ISIZE(x) MAS1_TSIZE(x) 111#define MAS6_ISIZE(x) MAS1_TSIZE(x)
@@ -118,6 +120,10 @@
118 120
119#define MAS7_RPN 0xFFFFFFFF 121#define MAS7_RPN 0xFFFFFFFF
120 122
123#define MAS8_TGS 0x80000000 /* Guest space */
124#define MAS8_VF 0x40000000 /* Virtualization Fault */
125#define MAS8_TLPID 0x000000ff
126
121/* Bit definitions for MMUCFG */ 127/* Bit definitions for MMUCFG */
122#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */ 128#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */
123#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */ 129#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 55e85631c42..413a5eaef56 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -240,6 +240,9 @@ struct thread_struct {
240#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 240#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
241 void* kvm_shadow_vcpu; /* KVM internal data */ 241 void* kvm_shadow_vcpu; /* KVM internal data */
242#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */ 242#endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
243#if defined(CONFIG_KVM) && defined(CONFIG_BOOKE)
244 struct kvm_vcpu *kvm_vcpu;
245#endif
243#ifdef CONFIG_PPC64 246#ifdef CONFIG_PPC64
244 unsigned long dscr; 247 unsigned long dscr;
245 int dscr_inherit; 248 int dscr_inherit;
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 9d7f0fb6902..f0cb7f461b9 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -257,7 +257,9 @@
257#define LPCR_LPES_SH 2 257#define LPCR_LPES_SH 2
258#define LPCR_RMI 0x00000002 /* real mode is cache inhibit */ 258#define LPCR_RMI 0x00000002 /* real mode is cache inhibit */
259#define LPCR_HDICE 0x00000001 /* Hyp Decr enable (HV,PR,EE) */ 259#define LPCR_HDICE 0x00000001 /* Hyp Decr enable (HV,PR,EE) */
260#ifndef SPRN_LPID
260#define SPRN_LPID 0x13F /* Logical Partition Identifier */ 261#define SPRN_LPID 0x13F /* Logical Partition Identifier */
262#endif
261#define LPID_RSVD 0x3ff /* Reserved LPID for partn switching */ 263#define LPID_RSVD 0x3ff /* Reserved LPID for partn switching */
262#define SPRN_HMER 0x150 /* Hardware m? error recovery */ 264#define SPRN_HMER 0x150 /* Hardware m? error recovery */
263#define SPRN_HMEER 0x151 /* Hardware m? enable error recovery */ 265#define SPRN_HMEER 0x151 /* Hardware m? enable error recovery */
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 8a97aa7289d..2d916c4982c 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -56,18 +56,30 @@
56#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */ 56#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */
57#define SPRN_EPCR 0x133 /* Embedded Processor Control Register */ 57#define SPRN_EPCR 0x133 /* Embedded Processor Control Register */
58#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */ 58#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */
59#define SPRN_MSRP 0x137 /* MSR Protect Register */
59#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */ 60#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */
60#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */ 61#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */
61#define SPRN_DVC1 0x13E /* Data Value Compare Register 1 */ 62#define SPRN_DVC1 0x13E /* Data Value Compare Register 1 */
62#define SPRN_DVC2 0x13F /* Data Value Compare Register 2 */ 63#define SPRN_DVC2 0x13F /* Data Value Compare Register 2 */
64#define SPRN_LPID 0x152 /* Logical Partition ID */
63#define SPRN_MAS8 0x155 /* MMU Assist Register 8 */ 65#define SPRN_MAS8 0x155 /* MMU Assist Register 8 */
64#define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ 66#define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */
65#define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */ 67#define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */
66#define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */ 68#define SPRN_MAS5_MAS6 0x15c /* MMU Assist Register 5 || 6 */
67#define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */ 69#define SPRN_MAS8_MAS1 0x15d /* MMU Assist Register 8 || 1 */
68#define SPRN_EPTCFG 0x15e /* Embedded Page Table Config */ 70#define SPRN_EPTCFG 0x15e /* Embedded Page Table Config */
71#define SPRN_GSPRG0 0x170 /* Guest SPRG0 */
72#define SPRN_GSPRG1 0x171 /* Guest SPRG1 */
73#define SPRN_GSPRG2 0x172 /* Guest SPRG2 */
74#define SPRN_GSPRG3 0x173 /* Guest SPRG3 */
69#define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */ 75#define SPRN_MAS7_MAS3 0x174 /* MMU Assist Register 7 || 3 */
70#define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */ 76#define SPRN_MAS0_MAS1 0x175 /* MMU Assist Register 0 || 1 */
77#define SPRN_GSRR0 0x17A /* Guest SRR0 */
78#define SPRN_GSRR1 0x17B /* Guest SRR1 */
79#define SPRN_GEPR 0x17C /* Guest EPR */
80#define SPRN_GDEAR 0x17D /* Guest DEAR */
81#define SPRN_GPIR 0x17E /* Guest PIR */
82#define SPRN_GESR 0x17F /* Guest Exception Syndrome Register */
71#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ 83#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */
72#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */ 84#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */
73#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */ 85#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */
@@ -88,6 +100,13 @@
88#define SPRN_IVOR39 0x1B1 /* Interrupt Vector Offset Register 39 */ 100#define SPRN_IVOR39 0x1B1 /* Interrupt Vector Offset Register 39 */
89#define SPRN_IVOR40 0x1B2 /* Interrupt Vector Offset Register 40 */ 101#define SPRN_IVOR40 0x1B2 /* Interrupt Vector Offset Register 40 */
90#define SPRN_IVOR41 0x1B3 /* Interrupt Vector Offset Register 41 */ 102#define SPRN_IVOR41 0x1B3 /* Interrupt Vector Offset Register 41 */
103#define SPRN_GIVOR2 0x1B8 /* Guest IVOR2 */
104#define SPRN_GIVOR3 0x1B9 /* Guest IVOR3 */
105#define SPRN_GIVOR4 0x1BA /* Guest IVOR4 */
106#define SPRN_GIVOR8 0x1BB /* Guest IVOR8 */
107#define SPRN_GIVOR13 0x1BC /* Guest IVOR13 */
108#define SPRN_GIVOR14 0x1BD /* Guest IVOR14 */
109#define SPRN_GIVPR 0x1BF /* Guest IVPR */
91#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */ 110#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */
92#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */ 111#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */
93#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */ 112#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */
@@ -240,6 +259,10 @@
240#define MCSR_LDG 0x00002000UL /* Guarded Load */ 259#define MCSR_LDG 0x00002000UL /* Guarded Load */
241#define MCSR_TLBSYNC 0x00000002UL /* Multiple tlbsyncs detected */ 260#define MCSR_TLBSYNC 0x00000002UL /* Multiple tlbsyncs detected */
242#define MCSR_BSL2_ERR 0x00000001UL /* Backside L2 cache error */ 261#define MCSR_BSL2_ERR 0x00000001UL /* Backside L2 cache error */
262
263#define MSRP_UCLEP 0x04000000 /* Protect MSR[UCLE] */
264#define MSRP_DEP 0x00000200 /* Protect MSR[DE] */
265#define MSRP_PMMP 0x00000004 /* Protect MSR[PMM] */
243#endif 266#endif
244 267
245#ifdef CONFIG_E200 268#ifdef CONFIG_E200
@@ -594,6 +617,17 @@
594#define SPRN_EPCR_DMIUH 0x00400000 /* Disable MAS Interrupt updates 617#define SPRN_EPCR_DMIUH 0x00400000 /* Disable MAS Interrupt updates
595 * for hypervisor */ 618 * for hypervisor */
596 619
620/* Bit definitions for EPLC/EPSC */
621#define EPC_EPR 0x80000000 /* 1 = user, 0 = kernel */
622#define EPC_EPR_SHIFT 31
623#define EPC_EAS 0x40000000 /* Address Space */
624#define EPC_EAS_SHIFT 30
625#define EPC_EGS 0x20000000 /* 1 = guest, 0 = hypervisor */
626#define EPC_EGS_SHIFT 29
627#define EPC_ELPID 0x00ff0000
628#define EPC_ELPID_SHIFT 16
629#define EPC_EPID 0x00003fff
630#define EPC_EPID_SHIFT 0
597 631
598/* 632/*
599 * The IBM-403 is an even more odd special case, as it is much 633 * The IBM-403 is an even more odd special case, as it is much
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 1a6320290d2..200d763a0a6 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -17,6 +17,7 @@ extern struct task_struct *_switch(struct thread_struct *prev,
17 struct thread_struct *next); 17 struct thread_struct *next);
18 18
19extern void giveup_fpu(struct task_struct *); 19extern void giveup_fpu(struct task_struct *);
20extern void load_up_fpu(void);
20extern void disable_kernel_fp(void); 21extern void disable_kernel_fp(void);
21extern void enable_kernel_fp(void); 22extern void enable_kernel_fp(void);
22extern void flush_fp_to_thread(struct task_struct *); 23extern void flush_fp_to_thread(struct task_struct *);
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 2136f58a54e..3b4b4a8da92 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -23,6 +23,7 @@
23extern unsigned long tb_ticks_per_jiffy; 23extern unsigned long tb_ticks_per_jiffy;
24extern unsigned long tb_ticks_per_usec; 24extern unsigned long tb_ticks_per_usec;
25extern unsigned long tb_ticks_per_sec; 25extern unsigned long tb_ticks_per_sec;
26extern struct clock_event_device decrementer_clockevent;
26 27
27struct rtc_time; 28struct rtc_time;
28extern void to_tm(int tim, struct rtc_time * tm); 29extern void to_tm(int tim, struct rtc_time * tm);
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index bd0fb849515..17bb40cad5b 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -40,6 +40,8 @@
40 40
41#define segment_eq(a, b) ((a).seg == (b).seg) 41#define segment_eq(a, b) ((a).seg == (b).seg)
42 42
43#define user_addr_max() (get_fs().seg)
44
43#ifdef __powerpc64__ 45#ifdef __powerpc64__
44/* 46/*
45 * This check is sufficient because there is a large enough 47 * This check is sufficient because there is a large enough
@@ -453,42 +455,9 @@ static inline unsigned long clear_user(void __user *addr, unsigned long size)
453 return size; 455 return size;
454} 456}
455 457
456extern int __strncpy_from_user(char *dst, const char __user *src, long count); 458extern long strncpy_from_user(char *dst, const char __user *src, long count);
457 459extern __must_check long strlen_user(const char __user *str);
458static inline long strncpy_from_user(char *dst, const char __user *src, 460extern __must_check long strnlen_user(const char __user *str, long n);
459 long count)
460{
461 might_sleep();
462 if (likely(access_ok(VERIFY_READ, src, 1)))
463 return __strncpy_from_user(dst, src, count);
464 return -EFAULT;
465}
466
467/*
468 * Return the size of a string (including the ending 0)
469 *
470 * Return 0 for error
471 */
472extern int __strnlen_user(const char __user *str, long len, unsigned long top);
473
474/*
475 * Returns the length of the string at str (including the null byte),
476 * or 0 if we hit a page we can't access,
477 * or something > len if we didn't find a null byte.
478 *
479 * The `top' parameter to __strnlen_user is to make sure that
480 * we can never overflow from the user area into kernel space.
481 */
482static inline int strnlen_user(const char __user *str, long len)
483{
484 unsigned long top = current->thread.fs.seg;
485
486 if ((unsigned long)str > top)
487 return 0;
488 return __strnlen_user(str, len, top);
489}
490
491#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
492 461
493#endif /* __ASSEMBLY__ */ 462#endif /* __ASSEMBLY__ */
494#endif /* __KERNEL__ */ 463#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h
new file mode 100644
index 00000000000..d0b6d4ac6dd
--- /dev/null
+++ b/arch/powerpc/include/asm/word-at-a-time.h
@@ -0,0 +1,41 @@
1#ifndef _ASM_WORD_AT_A_TIME_H
2#define _ASM_WORD_AT_A_TIME_H
3
4/*
5 * Word-at-a-time interfaces for PowerPC.
6 */
7
8#include <linux/kernel.h>
9#include <asm/asm-compat.h>
10
11struct word_at_a_time {
12 const unsigned long high_bits, low_bits;
13};
14
15#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0xfe) + 1, REPEAT_BYTE(0x7f) }
16
17/* Bit set in the bytes that have a zero */
18static inline long prep_zero_mask(unsigned long val, unsigned long rhs, const struct word_at_a_time *c)
19{
20 unsigned long mask = (val & c->low_bits) + c->low_bits;
21 return ~(mask | rhs);
22}
23
24#define create_zero_mask(mask) (mask)
25
26static inline long find_zero(unsigned long mask)
27{
28 long leading_zero_bits;
29
30 asm (PPC_CNTLZL "%0,%1" : "=r" (leading_zero_bits) : "r" (mask));
31 return leading_zero_bits >> 3;
32}
33
34static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
35{
36 unsigned long rhs = val | c->low_bits;
37 *data = rhs;
38 return (val + c->high_bits) & ~rhs;
39}
40
41#endif /* _ASM_WORD_AT_A_TIME_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 4554dc2fe85..52c7ad78242 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -116,6 +116,9 @@ int main(void)
116#ifdef CONFIG_KVM_BOOK3S_32_HANDLER 116#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
117 DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu)); 117 DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu));
118#endif 118#endif
119#ifdef CONFIG_KVM_BOOKE_HV
120 DEFINE(THREAD_KVM_VCPU, offsetof(struct thread_struct, kvm_vcpu));
121#endif
119 122
120 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 123 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
121 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); 124 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
@@ -383,6 +386,7 @@ int main(void)
383#ifdef CONFIG_KVM 386#ifdef CONFIG_KVM
384 DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack)); 387 DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
385 DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid)); 388 DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
389 DEFINE(VCPU_GUEST_PID, offsetof(struct kvm_vcpu, arch.pid));
386 DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); 390 DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
387 DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave)); 391 DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
388 DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fpr)); 392 DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fpr));
@@ -425,9 +429,11 @@ int main(void)
425 DEFINE(VCPU_SHARED_MAS4, offsetof(struct kvm_vcpu_arch_shared, mas4)); 429 DEFINE(VCPU_SHARED_MAS4, offsetof(struct kvm_vcpu_arch_shared, mas4));
426 DEFINE(VCPU_SHARED_MAS6, offsetof(struct kvm_vcpu_arch_shared, mas6)); 430 DEFINE(VCPU_SHARED_MAS6, offsetof(struct kvm_vcpu_arch_shared, mas6));
427 431
432 DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
433 DEFINE(KVM_LPID, offsetof(struct kvm, arch.lpid));
434
428 /* book3s */ 435 /* book3s */
429#ifdef CONFIG_KVM_BOOK3S_64_HV 436#ifdef CONFIG_KVM_BOOK3S_64_HV
430 DEFINE(KVM_LPID, offsetof(struct kvm, arch.lpid));
431 DEFINE(KVM_SDR1, offsetof(struct kvm, arch.sdr1)); 437 DEFINE(KVM_SDR1, offsetof(struct kvm, arch.sdr1));
432 DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid)); 438 DEFINE(KVM_HOST_LPID, offsetof(struct kvm, arch.host_lpid));
433 DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr)); 439 DEFINE(KVM_HOST_LPCR, offsetof(struct kvm, arch.host_lpcr));
@@ -440,9 +446,9 @@ int main(void)
440 DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); 446 DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v));
441 DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr)); 447 DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr));
442 DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); 448 DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar));
449 DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr));
443#endif 450#endif
444#ifdef CONFIG_PPC_BOOK3S 451#ifdef CONFIG_PPC_BOOK3S
445 DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm));
446 DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id)); 452 DEFINE(VCPU_VCPUID, offsetof(struct kvm_vcpu, vcpu_id));
447 DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr)); 453 DEFINE(VCPU_PURR, offsetof(struct kvm_vcpu, arch.purr));
448 DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr)); 454 DEFINE(VCPU_SPURR, offsetof(struct kvm_vcpu, arch.spurr));
@@ -457,7 +463,6 @@ int main(void)
457 DEFINE(VCPU_PENDING_EXC, offsetof(struct kvm_vcpu, arch.pending_exceptions)); 463 DEFINE(VCPU_PENDING_EXC, offsetof(struct kvm_vcpu, arch.pending_exceptions));
458 DEFINE(VCPU_CEDED, offsetof(struct kvm_vcpu, arch.ceded)); 464 DEFINE(VCPU_CEDED, offsetof(struct kvm_vcpu, arch.ceded));
459 DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded)); 465 DEFINE(VCPU_PRODDED, offsetof(struct kvm_vcpu, arch.prodded));
460 DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa));
461 DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); 466 DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr));
462 DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); 467 DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc));
463 DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb)); 468 DEFINE(VCPU_SLB, offsetof(struct kvm_vcpu, arch.slb));
@@ -533,6 +538,8 @@ int main(void)
533 HSTATE_FIELD(HSTATE_NAPPING, napping); 538 HSTATE_FIELD(HSTATE_NAPPING, napping);
534 539
535#ifdef CONFIG_KVM_BOOK3S_64_HV 540#ifdef CONFIG_KVM_BOOK3S_64_HV
541 HSTATE_FIELD(HSTATE_HWTHREAD_REQ, hwthread_req);
542 HSTATE_FIELD(HSTATE_HWTHREAD_STATE, hwthread_state);
536 HSTATE_FIELD(HSTATE_KVM_VCPU, kvm_vcpu); 543 HSTATE_FIELD(HSTATE_KVM_VCPU, kvm_vcpu);
537 HSTATE_FIELD(HSTATE_KVM_VCORE, kvm_vcore); 544 HSTATE_FIELD(HSTATE_KVM_VCORE, kvm_vcore);
538 HSTATE_FIELD(HSTATE_XICS_PHYS, xics_phys); 545 HSTATE_FIELD(HSTATE_XICS_PHYS, xics_phys);
@@ -593,6 +600,12 @@ int main(void)
593 DEFINE(VCPU_HOST_SPEFSCR, offsetof(struct kvm_vcpu, arch.host_spefscr)); 600 DEFINE(VCPU_HOST_SPEFSCR, offsetof(struct kvm_vcpu, arch.host_spefscr));
594#endif 601#endif
595 602
603#ifdef CONFIG_KVM_BOOKE_HV
604 DEFINE(VCPU_HOST_MAS4, offsetof(struct kvm_vcpu, arch.host_mas4));
605 DEFINE(VCPU_HOST_MAS6, offsetof(struct kvm_vcpu, arch.host_mas6));
606 DEFINE(VCPU_EPLC, offsetof(struct kvm_vcpu, arch.eplc));
607#endif
608
596#ifdef CONFIG_KVM_EXIT_TIMING 609#ifdef CONFIG_KVM_EXIT_TIMING
597 DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu, 610 DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu,
598 arch.timing_exit.tv32.tbu)); 611 arch.timing_exit.tv32.tbu));
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
index 8053db02b85..69fdd2322a6 100644
--- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -73,6 +73,7 @@ _GLOBAL(__setup_cpu_e500v2)
73 mtlr r4 73 mtlr r4
74 blr 74 blr
75_GLOBAL(__setup_cpu_e500mc) 75_GLOBAL(__setup_cpu_e500mc)
76 mr r5, r4
76 mflr r4 77 mflr r4
77 bl __e500_icache_setup 78 bl __e500_icache_setup
78 bl __e500_dcache_setup 79 bl __e500_dcache_setup
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index f7bed44ee16..1c06d297154 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -63,11 +63,13 @@ BEGIN_FTR_SECTION
63 GET_PACA(r13) 63 GET_PACA(r13)
64 64
65#ifdef CONFIG_KVM_BOOK3S_64_HV 65#ifdef CONFIG_KVM_BOOK3S_64_HV
66 lbz r0,PACAPROCSTART(r13) 66 li r0,KVM_HWTHREAD_IN_KERNEL
67 cmpwi r0,0x80 67 stb r0,HSTATE_HWTHREAD_STATE(r13)
68 bne 1f 68 /* Order setting hwthread_state vs. testing hwthread_req */
69 li r0,1 69 sync
70 stb r0,PACAPROCSTART(r13) 70 lbz r0,HSTATE_HWTHREAD_REQ(r13)
71 cmpwi r0,0
72 beq 1f
71 b kvm_start_guest 73 b kvm_start_guest
721: 741:
73#endif 75#endif
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 22d608e8bb7..7a2e5e421ab 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -248,10 +248,11 @@ _ENTRY(_start);
248 248
249interrupt_base: 249interrupt_base:
250 /* Critical Input Interrupt */ 250 /* Critical Input Interrupt */
251 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) 251 CRITICAL_EXCEPTION(0x0100, CRITICAL, CriticalInput, unknown_exception)
252 252
253 /* Machine Check Interrupt */ 253 /* Machine Check Interrupt */
254 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 254 CRITICAL_EXCEPTION(0x0200, MACHINE_CHECK, MachineCheck, \
255 machine_check_exception)
255 MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) 256 MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
256 257
257 /* Data Storage Interrupt */ 258 /* Data Storage Interrupt */
@@ -261,7 +262,8 @@ interrupt_base:
261 INSTRUCTION_STORAGE_EXCEPTION 262 INSTRUCTION_STORAGE_EXCEPTION
262 263
263 /* External Input Interrupt */ 264 /* External Input Interrupt */
264 EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) 265 EXCEPTION(0x0500, BOOKE_INTERRUPT_EXTERNAL, ExternalInput, \
266 do_IRQ, EXC_XFER_LITE)
265 267
266 /* Alignment Interrupt */ 268 /* Alignment Interrupt */
267 ALIGNMENT_EXCEPTION 269 ALIGNMENT_EXCEPTION
@@ -273,29 +275,32 @@ interrupt_base:
273#ifdef CONFIG_PPC_FPU 275#ifdef CONFIG_PPC_FPU
274 FP_UNAVAILABLE_EXCEPTION 276 FP_UNAVAILABLE_EXCEPTION
275#else 277#else
276 EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) 278 EXCEPTION(0x2010, BOOKE_INTERRUPT_FP_UNAVAIL, \
279 FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
277#endif 280#endif
278 /* System Call Interrupt */ 281 /* System Call Interrupt */
279 START_EXCEPTION(SystemCall) 282 START_EXCEPTION(SystemCall)
280 NORMAL_EXCEPTION_PROLOG 283 NORMAL_EXCEPTION_PROLOG(BOOKE_INTERRUPT_SYSCALL)
281 EXC_XFER_EE_LITE(0x0c00, DoSyscall) 284 EXC_XFER_EE_LITE(0x0c00, DoSyscall)
282 285
283 /* Auxiliary Processor Unavailable Interrupt */ 286 /* Auxiliary Processor Unavailable Interrupt */
284 EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) 287 EXCEPTION(0x2020, BOOKE_INTERRUPT_AP_UNAVAIL, \
288 AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
285 289
286 /* Decrementer Interrupt */ 290 /* Decrementer Interrupt */
287 DECREMENTER_EXCEPTION 291 DECREMENTER_EXCEPTION
288 292
289 /* Fixed Internal Timer Interrupt */ 293 /* Fixed Internal Timer Interrupt */
290 /* TODO: Add FIT support */ 294 /* TODO: Add FIT support */
291 EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) 295 EXCEPTION(0x1010, BOOKE_INTERRUPT_FIT, FixedIntervalTimer, \
296 unknown_exception, EXC_XFER_EE)
292 297
293 /* Watchdog Timer Interrupt */ 298 /* Watchdog Timer Interrupt */
294 /* TODO: Add watchdog support */ 299 /* TODO: Add watchdog support */
295#ifdef CONFIG_BOOKE_WDT 300#ifdef CONFIG_BOOKE_WDT
296 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException) 301 CRITICAL_EXCEPTION(0x1020, WATCHDOG, WatchdogTimer, WatchdogException)
297#else 302#else
298 CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception) 303 CRITICAL_EXCEPTION(0x1020, WATCHDOG, WatchdogTimer, unknown_exception)
299#endif 304#endif
300 305
301 /* Data TLB Error Interrupt */ 306 /* Data TLB Error Interrupt */
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 0e4175388f4..5f051eeb93a 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -2,6 +2,9 @@
2#define __HEAD_BOOKE_H__ 2#define __HEAD_BOOKE_H__
3 3
4#include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */ 4#include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */
5#include <asm/kvm_asm.h>
6#include <asm/kvm_booke_hv_asm.h>
7
5/* 8/*
6 * Macros used for common Book-e exception handling 9 * Macros used for common Book-e exception handling
7 */ 10 */
@@ -28,14 +31,15 @@
28 */ 31 */
29#define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4)) 32#define THREAD_NORMSAVE(offset) (THREAD_NORMSAVES + (offset * 4))
30 33
31#define NORMAL_EXCEPTION_PROLOG \ 34#define NORMAL_EXCEPTION_PROLOG(intno) \
32 mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \ 35 mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \
33 mfspr r10, SPRN_SPRG_THREAD; \ 36 mfspr r10, SPRN_SPRG_THREAD; \
34 stw r11, THREAD_NORMSAVE(0)(r10); \ 37 stw r11, THREAD_NORMSAVE(0)(r10); \
35 stw r13, THREAD_NORMSAVE(2)(r10); \ 38 stw r13, THREAD_NORMSAVE(2)(r10); \
36 mfcr r13; /* save CR in r13 for now */\ 39 mfcr r13; /* save CR in r13 for now */\
37 mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ 40 mfspr r11, SPRN_SRR1; \
38 andi. r11,r11,MSR_PR; \ 41 DO_KVM BOOKE_INTERRUPT_##intno SPRN_SRR1; \
42 andi. r11, r11, MSR_PR; /* check whether user or kernel */\
39 mr r11, r1; \ 43 mr r11, r1; \
40 beq 1f; \ 44 beq 1f; \
41 /* if from user, start at top of this thread's kernel stack */ \ 45 /* if from user, start at top of this thread's kernel stack */ \
@@ -113,7 +117,7 @@
113 * registers as the normal prolog above. Instead we use a portion of the 117 * registers as the normal prolog above. Instead we use a portion of the
114 * critical/machine check exception stack at low physical addresses. 118 * critical/machine check exception stack at low physical addresses.
115 */ 119 */
116#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \ 120#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, intno, exc_level_srr0, exc_level_srr1) \
117 mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \ 121 mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \
118 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \ 122 BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
119 stw r9,GPR9(r8); /* save various registers */\ 123 stw r9,GPR9(r8); /* save various registers */\
@@ -121,8 +125,9 @@
121 stw r10,GPR10(r8); \ 125 stw r10,GPR10(r8); \
122 stw r11,GPR11(r8); \ 126 stw r11,GPR11(r8); \
123 stw r9,_CCR(r8); /* save CR on stack */\ 127 stw r9,_CCR(r8); /* save CR on stack */\
124 mfspr r10,exc_level_srr1; /* check whether user or kernel */\ 128 mfspr r11,exc_level_srr1; /* check whether user or kernel */\
125 andi. r10,r10,MSR_PR; \ 129 DO_KVM BOOKE_INTERRUPT_##intno exc_level_srr1; \
130 andi. r11,r11,MSR_PR; \
126 mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\ 131 mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\
127 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ 132 lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
128 addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\ 133 addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\
@@ -162,12 +167,30 @@
162 SAVE_4GPRS(3, r11); \ 167 SAVE_4GPRS(3, r11); \
163 SAVE_2GPRS(7, r11) 168 SAVE_2GPRS(7, r11)
164 169
165#define CRITICAL_EXCEPTION_PROLOG \ 170#define CRITICAL_EXCEPTION_PROLOG(intno) \
166 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1) 171 EXC_LEVEL_EXCEPTION_PROLOG(CRIT, intno, SPRN_CSRR0, SPRN_CSRR1)
167#define DEBUG_EXCEPTION_PROLOG \ 172#define DEBUG_EXCEPTION_PROLOG \
168 EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0, SPRN_DSRR1) 173 EXC_LEVEL_EXCEPTION_PROLOG(DBG, DEBUG, SPRN_DSRR0, SPRN_DSRR1)
169#define MCHECK_EXCEPTION_PROLOG \ 174#define MCHECK_EXCEPTION_PROLOG \
170 EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1) 175 EXC_LEVEL_EXCEPTION_PROLOG(MC, MACHINE_CHECK, \
176 SPRN_MCSRR0, SPRN_MCSRR1)
177
178/*
179 * Guest Doorbell -- this is a bit odd in that uses GSRR0/1 despite
180 * being delivered to the host. This exception can only happen
181 * inside a KVM guest -- so we just handle up to the DO_KVM rather
182 * than try to fit this into one of the existing prolog macros.
183 */
184#define GUEST_DOORBELL_EXCEPTION \
185 START_EXCEPTION(GuestDoorbell); \
186 mtspr SPRN_SPRG_WSCRATCH0, r10; /* save one register */ \
187 mfspr r10, SPRN_SPRG_THREAD; \
188 stw r11, THREAD_NORMSAVE(0)(r10); \
189 mfspr r11, SPRN_SRR1; \
190 stw r13, THREAD_NORMSAVE(2)(r10); \
191 mfcr r13; /* save CR in r13 for now */\
192 DO_KVM BOOKE_INTERRUPT_GUEST_DBELL SPRN_GSRR1; \
193 trap
171 194
172/* 195/*
173 * Exception vectors. 196 * Exception vectors.
@@ -181,16 +204,16 @@ label:
181 .long func; \ 204 .long func; \
182 .long ret_from_except_full 205 .long ret_from_except_full
183 206
184#define EXCEPTION(n, label, hdlr, xfer) \ 207#define EXCEPTION(n, intno, label, hdlr, xfer) \
185 START_EXCEPTION(label); \ 208 START_EXCEPTION(label); \
186 NORMAL_EXCEPTION_PROLOG; \ 209 NORMAL_EXCEPTION_PROLOG(intno); \
187 addi r3,r1,STACK_FRAME_OVERHEAD; \ 210 addi r3,r1,STACK_FRAME_OVERHEAD; \
188 xfer(n, hdlr) 211 xfer(n, hdlr)
189 212
190#define CRITICAL_EXCEPTION(n, label, hdlr) \ 213#define CRITICAL_EXCEPTION(n, intno, label, hdlr) \
191 START_EXCEPTION(label); \ 214 START_EXCEPTION(label); \
192 CRITICAL_EXCEPTION_PROLOG; \ 215 CRITICAL_EXCEPTION_PROLOG(intno); \
193 addi r3,r1,STACK_FRAME_OVERHEAD; \ 216 addi r3,r1,STACK_FRAME_OVERHEAD; \
194 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ 217 EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
195 NOCOPY, crit_transfer_to_handler, \ 218 NOCOPY, crit_transfer_to_handler, \
196 ret_from_crit_exc) 219 ret_from_crit_exc)
@@ -302,7 +325,7 @@ label:
302 325
303#define DEBUG_CRIT_EXCEPTION \ 326#define DEBUG_CRIT_EXCEPTION \
304 START_EXCEPTION(DebugCrit); \ 327 START_EXCEPTION(DebugCrit); \
305 CRITICAL_EXCEPTION_PROLOG; \ 328 CRITICAL_EXCEPTION_PROLOG(DEBUG); \
306 \ 329 \
307 /* \ 330 /* \
308 * If there is a single step or branch-taken exception in an \ 331 * If there is a single step or branch-taken exception in an \
@@ -355,7 +378,7 @@ label:
355 378
356#define DATA_STORAGE_EXCEPTION \ 379#define DATA_STORAGE_EXCEPTION \
357 START_EXCEPTION(DataStorage) \ 380 START_EXCEPTION(DataStorage) \
358 NORMAL_EXCEPTION_PROLOG; \ 381 NORMAL_EXCEPTION_PROLOG(DATA_STORAGE); \
359 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ 382 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
360 stw r5,_ESR(r11); \ 383 stw r5,_ESR(r11); \
361 mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \ 384 mfspr r4,SPRN_DEAR; /* Grab the DEAR */ \
@@ -363,7 +386,7 @@ label:
363 386
364#define INSTRUCTION_STORAGE_EXCEPTION \ 387#define INSTRUCTION_STORAGE_EXCEPTION \
365 START_EXCEPTION(InstructionStorage) \ 388 START_EXCEPTION(InstructionStorage) \
366 NORMAL_EXCEPTION_PROLOG; \ 389 NORMAL_EXCEPTION_PROLOG(INST_STORAGE); \
367 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ 390 mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
368 stw r5,_ESR(r11); \ 391 stw r5,_ESR(r11); \
369 mr r4,r12; /* Pass SRR0 as arg2 */ \ 392 mr r4,r12; /* Pass SRR0 as arg2 */ \
@@ -372,7 +395,7 @@ label:
372 395
373#define ALIGNMENT_EXCEPTION \ 396#define ALIGNMENT_EXCEPTION \
374 START_EXCEPTION(Alignment) \ 397 START_EXCEPTION(Alignment) \
375 NORMAL_EXCEPTION_PROLOG; \ 398 NORMAL_EXCEPTION_PROLOG(ALIGNMENT); \
376 mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \ 399 mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
377 stw r4,_DEAR(r11); \ 400 stw r4,_DEAR(r11); \
378 addi r3,r1,STACK_FRAME_OVERHEAD; \ 401 addi r3,r1,STACK_FRAME_OVERHEAD; \
@@ -380,7 +403,7 @@ label:
380 403
381#define PROGRAM_EXCEPTION \ 404#define PROGRAM_EXCEPTION \
382 START_EXCEPTION(Program) \ 405 START_EXCEPTION(Program) \
383 NORMAL_EXCEPTION_PROLOG; \ 406 NORMAL_EXCEPTION_PROLOG(PROGRAM); \
384 mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \ 407 mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
385 stw r4,_ESR(r11); \ 408 stw r4,_ESR(r11); \
386 addi r3,r1,STACK_FRAME_OVERHEAD; \ 409 addi r3,r1,STACK_FRAME_OVERHEAD; \
@@ -388,7 +411,7 @@ label:
388 411
389#define DECREMENTER_EXCEPTION \ 412#define DECREMENTER_EXCEPTION \
390 START_EXCEPTION(Decrementer) \ 413 START_EXCEPTION(Decrementer) \
391 NORMAL_EXCEPTION_PROLOG; \ 414 NORMAL_EXCEPTION_PROLOG(DECREMENTER); \
392 lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \ 415 lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
393 mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \ 416 mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
394 addi r3,r1,STACK_FRAME_OVERHEAD; \ 417 addi r3,r1,STACK_FRAME_OVERHEAD; \
@@ -396,7 +419,7 @@ label:
396 419
397#define FP_UNAVAILABLE_EXCEPTION \ 420#define FP_UNAVAILABLE_EXCEPTION \
398 START_EXCEPTION(FloatingPointUnavailable) \ 421 START_EXCEPTION(FloatingPointUnavailable) \
399 NORMAL_EXCEPTION_PROLOG; \ 422 NORMAL_EXCEPTION_PROLOG(FP_UNAVAIL); \
400 beq 1f; \ 423 beq 1f; \
401 bl load_up_fpu; /* if from user, just load it up */ \ 424 bl load_up_fpu; /* if from user, just load it up */ \
402 b fast_exception_return; \ 425 b fast_exception_return; \
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index de80e0f9a2b..1f4434a3860 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -301,19 +301,20 @@ _ENTRY(__early_start)
301 301
302interrupt_base: 302interrupt_base:
303 /* Critical Input Interrupt */ 303 /* Critical Input Interrupt */
304 CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) 304 CRITICAL_EXCEPTION(0x0100, CRITICAL, CriticalInput, unknown_exception)
305 305
306 /* Machine Check Interrupt */ 306 /* Machine Check Interrupt */
307#ifdef CONFIG_E200 307#ifdef CONFIG_E200
308 /* no RFMCI, MCSRRs on E200 */ 308 /* no RFMCI, MCSRRs on E200 */
309 CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 309 CRITICAL_EXCEPTION(0x0200, MACHINE_CHECK, MachineCheck, \
310 machine_check_exception)
310#else 311#else
311 MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 312 MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
312#endif 313#endif
313 314
314 /* Data Storage Interrupt */ 315 /* Data Storage Interrupt */
315 START_EXCEPTION(DataStorage) 316 START_EXCEPTION(DataStorage)
316 NORMAL_EXCEPTION_PROLOG 317 NORMAL_EXCEPTION_PROLOG(DATA_STORAGE)
317 mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ 318 mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
318 stw r5,_ESR(r11) 319 stw r5,_ESR(r11)
319 mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ 320 mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
@@ -328,7 +329,7 @@ interrupt_base:
328 INSTRUCTION_STORAGE_EXCEPTION 329 INSTRUCTION_STORAGE_EXCEPTION
329 330
330 /* External Input Interrupt */ 331 /* External Input Interrupt */
331 EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) 332 EXCEPTION(0x0500, EXTERNAL, ExternalInput, do_IRQ, EXC_XFER_LITE)
332 333
333 /* Alignment Interrupt */ 334 /* Alignment Interrupt */
334 ALIGNMENT_EXCEPTION 335 ALIGNMENT_EXCEPTION
@@ -342,32 +343,36 @@ interrupt_base:
342#else 343#else
343#ifdef CONFIG_E200 344#ifdef CONFIG_E200
344 /* E200 treats 'normal' floating point instructions as FP Unavail exception */ 345 /* E200 treats 'normal' floating point instructions as FP Unavail exception */
345 EXCEPTION(0x0800, FloatingPointUnavailable, program_check_exception, EXC_XFER_EE) 346 EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \
347 program_check_exception, EXC_XFER_EE)
346#else 348#else
347 EXCEPTION(0x0800, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE) 349 EXCEPTION(0x0800, FP_UNAVAIL, FloatingPointUnavailable, \
350 unknown_exception, EXC_XFER_EE)
348#endif 351#endif
349#endif 352#endif
350 353
351 /* System Call Interrupt */ 354 /* System Call Interrupt */
352 START_EXCEPTION(SystemCall) 355 START_EXCEPTION(SystemCall)
353 NORMAL_EXCEPTION_PROLOG 356 NORMAL_EXCEPTION_PROLOG(SYSCALL)
354 EXC_XFER_EE_LITE(0x0c00, DoSyscall) 357 EXC_XFER_EE_LITE(0x0c00, DoSyscall)
355 358
356 /* Auxiliary Processor Unavailable Interrupt */ 359 /* Auxiliary Processor Unavailable Interrupt */
357 EXCEPTION(0x2900, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE) 360 EXCEPTION(0x2900, AP_UNAVAIL, AuxillaryProcessorUnavailable, \
361 unknown_exception, EXC_XFER_EE)
358 362
359 /* Decrementer Interrupt */ 363 /* Decrementer Interrupt */
360 DECREMENTER_EXCEPTION 364 DECREMENTER_EXCEPTION
361 365
362 /* Fixed Internal Timer Interrupt */ 366 /* Fixed Internal Timer Interrupt */
363 /* TODO: Add FIT support */ 367 /* TODO: Add FIT support */
364 EXCEPTION(0x3100, FixedIntervalTimer, unknown_exception, EXC_XFER_EE) 368 EXCEPTION(0x3100, FIT, FixedIntervalTimer, \
369 unknown_exception, EXC_XFER_EE)
365 370
366 /* Watchdog Timer Interrupt */ 371 /* Watchdog Timer Interrupt */
367#ifdef CONFIG_BOOKE_WDT 372#ifdef CONFIG_BOOKE_WDT
368 CRITICAL_EXCEPTION(0x3200, WatchdogTimer, WatchdogException) 373 CRITICAL_EXCEPTION(0x3200, WATCHDOG, WatchdogTimer, WatchdogException)
369#else 374#else
370 CRITICAL_EXCEPTION(0x3200, WatchdogTimer, unknown_exception) 375 CRITICAL_EXCEPTION(0x3200, WATCHDOG, WatchdogTimer, unknown_exception)
371#endif 376#endif
372 377
373 /* Data TLB Error Interrupt */ 378 /* Data TLB Error Interrupt */
@@ -375,10 +380,16 @@ interrupt_base:
375 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 380 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
376 mfspr r10, SPRN_SPRG_THREAD 381 mfspr r10, SPRN_SPRG_THREAD
377 stw r11, THREAD_NORMSAVE(0)(r10) 382 stw r11, THREAD_NORMSAVE(0)(r10)
383#ifdef CONFIG_KVM_BOOKE_HV
384BEGIN_FTR_SECTION
385 mfspr r11, SPRN_SRR1
386END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
387#endif
378 stw r12, THREAD_NORMSAVE(1)(r10) 388 stw r12, THREAD_NORMSAVE(1)(r10)
379 stw r13, THREAD_NORMSAVE(2)(r10) 389 stw r13, THREAD_NORMSAVE(2)(r10)
380 mfcr r13 390 mfcr r13
381 stw r13, THREAD_NORMSAVE(3)(r10) 391 stw r13, THREAD_NORMSAVE(3)(r10)
392 DO_KVM BOOKE_INTERRUPT_DTLB_MISS SPRN_SRR1
382 mfspr r10, SPRN_DEAR /* Get faulting address */ 393 mfspr r10, SPRN_DEAR /* Get faulting address */
383 394
384 /* If we are faulting a kernel address, we have to use the 395 /* If we are faulting a kernel address, we have to use the
@@ -463,10 +474,16 @@ interrupt_base:
463 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */ 474 mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
464 mfspr r10, SPRN_SPRG_THREAD 475 mfspr r10, SPRN_SPRG_THREAD
465 stw r11, THREAD_NORMSAVE(0)(r10) 476 stw r11, THREAD_NORMSAVE(0)(r10)
477#ifdef CONFIG_KVM_BOOKE_HV
478BEGIN_FTR_SECTION
479 mfspr r11, SPRN_SRR1
480END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
481#endif
466 stw r12, THREAD_NORMSAVE(1)(r10) 482 stw r12, THREAD_NORMSAVE(1)(r10)
467 stw r13, THREAD_NORMSAVE(2)(r10) 483 stw r13, THREAD_NORMSAVE(2)(r10)
468 mfcr r13 484 mfcr r13
469 stw r13, THREAD_NORMSAVE(3)(r10) 485 stw r13, THREAD_NORMSAVE(3)(r10)
486 DO_KVM BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR1
470 mfspr r10, SPRN_SRR0 /* Get faulting address */ 487 mfspr r10, SPRN_SRR0 /* Get faulting address */
471 488
472 /* If we are faulting a kernel address, we have to use the 489 /* If we are faulting a kernel address, we have to use the
@@ -538,36 +555,54 @@ interrupt_base:
538#ifdef CONFIG_SPE 555#ifdef CONFIG_SPE
539 /* SPE Unavailable */ 556 /* SPE Unavailable */
540 START_EXCEPTION(SPEUnavailable) 557 START_EXCEPTION(SPEUnavailable)
541 NORMAL_EXCEPTION_PROLOG 558 NORMAL_EXCEPTION_PROLOG(SPE_UNAVAIL)
542 bne load_up_spe 559 bne load_up_spe
543 addi r3,r1,STACK_FRAME_OVERHEAD 560 addi r3,r1,STACK_FRAME_OVERHEAD
544 EXC_XFER_EE_LITE(0x2010, KernelSPE) 561 EXC_XFER_EE_LITE(0x2010, KernelSPE)
545#else 562#else
546 EXCEPTION(0x2020, SPEUnavailable, unknown_exception, EXC_XFER_EE) 563 EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \
564 unknown_exception, EXC_XFER_EE)
547#endif /* CONFIG_SPE */ 565#endif /* CONFIG_SPE */
548 566
549 /* SPE Floating Point Data */ 567 /* SPE Floating Point Data */
550#ifdef CONFIG_SPE 568#ifdef CONFIG_SPE
551 EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); 569 EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData, \
570 SPEFloatingPointException, EXC_XFER_EE);
552 571
553 /* SPE Floating Point Round */ 572 /* SPE Floating Point Round */
554 EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointRoundException, EXC_XFER_EE) 573 EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
574 SPEFloatingPointRoundException, EXC_XFER_EE)
555#else 575#else
556 EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) 576 EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData, \
557 EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) 577 unknown_exception, EXC_XFER_EE)
578 EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
579 unknown_exception, EXC_XFER_EE)
558#endif /* CONFIG_SPE */ 580#endif /* CONFIG_SPE */
559 581
560 /* Performance Monitor */ 582 /* Performance Monitor */
561 EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) 583 EXCEPTION(0x2060, PERFORMANCE_MONITOR, PerformanceMonitor, \
584 performance_monitor_exception, EXC_XFER_STD)
562 585
563 EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD) 586 EXCEPTION(0x2070, DOORBELL, Doorbell, doorbell_exception, EXC_XFER_STD)
564 587
565 CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception) 588 CRITICAL_EXCEPTION(0x2080, DOORBELL_CRITICAL, \
589 CriticalDoorbell, unknown_exception)
566 590
567 /* Debug Interrupt */ 591 /* Debug Interrupt */
568 DEBUG_DEBUG_EXCEPTION 592 DEBUG_DEBUG_EXCEPTION
569 DEBUG_CRIT_EXCEPTION 593 DEBUG_CRIT_EXCEPTION
570 594
595 GUEST_DOORBELL_EXCEPTION
596
597 CRITICAL_EXCEPTION(0, GUEST_DBELL_CRIT, CriticalGuestDoorbell, \
598 unknown_exception)
599
600 /* Hypercall */
601 EXCEPTION(0, HV_SYSCALL, Hypercall, unknown_exception, EXC_XFER_EE)
602
603 /* Embedded Hypervisor Privilege */
604 EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE)
605
571/* 606/*
572 * Local functions 607 * Local functions
573 */ 608 */
@@ -871,8 +906,31 @@ _GLOBAL(__setup_e500mc_ivors)
871 mtspr SPRN_IVOR36,r3 906 mtspr SPRN_IVOR36,r3
872 li r3,CriticalDoorbell@l 907 li r3,CriticalDoorbell@l
873 mtspr SPRN_IVOR37,r3 908 mtspr SPRN_IVOR37,r3
909
910 /*
911 * We only want to touch IVOR38-41 if we're running on hardware
912 * that supports category E.HV. The architectural way to determine
913 * this is MMUCFG[LPIDSIZE].
914 */
915 mfspr r3, SPRN_MMUCFG
916 andis. r3, r3, MMUCFG_LPIDSIZE@h
917 beq no_hv
918 li r3,GuestDoorbell@l
919 mtspr SPRN_IVOR38,r3
920 li r3,CriticalGuestDoorbell@l
921 mtspr SPRN_IVOR39,r3
922 li r3,Hypercall@l
923 mtspr SPRN_IVOR40,r3
924 li r3,Ehvpriv@l
925 mtspr SPRN_IVOR41,r3
926skip_hv_ivors:
874 sync 927 sync
875 blr 928 blr
929no_hv:
930 lwz r3, CPU_SPEC_FEATURES(r5)
931 rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV
932 stw r3, CPU_SPEC_FEATURES(r5)
933 b skip_hv_ivors
876 934
877#ifdef CONFIG_SPE 935#ifdef CONFIG_SPE
878/* 936/*
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 0cdc9a39283..7140d838339 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -16,6 +16,7 @@
16#include <asm/asm-offsets.h> 16#include <asm/asm-offsets.h>
17#include <asm/ppc-opcode.h> 17#include <asm/ppc-opcode.h>
18#include <asm/hw_irq.h> 18#include <asm/hw_irq.h>
19#include <asm/kvm_book3s_asm.h>
19 20
20#undef DEBUG 21#undef DEBUG
21 22
@@ -81,6 +82,12 @@ _GLOBAL(power7_idle)
81 std r9,_MSR(r1) 82 std r9,_MSR(r1)
82 std r1,PACAR1(r13) 83 std r1,PACAR1(r13)
83 84
85#ifdef CONFIG_KVM_BOOK3S_64_HV
86 /* Tell KVM we're napping */
87 li r4,KVM_HWTHREAD_IN_NAP
88 stb r4,HSTATE_HWTHREAD_STATE(r13)
89#endif
90
84 /* Magic NAP mode enter sequence */ 91 /* Magic NAP mode enter sequence */
85 std r0,0(r1) 92 std r0,0(r1)
86 ptesync 93 ptesync
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 786a2700ec2..3e4031581c6 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -85,8 +85,6 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
85 85
86EXPORT_SYMBOL(__copy_tofrom_user); 86EXPORT_SYMBOL(__copy_tofrom_user);
87EXPORT_SYMBOL(__clear_user); 87EXPORT_SYMBOL(__clear_user);
88EXPORT_SYMBOL(__strncpy_from_user);
89EXPORT_SYMBOL(__strnlen_user);
90EXPORT_SYMBOL(copy_page); 88EXPORT_SYMBOL(copy_page);
91 89
92#if defined(CONFIG_PCI) && defined(CONFIG_PPC32) 90#if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
@@ -190,3 +188,7 @@ EXPORT_SYMBOL(__arch_hweight16);
190EXPORT_SYMBOL(__arch_hweight32); 188EXPORT_SYMBOL(__arch_hweight32);
191EXPORT_SYMBOL(__arch_hweight64); 189EXPORT_SYMBOL(__arch_hweight64);
192#endif 190#endif
191
192#ifdef CONFIG_PPC_BOOK3S_64
193EXPORT_SYMBOL_GPL(mmu_psize_defs);
194#endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 2c42cd72d0f..99a995c2a3f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -100,7 +100,7 @@ static int decrementer_set_next_event(unsigned long evt,
100static void decrementer_set_mode(enum clock_event_mode mode, 100static void decrementer_set_mode(enum clock_event_mode mode,
101 struct clock_event_device *dev); 101 struct clock_event_device *dev);
102 102
103static struct clock_event_device decrementer_clockevent = { 103struct clock_event_device decrementer_clockevent = {
104 .name = "decrementer", 104 .name = "decrementer",
105 .rating = 200, 105 .rating = 200,
106 .irq = 0, 106 .irq = 0,
@@ -108,6 +108,7 @@ static struct clock_event_device decrementer_clockevent = {
108 .set_mode = decrementer_set_mode, 108 .set_mode = decrementer_set_mode,
109 .features = CLOCK_EVT_FEAT_ONESHOT, 109 .features = CLOCK_EVT_FEAT_ONESHOT,
110}; 110};
111EXPORT_SYMBOL(decrementer_clockevent);
111 112
112DEFINE_PER_CPU(u64, decrementers_next_tb); 113DEFINE_PER_CPU(u64, decrementers_next_tb);
113static DEFINE_PER_CPU(struct clock_event_device, decrementers); 114static DEFINE_PER_CPU(struct clock_event_device, decrementers);
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 7b612a76c70..50e7dbc7356 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -29,15 +29,18 @@
29#include <asm/kvm_ppc.h> 29#include <asm/kvm_ppc.h>
30 30
31#include "44x_tlb.h" 31#include "44x_tlb.h"
32#include "booke.h"
32 33
33void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 34void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
34{ 35{
36 kvmppc_booke_vcpu_load(vcpu, cpu);
35 kvmppc_44x_tlb_load(vcpu); 37 kvmppc_44x_tlb_load(vcpu);
36} 38}
37 39
38void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) 40void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
39{ 41{
40 kvmppc_44x_tlb_put(vcpu); 42 kvmppc_44x_tlb_put(vcpu);
43 kvmppc_booke_vcpu_put(vcpu);
41} 44}
42 45
43int kvmppc_core_check_processor_compat(void) 46int kvmppc_core_check_processor_compat(void)
@@ -160,6 +163,15 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
160 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 163 kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
161} 164}
162 165
166int kvmppc_core_init_vm(struct kvm *kvm)
167{
168 return 0;
169}
170
171void kvmppc_core_destroy_vm(struct kvm *kvm)
172{
173}
174
163static int __init kvmppc_44x_init(void) 175static int __init kvmppc_44x_init(void)
164{ 176{
165 int r; 177 int r;
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c
index 549bb2c9a47..c8c61578fdf 100644
--- a/arch/powerpc/kvm/44x_emulate.c
+++ b/arch/powerpc/kvm/44x_emulate.c
@@ -37,22 +37,19 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
37 unsigned int inst, int *advance) 37 unsigned int inst, int *advance)
38{ 38{
39 int emulated = EMULATE_DONE; 39 int emulated = EMULATE_DONE;
40 int dcrn; 40 int dcrn = get_dcrn(inst);
41 int ra; 41 int ra = get_ra(inst);
42 int rb; 42 int rb = get_rb(inst);
43 int rc; 43 int rc = get_rc(inst);
44 int rs; 44 int rs = get_rs(inst);
45 int rt; 45 int rt = get_rt(inst);
46 int ws; 46 int ws = get_ws(inst);
47 47
48 switch (get_op(inst)) { 48 switch (get_op(inst)) {
49 case 31: 49 case 31:
50 switch (get_xop(inst)) { 50 switch (get_xop(inst)) {
51 51
52 case XOP_MFDCR: 52 case XOP_MFDCR:
53 dcrn = get_dcrn(inst);
54 rt = get_rt(inst);
55
56 /* The guest may access CPR0 registers to determine the timebase 53 /* The guest may access CPR0 registers to determine the timebase
57 * frequency, and it must know the real host frequency because it 54 * frequency, and it must know the real host frequency because it
58 * can directly access the timebase registers. 55 * can directly access the timebase registers.
@@ -88,9 +85,6 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
88 break; 85 break;
89 86
90 case XOP_MTDCR: 87 case XOP_MTDCR:
91 dcrn = get_dcrn(inst);
92 rs = get_rs(inst);
93
94 /* emulate some access in kernel */ 88 /* emulate some access in kernel */
95 switch (dcrn) { 89 switch (dcrn) {
96 case DCRN_CPR0_CONFIG_ADDR: 90 case DCRN_CPR0_CONFIG_ADDR:
@@ -108,17 +102,10 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
108 break; 102 break;
109 103
110 case XOP_TLBWE: 104 case XOP_TLBWE:
111 ra = get_ra(inst);
112 rs = get_rs(inst);
113 ws = get_ws(inst);
114 emulated = kvmppc_44x_emul_tlbwe(vcpu, ra, rs, ws); 105 emulated = kvmppc_44x_emul_tlbwe(vcpu, ra, rs, ws);
115 break; 106 break;
116 107
117 case XOP_TLBSX: 108 case XOP_TLBSX:
118 rt = get_rt(inst);
119 ra = get_ra(inst);
120 rb = get_rb(inst);
121 rc = get_rc(inst);
122 emulated = kvmppc_44x_emul_tlbsx(vcpu, rt, ra, rb, rc); 109 emulated = kvmppc_44x_emul_tlbsx(vcpu, rt, ra, rb, rc);
123 break; 110 break;
124 111
@@ -141,41 +128,41 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
141 return emulated; 128 return emulated;
142} 129}
143 130
144int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 131int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
145{ 132{
146 int emulated = EMULATE_DONE; 133 int emulated = EMULATE_DONE;
147 134
148 switch (sprn) { 135 switch (sprn) {
149 case SPRN_PID: 136 case SPRN_PID:
150 kvmppc_set_pid(vcpu, kvmppc_get_gpr(vcpu, rs)); break; 137 kvmppc_set_pid(vcpu, spr_val); break;
151 case SPRN_MMUCR: 138 case SPRN_MMUCR:
152 vcpu->arch.mmucr = kvmppc_get_gpr(vcpu, rs); break; 139 vcpu->arch.mmucr = spr_val; break;
153 case SPRN_CCR0: 140 case SPRN_CCR0:
154 vcpu->arch.ccr0 = kvmppc_get_gpr(vcpu, rs); break; 141 vcpu->arch.ccr0 = spr_val; break;
155 case SPRN_CCR1: 142 case SPRN_CCR1:
156 vcpu->arch.ccr1 = kvmppc_get_gpr(vcpu, rs); break; 143 vcpu->arch.ccr1 = spr_val; break;
157 default: 144 default:
158 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs); 145 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val);
159 } 146 }
160 147
161 return emulated; 148 return emulated;
162} 149}
163 150
164int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 151int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
165{ 152{
166 int emulated = EMULATE_DONE; 153 int emulated = EMULATE_DONE;
167 154
168 switch (sprn) { 155 switch (sprn) {
169 case SPRN_PID: 156 case SPRN_PID:
170 kvmppc_set_gpr(vcpu, rt, vcpu->arch.pid); break; 157 *spr_val = vcpu->arch.pid; break;
171 case SPRN_MMUCR: 158 case SPRN_MMUCR:
172 kvmppc_set_gpr(vcpu, rt, vcpu->arch.mmucr); break; 159 *spr_val = vcpu->arch.mmucr; break;
173 case SPRN_CCR0: 160 case SPRN_CCR0:
174 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr0); break; 161 *spr_val = vcpu->arch.ccr0; break;
175 case SPRN_CCR1: 162 case SPRN_CCR1:
176 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ccr1); break; 163 *spr_val = vcpu->arch.ccr1; break;
177 default: 164 default:
178 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt); 165 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val);
179 } 166 }
180 167
181 return emulated; 168 return emulated;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 8f64709ae33..f4dacb9c57f 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -90,6 +90,9 @@ config KVM_BOOK3S_64_PR
90 depends on KVM_BOOK3S_64 && !KVM_BOOK3S_64_HV 90 depends on KVM_BOOK3S_64 && !KVM_BOOK3S_64_HV
91 select KVM_BOOK3S_PR 91 select KVM_BOOK3S_PR
92 92
93config KVM_BOOKE_HV
94 bool
95
93config KVM_440 96config KVM_440
94 bool "KVM support for PowerPC 440 processors" 97 bool "KVM support for PowerPC 440 processors"
95 depends on EXPERIMENTAL && 44x 98 depends on EXPERIMENTAL && 44x
@@ -106,7 +109,7 @@ config KVM_440
106 109
107config KVM_EXIT_TIMING 110config KVM_EXIT_TIMING
108 bool "Detailed exit timing" 111 bool "Detailed exit timing"
109 depends on KVM_440 || KVM_E500 112 depends on KVM_440 || KVM_E500V2 || KVM_E500MC
110 ---help--- 113 ---help---
111 Calculate elapsed time for every exit/enter cycle. A per-vcpu 114 Calculate elapsed time for every exit/enter cycle. A per-vcpu
112 report is available in debugfs kvm/vm#_vcpu#_timing. 115 report is available in debugfs kvm/vm#_vcpu#_timing.
@@ -115,14 +118,29 @@ config KVM_EXIT_TIMING
115 118
116 If unsure, say N. 119 If unsure, say N.
117 120
118config KVM_E500 121config KVM_E500V2
119 bool "KVM support for PowerPC E500 processors" 122 bool "KVM support for PowerPC E500v2 processors"
120 depends on EXPERIMENTAL && E500 123 depends on EXPERIMENTAL && E500 && !PPC_E500MC
121 select KVM 124 select KVM
122 select KVM_MMIO 125 select KVM_MMIO
123 ---help--- 126 ---help---
124 Support running unmodified E500 guest kernels in virtual machines on 127 Support running unmodified E500 guest kernels in virtual machines on
125 E500 host processors. 128 E500v2 host processors.
129
130 This module provides access to the hardware capabilities through
131 a character device node named /dev/kvm.
132
133 If unsure, say N.
134
135config KVM_E500MC
136 bool "KVM support for PowerPC E500MC/E5500 processors"
137 depends on EXPERIMENTAL && PPC_E500MC
138 select KVM
139 select KVM_MMIO
140 select KVM_BOOKE_HV
141 ---help---
142 Support running unmodified E500MC/E5500 (32-bit) guest kernels in
143 virtual machines on E500MC/E5500 host processors.
126 144
127 This module provides access to the hardware capabilities through 145 This module provides access to the hardware capabilities through
128 a character device node named /dev/kvm. 146 a character device node named /dev/kvm.
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 3688aeecc4b..c2a08636e6d 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -36,7 +36,17 @@ kvm-e500-objs := \
36 e500.o \ 36 e500.o \
37 e500_tlb.o \ 37 e500_tlb.o \
38 e500_emulate.o 38 e500_emulate.o
39kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs) 39kvm-objs-$(CONFIG_KVM_E500V2) := $(kvm-e500-objs)
40
41kvm-e500mc-objs := \
42 $(common-objs-y) \
43 booke.o \
44 booke_emulate.o \
45 bookehv_interrupts.o \
46 e500mc.o \
47 e500_tlb.o \
48 e500_emulate.o
49kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
40 50
41kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \ 51kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \
42 ../../../virt/kvm/coalesced_mmio.o \ 52 ../../../virt/kvm/coalesced_mmio.o \
@@ -44,6 +54,7 @@ kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_PR) := \
44 book3s_paired_singles.o \ 54 book3s_paired_singles.o \
45 book3s_pr.o \ 55 book3s_pr.o \
46 book3s_pr_papr.o \ 56 book3s_pr_papr.o \
57 book3s_64_vio_hv.o \
47 book3s_emulate.o \ 58 book3s_emulate.o \
48 book3s_interrupts.o \ 59 book3s_interrupts.o \
49 book3s_mmu_hpte.o \ 60 book3s_mmu_hpte.o \
@@ -68,6 +79,7 @@ kvm-book3s_64-module-objs := \
68 powerpc.o \ 79 powerpc.o \
69 emulate.o \ 80 emulate.o \
70 book3s.o \ 81 book3s.o \
82 book3s_64_vio.o \
71 $(kvm-book3s_64-objs-y) 83 $(kvm-book3s_64-objs-y)
72 84
73kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs) 85kvm-objs-$(CONFIG_KVM_BOOK3S_64) := $(kvm-book3s_64-module-objs)
@@ -88,7 +100,8 @@ kvm-objs-$(CONFIG_KVM_BOOK3S_32) := $(kvm-book3s_32-objs)
88kvm-objs := $(kvm-objs-m) $(kvm-objs-y) 100kvm-objs := $(kvm-objs-m) $(kvm-objs-y)
89 101
90obj-$(CONFIG_KVM_440) += kvm.o 102obj-$(CONFIG_KVM_440) += kvm.o
91obj-$(CONFIG_KVM_E500) += kvm.o 103obj-$(CONFIG_KVM_E500V2) += kvm.o
104obj-$(CONFIG_KVM_E500MC) += kvm.o
92obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o 105obj-$(CONFIG_KVM_BOOK3S_64) += kvm.o
93obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o 106obj-$(CONFIG_KVM_BOOK3S_32) += kvm.o
94 107
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 7d54f4ed6d9..3f2a8360c85 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -258,7 +258,7 @@ static bool clear_irqprio(struct kvm_vcpu *vcpu, unsigned int priority)
258 return true; 258 return true;
259} 259}
260 260
261void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) 261int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
262{ 262{
263 unsigned long *pending = &vcpu->arch.pending_exceptions; 263 unsigned long *pending = &vcpu->arch.pending_exceptions;
264 unsigned long old_pending = vcpu->arch.pending_exceptions; 264 unsigned long old_pending = vcpu->arch.pending_exceptions;
@@ -283,12 +283,17 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
283 283
284 /* Tell the guest about our interrupt status */ 284 /* Tell the guest about our interrupt status */
285 kvmppc_update_int_pending(vcpu, *pending, old_pending); 285 kvmppc_update_int_pending(vcpu, *pending, old_pending);
286
287 return 0;
286} 288}
287 289
288pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) 290pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
289{ 291{
290 ulong mp_pa = vcpu->arch.magic_page_pa; 292 ulong mp_pa = vcpu->arch.magic_page_pa;
291 293
294 if (!(vcpu->arch.shared->msr & MSR_SF))
295 mp_pa = (uint32_t)mp_pa;
296
292 /* Magic page override */ 297 /* Magic page override */
293 if (unlikely(mp_pa) && 298 if (unlikely(mp_pa) &&
294 unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) == 299 unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) ==
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index c3beaeef3f6..80a57751758 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -36,13 +36,11 @@
36 36
37/* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ 37/* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */
38#define MAX_LPID_970 63 38#define MAX_LPID_970 63
39#define NR_LPIDS (LPID_RSVD + 1)
40unsigned long lpid_inuse[BITS_TO_LONGS(NR_LPIDS)];
41 39
42long kvmppc_alloc_hpt(struct kvm *kvm) 40long kvmppc_alloc_hpt(struct kvm *kvm)
43{ 41{
44 unsigned long hpt; 42 unsigned long hpt;
45 unsigned long lpid; 43 long lpid;
46 struct revmap_entry *rev; 44 struct revmap_entry *rev;
47 struct kvmppc_linear_info *li; 45 struct kvmppc_linear_info *li;
48 46
@@ -72,14 +70,9 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
72 } 70 }
73 kvm->arch.revmap = rev; 71 kvm->arch.revmap = rev;
74 72
75 /* Allocate the guest's logical partition ID */ 73 lpid = kvmppc_alloc_lpid();
76 do { 74 if (lpid < 0)
77 lpid = find_first_zero_bit(lpid_inuse, NR_LPIDS); 75 goto out_freeboth;
78 if (lpid >= NR_LPIDS) {
79 pr_err("kvm_alloc_hpt: No LPIDs free\n");
80 goto out_freeboth;
81 }
82 } while (test_and_set_bit(lpid, lpid_inuse));
83 76
84 kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); 77 kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18);
85 kvm->arch.lpid = lpid; 78 kvm->arch.lpid = lpid;
@@ -96,7 +89,7 @@ long kvmppc_alloc_hpt(struct kvm *kvm)
96 89
97void kvmppc_free_hpt(struct kvm *kvm) 90void kvmppc_free_hpt(struct kvm *kvm)
98{ 91{
99 clear_bit(kvm->arch.lpid, lpid_inuse); 92 kvmppc_free_lpid(kvm->arch.lpid);
100 vfree(kvm->arch.revmap); 93 vfree(kvm->arch.revmap);
101 if (kvm->arch.hpt_li) 94 if (kvm->arch.hpt_li)
102 kvm_release_hpt(kvm->arch.hpt_li); 95 kvm_release_hpt(kvm->arch.hpt_li);
@@ -171,8 +164,7 @@ int kvmppc_mmu_hv_init(void)
171 if (!cpu_has_feature(CPU_FTR_HVMODE)) 164 if (!cpu_has_feature(CPU_FTR_HVMODE))
172 return -EINVAL; 165 return -EINVAL;
173 166
174 memset(lpid_inuse, 0, sizeof(lpid_inuse)); 167 /* POWER7 has 10-bit LPIDs, PPC970 and e500mc have 6-bit LPIDs */
175
176 if (cpu_has_feature(CPU_FTR_ARCH_206)) { 168 if (cpu_has_feature(CPU_FTR_ARCH_206)) {
177 host_lpid = mfspr(SPRN_LPID); /* POWER7 */ 169 host_lpid = mfspr(SPRN_LPID); /* POWER7 */
178 rsvd_lpid = LPID_RSVD; 170 rsvd_lpid = LPID_RSVD;
@@ -181,9 +173,11 @@ int kvmppc_mmu_hv_init(void)
181 rsvd_lpid = MAX_LPID_970; 173 rsvd_lpid = MAX_LPID_970;
182 } 174 }
183 175
184 set_bit(host_lpid, lpid_inuse); 176 kvmppc_init_lpid(rsvd_lpid + 1);
177
178 kvmppc_claim_lpid(host_lpid);
185 /* rsvd_lpid is reserved for use in partition switching */ 179 /* rsvd_lpid is reserved for use in partition switching */
186 set_bit(rsvd_lpid, lpid_inuse); 180 kvmppc_claim_lpid(rsvd_lpid);
187 181
188 return 0; 182 return 0;
189} 183}
@@ -452,7 +446,7 @@ static int instruction_is_store(unsigned int instr)
452} 446}
453 447
454static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu, 448static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu,
455 unsigned long gpa, int is_store) 449 unsigned long gpa, gva_t ea, int is_store)
456{ 450{
457 int ret; 451 int ret;
458 u32 last_inst; 452 u32 last_inst;
@@ -499,6 +493,7 @@ static int kvmppc_hv_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu,
499 */ 493 */
500 494
501 vcpu->arch.paddr_accessed = gpa; 495 vcpu->arch.paddr_accessed = gpa;
496 vcpu->arch.vaddr_accessed = ea;
502 return kvmppc_emulate_mmio(run, vcpu); 497 return kvmppc_emulate_mmio(run, vcpu);
503} 498}
504 499
@@ -552,7 +547,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
552 /* No memslot means it's an emulated MMIO region */ 547 /* No memslot means it's an emulated MMIO region */
553 if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) { 548 if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) {
554 unsigned long gpa = (gfn << PAGE_SHIFT) | (ea & (psize - 1)); 549 unsigned long gpa = (gfn << PAGE_SHIFT) | (ea & (psize - 1));
555 return kvmppc_hv_emulate_mmio(run, vcpu, gpa, 550 return kvmppc_hv_emulate_mmio(run, vcpu, gpa, ea,
556 dsisr & DSISR_ISSTORE); 551 dsisr & DSISR_ISSTORE);
557 } 552 }
558 553
diff --git a/arch/powerpc/kvm/book3s_64_slb.S b/arch/powerpc/kvm/book3s_64_slb.S
index f2e6e48ea46..56b983e7b73 100644
--- a/arch/powerpc/kvm/book3s_64_slb.S
+++ b/arch/powerpc/kvm/book3s_64_slb.S
@@ -90,8 +90,6 @@ slb_exit_skip_ ## num:
90 or r10, r10, r12 90 or r10, r10, r12
91 slbie r10 91 slbie r10
92 92
93 isync
94
95 /* Fill SLB with our shadow */ 93 /* Fill SLB with our shadow */
96 94
97 lbz r12, SVCPU_SLB_MAX(r3) 95 lbz r12, SVCPU_SLB_MAX(r3)
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
new file mode 100644
index 00000000000..72ffc899c08
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -0,0 +1,150 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
16 * Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com>
17 */
18
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/kvm.h>
22#include <linux/kvm_host.h>
23#include <linux/highmem.h>
24#include <linux/gfp.h>
25#include <linux/slab.h>
26#include <linux/hugetlb.h>
27#include <linux/list.h>
28#include <linux/anon_inodes.h>
29
30#include <asm/tlbflush.h>
31#include <asm/kvm_ppc.h>
32#include <asm/kvm_book3s.h>
33#include <asm/mmu-hash64.h>
34#include <asm/hvcall.h>
35#include <asm/synch.h>
36#include <asm/ppc-opcode.h>
37#include <asm/kvm_host.h>
38#include <asm/udbg.h>
39
40#define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64))
41
42static long kvmppc_stt_npages(unsigned long window_size)
43{
44 return ALIGN((window_size >> SPAPR_TCE_SHIFT)
45 * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
46}
47
48static void release_spapr_tce_table(struct kvmppc_spapr_tce_table *stt)
49{
50 struct kvm *kvm = stt->kvm;
51 int i;
52
53 mutex_lock(&kvm->lock);
54 list_del(&stt->list);
55 for (i = 0; i < kvmppc_stt_npages(stt->window_size); i++)
56 __free_page(stt->pages[i]);
57 kfree(stt);
58 mutex_unlock(&kvm->lock);
59
60 kvm_put_kvm(kvm);
61}
62
63static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
64{
65 struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data;
66 struct page *page;
67
68 if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size))
69 return VM_FAULT_SIGBUS;
70
71 page = stt->pages[vmf->pgoff];
72 get_page(page);
73 vmf->page = page;
74 return 0;
75}
76
77static const struct vm_operations_struct kvm_spapr_tce_vm_ops = {
78 .fault = kvm_spapr_tce_fault,
79};
80
81static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma)
82{
83 vma->vm_ops = &kvm_spapr_tce_vm_ops;
84 return 0;
85}
86
87static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
88{
89 struct kvmppc_spapr_tce_table *stt = filp->private_data;
90
91 release_spapr_tce_table(stt);
92 return 0;
93}
94
95static struct file_operations kvm_spapr_tce_fops = {
96 .mmap = kvm_spapr_tce_mmap,
97 .release = kvm_spapr_tce_release,
98};
99
100long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
101 struct kvm_create_spapr_tce *args)
102{
103 struct kvmppc_spapr_tce_table *stt = NULL;
104 long npages;
105 int ret = -ENOMEM;
106 int i;
107
108 /* Check this LIOBN hasn't been previously allocated */
109 list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
110 if (stt->liobn == args->liobn)
111 return -EBUSY;
112 }
113
114 npages = kvmppc_stt_npages(args->window_size);
115
116 stt = kzalloc(sizeof(*stt) + npages * sizeof(struct page *),
117 GFP_KERNEL);
118 if (!stt)
119 goto fail;
120
121 stt->liobn = args->liobn;
122 stt->window_size = args->window_size;
123 stt->kvm = kvm;
124
125 for (i = 0; i < npages; i++) {
126 stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
127 if (!stt->pages[i])
128 goto fail;
129 }
130
131 kvm_get_kvm(kvm);
132
133 mutex_lock(&kvm->lock);
134 list_add(&stt->list, &kvm->arch.spapr_tce_tables);
135
136 mutex_unlock(&kvm->lock);
137
138 return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops,
139 stt, O_RDWR);
140
141fail:
142 if (stt) {
143 for (i = 0; i < npages; i++)
144 if (stt->pages[i])
145 __free_page(stt->pages[i]);
146
147 kfree(stt);
148 }
149 return ret;
150}
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index ea0f8c537c2..30c2f3b134c 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -38,6 +38,9 @@
38 38
39#define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64)) 39#define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64))
40 40
41/* WARNING: This will be called in real-mode on HV KVM and virtual
42 * mode on PR KVM
43 */
41long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, 44long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
42 unsigned long ioba, unsigned long tce) 45 unsigned long ioba, unsigned long tce)
43{ 46{
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 135663a3e4f..b9a989dc76c 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -87,6 +87,10 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
87 unsigned int inst, int *advance) 87 unsigned int inst, int *advance)
88{ 88{
89 int emulated = EMULATE_DONE; 89 int emulated = EMULATE_DONE;
90 int rt = get_rt(inst);
91 int rs = get_rs(inst);
92 int ra = get_ra(inst);
93 int rb = get_rb(inst);
90 94
91 switch (get_op(inst)) { 95 switch (get_op(inst)) {
92 case 19: 96 case 19:
@@ -106,21 +110,22 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
106 case 31: 110 case 31:
107 switch (get_xop(inst)) { 111 switch (get_xop(inst)) {
108 case OP_31_XOP_MFMSR: 112 case OP_31_XOP_MFMSR:
109 kvmppc_set_gpr(vcpu, get_rt(inst), 113 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
110 vcpu->arch.shared->msr);
111 break; 114 break;
112 case OP_31_XOP_MTMSRD: 115 case OP_31_XOP_MTMSRD:
113 { 116 {
114 ulong rs = kvmppc_get_gpr(vcpu, get_rs(inst)); 117 ulong rs_val = kvmppc_get_gpr(vcpu, rs);
115 if (inst & 0x10000) { 118 if (inst & 0x10000) {
116 vcpu->arch.shared->msr &= ~(MSR_RI | MSR_EE); 119 ulong new_msr = vcpu->arch.shared->msr;
117 vcpu->arch.shared->msr |= rs & (MSR_RI | MSR_EE); 120 new_msr &= ~(MSR_RI | MSR_EE);
121 new_msr |= rs_val & (MSR_RI | MSR_EE);
122 vcpu->arch.shared->msr = new_msr;
118 } else 123 } else
119 kvmppc_set_msr(vcpu, rs); 124 kvmppc_set_msr(vcpu, rs_val);
120 break; 125 break;
121 } 126 }
122 case OP_31_XOP_MTMSR: 127 case OP_31_XOP_MTMSR:
123 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, get_rs(inst))); 128 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
124 break; 129 break;
125 case OP_31_XOP_MFSR: 130 case OP_31_XOP_MFSR:
126 { 131 {
@@ -130,7 +135,7 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
130 if (vcpu->arch.mmu.mfsrin) { 135 if (vcpu->arch.mmu.mfsrin) {
131 u32 sr; 136 u32 sr;
132 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); 137 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
133 kvmppc_set_gpr(vcpu, get_rt(inst), sr); 138 kvmppc_set_gpr(vcpu, rt, sr);
134 } 139 }
135 break; 140 break;
136 } 141 }
@@ -138,29 +143,29 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
138 { 143 {
139 int srnum; 144 int srnum;
140 145
141 srnum = (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf; 146 srnum = (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf;
142 if (vcpu->arch.mmu.mfsrin) { 147 if (vcpu->arch.mmu.mfsrin) {
143 u32 sr; 148 u32 sr;
144 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum); 149 sr = vcpu->arch.mmu.mfsrin(vcpu, srnum);
145 kvmppc_set_gpr(vcpu, get_rt(inst), sr); 150 kvmppc_set_gpr(vcpu, rt, sr);
146 } 151 }
147 break; 152 break;
148 } 153 }
149 case OP_31_XOP_MTSR: 154 case OP_31_XOP_MTSR:
150 vcpu->arch.mmu.mtsrin(vcpu, 155 vcpu->arch.mmu.mtsrin(vcpu,
151 (inst >> 16) & 0xf, 156 (inst >> 16) & 0xf,
152 kvmppc_get_gpr(vcpu, get_rs(inst))); 157 kvmppc_get_gpr(vcpu, rs));
153 break; 158 break;
154 case OP_31_XOP_MTSRIN: 159 case OP_31_XOP_MTSRIN:
155 vcpu->arch.mmu.mtsrin(vcpu, 160 vcpu->arch.mmu.mtsrin(vcpu,
156 (kvmppc_get_gpr(vcpu, get_rb(inst)) >> 28) & 0xf, 161 (kvmppc_get_gpr(vcpu, rb) >> 28) & 0xf,
157 kvmppc_get_gpr(vcpu, get_rs(inst))); 162 kvmppc_get_gpr(vcpu, rs));
158 break; 163 break;
159 case OP_31_XOP_TLBIE: 164 case OP_31_XOP_TLBIE:
160 case OP_31_XOP_TLBIEL: 165 case OP_31_XOP_TLBIEL:
161 { 166 {
162 bool large = (inst & 0x00200000) ? true : false; 167 bool large = (inst & 0x00200000) ? true : false;
163 ulong addr = kvmppc_get_gpr(vcpu, get_rb(inst)); 168 ulong addr = kvmppc_get_gpr(vcpu, rb);
164 vcpu->arch.mmu.tlbie(vcpu, addr, large); 169 vcpu->arch.mmu.tlbie(vcpu, addr, large);
165 break; 170 break;
166 } 171 }
@@ -171,15 +176,15 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
171 return EMULATE_FAIL; 176 return EMULATE_FAIL;
172 177
173 vcpu->arch.mmu.slbmte(vcpu, 178 vcpu->arch.mmu.slbmte(vcpu,
174 kvmppc_get_gpr(vcpu, get_rs(inst)), 179 kvmppc_get_gpr(vcpu, rs),
175 kvmppc_get_gpr(vcpu, get_rb(inst))); 180 kvmppc_get_gpr(vcpu, rb));
176 break; 181 break;
177 case OP_31_XOP_SLBIE: 182 case OP_31_XOP_SLBIE:
178 if (!vcpu->arch.mmu.slbie) 183 if (!vcpu->arch.mmu.slbie)
179 return EMULATE_FAIL; 184 return EMULATE_FAIL;
180 185
181 vcpu->arch.mmu.slbie(vcpu, 186 vcpu->arch.mmu.slbie(vcpu,
182 kvmppc_get_gpr(vcpu, get_rb(inst))); 187 kvmppc_get_gpr(vcpu, rb));
183 break; 188 break;
184 case OP_31_XOP_SLBIA: 189 case OP_31_XOP_SLBIA:
185 if (!vcpu->arch.mmu.slbia) 190 if (!vcpu->arch.mmu.slbia)
@@ -191,22 +196,22 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
191 if (!vcpu->arch.mmu.slbmfee) { 196 if (!vcpu->arch.mmu.slbmfee) {
192 emulated = EMULATE_FAIL; 197 emulated = EMULATE_FAIL;
193 } else { 198 } else {
194 ulong t, rb; 199 ulong t, rb_val;
195 200
196 rb = kvmppc_get_gpr(vcpu, get_rb(inst)); 201 rb_val = kvmppc_get_gpr(vcpu, rb);
197 t = vcpu->arch.mmu.slbmfee(vcpu, rb); 202 t = vcpu->arch.mmu.slbmfee(vcpu, rb_val);
198 kvmppc_set_gpr(vcpu, get_rt(inst), t); 203 kvmppc_set_gpr(vcpu, rt, t);
199 } 204 }
200 break; 205 break;
201 case OP_31_XOP_SLBMFEV: 206 case OP_31_XOP_SLBMFEV:
202 if (!vcpu->arch.mmu.slbmfev) { 207 if (!vcpu->arch.mmu.slbmfev) {
203 emulated = EMULATE_FAIL; 208 emulated = EMULATE_FAIL;
204 } else { 209 } else {
205 ulong t, rb; 210 ulong t, rb_val;
206 211
207 rb = kvmppc_get_gpr(vcpu, get_rb(inst)); 212 rb_val = kvmppc_get_gpr(vcpu, rb);
208 t = vcpu->arch.mmu.slbmfev(vcpu, rb); 213 t = vcpu->arch.mmu.slbmfev(vcpu, rb_val);
209 kvmppc_set_gpr(vcpu, get_rt(inst), t); 214 kvmppc_set_gpr(vcpu, rt, t);
210 } 215 }
211 break; 216 break;
212 case OP_31_XOP_DCBA: 217 case OP_31_XOP_DCBA:
@@ -214,17 +219,17 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
214 break; 219 break;
215 case OP_31_XOP_DCBZ: 220 case OP_31_XOP_DCBZ:
216 { 221 {
217 ulong rb = kvmppc_get_gpr(vcpu, get_rb(inst)); 222 ulong rb_val = kvmppc_get_gpr(vcpu, rb);
218 ulong ra = 0; 223 ulong ra_val = 0;
219 ulong addr, vaddr; 224 ulong addr, vaddr;
220 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 225 u32 zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
221 u32 dsisr; 226 u32 dsisr;
222 int r; 227 int r;
223 228
224 if (get_ra(inst)) 229 if (ra)
225 ra = kvmppc_get_gpr(vcpu, get_ra(inst)); 230 ra_val = kvmppc_get_gpr(vcpu, ra);
226 231
227 addr = (ra + rb) & ~31ULL; 232 addr = (ra_val + rb_val) & ~31ULL;
228 if (!(vcpu->arch.shared->msr & MSR_SF)) 233 if (!(vcpu->arch.shared->msr & MSR_SF))
229 addr &= 0xffffffff; 234 addr &= 0xffffffff;
230 vaddr = addr; 235 vaddr = addr;
@@ -313,10 +318,9 @@ static struct kvmppc_bat *kvmppc_find_bat(struct kvm_vcpu *vcpu, int sprn)
313 return bat; 318 return bat;
314} 319}
315 320
316int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 321int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
317{ 322{
318 int emulated = EMULATE_DONE; 323 int emulated = EMULATE_DONE;
319 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
320 324
321 switch (sprn) { 325 switch (sprn) {
322 case SPRN_SDR1: 326 case SPRN_SDR1:
@@ -428,7 +432,7 @@ unprivileged:
428 return emulated; 432 return emulated;
429} 433}
430 434
431int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 435int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
432{ 436{
433 int emulated = EMULATE_DONE; 437 int emulated = EMULATE_DONE;
434 438
@@ -441,46 +445,46 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
441 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn); 445 struct kvmppc_bat *bat = kvmppc_find_bat(vcpu, sprn);
442 446
443 if (sprn % 2) 447 if (sprn % 2)
444 kvmppc_set_gpr(vcpu, rt, bat->raw >> 32); 448 *spr_val = bat->raw >> 32;
445 else 449 else
446 kvmppc_set_gpr(vcpu, rt, bat->raw); 450 *spr_val = bat->raw;
447 451
448 break; 452 break;
449 } 453 }
450 case SPRN_SDR1: 454 case SPRN_SDR1:
451 if (!spr_allowed(vcpu, PRIV_HYPER)) 455 if (!spr_allowed(vcpu, PRIV_HYPER))
452 goto unprivileged; 456 goto unprivileged;
453 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->sdr1); 457 *spr_val = to_book3s(vcpu)->sdr1;
454 break; 458 break;
455 case SPRN_DSISR: 459 case SPRN_DSISR:
456 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dsisr); 460 *spr_val = vcpu->arch.shared->dsisr;
457 break; 461 break;
458 case SPRN_DAR: 462 case SPRN_DAR:
459 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar); 463 *spr_val = vcpu->arch.shared->dar;
460 break; 464 break;
461 case SPRN_HIOR: 465 case SPRN_HIOR:
462 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hior); 466 *spr_val = to_book3s(vcpu)->hior;
463 break; 467 break;
464 case SPRN_HID0: 468 case SPRN_HID0:
465 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[0]); 469 *spr_val = to_book3s(vcpu)->hid[0];
466 break; 470 break;
467 case SPRN_HID1: 471 case SPRN_HID1:
468 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[1]); 472 *spr_val = to_book3s(vcpu)->hid[1];
469 break; 473 break;
470 case SPRN_HID2: 474 case SPRN_HID2:
471 case SPRN_HID2_GEKKO: 475 case SPRN_HID2_GEKKO:
472 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[2]); 476 *spr_val = to_book3s(vcpu)->hid[2];
473 break; 477 break;
474 case SPRN_HID4: 478 case SPRN_HID4:
475 case SPRN_HID4_GEKKO: 479 case SPRN_HID4_GEKKO:
476 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[4]); 480 *spr_val = to_book3s(vcpu)->hid[4];
477 break; 481 break;
478 case SPRN_HID5: 482 case SPRN_HID5:
479 kvmppc_set_gpr(vcpu, rt, to_book3s(vcpu)->hid[5]); 483 *spr_val = to_book3s(vcpu)->hid[5];
480 break; 484 break;
481 case SPRN_CFAR: 485 case SPRN_CFAR:
482 case SPRN_PURR: 486 case SPRN_PURR:
483 kvmppc_set_gpr(vcpu, rt, 0); 487 *spr_val = 0;
484 break; 488 break;
485 case SPRN_GQR0: 489 case SPRN_GQR0:
486 case SPRN_GQR1: 490 case SPRN_GQR1:
@@ -490,8 +494,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
490 case SPRN_GQR5: 494 case SPRN_GQR5:
491 case SPRN_GQR6: 495 case SPRN_GQR6:
492 case SPRN_GQR7: 496 case SPRN_GQR7:
493 kvmppc_set_gpr(vcpu, rt, 497 *spr_val = to_book3s(vcpu)->gqr[sprn - SPRN_GQR0];
494 to_book3s(vcpu)->gqr[sprn - SPRN_GQR0]);
495 break; 498 break;
496 case SPRN_THRM1: 499 case SPRN_THRM1:
497 case SPRN_THRM2: 500 case SPRN_THRM2:
@@ -506,7 +509,7 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
506 case SPRN_PMC3_GEKKO: 509 case SPRN_PMC3_GEKKO:
507 case SPRN_PMC4_GEKKO: 510 case SPRN_PMC4_GEKKO:
508 case SPRN_WPAR_GEKKO: 511 case SPRN_WPAR_GEKKO:
509 kvmppc_set_gpr(vcpu, rt, 0); 512 *spr_val = 0;
510 break; 513 break;
511 default: 514 default:
512unprivileged: 515unprivileged:
@@ -565,23 +568,22 @@ u32 kvmppc_alignment_dsisr(struct kvm_vcpu *vcpu, unsigned int inst)
565ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst) 568ulong kvmppc_alignment_dar(struct kvm_vcpu *vcpu, unsigned int inst)
566{ 569{
567 ulong dar = 0; 570 ulong dar = 0;
568 ulong ra; 571 ulong ra = get_ra(inst);
572 ulong rb = get_rb(inst);
569 573
570 switch (get_op(inst)) { 574 switch (get_op(inst)) {
571 case OP_LFS: 575 case OP_LFS:
572 case OP_LFD: 576 case OP_LFD:
573 case OP_STFD: 577 case OP_STFD:
574 case OP_STFS: 578 case OP_STFS:
575 ra = get_ra(inst);
576 if (ra) 579 if (ra)
577 dar = kvmppc_get_gpr(vcpu, ra); 580 dar = kvmppc_get_gpr(vcpu, ra);
578 dar += (s32)((s16)inst); 581 dar += (s32)((s16)inst);
579 break; 582 break;
580 case 31: 583 case 31:
581 ra = get_ra(inst);
582 if (ra) 584 if (ra)
583 dar = kvmppc_get_gpr(vcpu, ra); 585 dar = kvmppc_get_gpr(vcpu, ra);
584 dar += kvmppc_get_gpr(vcpu, get_rb(inst)); 586 dar += kvmppc_get_gpr(vcpu, rb);
585 break; 587 break;
586 default: 588 default:
587 printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst); 589 printk(KERN_INFO "KVM: Unaligned instruction 0x%x\n", inst);
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 108d1f58017..c6af1d62383 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -60,12 +60,20 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu);
60 60
61void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 61void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
62{ 62{
63 struct kvmppc_vcore *vc = vcpu->arch.vcore;
64
63 local_paca->kvm_hstate.kvm_vcpu = vcpu; 65 local_paca->kvm_hstate.kvm_vcpu = vcpu;
64 local_paca->kvm_hstate.kvm_vcore = vcpu->arch.vcore; 66 local_paca->kvm_hstate.kvm_vcore = vc;
67 if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
68 vc->stolen_tb += mftb() - vc->preempt_tb;
65} 69}
66 70
67void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) 71void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
68{ 72{
73 struct kvmppc_vcore *vc = vcpu->arch.vcore;
74
75 if (vc->runner == vcpu && vc->vcore_state != VCORE_INACTIVE)
76 vc->preempt_tb = mftb();
69} 77}
70 78
71void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr) 79void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
@@ -134,6 +142,22 @@ static void init_vpa(struct kvm_vcpu *vcpu, struct lppaca *vpa)
134 vpa->yield_count = 1; 142 vpa->yield_count = 1;
135} 143}
136 144
145/* Length for a per-processor buffer is passed in at offset 4 in the buffer */
146struct reg_vpa {
147 u32 dummy;
148 union {
149 u16 hword;
150 u32 word;
151 } length;
152};
153
154static int vpa_is_registered(struct kvmppc_vpa *vpap)
155{
156 if (vpap->update_pending)
157 return vpap->next_gpa != 0;
158 return vpap->pinned_addr != NULL;
159}
160
137static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, 161static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu,
138 unsigned long flags, 162 unsigned long flags,
139 unsigned long vcpuid, unsigned long vpa) 163 unsigned long vcpuid, unsigned long vpa)
@@ -142,88 +166,182 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu,
142 unsigned long len, nb; 166 unsigned long len, nb;
143 void *va; 167 void *va;
144 struct kvm_vcpu *tvcpu; 168 struct kvm_vcpu *tvcpu;
145 int err = H_PARAMETER; 169 int err;
170 int subfunc;
171 struct kvmppc_vpa *vpap;
146 172
147 tvcpu = kvmppc_find_vcpu(kvm, vcpuid); 173 tvcpu = kvmppc_find_vcpu(kvm, vcpuid);
148 if (!tvcpu) 174 if (!tvcpu)
149 return H_PARAMETER; 175 return H_PARAMETER;
150 176
151 flags >>= 63 - 18; 177 subfunc = (flags >> H_VPA_FUNC_SHIFT) & H_VPA_FUNC_MASK;
152 flags &= 7; 178 if (subfunc == H_VPA_REG_VPA || subfunc == H_VPA_REG_DTL ||
153 if (flags == 0 || flags == 4) 179 subfunc == H_VPA_REG_SLB) {
154 return H_PARAMETER; 180 /* Registering new area - address must be cache-line aligned */
155 if (flags < 4) { 181 if ((vpa & (L1_CACHE_BYTES - 1)) || !vpa)
156 if (vpa & 0x7f)
157 return H_PARAMETER; 182 return H_PARAMETER;
158 if (flags >= 2 && !tvcpu->arch.vpa) 183
159 return H_RESOURCE; 184 /* convert logical addr to kernel addr and read length */
160 /* registering new area; convert logical addr to real */
161 va = kvmppc_pin_guest_page(kvm, vpa, &nb); 185 va = kvmppc_pin_guest_page(kvm, vpa, &nb);
162 if (va == NULL) 186 if (va == NULL)
163 return H_PARAMETER; 187 return H_PARAMETER;
164 if (flags <= 1) 188 if (subfunc == H_VPA_REG_VPA)
165 len = *(unsigned short *)(va + 4); 189 len = ((struct reg_vpa *)va)->length.hword;
166 else 190 else
167 len = *(unsigned int *)(va + 4); 191 len = ((struct reg_vpa *)va)->length.word;
168 if (len > nb) 192 kvmppc_unpin_guest_page(kvm, va);
169 goto out_unpin; 193
170 switch (flags) { 194 /* Check length */
171 case 1: /* register VPA */ 195 if (len > nb || len < sizeof(struct reg_vpa))
172 if (len < 640) 196 return H_PARAMETER;
173 goto out_unpin; 197 } else {
174 if (tvcpu->arch.vpa) 198 vpa = 0;
175 kvmppc_unpin_guest_page(kvm, vcpu->arch.vpa); 199 len = 0;
176 tvcpu->arch.vpa = va; 200 }
177 init_vpa(vcpu, va); 201
178 break; 202 err = H_PARAMETER;
179 case 2: /* register DTL */ 203 vpap = NULL;
180 if (len < 48) 204 spin_lock(&tvcpu->arch.vpa_update_lock);
181 goto out_unpin; 205
182 len -= len % 48; 206 switch (subfunc) {
183 if (tvcpu->arch.dtl) 207 case H_VPA_REG_VPA: /* register VPA */
184 kvmppc_unpin_guest_page(kvm, vcpu->arch.dtl); 208 if (len < sizeof(struct lppaca))
185 tvcpu->arch.dtl = va;
186 tvcpu->arch.dtl_end = va + len;
187 break; 209 break;
188 case 3: /* register SLB shadow buffer */ 210 vpap = &tvcpu->arch.vpa;
189 if (len < 16) 211 err = 0;
190 goto out_unpin; 212 break;
191 if (tvcpu->arch.slb_shadow) 213
192 kvmppc_unpin_guest_page(kvm, vcpu->arch.slb_shadow); 214 case H_VPA_REG_DTL: /* register DTL */
193 tvcpu->arch.slb_shadow = va; 215 if (len < sizeof(struct dtl_entry))
194 break; 216 break;
195 } 217 len -= len % sizeof(struct dtl_entry);
196 } else { 218
197 switch (flags) { 219 /* Check that they have previously registered a VPA */
198 case 5: /* unregister VPA */ 220 err = H_RESOURCE;
199 if (tvcpu->arch.slb_shadow || tvcpu->arch.dtl) 221 if (!vpa_is_registered(&tvcpu->arch.vpa))
200 return H_RESOURCE;
201 if (!tvcpu->arch.vpa)
202 break;
203 kvmppc_unpin_guest_page(kvm, tvcpu->arch.vpa);
204 tvcpu->arch.vpa = NULL;
205 break; 222 break;
206 case 6: /* unregister DTL */ 223
207 if (!tvcpu->arch.dtl) 224 vpap = &tvcpu->arch.dtl;
208 break; 225 err = 0;
209 kvmppc_unpin_guest_page(kvm, tvcpu->arch.dtl); 226 break;
210 tvcpu->arch.dtl = NULL; 227
228 case H_VPA_REG_SLB: /* register SLB shadow buffer */
229 /* Check that they have previously registered a VPA */
230 err = H_RESOURCE;
231 if (!vpa_is_registered(&tvcpu->arch.vpa))
211 break; 232 break;
212 case 7: /* unregister SLB shadow buffer */ 233
213 if (!tvcpu->arch.slb_shadow) 234 vpap = &tvcpu->arch.slb_shadow;
214 break; 235 err = 0;
215 kvmppc_unpin_guest_page(kvm, tvcpu->arch.slb_shadow); 236 break;
216 tvcpu->arch.slb_shadow = NULL; 237
238 case H_VPA_DEREG_VPA: /* deregister VPA */
239 /* Check they don't still have a DTL or SLB buf registered */
240 err = H_RESOURCE;
241 if (vpa_is_registered(&tvcpu->arch.dtl) ||
242 vpa_is_registered(&tvcpu->arch.slb_shadow))
217 break; 243 break;
218 } 244
245 vpap = &tvcpu->arch.vpa;
246 err = 0;
247 break;
248
249 case H_VPA_DEREG_DTL: /* deregister DTL */
250 vpap = &tvcpu->arch.dtl;
251 err = 0;
252 break;
253
254 case H_VPA_DEREG_SLB: /* deregister SLB shadow buffer */
255 vpap = &tvcpu->arch.slb_shadow;
256 err = 0;
257 break;
258 }
259
260 if (vpap) {
261 vpap->next_gpa = vpa;
262 vpap->len = len;
263 vpap->update_pending = 1;
219 } 264 }
220 return H_SUCCESS;
221 265
222 out_unpin: 266 spin_unlock(&tvcpu->arch.vpa_update_lock);
223 kvmppc_unpin_guest_page(kvm, va); 267
224 return err; 268 return err;
225} 269}
226 270
271static void kvmppc_update_vpa(struct kvm *kvm, struct kvmppc_vpa *vpap)
272{
273 void *va;
274 unsigned long nb;
275
276 vpap->update_pending = 0;
277 va = NULL;
278 if (vpap->next_gpa) {
279 va = kvmppc_pin_guest_page(kvm, vpap->next_gpa, &nb);
280 if (nb < vpap->len) {
281 /*
282 * If it's now too short, it must be that userspace
283 * has changed the mappings underlying guest memory,
284 * so unregister the region.
285 */
286 kvmppc_unpin_guest_page(kvm, va);
287 va = NULL;
288 }
289 }
290 if (vpap->pinned_addr)
291 kvmppc_unpin_guest_page(kvm, vpap->pinned_addr);
292 vpap->pinned_addr = va;
293 if (va)
294 vpap->pinned_end = va + vpap->len;
295}
296
297static void kvmppc_update_vpas(struct kvm_vcpu *vcpu)
298{
299 struct kvm *kvm = vcpu->kvm;
300
301 spin_lock(&vcpu->arch.vpa_update_lock);
302 if (vcpu->arch.vpa.update_pending) {
303 kvmppc_update_vpa(kvm, &vcpu->arch.vpa);
304 init_vpa(vcpu, vcpu->arch.vpa.pinned_addr);
305 }
306 if (vcpu->arch.dtl.update_pending) {
307 kvmppc_update_vpa(kvm, &vcpu->arch.dtl);
308 vcpu->arch.dtl_ptr = vcpu->arch.dtl.pinned_addr;
309 vcpu->arch.dtl_index = 0;
310 }
311 if (vcpu->arch.slb_shadow.update_pending)
312 kvmppc_update_vpa(kvm, &vcpu->arch.slb_shadow);
313 spin_unlock(&vcpu->arch.vpa_update_lock);
314}
315
316static void kvmppc_create_dtl_entry(struct kvm_vcpu *vcpu,
317 struct kvmppc_vcore *vc)
318{
319 struct dtl_entry *dt;
320 struct lppaca *vpa;
321 unsigned long old_stolen;
322
323 dt = vcpu->arch.dtl_ptr;
324 vpa = vcpu->arch.vpa.pinned_addr;
325 old_stolen = vcpu->arch.stolen_logged;
326 vcpu->arch.stolen_logged = vc->stolen_tb;
327 if (!dt || !vpa)
328 return;
329 memset(dt, 0, sizeof(struct dtl_entry));
330 dt->dispatch_reason = 7;
331 dt->processor_id = vc->pcpu + vcpu->arch.ptid;
332 dt->timebase = mftb();
333 dt->enqueue_to_dispatch_time = vc->stolen_tb - old_stolen;
334 dt->srr0 = kvmppc_get_pc(vcpu);
335 dt->srr1 = vcpu->arch.shregs.msr;
336 ++dt;
337 if (dt == vcpu->arch.dtl.pinned_end)
338 dt = vcpu->arch.dtl.pinned_addr;
339 vcpu->arch.dtl_ptr = dt;
340 /* order writing *dt vs. writing vpa->dtl_idx */
341 smp_wmb();
342 vpa->dtl_idx = ++vcpu->arch.dtl_index;
343}
344
227int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) 345int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
228{ 346{
229 unsigned long req = kvmppc_get_gpr(vcpu, 3); 347 unsigned long req = kvmppc_get_gpr(vcpu, 3);
@@ -468,6 +586,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
468 /* default to host PVR, since we can't spoof it */ 586 /* default to host PVR, since we can't spoof it */
469 vcpu->arch.pvr = mfspr(SPRN_PVR); 587 vcpu->arch.pvr = mfspr(SPRN_PVR);
470 kvmppc_set_pvr(vcpu, vcpu->arch.pvr); 588 kvmppc_set_pvr(vcpu, vcpu->arch.pvr);
589 spin_lock_init(&vcpu->arch.vpa_update_lock);
471 590
472 kvmppc_mmu_book3s_hv_init(vcpu); 591 kvmppc_mmu_book3s_hv_init(vcpu);
473 592
@@ -486,6 +605,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
486 INIT_LIST_HEAD(&vcore->runnable_threads); 605 INIT_LIST_HEAD(&vcore->runnable_threads);
487 spin_lock_init(&vcore->lock); 606 spin_lock_init(&vcore->lock);
488 init_waitqueue_head(&vcore->wq); 607 init_waitqueue_head(&vcore->wq);
608 vcore->preempt_tb = mftb();
489 } 609 }
490 kvm->arch.vcores[core] = vcore; 610 kvm->arch.vcores[core] = vcore;
491 } 611 }
@@ -498,6 +618,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
498 ++vcore->num_threads; 618 ++vcore->num_threads;
499 spin_unlock(&vcore->lock); 619 spin_unlock(&vcore->lock);
500 vcpu->arch.vcore = vcore; 620 vcpu->arch.vcore = vcore;
621 vcpu->arch.stolen_logged = vcore->stolen_tb;
501 622
502 vcpu->arch.cpu_type = KVM_CPU_3S_64; 623 vcpu->arch.cpu_type = KVM_CPU_3S_64;
503 kvmppc_sanity_check(vcpu); 624 kvmppc_sanity_check(vcpu);
@@ -512,12 +633,14 @@ out:
512 633
513void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) 634void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
514{ 635{
515 if (vcpu->arch.dtl) 636 spin_lock(&vcpu->arch.vpa_update_lock);
516 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.dtl); 637 if (vcpu->arch.dtl.pinned_addr)
517 if (vcpu->arch.slb_shadow) 638 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.dtl.pinned_addr);
518 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.slb_shadow); 639 if (vcpu->arch.slb_shadow.pinned_addr)
519 if (vcpu->arch.vpa) 640 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.slb_shadow.pinned_addr);
520 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.vpa); 641 if (vcpu->arch.vpa.pinned_addr)
642 kvmppc_unpin_guest_page(vcpu->kvm, vcpu->arch.vpa.pinned_addr);
643 spin_unlock(&vcpu->arch.vpa_update_lock);
521 kvm_vcpu_uninit(vcpu); 644 kvm_vcpu_uninit(vcpu);
522 kmem_cache_free(kvm_vcpu_cache, vcpu); 645 kmem_cache_free(kvm_vcpu_cache, vcpu);
523} 646}
@@ -569,6 +692,45 @@ static void kvmppc_remove_runnable(struct kvmppc_vcore *vc,
569 list_del(&vcpu->arch.run_list); 692 list_del(&vcpu->arch.run_list);
570} 693}
571 694
695static int kvmppc_grab_hwthread(int cpu)
696{
697 struct paca_struct *tpaca;
698 long timeout = 1000;
699
700 tpaca = &paca[cpu];
701
702 /* Ensure the thread won't go into the kernel if it wakes */
703 tpaca->kvm_hstate.hwthread_req = 1;
704
705 /*
706 * If the thread is already executing in the kernel (e.g. handling
707 * a stray interrupt), wait for it to get back to nap mode.
708 * The smp_mb() is to ensure that our setting of hwthread_req
709 * is visible before we look at hwthread_state, so if this
710 * races with the code at system_reset_pSeries and the thread
711 * misses our setting of hwthread_req, we are sure to see its
712 * setting of hwthread_state, and vice versa.
713 */
714 smp_mb();
715 while (tpaca->kvm_hstate.hwthread_state == KVM_HWTHREAD_IN_KERNEL) {
716 if (--timeout <= 0) {
717 pr_err("KVM: couldn't grab cpu %d\n", cpu);
718 return -EBUSY;
719 }
720 udelay(1);
721 }
722 return 0;
723}
724
725static void kvmppc_release_hwthread(int cpu)
726{
727 struct paca_struct *tpaca;
728
729 tpaca = &paca[cpu];
730 tpaca->kvm_hstate.hwthread_req = 0;
731 tpaca->kvm_hstate.kvm_vcpu = NULL;
732}
733
572static void kvmppc_start_thread(struct kvm_vcpu *vcpu) 734static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
573{ 735{
574 int cpu; 736 int cpu;
@@ -588,8 +750,7 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
588 smp_wmb(); 750 smp_wmb();
589#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP) 751#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
590 if (vcpu->arch.ptid) { 752 if (vcpu->arch.ptid) {
591 tpaca->cpu_start = 0x80; 753 kvmppc_grab_hwthread(cpu);
592 wmb();
593 xics_wake_cpu(cpu); 754 xics_wake_cpu(cpu);
594 ++vc->n_woken; 755 ++vc->n_woken;
595 } 756 }
@@ -639,7 +800,7 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc)
639 struct kvm_vcpu *vcpu, *vcpu0, *vnext; 800 struct kvm_vcpu *vcpu, *vcpu0, *vnext;
640 long ret; 801 long ret;
641 u64 now; 802 u64 now;
642 int ptid; 803 int ptid, i;
643 804
644 /* don't start if any threads have a signal pending */ 805 /* don't start if any threads have a signal pending */
645 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) 806 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)
@@ -681,17 +842,29 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc)
681 vc->nap_count = 0; 842 vc->nap_count = 0;
682 vc->entry_exit_count = 0; 843 vc->entry_exit_count = 0;
683 vc->vcore_state = VCORE_RUNNING; 844 vc->vcore_state = VCORE_RUNNING;
845 vc->stolen_tb += mftb() - vc->preempt_tb;
684 vc->in_guest = 0; 846 vc->in_guest = 0;
685 vc->pcpu = smp_processor_id(); 847 vc->pcpu = smp_processor_id();
686 vc->napping_threads = 0; 848 vc->napping_threads = 0;
687 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) 849 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) {
688 kvmppc_start_thread(vcpu); 850 kvmppc_start_thread(vcpu);
851 if (vcpu->arch.vpa.update_pending ||
852 vcpu->arch.slb_shadow.update_pending ||
853 vcpu->arch.dtl.update_pending)
854 kvmppc_update_vpas(vcpu);
855 kvmppc_create_dtl_entry(vcpu, vc);
856 }
857 /* Grab any remaining hw threads so they can't go into the kernel */
858 for (i = ptid; i < threads_per_core; ++i)
859 kvmppc_grab_hwthread(vc->pcpu + i);
689 860
690 preempt_disable(); 861 preempt_disable();
691 spin_unlock(&vc->lock); 862 spin_unlock(&vc->lock);
692 863
693 kvm_guest_enter(); 864 kvm_guest_enter();
694 __kvmppc_vcore_entry(NULL, vcpu0); 865 __kvmppc_vcore_entry(NULL, vcpu0);
866 for (i = 0; i < threads_per_core; ++i)
867 kvmppc_release_hwthread(vc->pcpu + i);
695 868
696 spin_lock(&vc->lock); 869 spin_lock(&vc->lock);
697 /* disable sending of IPIs on virtual external irqs */ 870 /* disable sending of IPIs on virtual external irqs */
@@ -737,6 +910,7 @@ static int kvmppc_run_core(struct kvmppc_vcore *vc)
737 spin_lock(&vc->lock); 910 spin_lock(&vc->lock);
738 out: 911 out:
739 vc->vcore_state = VCORE_INACTIVE; 912 vc->vcore_state = VCORE_INACTIVE;
913 vc->preempt_tb = mftb();
740 list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads, 914 list_for_each_entry_safe(vcpu, vnext, &vc->runnable_threads,
741 arch.run_list) { 915 arch.run_list) {
742 if (vcpu->arch.ret != RESUME_GUEST) { 916 if (vcpu->arch.ret != RESUME_GUEST) {
@@ -835,6 +1009,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
835 spin_lock(&vc->lock); 1009 spin_lock(&vc->lock);
836 continue; 1010 continue;
837 } 1011 }
1012 vc->runner = vcpu;
838 n_ceded = 0; 1013 n_ceded = 0;
839 list_for_each_entry(v, &vc->runnable_threads, arch.run_list) 1014 list_for_each_entry(v, &vc->runnable_threads, arch.run_list)
840 n_ceded += v->arch.ceded; 1015 n_ceded += v->arch.ceded;
@@ -854,6 +1029,7 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
854 wake_up(&v->arch.cpu_run); 1029 wake_up(&v->arch.cpu_run);
855 } 1030 }
856 } 1031 }
1032 vc->runner = NULL;
857 } 1033 }
858 1034
859 if (signal_pending(current)) { 1035 if (signal_pending(current)) {
@@ -917,115 +1093,6 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu)
917 return r; 1093 return r;
918} 1094}
919 1095
920static long kvmppc_stt_npages(unsigned long window_size)
921{
922 return ALIGN((window_size >> SPAPR_TCE_SHIFT)
923 * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
924}
925
926static void release_spapr_tce_table(struct kvmppc_spapr_tce_table *stt)
927{
928 struct kvm *kvm = stt->kvm;
929 int i;
930
931 mutex_lock(&kvm->lock);
932 list_del(&stt->list);
933 for (i = 0; i < kvmppc_stt_npages(stt->window_size); i++)
934 __free_page(stt->pages[i]);
935 kfree(stt);
936 mutex_unlock(&kvm->lock);
937
938 kvm_put_kvm(kvm);
939}
940
941static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
942{
943 struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data;
944 struct page *page;
945
946 if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size))
947 return VM_FAULT_SIGBUS;
948
949 page = stt->pages[vmf->pgoff];
950 get_page(page);
951 vmf->page = page;
952 return 0;
953}
954
955static const struct vm_operations_struct kvm_spapr_tce_vm_ops = {
956 .fault = kvm_spapr_tce_fault,
957};
958
959static int kvm_spapr_tce_mmap(struct file *file, struct vm_area_struct *vma)
960{
961 vma->vm_ops = &kvm_spapr_tce_vm_ops;
962 return 0;
963}
964
965static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
966{
967 struct kvmppc_spapr_tce_table *stt = filp->private_data;
968
969 release_spapr_tce_table(stt);
970 return 0;
971}
972
973static struct file_operations kvm_spapr_tce_fops = {
974 .mmap = kvm_spapr_tce_mmap,
975 .release = kvm_spapr_tce_release,
976};
977
978long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
979 struct kvm_create_spapr_tce *args)
980{
981 struct kvmppc_spapr_tce_table *stt = NULL;
982 long npages;
983 int ret = -ENOMEM;
984 int i;
985
986 /* Check this LIOBN hasn't been previously allocated */
987 list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
988 if (stt->liobn == args->liobn)
989 return -EBUSY;
990 }
991
992 npages = kvmppc_stt_npages(args->window_size);
993
994 stt = kzalloc(sizeof(*stt) + npages* sizeof(struct page *),
995 GFP_KERNEL);
996 if (!stt)
997 goto fail;
998
999 stt->liobn = args->liobn;
1000 stt->window_size = args->window_size;
1001 stt->kvm = kvm;
1002
1003 for (i = 0; i < npages; i++) {
1004 stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
1005 if (!stt->pages[i])
1006 goto fail;
1007 }
1008
1009 kvm_get_kvm(kvm);
1010
1011 mutex_lock(&kvm->lock);
1012 list_add(&stt->list, &kvm->arch.spapr_tce_tables);
1013
1014 mutex_unlock(&kvm->lock);
1015
1016 return anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops,
1017 stt, O_RDWR);
1018
1019fail:
1020 if (stt) {
1021 for (i = 0; i < npages; i++)
1022 if (stt->pages[i])
1023 __free_page(stt->pages[i]);
1024
1025 kfree(stt);
1026 }
1027 return ret;
1028}
1029 1096
1030/* Work out RMLS (real mode limit selector) field value for a given RMA size. 1097/* Work out RMLS (real mode limit selector) field value for a given RMA size.
1031 Assumes POWER7 or PPC970. */ 1098 Assumes POWER7 or PPC970. */
@@ -1108,6 +1175,38 @@ long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret)
1108 return fd; 1175 return fd;
1109} 1176}
1110 1177
1178static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps,
1179 int linux_psize)
1180{
1181 struct mmu_psize_def *def = &mmu_psize_defs[linux_psize];
1182
1183 if (!def->shift)
1184 return;
1185 (*sps)->page_shift = def->shift;
1186 (*sps)->slb_enc = def->sllp;
1187 (*sps)->enc[0].page_shift = def->shift;
1188 (*sps)->enc[0].pte_enc = def->penc;
1189 (*sps)++;
1190}
1191
1192int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info)
1193{
1194 struct kvm_ppc_one_seg_page_size *sps;
1195
1196 info->flags = KVM_PPC_PAGE_SIZES_REAL;
1197 if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
1198 info->flags |= KVM_PPC_1T_SEGMENTS;
1199 info->slb_size = mmu_slb_size;
1200
1201 /* We only support these sizes for now, and no muti-size segments */
1202 sps = &info->sps[0];
1203 kvmppc_add_seg_page_size(&sps, MMU_PAGE_4K);
1204 kvmppc_add_seg_page_size(&sps, MMU_PAGE_64K);
1205 kvmppc_add_seg_page_size(&sps, MMU_PAGE_16M);
1206
1207 return 0;
1208}
1209
1111/* 1210/*
1112 * Get (and clear) the dirty memory log for a memory slot. 1211 * Get (and clear) the dirty memory log for a memory slot.
1113 */ 1212 */
@@ -1404,12 +1503,12 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
1404 return EMULATE_FAIL; 1503 return EMULATE_FAIL;
1405} 1504}
1406 1505
1407int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 1506int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
1408{ 1507{
1409 return EMULATE_FAIL; 1508 return EMULATE_FAIL;
1410} 1509}
1411 1510
1412int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 1511int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
1413{ 1512{
1414 return EMULATE_FAIL; 1513 return EMULATE_FAIL;
1415} 1514}
diff --git a/arch/powerpc/kvm/book3s_hv_interrupts.S b/arch/powerpc/kvm/book3s_hv_interrupts.S
index d3fb4df02c4..84035a528c8 100644
--- a/arch/powerpc/kvm/book3s_hv_interrupts.S
+++ b/arch/powerpc/kvm/book3s_hv_interrupts.S
@@ -68,19 +68,24 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
68 rotldi r10,r10,16 68 rotldi r10,r10,16
69 mtmsrd r10,1 69 mtmsrd r10,1
70 70
71 /* Save host PMU registers and load guest PMU registers */ 71 /* Save host PMU registers */
72 /* R4 is live here (vcpu pointer) but not r3 or r5 */ 72 /* R4 is live here (vcpu pointer) but not r3 or r5 */
73 li r3, 1 73 li r3, 1
74 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */ 74 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */
75 mfspr r7, SPRN_MMCR0 /* save MMCR0 */ 75 mfspr r7, SPRN_MMCR0 /* save MMCR0 */
76 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable interrupts */ 76 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable interrupts */
77 mfspr r6, SPRN_MMCRA
78BEGIN_FTR_SECTION
79 /* On P7, clear MMCRA in order to disable SDAR updates */
80 li r5, 0
81 mtspr SPRN_MMCRA, r5
82END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
77 isync 83 isync
78 ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */ 84 ld r3, PACALPPACAPTR(r13) /* is the host using the PMU? */
79 lbz r5, LPPACA_PMCINUSE(r3) 85 lbz r5, LPPACA_PMCINUSE(r3)
80 cmpwi r5, 0 86 cmpwi r5, 0
81 beq 31f /* skip if not */ 87 beq 31f /* skip if not */
82 mfspr r5, SPRN_MMCR1 88 mfspr r5, SPRN_MMCR1
83 mfspr r6, SPRN_MMCRA
84 std r7, HSTATE_MMCR(r13) 89 std r7, HSTATE_MMCR(r13)
85 std r5, HSTATE_MMCR + 8(r13) 90 std r5, HSTATE_MMCR + 8(r13)
86 std r6, HSTATE_MMCR + 16(r13) 91 std r6, HSTATE_MMCR + 16(r13)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index b70bf22a3ff..a84aafce2a1 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -26,6 +26,7 @@
26#include <asm/hvcall.h> 26#include <asm/hvcall.h>
27#include <asm/asm-offsets.h> 27#include <asm/asm-offsets.h>
28#include <asm/exception-64s.h> 28#include <asm/exception-64s.h>
29#include <asm/kvm_book3s_asm.h>
29 30
30/***************************************************************************** 31/*****************************************************************************
31 * * 32 * *
@@ -82,6 +83,7 @@ _GLOBAL(kvmppc_hv_entry_trampoline)
82 83
83#define XICS_XIRR 4 84#define XICS_XIRR 4
84#define XICS_QIRR 0xc 85#define XICS_QIRR 0xc
86#define XICS_IPI 2 /* interrupt source # for IPIs */
85 87
86/* 88/*
87 * We come in here when wakened from nap mode on a secondary hw thread. 89 * We come in here when wakened from nap mode on a secondary hw thread.
@@ -94,26 +96,54 @@ kvm_start_guest:
94 subi r1,r1,STACK_FRAME_OVERHEAD 96 subi r1,r1,STACK_FRAME_OVERHEAD
95 ld r2,PACATOC(r13) 97 ld r2,PACATOC(r13)
96 98
97 /* were we napping due to cede? */ 99 li r0,KVM_HWTHREAD_IN_KVM
98 lbz r0,HSTATE_NAPPING(r13) 100 stb r0,HSTATE_HWTHREAD_STATE(r13)
99 cmpwi r0,0
100 bne kvm_end_cede
101 101
102 /* get vcpu pointer */ 102 /* NV GPR values from power7_idle() will no longer be valid */
103 ld r4, HSTATE_KVM_VCPU(r13) 103 li r0,1
104 stb r0,PACA_NAPSTATELOST(r13)
104 105
105 /* We got here with an IPI; clear it */ 106 /* get vcpu pointer, NULL if we have no vcpu to run */
106 ld r5, HSTATE_XICS_PHYS(r13) 107 ld r4,HSTATE_KVM_VCPU(r13)
107 li r0, 0xff 108 cmpdi cr1,r4,0
108 li r6, XICS_QIRR 109
109 li r7, XICS_XIRR 110 /* Check the wake reason in SRR1 to see why we got here */
110 lwzcix r8, r5, r7 /* ack the interrupt */ 111 mfspr r3,SPRN_SRR1
112 rlwinm r3,r3,44-31,0x7 /* extract wake reason field */
113 cmpwi r3,4 /* was it an external interrupt? */
114 bne 27f
115
116 /*
117 * External interrupt - for now assume it is an IPI, since we
118 * should never get any other interrupts sent to offline threads.
119 * Only do this for secondary threads.
120 */
121 beq cr1,25f
122 lwz r3,VCPU_PTID(r4)
123 cmpwi r3,0
124 beq 27f
12525: ld r5,HSTATE_XICS_PHYS(r13)
126 li r0,0xff
127 li r6,XICS_QIRR
128 li r7,XICS_XIRR
129 lwzcix r8,r5,r7 /* get and ack the interrupt */
111 sync 130 sync
112 stbcix r0, r5, r6 /* clear it */ 131 clrldi. r9,r8,40 /* get interrupt source ID. */
113 stwcix r8, r5, r7 /* EOI it */ 132 beq 27f /* none there? */
133 cmpwi r9,XICS_IPI
134 bne 26f
135 stbcix r0,r5,r6 /* clear IPI */
13626: stwcix r8,r5,r7 /* EOI the interrupt */
114 137
115 /* NV GPR values from power7_idle() will no longer be valid */ 13827: /* XXX should handle hypervisor maintenance interrupts etc. here */
116 stb r0, PACA_NAPSTATELOST(r13) 139
140 /* if we have no vcpu to run, go back to sleep */
141 beq cr1,kvm_no_guest
142
143 /* were we napping due to cede? */
144 lbz r0,HSTATE_NAPPING(r13)
145 cmpwi r0,0
146 bne kvm_end_cede
117 147
118.global kvmppc_hv_entry 148.global kvmppc_hv_entry
119kvmppc_hv_entry: 149kvmppc_hv_entry:
@@ -129,24 +159,15 @@ kvmppc_hv_entry:
129 mflr r0 159 mflr r0
130 std r0, HSTATE_VMHANDLER(r13) 160 std r0, HSTATE_VMHANDLER(r13)
131 161
132 ld r14, VCPU_GPR(r14)(r4) 162 /* Set partition DABR */
133 ld r15, VCPU_GPR(r15)(r4) 163 /* Do this before re-enabling PMU to avoid P7 DABR corruption bug */
134 ld r16, VCPU_GPR(r16)(r4) 164 li r5,3
135 ld r17, VCPU_GPR(r17)(r4) 165 ld r6,VCPU_DABR(r4)
136 ld r18, VCPU_GPR(r18)(r4) 166 mtspr SPRN_DABRX,r5
137 ld r19, VCPU_GPR(r19)(r4) 167 mtspr SPRN_DABR,r6
138 ld r20, VCPU_GPR(r20)(r4) 168BEGIN_FTR_SECTION
139 ld r21, VCPU_GPR(r21)(r4) 169 isync
140 ld r22, VCPU_GPR(r22)(r4) 170END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
141 ld r23, VCPU_GPR(r23)(r4)
142 ld r24, VCPU_GPR(r24)(r4)
143 ld r25, VCPU_GPR(r25)(r4)
144 ld r26, VCPU_GPR(r26)(r4)
145 ld r27, VCPU_GPR(r27)(r4)
146 ld r28, VCPU_GPR(r28)(r4)
147 ld r29, VCPU_GPR(r29)(r4)
148 ld r30, VCPU_GPR(r30)(r4)
149 ld r31, VCPU_GPR(r31)(r4)
150 171
151 /* Load guest PMU registers */ 172 /* Load guest PMU registers */
152 /* R4 is live here (vcpu pointer) */ 173 /* R4 is live here (vcpu pointer) */
@@ -185,6 +206,25 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
185 /* Load up FP, VMX and VSX registers */ 206 /* Load up FP, VMX and VSX registers */
186 bl kvmppc_load_fp 207 bl kvmppc_load_fp
187 208
209 ld r14, VCPU_GPR(r14)(r4)
210 ld r15, VCPU_GPR(r15)(r4)
211 ld r16, VCPU_GPR(r16)(r4)
212 ld r17, VCPU_GPR(r17)(r4)
213 ld r18, VCPU_GPR(r18)(r4)
214 ld r19, VCPU_GPR(r19)(r4)
215 ld r20, VCPU_GPR(r20)(r4)
216 ld r21, VCPU_GPR(r21)(r4)
217 ld r22, VCPU_GPR(r22)(r4)
218 ld r23, VCPU_GPR(r23)(r4)
219 ld r24, VCPU_GPR(r24)(r4)
220 ld r25, VCPU_GPR(r25)(r4)
221 ld r26, VCPU_GPR(r26)(r4)
222 ld r27, VCPU_GPR(r27)(r4)
223 ld r28, VCPU_GPR(r28)(r4)
224 ld r29, VCPU_GPR(r29)(r4)
225 ld r30, VCPU_GPR(r30)(r4)
226 ld r31, VCPU_GPR(r31)(r4)
227
188BEGIN_FTR_SECTION 228BEGIN_FTR_SECTION
189 /* Switch DSCR to guest value */ 229 /* Switch DSCR to guest value */
190 ld r5, VCPU_DSCR(r4) 230 ld r5, VCPU_DSCR(r4)
@@ -226,12 +266,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
226 mtspr SPRN_DAR, r5 266 mtspr SPRN_DAR, r5
227 mtspr SPRN_DSISR, r6 267 mtspr SPRN_DSISR, r6
228 268
229 /* Set partition DABR */
230 li r5,3
231 ld r6,VCPU_DABR(r4)
232 mtspr SPRN_DABRX,r5
233 mtspr SPRN_DABR,r6
234
235BEGIN_FTR_SECTION 269BEGIN_FTR_SECTION
236 /* Restore AMR and UAMOR, set AMOR to all 1s */ 270 /* Restore AMR and UAMOR, set AMOR to all 1s */
237 ld r5,VCPU_AMR(r4) 271 ld r5,VCPU_AMR(r4)
@@ -925,12 +959,6 @@ BEGIN_FTR_SECTION
925 mtspr SPRN_AMR,r6 959 mtspr SPRN_AMR,r6
926END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) 960END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
927 961
928 /* Restore host DABR and DABRX */
929 ld r5,HSTATE_DABR(r13)
930 li r6,7
931 mtspr SPRN_DABR,r5
932 mtspr SPRN_DABRX,r6
933
934 /* Switch DSCR back to host value */ 962 /* Switch DSCR back to host value */
935BEGIN_FTR_SECTION 963BEGIN_FTR_SECTION
936 mfspr r8, SPRN_DSCR 964 mfspr r8, SPRN_DSCR
@@ -969,6 +997,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
969 std r5, VCPU_SPRG2(r9) 997 std r5, VCPU_SPRG2(r9)
970 std r6, VCPU_SPRG3(r9) 998 std r6, VCPU_SPRG3(r9)
971 999
1000 /* save FP state */
1001 mr r3, r9
1002 bl .kvmppc_save_fp
1003
972 /* Increment yield count if they have a VPA */ 1004 /* Increment yield count if they have a VPA */
973 ld r8, VCPU_VPA(r9) /* do they have a VPA? */ 1005 ld r8, VCPU_VPA(r9) /* do they have a VPA? */
974 cmpdi r8, 0 1006 cmpdi r8, 0
@@ -983,6 +1015,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
983 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */ 1015 sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */
984 mfspr r4, SPRN_MMCR0 /* save MMCR0 */ 1016 mfspr r4, SPRN_MMCR0 /* save MMCR0 */
985 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */ 1017 mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */
1018 mfspr r6, SPRN_MMCRA
1019BEGIN_FTR_SECTION
1020 /* On P7, clear MMCRA in order to disable SDAR updates */
1021 li r7, 0
1022 mtspr SPRN_MMCRA, r7
1023END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
986 isync 1024 isync
987 beq 21f /* if no VPA, save PMU stuff anyway */ 1025 beq 21f /* if no VPA, save PMU stuff anyway */
988 lbz r7, LPPACA_PMCINUSE(r8) 1026 lbz r7, LPPACA_PMCINUSE(r8)
@@ -991,7 +1029,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
991 std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */ 1029 std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */
992 b 22f 1030 b 22f
99321: mfspr r5, SPRN_MMCR1 103121: mfspr r5, SPRN_MMCR1
994 mfspr r6, SPRN_MMCRA
995 std r4, VCPU_MMCR(r9) 1032 std r4, VCPU_MMCR(r9)
996 std r5, VCPU_MMCR + 8(r9) 1033 std r5, VCPU_MMCR + 8(r9)
997 std r6, VCPU_MMCR + 16(r9) 1034 std r6, VCPU_MMCR + 16(r9)
@@ -1016,17 +1053,20 @@ BEGIN_FTR_SECTION
1016 stw r11, VCPU_PMC + 28(r9) 1053 stw r11, VCPU_PMC + 28(r9)
1017END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201) 1054END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
101822: 105522:
1019 /* save FP state */
1020 mr r3, r9
1021 bl .kvmppc_save_fp
1022 1056
1023 /* Secondary threads go off to take a nap on POWER7 */ 1057 /* Secondary threads go off to take a nap on POWER7 */
1024BEGIN_FTR_SECTION 1058BEGIN_FTR_SECTION
1025 lwz r0,VCPU_PTID(r3) 1059 lwz r0,VCPU_PTID(r9)
1026 cmpwi r0,0 1060 cmpwi r0,0
1027 bne secondary_nap 1061 bne secondary_nap
1028END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) 1062END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
1029 1063
1064 /* Restore host DABR and DABRX */
1065 ld r5,HSTATE_DABR(r13)
1066 li r6,7
1067 mtspr SPRN_DABR,r5
1068 mtspr SPRN_DABRX,r6
1069
1030 /* 1070 /*
1031 * Reload DEC. HDEC interrupts were disabled when 1071 * Reload DEC. HDEC interrupts were disabled when
1032 * we reloaded the host's LPCR value. 1072 * we reloaded the host's LPCR value.
@@ -1363,7 +1403,12 @@ bounce_ext_interrupt:
1363 1403
1364_GLOBAL(kvmppc_h_set_dabr) 1404_GLOBAL(kvmppc_h_set_dabr)
1365 std r4,VCPU_DABR(r3) 1405 std r4,VCPU_DABR(r3)
1366 mtspr SPRN_DABR,r4 1406 /* Work around P7 bug where DABR can get corrupted on mtspr */
14071: mtspr SPRN_DABR,r4
1408 mfspr r5, SPRN_DABR
1409 cmpd r4, r5
1410 bne 1b
1411 isync
1367 li r3,0 1412 li r3,0
1368 blr 1413 blr
1369 1414
@@ -1445,8 +1490,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
1445 * Take a nap until a decrementer or external interrupt occurs, 1490 * Take a nap until a decrementer or external interrupt occurs,
1446 * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR 1491 * with PECE1 (wake on decr) and PECE0 (wake on external) set in LPCR
1447 */ 1492 */
1448 li r0,0x80 1493 li r0,1
1449 stb r0,PACAPROCSTART(r13) 1494 stb r0,HSTATE_HWTHREAD_REQ(r13)
1450 mfspr r5,SPRN_LPCR 1495 mfspr r5,SPRN_LPCR
1451 ori r5,r5,LPCR_PECE0 | LPCR_PECE1 1496 ori r5,r5,LPCR_PECE0 | LPCR_PECE1
1452 mtspr SPRN_LPCR,r5 1497 mtspr SPRN_LPCR,r5
@@ -1463,26 +1508,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
1463kvm_end_cede: 1508kvm_end_cede:
1464 /* Woken by external or decrementer interrupt */ 1509 /* Woken by external or decrementer interrupt */
1465 ld r1, HSTATE_HOST_R1(r13) 1510 ld r1, HSTATE_HOST_R1(r13)
1466 ld r2, PACATOC(r13)
1467 1511
1468 /* If we're a secondary thread and we got here by an IPI, ack it */
1469 ld r4,HSTATE_KVM_VCPU(r13)
1470 lwz r3,VCPU_PTID(r4)
1471 cmpwi r3,0
1472 beq 27f
1473 mfspr r3,SPRN_SRR1
1474 rlwinm r3,r3,44-31,0x7 /* extract wake reason field */
1475 cmpwi r3,4 /* was it an external interrupt? */
1476 bne 27f
1477 ld r5, HSTATE_XICS_PHYS(r13)
1478 li r0,0xff
1479 li r6,XICS_QIRR
1480 li r7,XICS_XIRR
1481 lwzcix r8,r5,r7 /* ack the interrupt */
1482 sync
1483 stbcix r0,r5,r6 /* clear it */
1484 stwcix r8,r5,r7 /* EOI it */
148527:
1486 /* load up FP state */ 1512 /* load up FP state */
1487 bl kvmppc_load_fp 1513 bl kvmppc_load_fp
1488 1514
@@ -1580,12 +1606,17 @@ secondary_nap:
1580 stwcx. r3, 0, r4 1606 stwcx. r3, 0, r4
1581 bne 51b 1607 bne 51b
1582 1608
1609kvm_no_guest:
1610 li r0, KVM_HWTHREAD_IN_NAP
1611 stb r0, HSTATE_HWTHREAD_STATE(r13)
1612 li r0, 0
1613 std r0, HSTATE_KVM_VCPU(r13)
1614
1583 li r3, LPCR_PECE0 1615 li r3, LPCR_PECE0
1584 mfspr r4, SPRN_LPCR 1616 mfspr r4, SPRN_LPCR
1585 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 1617 rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
1586 mtspr SPRN_LPCR, r4 1618 mtspr SPRN_LPCR, r4
1587 isync 1619 isync
1588 li r0, 0
1589 std r0, HSTATE_SCRATCH0(r13) 1620 std r0, HSTATE_SCRATCH0(r13)
1590 ptesync 1621 ptesync
1591 ld r0, HSTATE_SCRATCH0(r13) 1622 ld r0, HSTATE_SCRATCH0(r13)
@@ -1599,8 +1630,8 @@ secondary_nap:
1599 * r3 = vcpu pointer 1630 * r3 = vcpu pointer
1600 */ 1631 */
1601_GLOBAL(kvmppc_save_fp) 1632_GLOBAL(kvmppc_save_fp)
1602 mfmsr r9 1633 mfmsr r5
1603 ori r8,r9,MSR_FP 1634 ori r8,r5,MSR_FP
1604#ifdef CONFIG_ALTIVEC 1635#ifdef CONFIG_ALTIVEC
1605BEGIN_FTR_SECTION 1636BEGIN_FTR_SECTION
1606 oris r8,r8,MSR_VEC@h 1637 oris r8,r8,MSR_VEC@h
@@ -1649,7 +1680,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
1649#endif 1680#endif
1650 mfspr r6,SPRN_VRSAVE 1681 mfspr r6,SPRN_VRSAVE
1651 stw r6,VCPU_VRSAVE(r3) 1682 stw r6,VCPU_VRSAVE(r3)
1652 mtmsrd r9 1683 mtmsrd r5
1653 isync 1684 isync
1654 blr 1685 blr
1655 1686
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 7759053d391..a1baec340f7 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -120,6 +120,7 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
120 if (msr & MSR_POW) { 120 if (msr & MSR_POW) {
121 if (!vcpu->arch.pending_exceptions) { 121 if (!vcpu->arch.pending_exceptions) {
122 kvm_vcpu_block(vcpu); 122 kvm_vcpu_block(vcpu);
123 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
123 vcpu->stat.halt_wakeup++; 124 vcpu->stat.halt_wakeup++;
124 125
125 /* Unset POW bit after we woke up */ 126 /* Unset POW bit after we woke up */
@@ -144,6 +145,21 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
144 } 145 }
145 } 146 }
146 147
148 /*
149 * When switching from 32 to 64-bit, we may have a stale 32-bit
150 * magic page around, we need to flush it. Typically 32-bit magic
151 * page will be instanciated when calling into RTAS. Note: We
152 * assume that such transition only happens while in kernel mode,
153 * ie, we never transition from user 32-bit to kernel 64-bit with
154 * a 32-bit magic page around.
155 */
156 if (vcpu->arch.magic_page_pa &&
157 !(old_msr & MSR_PR) && !(old_msr & MSR_SF) && (msr & MSR_SF)) {
158 /* going from RTAS to normal kernel code */
159 kvmppc_mmu_pte_flush(vcpu, (uint32_t)vcpu->arch.magic_page_pa,
160 ~0xFFFUL);
161 }
162
147 /* Preload FPU if it's enabled */ 163 /* Preload FPU if it's enabled */
148 if (vcpu->arch.shared->msr & MSR_FP) 164 if (vcpu->arch.shared->msr & MSR_FP)
149 kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP); 165 kvmppc_handle_ext(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, MSR_FP);
@@ -251,6 +267,9 @@ static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
251{ 267{
252 ulong mp_pa = vcpu->arch.magic_page_pa; 268 ulong mp_pa = vcpu->arch.magic_page_pa;
253 269
270 if (!(vcpu->arch.shared->msr & MSR_SF))
271 mp_pa = (uint32_t)mp_pa;
272
254 if (unlikely(mp_pa) && 273 if (unlikely(mp_pa) &&
255 unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) { 274 unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) {
256 return 1; 275 return 1;
@@ -351,6 +370,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
351 /* MMIO */ 370 /* MMIO */
352 vcpu->stat.mmio_exits++; 371 vcpu->stat.mmio_exits++;
353 vcpu->arch.paddr_accessed = pte.raddr; 372 vcpu->arch.paddr_accessed = pte.raddr;
373 vcpu->arch.vaddr_accessed = pte.eaddr;
354 r = kvmppc_emulate_mmio(run, vcpu); 374 r = kvmppc_emulate_mmio(run, vcpu);
355 if ( r == RESUME_HOST_NV ) 375 if ( r == RESUME_HOST_NV )
356 r = RESUME_HOST; 376 r = RESUME_HOST;
@@ -528,6 +548,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
528 run->exit_reason = KVM_EXIT_UNKNOWN; 548 run->exit_reason = KVM_EXIT_UNKNOWN;
529 run->ready_for_interrupt_injection = 1; 549 run->ready_for_interrupt_injection = 1;
530 550
551 /* We get here with MSR.EE=0, so enable it to be a nice citizen */
552 __hard_irq_enable();
553
531 trace_kvm_book3s_exit(exit_nr, vcpu); 554 trace_kvm_book3s_exit(exit_nr, vcpu);
532 preempt_enable(); 555 preempt_enable();
533 kvm_resched(vcpu); 556 kvm_resched(vcpu);
@@ -617,10 +640,13 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
617 break; 640 break;
618 /* We're good on these - the host merely wanted to get our attention */ 641 /* We're good on these - the host merely wanted to get our attention */
619 case BOOK3S_INTERRUPT_DECREMENTER: 642 case BOOK3S_INTERRUPT_DECREMENTER:
643 case BOOK3S_INTERRUPT_HV_DECREMENTER:
620 vcpu->stat.dec_exits++; 644 vcpu->stat.dec_exits++;
621 r = RESUME_GUEST; 645 r = RESUME_GUEST;
622 break; 646 break;
623 case BOOK3S_INTERRUPT_EXTERNAL: 647 case BOOK3S_INTERRUPT_EXTERNAL:
648 case BOOK3S_INTERRUPT_EXTERNAL_LEVEL:
649 case BOOK3S_INTERRUPT_EXTERNAL_HV:
624 vcpu->stat.ext_intr_exits++; 650 vcpu->stat.ext_intr_exits++;
625 r = RESUME_GUEST; 651 r = RESUME_GUEST;
626 break; 652 break;
@@ -628,6 +654,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
628 r = RESUME_GUEST; 654 r = RESUME_GUEST;
629 break; 655 break;
630 case BOOK3S_INTERRUPT_PROGRAM: 656 case BOOK3S_INTERRUPT_PROGRAM:
657 case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
631 { 658 {
632 enum emulation_result er; 659 enum emulation_result er;
633 struct kvmppc_book3s_shadow_vcpu *svcpu; 660 struct kvmppc_book3s_shadow_vcpu *svcpu;
@@ -1131,6 +1158,31 @@ out:
1131 return r; 1158 return r;
1132} 1159}
1133 1160
1161#ifdef CONFIG_PPC64
1162int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, struct kvm_ppc_smmu_info *info)
1163{
1164 /* No flags */
1165 info->flags = 0;
1166
1167 /* SLB is always 64 entries */
1168 info->slb_size = 64;
1169
1170 /* Standard 4k base page size segment */
1171 info->sps[0].page_shift = 12;
1172 info->sps[0].slb_enc = 0;
1173 info->sps[0].enc[0].page_shift = 12;
1174 info->sps[0].enc[0].pte_enc = 0;
1175
1176 /* Standard 16M large page size segment */
1177 info->sps[1].page_shift = 24;
1178 info->sps[1].slb_enc = SLB_VSID_L;
1179 info->sps[1].enc[0].page_shift = 24;
1180 info->sps[1].enc[0].pte_enc = 0;
1181
1182 return 0;
1183}
1184#endif /* CONFIG_PPC64 */
1185
1134int kvmppc_core_prepare_memory_region(struct kvm *kvm, 1186int kvmppc_core_prepare_memory_region(struct kvm *kvm,
1135 struct kvm_userspace_memory_region *mem) 1187 struct kvm_userspace_memory_region *mem)
1136{ 1188{
@@ -1144,11 +1196,18 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm,
1144 1196
1145int kvmppc_core_init_vm(struct kvm *kvm) 1197int kvmppc_core_init_vm(struct kvm *kvm)
1146{ 1198{
1199#ifdef CONFIG_PPC64
1200 INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables);
1201#endif
1202
1147 return 0; 1203 return 0;
1148} 1204}
1149 1205
1150void kvmppc_core_destroy_vm(struct kvm *kvm) 1206void kvmppc_core_destroy_vm(struct kvm *kvm)
1151{ 1207{
1208#ifdef CONFIG_PPC64
1209 WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
1210#endif
1152} 1211}
1153 1212
1154static int kvmppc_book3s_init(void) 1213static int kvmppc_book3s_init(void)
diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c
index b9589324797..3ff9013d6e7 100644
--- a/arch/powerpc/kvm/book3s_pr_papr.c
+++ b/arch/powerpc/kvm/book3s_pr_papr.c
@@ -15,6 +15,8 @@
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16 */ 16 */
17 17
18#include <linux/anon_inodes.h>
19
18#include <asm/uaccess.h> 20#include <asm/uaccess.h>
19#include <asm/kvm_ppc.h> 21#include <asm/kvm_ppc.h>
20#include <asm/kvm_book3s.h> 22#include <asm/kvm_book3s.h>
@@ -98,6 +100,83 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu)
98 return EMULATE_DONE; 100 return EMULATE_DONE;
99} 101}
100 102
103/* Request defs for kvmppc_h_pr_bulk_remove() */
104#define H_BULK_REMOVE_TYPE 0xc000000000000000ULL
105#define H_BULK_REMOVE_REQUEST 0x4000000000000000ULL
106#define H_BULK_REMOVE_RESPONSE 0x8000000000000000ULL
107#define H_BULK_REMOVE_END 0xc000000000000000ULL
108#define H_BULK_REMOVE_CODE 0x3000000000000000ULL
109#define H_BULK_REMOVE_SUCCESS 0x0000000000000000ULL
110#define H_BULK_REMOVE_NOT_FOUND 0x1000000000000000ULL
111#define H_BULK_REMOVE_PARM 0x2000000000000000ULL
112#define H_BULK_REMOVE_HW 0x3000000000000000ULL
113#define H_BULK_REMOVE_RC 0x0c00000000000000ULL
114#define H_BULK_REMOVE_FLAGS 0x0300000000000000ULL
115#define H_BULK_REMOVE_ABSOLUTE 0x0000000000000000ULL
116#define H_BULK_REMOVE_ANDCOND 0x0100000000000000ULL
117#define H_BULK_REMOVE_AVPN 0x0200000000000000ULL
118#define H_BULK_REMOVE_PTEX 0x00ffffffffffffffULL
119#define H_BULK_REMOVE_MAX_BATCH 4
120
121static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu)
122{
123 int i;
124 int paramnr = 4;
125 int ret = H_SUCCESS;
126
127 for (i = 0; i < H_BULK_REMOVE_MAX_BATCH; i++) {
128 unsigned long tsh = kvmppc_get_gpr(vcpu, paramnr+(2*i));
129 unsigned long tsl = kvmppc_get_gpr(vcpu, paramnr+(2*i)+1);
130 unsigned long pteg, rb, flags;
131 unsigned long pte[2];
132 unsigned long v = 0;
133
134 if ((tsh & H_BULK_REMOVE_TYPE) == H_BULK_REMOVE_END) {
135 break; /* Exit success */
136 } else if ((tsh & H_BULK_REMOVE_TYPE) !=
137 H_BULK_REMOVE_REQUEST) {
138 ret = H_PARAMETER;
139 break; /* Exit fail */
140 }
141
142 tsh &= H_BULK_REMOVE_PTEX | H_BULK_REMOVE_FLAGS;
143 tsh |= H_BULK_REMOVE_RESPONSE;
144
145 if ((tsh & H_BULK_REMOVE_ANDCOND) &&
146 (tsh & H_BULK_REMOVE_AVPN)) {
147 tsh |= H_BULK_REMOVE_PARM;
148 kvmppc_set_gpr(vcpu, paramnr+(2*i), tsh);
149 ret = H_PARAMETER;
150 break; /* Exit fail */
151 }
152
153 pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX);
154 copy_from_user(pte, (void __user *)pteg, sizeof(pte));
155
156 /* tsl = AVPN */
157 flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26;
158
159 if ((pte[0] & HPTE_V_VALID) == 0 ||
160 ((flags & H_AVPN) && (pte[0] & ~0x7fUL) != tsl) ||
161 ((flags & H_ANDCOND) && (pte[0] & tsl) != 0)) {
162 tsh |= H_BULK_REMOVE_NOT_FOUND;
163 } else {
164 /* Splat the pteg in (userland) hpt */
165 copy_to_user((void __user *)pteg, &v, sizeof(v));
166
167 rb = compute_tlbie_rb(pte[0], pte[1],
168 tsh & H_BULK_REMOVE_PTEX);
169 vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
170 tsh |= H_BULK_REMOVE_SUCCESS;
171 tsh |= (pte[1] & (HPTE_R_C | HPTE_R_R)) << 43;
172 }
173 kvmppc_set_gpr(vcpu, paramnr+(2*i), tsh);
174 }
175 kvmppc_set_gpr(vcpu, 3, ret);
176
177 return EMULATE_DONE;
178}
179
101static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu) 180static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
102{ 181{
103 unsigned long flags = kvmppc_get_gpr(vcpu, 4); 182 unsigned long flags = kvmppc_get_gpr(vcpu, 4);
@@ -134,6 +213,20 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
134 return EMULATE_DONE; 213 return EMULATE_DONE;
135} 214}
136 215
216static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
217{
218 unsigned long liobn = kvmppc_get_gpr(vcpu, 4);
219 unsigned long ioba = kvmppc_get_gpr(vcpu, 5);
220 unsigned long tce = kvmppc_get_gpr(vcpu, 6);
221 long rc;
222
223 rc = kvmppc_h_put_tce(vcpu, liobn, ioba, tce);
224 if (rc == H_TOO_HARD)
225 return EMULATE_FAIL;
226 kvmppc_set_gpr(vcpu, 3, rc);
227 return EMULATE_DONE;
228}
229
137int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd) 230int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
138{ 231{
139 switch (cmd) { 232 switch (cmd) {
@@ -144,12 +237,12 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
144 case H_PROTECT: 237 case H_PROTECT:
145 return kvmppc_h_pr_protect(vcpu); 238 return kvmppc_h_pr_protect(vcpu);
146 case H_BULK_REMOVE: 239 case H_BULK_REMOVE:
147 /* We just flush all PTEs, so user space can 240 return kvmppc_h_pr_bulk_remove(vcpu);
148 handle the HPT modifications */ 241 case H_PUT_TCE:
149 kvmppc_mmu_pte_flush(vcpu, 0, 0); 242 return kvmppc_h_pr_put_tce(vcpu);
150 break;
151 case H_CEDE: 243 case H_CEDE:
152 kvm_vcpu_block(vcpu); 244 kvm_vcpu_block(vcpu);
245 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
153 vcpu->stat.halt_wakeup++; 246 vcpu->stat.halt_wakeup++;
154 return EMULATE_DONE; 247 return EMULATE_DONE;
155 } 248 }
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
index 6e6e9cef34a..798491a268b 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -128,24 +128,25 @@ no_dcbz32_on:
128 /* First clear RI in our current MSR value */ 128 /* First clear RI in our current MSR value */
129 li r0, MSR_RI 129 li r0, MSR_RI
130 andc r6, r6, r0 130 andc r6, r6, r0
131 MTMSR_EERI(r6)
132 mtsrr0 r9
133 mtsrr1 r4
134 131
135 PPC_LL r0, SVCPU_R0(r3) 132 PPC_LL r0, SVCPU_R0(r3)
136 PPC_LL r1, SVCPU_R1(r3) 133 PPC_LL r1, SVCPU_R1(r3)
137 PPC_LL r2, SVCPU_R2(r3) 134 PPC_LL r2, SVCPU_R2(r3)
138 PPC_LL r4, SVCPU_R4(r3)
139 PPC_LL r5, SVCPU_R5(r3) 135 PPC_LL r5, SVCPU_R5(r3)
140 PPC_LL r6, SVCPU_R6(r3)
141 PPC_LL r7, SVCPU_R7(r3) 136 PPC_LL r7, SVCPU_R7(r3)
142 PPC_LL r8, SVCPU_R8(r3) 137 PPC_LL r8, SVCPU_R8(r3)
143 PPC_LL r9, SVCPU_R9(r3)
144 PPC_LL r10, SVCPU_R10(r3) 138 PPC_LL r10, SVCPU_R10(r3)
145 PPC_LL r11, SVCPU_R11(r3) 139 PPC_LL r11, SVCPU_R11(r3)
146 PPC_LL r12, SVCPU_R12(r3) 140 PPC_LL r12, SVCPU_R12(r3)
147 PPC_LL r13, SVCPU_R13(r3) 141 PPC_LL r13, SVCPU_R13(r3)
148 142
143 MTMSR_EERI(r6)
144 mtsrr0 r9
145 mtsrr1 r4
146
147 PPC_LL r4, SVCPU_R4(r3)
148 PPC_LL r6, SVCPU_R6(r3)
149 PPC_LL r9, SVCPU_R9(r3)
149 PPC_LL r3, (SVCPU_R3)(r3) 150 PPC_LL r3, (SVCPU_R3)(r3)
150 151
151 RFI 152 RFI
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index ee9e1ee9c85..72f13f4a06e 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -17,6 +17,8 @@
17 * 17 *
18 * Authors: Hollis Blanchard <hollisb@us.ibm.com> 18 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
19 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> 19 * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
20 * Scott Wood <scottwood@freescale.com>
21 * Varun Sethi <varun.sethi@freescale.com>
20 */ 22 */
21 23
22#include <linux/errno.h> 24#include <linux/errno.h>
@@ -30,9 +32,12 @@
30#include <asm/cputable.h> 32#include <asm/cputable.h>
31#include <asm/uaccess.h> 33#include <asm/uaccess.h>
32#include <asm/kvm_ppc.h> 34#include <asm/kvm_ppc.h>
33#include "timing.h"
34#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
36#include <asm/dbell.h>
37#include <asm/hw_irq.h>
38#include <asm/irq.h>
35 39
40#include "timing.h"
36#include "booke.h" 41#include "booke.h"
37 42
38unsigned long kvmppc_booke_handlers; 43unsigned long kvmppc_booke_handlers;
@@ -55,6 +60,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
55 { "dec", VCPU_STAT(dec_exits) }, 60 { "dec", VCPU_STAT(dec_exits) },
56 { "ext_intr", VCPU_STAT(ext_intr_exits) }, 61 { "ext_intr", VCPU_STAT(ext_intr_exits) },
57 { "halt_wakeup", VCPU_STAT(halt_wakeup) }, 62 { "halt_wakeup", VCPU_STAT(halt_wakeup) },
63 { "doorbell", VCPU_STAT(dbell_exits) },
64 { "guest doorbell", VCPU_STAT(gdbell_exits) },
58 { NULL } 65 { NULL }
59}; 66};
60 67
@@ -121,6 +128,10 @@ void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
121{ 128{
122 u32 old_msr = vcpu->arch.shared->msr; 129 u32 old_msr = vcpu->arch.shared->msr;
123 130
131#ifdef CONFIG_KVM_BOOKE_HV
132 new_msr |= MSR_GS;
133#endif
134
124 vcpu->arch.shared->msr = new_msr; 135 vcpu->arch.shared->msr = new_msr;
125 136
126 kvmppc_mmu_msr_notify(vcpu, old_msr); 137 kvmppc_mmu_msr_notify(vcpu, old_msr);
@@ -195,17 +206,87 @@ void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu,
195 clear_bit(BOOKE_IRQPRIO_EXTERNAL_LEVEL, &vcpu->arch.pending_exceptions); 206 clear_bit(BOOKE_IRQPRIO_EXTERNAL_LEVEL, &vcpu->arch.pending_exceptions);
196} 207}
197 208
209static void set_guest_srr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
210{
211#ifdef CONFIG_KVM_BOOKE_HV
212 mtspr(SPRN_GSRR0, srr0);
213 mtspr(SPRN_GSRR1, srr1);
214#else
215 vcpu->arch.shared->srr0 = srr0;
216 vcpu->arch.shared->srr1 = srr1;
217#endif
218}
219
220static void set_guest_csrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
221{
222 vcpu->arch.csrr0 = srr0;
223 vcpu->arch.csrr1 = srr1;
224}
225
226static void set_guest_dsrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
227{
228 if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC)) {
229 vcpu->arch.dsrr0 = srr0;
230 vcpu->arch.dsrr1 = srr1;
231 } else {
232 set_guest_csrr(vcpu, srr0, srr1);
233 }
234}
235
236static void set_guest_mcsrr(struct kvm_vcpu *vcpu, unsigned long srr0, u32 srr1)
237{
238 vcpu->arch.mcsrr0 = srr0;
239 vcpu->arch.mcsrr1 = srr1;
240}
241
242static unsigned long get_guest_dear(struct kvm_vcpu *vcpu)
243{
244#ifdef CONFIG_KVM_BOOKE_HV
245 return mfspr(SPRN_GDEAR);
246#else
247 return vcpu->arch.shared->dar;
248#endif
249}
250
251static void set_guest_dear(struct kvm_vcpu *vcpu, unsigned long dear)
252{
253#ifdef CONFIG_KVM_BOOKE_HV
254 mtspr(SPRN_GDEAR, dear);
255#else
256 vcpu->arch.shared->dar = dear;
257#endif
258}
259
260static unsigned long get_guest_esr(struct kvm_vcpu *vcpu)
261{
262#ifdef CONFIG_KVM_BOOKE_HV
263 return mfspr(SPRN_GESR);
264#else
265 return vcpu->arch.shared->esr;
266#endif
267}
268
269static void set_guest_esr(struct kvm_vcpu *vcpu, u32 esr)
270{
271#ifdef CONFIG_KVM_BOOKE_HV
272 mtspr(SPRN_GESR, esr);
273#else
274 vcpu->arch.shared->esr = esr;
275#endif
276}
277
198/* Deliver the interrupt of the corresponding priority, if possible. */ 278/* Deliver the interrupt of the corresponding priority, if possible. */
199static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu, 279static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
200 unsigned int priority) 280 unsigned int priority)
201{ 281{
202 int allowed = 0; 282 int allowed = 0;
203 ulong uninitialized_var(msr_mask); 283 ulong msr_mask = 0;
204 bool update_esr = false, update_dear = false; 284 bool update_esr = false, update_dear = false;
205 ulong crit_raw = vcpu->arch.shared->critical; 285 ulong crit_raw = vcpu->arch.shared->critical;
206 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1); 286 ulong crit_r1 = kvmppc_get_gpr(vcpu, 1);
207 bool crit; 287 bool crit;
208 bool keep_irq = false; 288 bool keep_irq = false;
289 enum int_class int_class;
209 290
210 /* Truncate crit indicators in 32 bit mode */ 291 /* Truncate crit indicators in 32 bit mode */
211 if (!(vcpu->arch.shared->msr & MSR_SF)) { 292 if (!(vcpu->arch.shared->msr & MSR_SF)) {
@@ -241,46 +322,85 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
241 case BOOKE_IRQPRIO_AP_UNAVAIL: 322 case BOOKE_IRQPRIO_AP_UNAVAIL:
242 case BOOKE_IRQPRIO_ALIGNMENT: 323 case BOOKE_IRQPRIO_ALIGNMENT:
243 allowed = 1; 324 allowed = 1;
244 msr_mask = MSR_CE|MSR_ME|MSR_DE; 325 msr_mask = MSR_CE | MSR_ME | MSR_DE;
326 int_class = INT_CLASS_NONCRIT;
245 break; 327 break;
246 case BOOKE_IRQPRIO_CRITICAL: 328 case BOOKE_IRQPRIO_CRITICAL:
247 case BOOKE_IRQPRIO_WATCHDOG: 329 case BOOKE_IRQPRIO_DBELL_CRIT:
248 allowed = vcpu->arch.shared->msr & MSR_CE; 330 allowed = vcpu->arch.shared->msr & MSR_CE;
331 allowed = allowed && !crit;
249 msr_mask = MSR_ME; 332 msr_mask = MSR_ME;
333 int_class = INT_CLASS_CRIT;
250 break; 334 break;
251 case BOOKE_IRQPRIO_MACHINE_CHECK: 335 case BOOKE_IRQPRIO_MACHINE_CHECK:
252 allowed = vcpu->arch.shared->msr & MSR_ME; 336 allowed = vcpu->arch.shared->msr & MSR_ME;
253 msr_mask = 0; 337 allowed = allowed && !crit;
338 int_class = INT_CLASS_MC;
254 break; 339 break;
255 case BOOKE_IRQPRIO_DECREMENTER: 340 case BOOKE_IRQPRIO_DECREMENTER:
256 case BOOKE_IRQPRIO_FIT: 341 case BOOKE_IRQPRIO_FIT:
257 keep_irq = true; 342 keep_irq = true;
258 /* fall through */ 343 /* fall through */
259 case BOOKE_IRQPRIO_EXTERNAL: 344 case BOOKE_IRQPRIO_EXTERNAL:
345 case BOOKE_IRQPRIO_DBELL:
260 allowed = vcpu->arch.shared->msr & MSR_EE; 346 allowed = vcpu->arch.shared->msr & MSR_EE;
261 allowed = allowed && !crit; 347 allowed = allowed && !crit;
262 msr_mask = MSR_CE|MSR_ME|MSR_DE; 348 msr_mask = MSR_CE | MSR_ME | MSR_DE;
349 int_class = INT_CLASS_NONCRIT;
263 break; 350 break;
264 case BOOKE_IRQPRIO_DEBUG: 351 case BOOKE_IRQPRIO_DEBUG:
265 allowed = vcpu->arch.shared->msr & MSR_DE; 352 allowed = vcpu->arch.shared->msr & MSR_DE;
353 allowed = allowed && !crit;
266 msr_mask = MSR_ME; 354 msr_mask = MSR_ME;
355 int_class = INT_CLASS_CRIT;
267 break; 356 break;
268 } 357 }
269 358
270 if (allowed) { 359 if (allowed) {
271 vcpu->arch.shared->srr0 = vcpu->arch.pc; 360 switch (int_class) {
272 vcpu->arch.shared->srr1 = vcpu->arch.shared->msr; 361 case INT_CLASS_NONCRIT:
362 set_guest_srr(vcpu, vcpu->arch.pc,
363 vcpu->arch.shared->msr);
364 break;
365 case INT_CLASS_CRIT:
366 set_guest_csrr(vcpu, vcpu->arch.pc,
367 vcpu->arch.shared->msr);
368 break;
369 case INT_CLASS_DBG:
370 set_guest_dsrr(vcpu, vcpu->arch.pc,
371 vcpu->arch.shared->msr);
372 break;
373 case INT_CLASS_MC:
374 set_guest_mcsrr(vcpu, vcpu->arch.pc,
375 vcpu->arch.shared->msr);
376 break;
377 }
378
273 vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; 379 vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
274 if (update_esr == true) 380 if (update_esr == true)
275 vcpu->arch.shared->esr = vcpu->arch.queued_esr; 381 set_guest_esr(vcpu, vcpu->arch.queued_esr);
276 if (update_dear == true) 382 if (update_dear == true)
277 vcpu->arch.shared->dar = vcpu->arch.queued_dear; 383 set_guest_dear(vcpu, vcpu->arch.queued_dear);
278 kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask); 384 kvmppc_set_msr(vcpu, vcpu->arch.shared->msr & msr_mask);
279 385
280 if (!keep_irq) 386 if (!keep_irq)
281 clear_bit(priority, &vcpu->arch.pending_exceptions); 387 clear_bit(priority, &vcpu->arch.pending_exceptions);
282 } 388 }
283 389
390#ifdef CONFIG_KVM_BOOKE_HV
391 /*
392 * If an interrupt is pending but masked, raise a guest doorbell
393 * so that we are notified when the guest enables the relevant
394 * MSR bit.
395 */
396 if (vcpu->arch.pending_exceptions & BOOKE_IRQMASK_EE)
397 kvmppc_set_pending_interrupt(vcpu, INT_CLASS_NONCRIT);
398 if (vcpu->arch.pending_exceptions & BOOKE_IRQMASK_CE)
399 kvmppc_set_pending_interrupt(vcpu, INT_CLASS_CRIT);
400 if (vcpu->arch.pending_exceptions & BOOKE_IRQPRIO_MACHINE_CHECK)
401 kvmppc_set_pending_interrupt(vcpu, INT_CLASS_MC);
402#endif
403
284 return allowed; 404 return allowed;
285} 405}
286 406
@@ -305,7 +425,7 @@ static void kvmppc_core_check_exceptions(struct kvm_vcpu *vcpu)
305 } 425 }
306 426
307 priority = __ffs(*pending); 427 priority = __ffs(*pending);
308 while (priority <= BOOKE_IRQPRIO_MAX) { 428 while (priority < BOOKE_IRQPRIO_MAX) {
309 if (kvmppc_booke_irqprio_deliver(vcpu, priority)) 429 if (kvmppc_booke_irqprio_deliver(vcpu, priority))
310 break; 430 break;
311 431
@@ -319,8 +439,9 @@ static void kvmppc_core_check_exceptions(struct kvm_vcpu *vcpu)
319} 439}
320 440
321/* Check pending exceptions and deliver one, if possible. */ 441/* Check pending exceptions and deliver one, if possible. */
322void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) 442int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
323{ 443{
444 int r = 0;
324 WARN_ON_ONCE(!irqs_disabled()); 445 WARN_ON_ONCE(!irqs_disabled());
325 446
326 kvmppc_core_check_exceptions(vcpu); 447 kvmppc_core_check_exceptions(vcpu);
@@ -328,16 +449,60 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
328 if (vcpu->arch.shared->msr & MSR_WE) { 449 if (vcpu->arch.shared->msr & MSR_WE) {
329 local_irq_enable(); 450 local_irq_enable();
330 kvm_vcpu_block(vcpu); 451 kvm_vcpu_block(vcpu);
452 clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
331 local_irq_disable(); 453 local_irq_disable();
332 454
333 kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS); 455 kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS);
334 kvmppc_core_check_exceptions(vcpu); 456 r = 1;
335 }; 457 };
458
459 return r;
460}
461
462/*
463 * Common checks before entering the guest world. Call with interrupts
464 * disabled.
465 *
466 * returns !0 if a signal is pending and check_signal is true
467 */
468static int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu)
469{
470 int r = 0;
471
472 WARN_ON_ONCE(!irqs_disabled());
473 while (true) {
474 if (need_resched()) {
475 local_irq_enable();
476 cond_resched();
477 local_irq_disable();
478 continue;
479 }
480
481 if (signal_pending(current)) {
482 r = 1;
483 break;
484 }
485
486 if (kvmppc_core_prepare_to_enter(vcpu)) {
487 /* interrupts got enabled in between, so we
488 are back at square 1 */
489 continue;
490 }
491
492 break;
493 }
494
495 return r;
336} 496}
337 497
338int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) 498int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
339{ 499{
340 int ret; 500 int ret;
501#ifdef CONFIG_PPC_FPU
502 unsigned int fpscr;
503 int fpexc_mode;
504 u64 fpr[32];
505#endif
341 506
342 if (!vcpu->arch.sane) { 507 if (!vcpu->arch.sane) {
343 kvm_run->exit_reason = KVM_EXIT_INTERNAL_ERROR; 508 kvm_run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
@@ -345,17 +510,53 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
345 } 510 }
346 511
347 local_irq_disable(); 512 local_irq_disable();
348 513 if (kvmppc_prepare_to_enter(vcpu)) {
349 kvmppc_core_prepare_to_enter(vcpu);
350
351 if (signal_pending(current)) {
352 kvm_run->exit_reason = KVM_EXIT_INTR; 514 kvm_run->exit_reason = KVM_EXIT_INTR;
353 ret = -EINTR; 515 ret = -EINTR;
354 goto out; 516 goto out;
355 } 517 }
356 518
357 kvm_guest_enter(); 519 kvm_guest_enter();
520
521#ifdef CONFIG_PPC_FPU
522 /* Save userspace FPU state in stack */
523 enable_kernel_fp();
524 memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
525 fpscr = current->thread.fpscr.val;
526 fpexc_mode = current->thread.fpexc_mode;
527
528 /* Restore guest FPU state to thread */
529 memcpy(current->thread.fpr, vcpu->arch.fpr, sizeof(vcpu->arch.fpr));
530 current->thread.fpscr.val = vcpu->arch.fpscr;
531
532 /*
533 * Since we can't trap on MSR_FP in GS-mode, we consider the guest
534 * as always using the FPU. Kernel usage of FP (via
535 * enable_kernel_fp()) in this thread must not occur while
536 * vcpu->fpu_active is set.
537 */
538 vcpu->fpu_active = 1;
539
540 kvmppc_load_guest_fp(vcpu);
541#endif
542
358 ret = __kvmppc_vcpu_run(kvm_run, vcpu); 543 ret = __kvmppc_vcpu_run(kvm_run, vcpu);
544
545#ifdef CONFIG_PPC_FPU
546 kvmppc_save_guest_fp(vcpu);
547
548 vcpu->fpu_active = 0;
549
550 /* Save guest FPU state from thread */
551 memcpy(vcpu->arch.fpr, current->thread.fpr, sizeof(vcpu->arch.fpr));
552 vcpu->arch.fpscr = current->thread.fpscr.val;
553
554 /* Restore userspace FPU state from stack */
555 memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
556 current->thread.fpscr.val = fpscr;
557 current->thread.fpexc_mode = fpexc_mode;
558#endif
559
359 kvm_guest_exit(); 560 kvm_guest_exit();
360 561
361out: 562out:
@@ -363,6 +564,84 @@ out:
363 return ret; 564 return ret;
364} 565}
365 566
567static int emulation_exit(struct kvm_run *run, struct kvm_vcpu *vcpu)
568{
569 enum emulation_result er;
570
571 er = kvmppc_emulate_instruction(run, vcpu);
572 switch (er) {
573 case EMULATE_DONE:
574 /* don't overwrite subtypes, just account kvm_stats */
575 kvmppc_account_exit_stat(vcpu, EMULATED_INST_EXITS);
576 /* Future optimization: only reload non-volatiles if
577 * they were actually modified by emulation. */
578 return RESUME_GUEST_NV;
579
580 case EMULATE_DO_DCR:
581 run->exit_reason = KVM_EXIT_DCR;
582 return RESUME_HOST;
583
584 case EMULATE_FAIL:
585 printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
586 __func__, vcpu->arch.pc, vcpu->arch.last_inst);
587 /* For debugging, encode the failing instruction and
588 * report it to userspace. */
589 run->hw.hardware_exit_reason = ~0ULL << 32;
590 run->hw.hardware_exit_reason |= vcpu->arch.last_inst;
591 kvmppc_core_queue_program(vcpu, ESR_PIL);
592 return RESUME_HOST;
593
594 default:
595 BUG();
596 }
597}
598
599static void kvmppc_fill_pt_regs(struct pt_regs *regs)
600{
601 ulong r1, ip, msr, lr;
602
603 asm("mr %0, 1" : "=r"(r1));
604 asm("mflr %0" : "=r"(lr));
605 asm("mfmsr %0" : "=r"(msr));
606 asm("bl 1f; 1: mflr %0" : "=r"(ip));
607
608 memset(regs, 0, sizeof(*regs));
609 regs->gpr[1] = r1;
610 regs->nip = ip;
611 regs->msr = msr;
612 regs->link = lr;
613}
614
615static void kvmppc_restart_interrupt(struct kvm_vcpu *vcpu,
616 unsigned int exit_nr)
617{
618 struct pt_regs regs;
619
620 switch (exit_nr) {
621 case BOOKE_INTERRUPT_EXTERNAL:
622 kvmppc_fill_pt_regs(&regs);
623 do_IRQ(&regs);
624 break;
625 case BOOKE_INTERRUPT_DECREMENTER:
626 kvmppc_fill_pt_regs(&regs);
627 timer_interrupt(&regs);
628 break;
629#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_BOOK3E_64)
630 case BOOKE_INTERRUPT_DOORBELL:
631 kvmppc_fill_pt_regs(&regs);
632 doorbell_exception(&regs);
633 break;
634#endif
635 case BOOKE_INTERRUPT_MACHINE_CHECK:
636 /* FIXME */
637 break;
638 case BOOKE_INTERRUPT_PERFORMANCE_MONITOR:
639 kvmppc_fill_pt_regs(&regs);
640 performance_monitor_exception(&regs);
641 break;
642 }
643}
644
366/** 645/**
367 * kvmppc_handle_exit 646 * kvmppc_handle_exit
368 * 647 *
@@ -371,12 +650,14 @@ out:
371int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, 650int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
372 unsigned int exit_nr) 651 unsigned int exit_nr)
373{ 652{
374 enum emulation_result er;
375 int r = RESUME_HOST; 653 int r = RESUME_HOST;
376 654
377 /* update before a new last_exit_type is rewritten */ 655 /* update before a new last_exit_type is rewritten */
378 kvmppc_update_timing_stats(vcpu); 656 kvmppc_update_timing_stats(vcpu);
379 657
658 /* restart interrupts if they were meant for the host */
659 kvmppc_restart_interrupt(vcpu, exit_nr);
660
380 local_irq_enable(); 661 local_irq_enable();
381 662
382 run->exit_reason = KVM_EXIT_UNKNOWN; 663 run->exit_reason = KVM_EXIT_UNKNOWN;
@@ -386,62 +667,74 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
386 case BOOKE_INTERRUPT_MACHINE_CHECK: 667 case BOOKE_INTERRUPT_MACHINE_CHECK:
387 printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR)); 668 printk("MACHINE CHECK: %lx\n", mfspr(SPRN_MCSR));
388 kvmppc_dump_vcpu(vcpu); 669 kvmppc_dump_vcpu(vcpu);
670 /* For debugging, send invalid exit reason to user space */
671 run->hw.hardware_exit_reason = ~1ULL << 32;
672 run->hw.hardware_exit_reason |= mfspr(SPRN_MCSR);
389 r = RESUME_HOST; 673 r = RESUME_HOST;
390 break; 674 break;
391 675
392 case BOOKE_INTERRUPT_EXTERNAL: 676 case BOOKE_INTERRUPT_EXTERNAL:
393 kvmppc_account_exit(vcpu, EXT_INTR_EXITS); 677 kvmppc_account_exit(vcpu, EXT_INTR_EXITS);
394 if (need_resched())
395 cond_resched();
396 r = RESUME_GUEST; 678 r = RESUME_GUEST;
397 break; 679 break;
398 680
399 case BOOKE_INTERRUPT_DECREMENTER: 681 case BOOKE_INTERRUPT_DECREMENTER:
400 /* Since we switched IVPR back to the host's value, the host
401 * handled this interrupt the moment we enabled interrupts.
402 * Now we just offer it a chance to reschedule the guest. */
403 kvmppc_account_exit(vcpu, DEC_EXITS); 682 kvmppc_account_exit(vcpu, DEC_EXITS);
404 if (need_resched())
405 cond_resched();
406 r = RESUME_GUEST; 683 r = RESUME_GUEST;
407 break; 684 break;
408 685
686 case BOOKE_INTERRUPT_DOORBELL:
687 kvmppc_account_exit(vcpu, DBELL_EXITS);
688 r = RESUME_GUEST;
689 break;
690
691 case BOOKE_INTERRUPT_GUEST_DBELL_CRIT:
692 kvmppc_account_exit(vcpu, GDBELL_EXITS);
693
694 /*
695 * We are here because there is a pending guest interrupt
696 * which could not be delivered as MSR_CE or MSR_ME was not
697 * set. Once we break from here we will retry delivery.
698 */
699 r = RESUME_GUEST;
700 break;
701
702 case BOOKE_INTERRUPT_GUEST_DBELL:
703 kvmppc_account_exit(vcpu, GDBELL_EXITS);
704
705 /*
706 * We are here because there is a pending guest interrupt
707 * which could not be delivered as MSR_EE was not set. Once
708 * we break from here we will retry delivery.
709 */
710 r = RESUME_GUEST;
711 break;
712
713 case BOOKE_INTERRUPT_PERFORMANCE_MONITOR:
714 r = RESUME_GUEST;
715 break;
716
717 case BOOKE_INTERRUPT_HV_PRIV:
718 r = emulation_exit(run, vcpu);
719 break;
720
409 case BOOKE_INTERRUPT_PROGRAM: 721 case BOOKE_INTERRUPT_PROGRAM:
410 if (vcpu->arch.shared->msr & MSR_PR) { 722 if (vcpu->arch.shared->msr & (MSR_PR | MSR_GS)) {
411 /* Program traps generated by user-level software must be handled 723 /*
412 * by the guest kernel. */ 724 * Program traps generated by user-level software must
725 * be handled by the guest kernel.
726 *
727 * In GS mode, hypervisor privileged instructions trap
728 * on BOOKE_INTERRUPT_HV_PRIV, not here, so these are
729 * actual program interrupts, handled by the guest.
730 */
413 kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr); 731 kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
414 r = RESUME_GUEST; 732 r = RESUME_GUEST;
415 kvmppc_account_exit(vcpu, USR_PR_INST); 733 kvmppc_account_exit(vcpu, USR_PR_INST);
416 break; 734 break;
417 } 735 }
418 736
419 er = kvmppc_emulate_instruction(run, vcpu); 737 r = emulation_exit(run, vcpu);
420 switch (er) {
421 case EMULATE_DONE:
422 /* don't overwrite subtypes, just account kvm_stats */
423 kvmppc_account_exit_stat(vcpu, EMULATED_INST_EXITS);
424 /* Future optimization: only reload non-volatiles if
425 * they were actually modified by emulation. */
426 r = RESUME_GUEST_NV;
427 break;
428 case EMULATE_DO_DCR:
429 run->exit_reason = KVM_EXIT_DCR;
430 r = RESUME_HOST;
431 break;
432 case EMULATE_FAIL:
433 /* XXX Deliver Program interrupt to guest. */
434 printk(KERN_CRIT "%s: emulation at %lx failed (%08x)\n",
435 __func__, vcpu->arch.pc, vcpu->arch.last_inst);
436 /* For debugging, encode the failing instruction and
437 * report it to userspace. */
438 run->hw.hardware_exit_reason = ~0ULL << 32;
439 run->hw.hardware_exit_reason |= vcpu->arch.last_inst;
440 r = RESUME_HOST;
441 break;
442 default:
443 BUG();
444 }
445 break; 738 break;
446 739
447 case BOOKE_INTERRUPT_FP_UNAVAIL: 740 case BOOKE_INTERRUPT_FP_UNAVAIL:
@@ -506,6 +799,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
506 r = RESUME_GUEST; 799 r = RESUME_GUEST;
507 break; 800 break;
508 801
802#ifdef CONFIG_KVM_BOOKE_HV
803 case BOOKE_INTERRUPT_HV_SYSCALL:
804 if (!(vcpu->arch.shared->msr & MSR_PR)) {
805 kvmppc_set_gpr(vcpu, 3, kvmppc_kvm_pv(vcpu));
806 } else {
807 /*
808 * hcall from guest userspace -- send privileged
809 * instruction program check.
810 */
811 kvmppc_core_queue_program(vcpu, ESR_PPR);
812 }
813
814 r = RESUME_GUEST;
815 break;
816#else
509 case BOOKE_INTERRUPT_SYSCALL: 817 case BOOKE_INTERRUPT_SYSCALL:
510 if (!(vcpu->arch.shared->msr & MSR_PR) && 818 if (!(vcpu->arch.shared->msr & MSR_PR) &&
511 (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) { 819 (((u32)kvmppc_get_gpr(vcpu, 0)) == KVM_SC_MAGIC_R0)) {
@@ -519,6 +827,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
519 kvmppc_account_exit(vcpu, SYSCALL_EXITS); 827 kvmppc_account_exit(vcpu, SYSCALL_EXITS);
520 r = RESUME_GUEST; 828 r = RESUME_GUEST;
521 break; 829 break;
830#endif
522 831
523 case BOOKE_INTERRUPT_DTLB_MISS: { 832 case BOOKE_INTERRUPT_DTLB_MISS: {
524 unsigned long eaddr = vcpu->arch.fault_dear; 833 unsigned long eaddr = vcpu->arch.fault_dear;
@@ -526,7 +835,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
526 gpa_t gpaddr; 835 gpa_t gpaddr;
527 gfn_t gfn; 836 gfn_t gfn;
528 837
529#ifdef CONFIG_KVM_E500 838#ifdef CONFIG_KVM_E500V2
530 if (!(vcpu->arch.shared->msr & MSR_PR) && 839 if (!(vcpu->arch.shared->msr & MSR_PR) &&
531 (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) { 840 (eaddr & PAGE_MASK) == vcpu->arch.magic_page_ea) {
532 kvmppc_map_magic(vcpu); 841 kvmppc_map_magic(vcpu);
@@ -567,6 +876,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
567 /* Guest has mapped and accessed a page which is not 876 /* Guest has mapped and accessed a page which is not
568 * actually RAM. */ 877 * actually RAM. */
569 vcpu->arch.paddr_accessed = gpaddr; 878 vcpu->arch.paddr_accessed = gpaddr;
879 vcpu->arch.vaddr_accessed = eaddr;
570 r = kvmppc_emulate_mmio(run, vcpu); 880 r = kvmppc_emulate_mmio(run, vcpu);
571 kvmppc_account_exit(vcpu, MMIO_EXITS); 881 kvmppc_account_exit(vcpu, MMIO_EXITS);
572 } 882 }
@@ -634,15 +944,13 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
634 BUG(); 944 BUG();
635 } 945 }
636 946
637 local_irq_disable(); 947 /*
638 948 * To avoid clobbering exit_reason, only check for signals if we
639 kvmppc_core_prepare_to_enter(vcpu); 949 * aren't already exiting to userspace for some other reason.
640 950 */
641 if (!(r & RESUME_HOST)) { 951 if (!(r & RESUME_HOST)) {
642 /* To avoid clobbering exit_reason, only check for signals if 952 local_irq_disable();
643 * we aren't already exiting to userspace for some other 953 if (kvmppc_prepare_to_enter(vcpu)) {
644 * reason. */
645 if (signal_pending(current)) {
646 run->exit_reason = KVM_EXIT_INTR; 954 run->exit_reason = KVM_EXIT_INTR;
647 r = (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); 955 r = (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
648 kvmppc_account_exit(vcpu, SIGNAL_EXITS); 956 kvmppc_account_exit(vcpu, SIGNAL_EXITS);
@@ -659,12 +967,15 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
659 int r; 967 int r;
660 968
661 vcpu->arch.pc = 0; 969 vcpu->arch.pc = 0;
662 vcpu->arch.shared->msr = 0;
663 vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
664 vcpu->arch.shared->pir = vcpu->vcpu_id; 970 vcpu->arch.shared->pir = vcpu->vcpu_id;
665 kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */ 971 kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
972 kvmppc_set_msr(vcpu, 0);
666 973
974#ifndef CONFIG_KVM_BOOKE_HV
975 vcpu->arch.shadow_msr = MSR_USER | MSR_DE | MSR_IS | MSR_DS;
667 vcpu->arch.shadow_pid = 1; 976 vcpu->arch.shadow_pid = 1;
977 vcpu->arch.shared->msr = 0;
978#endif
668 979
669 /* Eye-catching numbers so we know if the guest takes an interrupt 980 /* Eye-catching numbers so we know if the guest takes an interrupt
670 * before it's programmed its own IVPR/IVORs. */ 981 * before it's programmed its own IVPR/IVORs. */
@@ -745,8 +1056,8 @@ static void get_sregs_base(struct kvm_vcpu *vcpu,
745 sregs->u.e.csrr0 = vcpu->arch.csrr0; 1056 sregs->u.e.csrr0 = vcpu->arch.csrr0;
746 sregs->u.e.csrr1 = vcpu->arch.csrr1; 1057 sregs->u.e.csrr1 = vcpu->arch.csrr1;
747 sregs->u.e.mcsr = vcpu->arch.mcsr; 1058 sregs->u.e.mcsr = vcpu->arch.mcsr;
748 sregs->u.e.esr = vcpu->arch.shared->esr; 1059 sregs->u.e.esr = get_guest_esr(vcpu);
749 sregs->u.e.dear = vcpu->arch.shared->dar; 1060 sregs->u.e.dear = get_guest_dear(vcpu);
750 sregs->u.e.tsr = vcpu->arch.tsr; 1061 sregs->u.e.tsr = vcpu->arch.tsr;
751 sregs->u.e.tcr = vcpu->arch.tcr; 1062 sregs->u.e.tcr = vcpu->arch.tcr;
752 sregs->u.e.dec = kvmppc_get_dec(vcpu, tb); 1063 sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
@@ -763,8 +1074,8 @@ static int set_sregs_base(struct kvm_vcpu *vcpu,
763 vcpu->arch.csrr0 = sregs->u.e.csrr0; 1074 vcpu->arch.csrr0 = sregs->u.e.csrr0;
764 vcpu->arch.csrr1 = sregs->u.e.csrr1; 1075 vcpu->arch.csrr1 = sregs->u.e.csrr1;
765 vcpu->arch.mcsr = sregs->u.e.mcsr; 1076 vcpu->arch.mcsr = sregs->u.e.mcsr;
766 vcpu->arch.shared->esr = sregs->u.e.esr; 1077 set_guest_esr(vcpu, sregs->u.e.esr);
767 vcpu->arch.shared->dar = sregs->u.e.dear; 1078 set_guest_dear(vcpu, sregs->u.e.dear);
768 vcpu->arch.vrsave = sregs->u.e.vrsave; 1079 vcpu->arch.vrsave = sregs->u.e.vrsave;
769 kvmppc_set_tcr(vcpu, sregs->u.e.tcr); 1080 kvmppc_set_tcr(vcpu, sregs->u.e.tcr);
770 1081
@@ -932,15 +1243,6 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm,
932{ 1243{
933} 1244}
934 1245
935int kvmppc_core_init_vm(struct kvm *kvm)
936{
937 return 0;
938}
939
940void kvmppc_core_destroy_vm(struct kvm *kvm)
941{
942}
943
944void kvmppc_set_tcr(struct kvm_vcpu *vcpu, u32 new_tcr) 1246void kvmppc_set_tcr(struct kvm_vcpu *vcpu, u32 new_tcr)
945{ 1247{
946 vcpu->arch.tcr = new_tcr; 1248 vcpu->arch.tcr = new_tcr;
@@ -968,8 +1270,19 @@ void kvmppc_decrementer_func(unsigned long data)
968 kvmppc_set_tsr_bits(vcpu, TSR_DIS); 1270 kvmppc_set_tsr_bits(vcpu, TSR_DIS);
969} 1271}
970 1272
1273void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1274{
1275 current->thread.kvm_vcpu = vcpu;
1276}
1277
1278void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu)
1279{
1280 current->thread.kvm_vcpu = NULL;
1281}
1282
971int __init kvmppc_booke_init(void) 1283int __init kvmppc_booke_init(void)
972{ 1284{
1285#ifndef CONFIG_KVM_BOOKE_HV
973 unsigned long ivor[16]; 1286 unsigned long ivor[16];
974 unsigned long max_ivor = 0; 1287 unsigned long max_ivor = 0;
975 int i; 1288 int i;
@@ -1012,7 +1325,7 @@ int __init kvmppc_booke_init(void)
1012 } 1325 }
1013 flush_icache_range(kvmppc_booke_handlers, 1326 flush_icache_range(kvmppc_booke_handlers,
1014 kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); 1327 kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
1015 1328#endif /* !BOOKE_HV */
1016 return 0; 1329 return 0;
1017} 1330}
1018 1331
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index 2fe202705a3..ba61974c1e2 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -23,6 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/kvm_host.h> 24#include <linux/kvm_host.h>
25#include <asm/kvm_ppc.h> 25#include <asm/kvm_ppc.h>
26#include <asm/switch_to.h>
26#include "timing.h" 27#include "timing.h"
27 28
28/* interrupt priortity ordering */ 29/* interrupt priortity ordering */
@@ -48,7 +49,20 @@
48#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19 49#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
49/* Internal pseudo-irqprio for level triggered externals */ 50/* Internal pseudo-irqprio for level triggered externals */
50#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20 51#define BOOKE_IRQPRIO_EXTERNAL_LEVEL 20
51#define BOOKE_IRQPRIO_MAX 20 52#define BOOKE_IRQPRIO_DBELL 21
53#define BOOKE_IRQPRIO_DBELL_CRIT 22
54#define BOOKE_IRQPRIO_MAX 23
55
56#define BOOKE_IRQMASK_EE ((1 << BOOKE_IRQPRIO_EXTERNAL_LEVEL) | \
57 (1 << BOOKE_IRQPRIO_PERFORMANCE_MONITOR) | \
58 (1 << BOOKE_IRQPRIO_DBELL) | \
59 (1 << BOOKE_IRQPRIO_DECREMENTER) | \
60 (1 << BOOKE_IRQPRIO_FIT) | \
61 (1 << BOOKE_IRQPRIO_EXTERNAL))
62
63#define BOOKE_IRQMASK_CE ((1 << BOOKE_IRQPRIO_DBELL_CRIT) | \
64 (1 << BOOKE_IRQPRIO_WATCHDOG) | \
65 (1 << BOOKE_IRQPRIO_CRITICAL))
52 66
53extern unsigned long kvmppc_booke_handlers; 67extern unsigned long kvmppc_booke_handlers;
54 68
@@ -61,8 +75,8 @@ void kvmppc_clr_tsr_bits(struct kvm_vcpu *vcpu, u32 tsr_bits);
61 75
62int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 76int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
63 unsigned int inst, int *advance); 77 unsigned int inst, int *advance);
64int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt); 78int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val);
65int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs); 79int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val);
66 80
67/* low-level asm code to transfer guest state */ 81/* low-level asm code to transfer guest state */
68void kvmppc_load_guest_spe(struct kvm_vcpu *vcpu); 82void kvmppc_load_guest_spe(struct kvm_vcpu *vcpu);
@@ -71,4 +85,46 @@ void kvmppc_save_guest_spe(struct kvm_vcpu *vcpu);
71/* high-level function, manages flags, host state */ 85/* high-level function, manages flags, host state */
72void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu); 86void kvmppc_vcpu_disable_spe(struct kvm_vcpu *vcpu);
73 87
88void kvmppc_booke_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
89void kvmppc_booke_vcpu_put(struct kvm_vcpu *vcpu);
90
91enum int_class {
92 INT_CLASS_NONCRIT,
93 INT_CLASS_CRIT,
94 INT_CLASS_MC,
95 INT_CLASS_DBG,
96};
97
98void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type);
99
100/*
101 * Load up guest vcpu FP state if it's needed.
102 * It also set the MSR_FP in thread so that host know
103 * we're holding FPU, and then host can help to save
104 * guest vcpu FP state if other threads require to use FPU.
105 * This simulates an FP unavailable fault.
106 *
107 * It requires to be called with preemption disabled.
108 */
109static inline void kvmppc_load_guest_fp(struct kvm_vcpu *vcpu)
110{
111#ifdef CONFIG_PPC_FPU
112 if (vcpu->fpu_active && !(current->thread.regs->msr & MSR_FP)) {
113 load_up_fpu();
114 current->thread.regs->msr |= MSR_FP;
115 }
116#endif
117}
118
119/*
120 * Save guest vcpu FP state into thread.
121 * It requires to be called with preemption disabled.
122 */
123static inline void kvmppc_save_guest_fp(struct kvm_vcpu *vcpu)
124{
125#ifdef CONFIG_PPC_FPU
126 if (vcpu->fpu_active && (current->thread.regs->msr & MSR_FP))
127 giveup_fpu(current);
128#endif
129}
74#endif /* __KVM_BOOKE_H__ */ 130#endif /* __KVM_BOOKE_H__ */
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
index 3e652da3653..6c76397f2af 100644
--- a/arch/powerpc/kvm/booke_emulate.c
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -40,8 +40,8 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
40 unsigned int inst, int *advance) 40 unsigned int inst, int *advance)
41{ 41{
42 int emulated = EMULATE_DONE; 42 int emulated = EMULATE_DONE;
43 int rs; 43 int rs = get_rs(inst);
44 int rt; 44 int rt = get_rt(inst);
45 45
46 switch (get_op(inst)) { 46 switch (get_op(inst)) {
47 case 19: 47 case 19:
@@ -62,19 +62,16 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
62 switch (get_xop(inst)) { 62 switch (get_xop(inst)) {
63 63
64 case OP_31_XOP_MFMSR: 64 case OP_31_XOP_MFMSR:
65 rt = get_rt(inst);
66 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr); 65 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->msr);
67 kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS); 66 kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
68 break; 67 break;
69 68
70 case OP_31_XOP_MTMSR: 69 case OP_31_XOP_MTMSR:
71 rs = get_rs(inst);
72 kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS); 70 kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
73 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs)); 71 kvmppc_set_msr(vcpu, kvmppc_get_gpr(vcpu, rs));
74 break; 72 break;
75 73
76 case OP_31_XOP_WRTEE: 74 case OP_31_XOP_WRTEE:
77 rs = get_rs(inst);
78 vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE) 75 vcpu->arch.shared->msr = (vcpu->arch.shared->msr & ~MSR_EE)
79 | (kvmppc_get_gpr(vcpu, rs) & MSR_EE); 76 | (kvmppc_get_gpr(vcpu, rs) & MSR_EE);
80 kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS); 77 kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
@@ -99,22 +96,32 @@ int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
99 return emulated; 96 return emulated;
100} 97}
101 98
102int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 99/*
100 * NOTE: some of these registers are not emulated on BOOKE_HV (GS-mode).
101 * Their backing store is in real registers, and these functions
102 * will return the wrong result if called for them in another context
103 * (such as debugging).
104 */
105int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
103{ 106{
104 int emulated = EMULATE_DONE; 107 int emulated = EMULATE_DONE;
105 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
106 108
107 switch (sprn) { 109 switch (sprn) {
108 case SPRN_DEAR: 110 case SPRN_DEAR:
109 vcpu->arch.shared->dar = spr_val; break; 111 vcpu->arch.shared->dar = spr_val;
112 break;
110 case SPRN_ESR: 113 case SPRN_ESR:
111 vcpu->arch.shared->esr = spr_val; break; 114 vcpu->arch.shared->esr = spr_val;
115 break;
112 case SPRN_DBCR0: 116 case SPRN_DBCR0:
113 vcpu->arch.dbcr0 = spr_val; break; 117 vcpu->arch.dbcr0 = spr_val;
118 break;
114 case SPRN_DBCR1: 119 case SPRN_DBCR1:
115 vcpu->arch.dbcr1 = spr_val; break; 120 vcpu->arch.dbcr1 = spr_val;
121 break;
116 case SPRN_DBSR: 122 case SPRN_DBSR:
117 vcpu->arch.dbsr &= ~spr_val; break; 123 vcpu->arch.dbsr &= ~spr_val;
124 break;
118 case SPRN_TSR: 125 case SPRN_TSR:
119 kvmppc_clr_tsr_bits(vcpu, spr_val); 126 kvmppc_clr_tsr_bits(vcpu, spr_val);
120 break; 127 break;
@@ -122,20 +129,29 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
122 kvmppc_set_tcr(vcpu, spr_val); 129 kvmppc_set_tcr(vcpu, spr_val);
123 break; 130 break;
124 131
125 /* Note: SPRG4-7 are user-readable. These values are 132 /*
126 * loaded into the real SPRGs when resuming the 133 * Note: SPRG4-7 are user-readable.
127 * guest. */ 134 * These values are loaded into the real SPRGs when resuming the
135 * guest (PR-mode only).
136 */
128 case SPRN_SPRG4: 137 case SPRN_SPRG4:
129 vcpu->arch.shared->sprg4 = spr_val; break; 138 vcpu->arch.shared->sprg4 = spr_val;
139 break;
130 case SPRN_SPRG5: 140 case SPRN_SPRG5:
131 vcpu->arch.shared->sprg5 = spr_val; break; 141 vcpu->arch.shared->sprg5 = spr_val;
142 break;
132 case SPRN_SPRG6: 143 case SPRN_SPRG6:
133 vcpu->arch.shared->sprg6 = spr_val; break; 144 vcpu->arch.shared->sprg6 = spr_val;
145 break;
134 case SPRN_SPRG7: 146 case SPRN_SPRG7:
135 vcpu->arch.shared->sprg7 = spr_val; break; 147 vcpu->arch.shared->sprg7 = spr_val;
148 break;
136 149
137 case SPRN_IVPR: 150 case SPRN_IVPR:
138 vcpu->arch.ivpr = spr_val; 151 vcpu->arch.ivpr = spr_val;
152#ifdef CONFIG_KVM_BOOKE_HV
153 mtspr(SPRN_GIVPR, spr_val);
154#endif
139 break; 155 break;
140 case SPRN_IVOR0: 156 case SPRN_IVOR0:
141 vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val; 157 vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = spr_val;
@@ -145,6 +161,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
145 break; 161 break;
146 case SPRN_IVOR2: 162 case SPRN_IVOR2:
147 vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val; 163 vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = spr_val;
164#ifdef CONFIG_KVM_BOOKE_HV
165 mtspr(SPRN_GIVOR2, spr_val);
166#endif
148 break; 167 break;
149 case SPRN_IVOR3: 168 case SPRN_IVOR3:
150 vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val; 169 vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = spr_val;
@@ -163,6 +182,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
163 break; 182 break;
164 case SPRN_IVOR8: 183 case SPRN_IVOR8:
165 vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val; 184 vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = spr_val;
185#ifdef CONFIG_KVM_BOOKE_HV
186 mtspr(SPRN_GIVOR8, spr_val);
187#endif
166 break; 188 break;
167 case SPRN_IVOR9: 189 case SPRN_IVOR9:
168 vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val; 190 vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = spr_val;
@@ -193,75 +215,83 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
193 return emulated; 215 return emulated;
194} 216}
195 217
196int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 218int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
197{ 219{
198 int emulated = EMULATE_DONE; 220 int emulated = EMULATE_DONE;
199 221
200 switch (sprn) { 222 switch (sprn) {
201 case SPRN_IVPR: 223 case SPRN_IVPR:
202 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivpr); break; 224 *spr_val = vcpu->arch.ivpr;
225 break;
203 case SPRN_DEAR: 226 case SPRN_DEAR:
204 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->dar); break; 227 *spr_val = vcpu->arch.shared->dar;
228 break;
205 case SPRN_ESR: 229 case SPRN_ESR:
206 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->esr); break; 230 *spr_val = vcpu->arch.shared->esr;
231 break;
207 case SPRN_DBCR0: 232 case SPRN_DBCR0:
208 kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr0); break; 233 *spr_val = vcpu->arch.dbcr0;
234 break;
209 case SPRN_DBCR1: 235 case SPRN_DBCR1:
210 kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbcr1); break; 236 *spr_val = vcpu->arch.dbcr1;
237 break;
211 case SPRN_DBSR: 238 case SPRN_DBSR:
212 kvmppc_set_gpr(vcpu, rt, vcpu->arch.dbsr); break; 239 *spr_val = vcpu->arch.dbsr;
240 break;
213 case SPRN_TSR: 241 case SPRN_TSR:
214 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tsr); break; 242 *spr_val = vcpu->arch.tsr;
243 break;
215 case SPRN_TCR: 244 case SPRN_TCR:
216 kvmppc_set_gpr(vcpu, rt, vcpu->arch.tcr); break; 245 *spr_val = vcpu->arch.tcr;
246 break;
217 247
218 case SPRN_IVOR0: 248 case SPRN_IVOR0:
219 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL]); 249 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
220 break; 250 break;
221 case SPRN_IVOR1: 251 case SPRN_IVOR1:
222 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK]); 252 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
223 break; 253 break;
224 case SPRN_IVOR2: 254 case SPRN_IVOR2:
225 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]); 255 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
226 break; 256 break;
227 case SPRN_IVOR3: 257 case SPRN_IVOR3:
228 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE]); 258 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
229 break; 259 break;
230 case SPRN_IVOR4: 260 case SPRN_IVOR4:
231 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL]); 261 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
232 break; 262 break;
233 case SPRN_IVOR5: 263 case SPRN_IVOR5:
234 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT]); 264 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
235 break; 265 break;
236 case SPRN_IVOR6: 266 case SPRN_IVOR6:
237 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM]); 267 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
238 break; 268 break;
239 case SPRN_IVOR7: 269 case SPRN_IVOR7:
240 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL]); 270 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
241 break; 271 break;
242 case SPRN_IVOR8: 272 case SPRN_IVOR8:
243 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]); 273 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
244 break; 274 break;
245 case SPRN_IVOR9: 275 case SPRN_IVOR9:
246 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL]); 276 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
247 break; 277 break;
248 case SPRN_IVOR10: 278 case SPRN_IVOR10:
249 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER]); 279 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
250 break; 280 break;
251 case SPRN_IVOR11: 281 case SPRN_IVOR11:
252 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_FIT]); 282 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
253 break; 283 break;
254 case SPRN_IVOR12: 284 case SPRN_IVOR12:
255 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG]); 285 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
256 break; 286 break;
257 case SPRN_IVOR13: 287 case SPRN_IVOR13:
258 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS]); 288 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
259 break; 289 break;
260 case SPRN_IVOR14: 290 case SPRN_IVOR14:
261 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS]); 291 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
262 break; 292 break;
263 case SPRN_IVOR15: 293 case SPRN_IVOR15:
264 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG]); 294 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
265 break; 295 break;
266 296
267 default: 297 default:
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index c8c4b878795..8feec2ff392 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -419,13 +419,13 @@ lightweight_exit:
419 * written directly to the shared area, so we 419 * written directly to the shared area, so we
420 * need to reload them here with the guest's values. 420 * need to reload them here with the guest's values.
421 */ 421 */
422 lwz r3, VCPU_SHARED_SPRG4(r5) 422 PPC_LD(r3, VCPU_SHARED_SPRG4, r5)
423 mtspr SPRN_SPRG4W, r3 423 mtspr SPRN_SPRG4W, r3
424 lwz r3, VCPU_SHARED_SPRG5(r5) 424 PPC_LD(r3, VCPU_SHARED_SPRG5, r5)
425 mtspr SPRN_SPRG5W, r3 425 mtspr SPRN_SPRG5W, r3
426 lwz r3, VCPU_SHARED_SPRG6(r5) 426 PPC_LD(r3, VCPU_SHARED_SPRG6, r5)
427 mtspr SPRN_SPRG6W, r3 427 mtspr SPRN_SPRG6W, r3
428 lwz r3, VCPU_SHARED_SPRG7(r5) 428 PPC_LD(r3, VCPU_SHARED_SPRG7, r5)
429 mtspr SPRN_SPRG7W, r3 429 mtspr SPRN_SPRG7W, r3
430 430
431#ifdef CONFIG_KVM_EXIT_TIMING 431#ifdef CONFIG_KVM_EXIT_TIMING
diff --git a/arch/powerpc/kvm/bookehv_interrupts.S b/arch/powerpc/kvm/bookehv_interrupts.S
new file mode 100644
index 00000000000..6048a00515d
--- /dev/null
+++ b/arch/powerpc/kvm/bookehv_interrupts.S
@@ -0,0 +1,597 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License, version 2, as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14 *
15 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
16 *
17 * Author: Varun Sethi <varun.sethi@freescale.com>
18 * Author: Scott Wood <scotwood@freescale.com>
19 *
20 * This file is derived from arch/powerpc/kvm/booke_interrupts.S
21 */
22
23#include <asm/ppc_asm.h>
24#include <asm/kvm_asm.h>
25#include <asm/reg.h>
26#include <asm/mmu-44x.h>
27#include <asm/page.h>
28#include <asm/asm-compat.h>
29#include <asm/asm-offsets.h>
30#include <asm/bitsperlong.h>
31#include <asm/thread_info.h>
32
33#include "../kernel/head_booke.h" /* for THREAD_NORMSAVE() */
34
35#define GET_VCPU(vcpu, thread) \
36 PPC_LL vcpu, THREAD_KVM_VCPU(thread)
37
38#define LONGBYTES (BITS_PER_LONG / 8)
39
40#define VCPU_GPR(n) (VCPU_GPRS + (n * LONGBYTES))
41#define VCPU_GUEST_SPRG(n) (VCPU_GUEST_SPRGS + (n * LONGBYTES))
42
43/* The host stack layout: */
44#define HOST_R1 (0 * LONGBYTES) /* Implied by stwu. */
45#define HOST_CALLEE_LR (1 * LONGBYTES)
46#define HOST_RUN (2 * LONGBYTES) /* struct kvm_run */
47/*
48 * r2 is special: it holds 'current', and it made nonvolatile in the
49 * kernel with the -ffixed-r2 gcc option.
50 */
51#define HOST_R2 (3 * LONGBYTES)
52#define HOST_CR (4 * LONGBYTES)
53#define HOST_NV_GPRS (5 * LONGBYTES)
54#define HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * LONGBYTES))
55#define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + LONGBYTES)
56#define HOST_STACK_SIZE ((HOST_MIN_STACK_SIZE + 15) & ~15) /* Align. */
57#define HOST_STACK_LR (HOST_STACK_SIZE + LONGBYTES) /* In caller stack frame. */
58
59#define NEED_EMU 0x00000001 /* emulation -- save nv regs */
60#define NEED_DEAR 0x00000002 /* save faulting DEAR */
61#define NEED_ESR 0x00000004 /* save faulting ESR */
62
63/*
64 * On entry:
65 * r4 = vcpu, r5 = srr0, r6 = srr1
66 * saved in vcpu: cr, ctr, r3-r13
67 */
68.macro kvm_handler_common intno, srr0, flags
69 /* Restore host stack pointer */
70 PPC_STL r1, VCPU_GPR(r1)(r4)
71 PPC_STL r2, VCPU_GPR(r2)(r4)
72 PPC_LL r1, VCPU_HOST_STACK(r4)
73 PPC_LL r2, HOST_R2(r1)
74
75 mfspr r10, SPRN_PID
76 lwz r8, VCPU_HOST_PID(r4)
77 PPC_LL r11, VCPU_SHARED(r4)
78 PPC_STL r14, VCPU_GPR(r14)(r4) /* We need a non-volatile GPR. */
79 li r14, \intno
80
81 stw r10, VCPU_GUEST_PID(r4)
82 mtspr SPRN_PID, r8
83
84#ifdef CONFIG_KVM_EXIT_TIMING
85 /* save exit time */
861: mfspr r7, SPRN_TBRU
87 mfspr r8, SPRN_TBRL
88 mfspr r9, SPRN_TBRU
89 cmpw r9, r7
90 stw r8, VCPU_TIMING_EXIT_TBL(r4)
91 bne- 1b
92 stw r9, VCPU_TIMING_EXIT_TBU(r4)
93#endif
94
95 oris r8, r6, MSR_CE@h
96 PPC_STD(r6, VCPU_SHARED_MSR, r11)
97 ori r8, r8, MSR_ME | MSR_RI
98 PPC_STL r5, VCPU_PC(r4)
99
100 /*
101 * Make sure CE/ME/RI are set (if appropriate for exception type)
102 * whether or not the guest had it set. Since mfmsr/mtmsr are
103 * somewhat expensive, skip in the common case where the guest
104 * had all these bits set (and thus they're still set if
105 * appropriate for the exception type).
106 */
107 cmpw r6, r8
108 beq 1f
109 mfmsr r7
110 .if \srr0 != SPRN_MCSRR0 && \srr0 != SPRN_CSRR0
111 oris r7, r7, MSR_CE@h
112 .endif
113 .if \srr0 != SPRN_MCSRR0
114 ori r7, r7, MSR_ME | MSR_RI
115 .endif
116 mtmsr r7
1171:
118
119 .if \flags & NEED_EMU
120 /*
121 * This assumes you have external PID support.
122 * To support a bookehv CPU without external PID, you'll
123 * need to look up the TLB entry and create a temporary mapping.
124 *
125 * FIXME: we don't currently handle if the lwepx faults. PR-mode
126 * booke doesn't handle it either. Since Linux doesn't use
127 * broadcast tlbivax anymore, the only way this should happen is
128 * if the guest maps its memory execute-but-not-read, or if we
129 * somehow take a TLB miss in the middle of this entry code and
130 * evict the relevant entry. On e500mc, all kernel lowmem is
131 * bolted into TLB1 large page mappings, and we don't use
132 * broadcast invalidates, so we should not take a TLB miss here.
133 *
134 * Later we'll need to deal with faults here. Disallowing guest
135 * mappings that are execute-but-not-read could be an option on
136 * e500mc, but not on chips with an LRAT if it is used.
137 */
138
139 mfspr r3, SPRN_EPLC /* will already have correct ELPID and EGS */
140 PPC_STL r15, VCPU_GPR(r15)(r4)
141 PPC_STL r16, VCPU_GPR(r16)(r4)
142 PPC_STL r17, VCPU_GPR(r17)(r4)
143 PPC_STL r18, VCPU_GPR(r18)(r4)
144 PPC_STL r19, VCPU_GPR(r19)(r4)
145 mr r8, r3
146 PPC_STL r20, VCPU_GPR(r20)(r4)
147 rlwimi r8, r6, EPC_EAS_SHIFT - MSR_IR_LG, EPC_EAS
148 PPC_STL r21, VCPU_GPR(r21)(r4)
149 rlwimi r8, r6, EPC_EPR_SHIFT - MSR_PR_LG, EPC_EPR
150 PPC_STL r22, VCPU_GPR(r22)(r4)
151 rlwimi r8, r10, EPC_EPID_SHIFT, EPC_EPID
152 PPC_STL r23, VCPU_GPR(r23)(r4)
153 PPC_STL r24, VCPU_GPR(r24)(r4)
154 PPC_STL r25, VCPU_GPR(r25)(r4)
155 PPC_STL r26, VCPU_GPR(r26)(r4)
156 PPC_STL r27, VCPU_GPR(r27)(r4)
157 PPC_STL r28, VCPU_GPR(r28)(r4)
158 PPC_STL r29, VCPU_GPR(r29)(r4)
159 PPC_STL r30, VCPU_GPR(r30)(r4)
160 PPC_STL r31, VCPU_GPR(r31)(r4)
161 mtspr SPRN_EPLC, r8
162
163 /* disable preemption, so we are sure we hit the fixup handler */
164#ifdef CONFIG_PPC64
165 clrrdi r8,r1,THREAD_SHIFT
166#else
167 rlwinm r8,r1,0,0,31-THREAD_SHIFT /* current thread_info */
168#endif
169 li r7, 1
170 stw r7, TI_PREEMPT(r8)
171
172 isync
173
174 /*
175 * In case the read goes wrong, we catch it and write an invalid value
176 * in LAST_INST instead.
177 */
1781: lwepx r9, 0, r5
1792:
180.section .fixup, "ax"
1813: li r9, KVM_INST_FETCH_FAILED
182 b 2b
183.previous
184.section __ex_table,"a"
185 PPC_LONG_ALIGN
186 PPC_LONG 1b,3b
187.previous
188
189 mtspr SPRN_EPLC, r3
190 li r7, 0
191 stw r7, TI_PREEMPT(r8)
192 stw r9, VCPU_LAST_INST(r4)
193 .endif
194
195 .if \flags & NEED_ESR
196 mfspr r8, SPRN_ESR
197 PPC_STL r8, VCPU_FAULT_ESR(r4)
198 .endif
199
200 .if \flags & NEED_DEAR
201 mfspr r9, SPRN_DEAR
202 PPC_STL r9, VCPU_FAULT_DEAR(r4)
203 .endif
204
205 b kvmppc_resume_host
206.endm
207
208/*
209 * For input register values, see arch/powerpc/include/asm/kvm_booke_hv_asm.h
210 */
211.macro kvm_handler intno srr0, srr1, flags
212_GLOBAL(kvmppc_handler_\intno\()_\srr1)
213 GET_VCPU(r11, r10)
214 PPC_STL r3, VCPU_GPR(r3)(r11)
215 mfspr r3, SPRN_SPRG_RSCRATCH0
216 PPC_STL r4, VCPU_GPR(r4)(r11)
217 PPC_LL r4, THREAD_NORMSAVE(0)(r10)
218 PPC_STL r5, VCPU_GPR(r5)(r11)
219 stw r13, VCPU_CR(r11)
220 mfspr r5, \srr0
221 PPC_STL r3, VCPU_GPR(r10)(r11)
222 PPC_LL r3, THREAD_NORMSAVE(2)(r10)
223 PPC_STL r6, VCPU_GPR(r6)(r11)
224 PPC_STL r4, VCPU_GPR(r11)(r11)
225 mfspr r6, \srr1
226 PPC_STL r7, VCPU_GPR(r7)(r11)
227 PPC_STL r8, VCPU_GPR(r8)(r11)
228 PPC_STL r9, VCPU_GPR(r9)(r11)
229 PPC_STL r3, VCPU_GPR(r13)(r11)
230 mfctr r7
231 PPC_STL r12, VCPU_GPR(r12)(r11)
232 PPC_STL r7, VCPU_CTR(r11)
233 mr r4, r11
234 kvm_handler_common \intno, \srr0, \flags
235.endm
236
237.macro kvm_lvl_handler intno scratch srr0, srr1, flags
238_GLOBAL(kvmppc_handler_\intno\()_\srr1)
239 mfspr r10, SPRN_SPRG_THREAD
240 GET_VCPU(r11, r10)
241 PPC_STL r3, VCPU_GPR(r3)(r11)
242 mfspr r3, \scratch
243 PPC_STL r4, VCPU_GPR(r4)(r11)
244 PPC_LL r4, GPR9(r8)
245 PPC_STL r5, VCPU_GPR(r5)(r11)
246 stw r9, VCPU_CR(r11)
247 mfspr r5, \srr0
248 PPC_STL r3, VCPU_GPR(r8)(r11)
249 PPC_LL r3, GPR10(r8)
250 PPC_STL r6, VCPU_GPR(r6)(r11)
251 PPC_STL r4, VCPU_GPR(r9)(r11)
252 mfspr r6, \srr1
253 PPC_LL r4, GPR11(r8)
254 PPC_STL r7, VCPU_GPR(r7)(r11)
255 PPC_STL r3, VCPU_GPR(r10)(r11)
256 mfctr r7
257 PPC_STL r12, VCPU_GPR(r12)(r11)
258 PPC_STL r13, VCPU_GPR(r13)(r11)
259 PPC_STL r4, VCPU_GPR(r11)(r11)
260 PPC_STL r7, VCPU_CTR(r11)
261 mr r4, r11
262 kvm_handler_common \intno, \srr0, \flags
263.endm
264
265kvm_lvl_handler BOOKE_INTERRUPT_CRITICAL, \
266 SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
267kvm_lvl_handler BOOKE_INTERRUPT_MACHINE_CHECK, \
268 SPRN_SPRG_RSCRATCH_MC, SPRN_MCSRR0, SPRN_MCSRR1, 0
269kvm_handler BOOKE_INTERRUPT_DATA_STORAGE, \
270 SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR)
271kvm_handler BOOKE_INTERRUPT_INST_STORAGE, SPRN_SRR0, SPRN_SRR1, NEED_ESR
272kvm_handler BOOKE_INTERRUPT_EXTERNAL, SPRN_SRR0, SPRN_SRR1, 0
273kvm_handler BOOKE_INTERRUPT_ALIGNMENT, \
274 SPRN_SRR0, SPRN_SRR1, (NEED_DEAR | NEED_ESR)
275kvm_handler BOOKE_INTERRUPT_PROGRAM, SPRN_SRR0, SPRN_SRR1, NEED_ESR
276kvm_handler BOOKE_INTERRUPT_FP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
277kvm_handler BOOKE_INTERRUPT_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
278kvm_handler BOOKE_INTERRUPT_AP_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
279kvm_handler BOOKE_INTERRUPT_DECREMENTER, SPRN_SRR0, SPRN_SRR1, 0
280kvm_handler BOOKE_INTERRUPT_FIT, SPRN_SRR0, SPRN_SRR1, 0
281kvm_lvl_handler BOOKE_INTERRUPT_WATCHDOG, \
282 SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
283kvm_handler BOOKE_INTERRUPT_DTLB_MISS, \
284 SPRN_SRR0, SPRN_SRR1, (NEED_EMU | NEED_DEAR | NEED_ESR)
285kvm_handler BOOKE_INTERRUPT_ITLB_MISS, SPRN_SRR0, SPRN_SRR1, 0
286kvm_handler BOOKE_INTERRUPT_SPE_UNAVAIL, SPRN_SRR0, SPRN_SRR1, 0
287kvm_handler BOOKE_INTERRUPT_SPE_FP_DATA, SPRN_SRR0, SPRN_SRR1, 0
288kvm_handler BOOKE_INTERRUPT_SPE_FP_ROUND, SPRN_SRR0, SPRN_SRR1, 0
289kvm_handler BOOKE_INTERRUPT_PERFORMANCE_MONITOR, SPRN_SRR0, SPRN_SRR1, 0
290kvm_handler BOOKE_INTERRUPT_DOORBELL, SPRN_SRR0, SPRN_SRR1, 0
291kvm_lvl_handler BOOKE_INTERRUPT_DOORBELL_CRITICAL, \
292 SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
293kvm_handler BOOKE_INTERRUPT_HV_PRIV, SPRN_SRR0, SPRN_SRR1, NEED_EMU
294kvm_handler BOOKE_INTERRUPT_HV_SYSCALL, SPRN_SRR0, SPRN_SRR1, 0
295kvm_handler BOOKE_INTERRUPT_GUEST_DBELL, SPRN_GSRR0, SPRN_GSRR1, 0
296kvm_lvl_handler BOOKE_INTERRUPT_GUEST_DBELL_CRIT, \
297 SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
298kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
299 SPRN_SPRG_RSCRATCH_CRIT, SPRN_CSRR0, SPRN_CSRR1, 0
300kvm_lvl_handler BOOKE_INTERRUPT_DEBUG, \
301 SPRN_SPRG_RSCRATCH_DBG, SPRN_DSRR0, SPRN_DSRR1, 0
302
303
304/* Registers:
305 * SPRG_SCRATCH0: guest r10
306 * r4: vcpu pointer
307 * r11: vcpu->arch.shared
308 * r14: KVM exit number
309 */
310_GLOBAL(kvmppc_resume_host)
311 /* Save remaining volatile guest register state to vcpu. */
312 mfspr r3, SPRN_VRSAVE
313 PPC_STL r0, VCPU_GPR(r0)(r4)
314 mflr r5
315 mfspr r6, SPRN_SPRG4
316 PPC_STL r5, VCPU_LR(r4)
317 mfspr r7, SPRN_SPRG5
318 stw r3, VCPU_VRSAVE(r4)
319 PPC_STD(r6, VCPU_SHARED_SPRG4, r11)
320 mfspr r8, SPRN_SPRG6
321 PPC_STD(r7, VCPU_SHARED_SPRG5, r11)
322 mfspr r9, SPRN_SPRG7
323 PPC_STD(r8, VCPU_SHARED_SPRG6, r11)
324 mfxer r3
325 PPC_STD(r9, VCPU_SHARED_SPRG7, r11)
326
327 /* save guest MAS registers and restore host mas4 & mas6 */
328 mfspr r5, SPRN_MAS0
329 PPC_STL r3, VCPU_XER(r4)
330 mfspr r6, SPRN_MAS1
331 stw r5, VCPU_SHARED_MAS0(r11)
332 mfspr r7, SPRN_MAS2
333 stw r6, VCPU_SHARED_MAS1(r11)
334 PPC_STD(r7, VCPU_SHARED_MAS2, r11)
335 mfspr r5, SPRN_MAS3
336 mfspr r6, SPRN_MAS4
337 stw r5, VCPU_SHARED_MAS7_3+4(r11)
338 mfspr r7, SPRN_MAS6
339 stw r6, VCPU_SHARED_MAS4(r11)
340 mfspr r5, SPRN_MAS7
341 lwz r6, VCPU_HOST_MAS4(r4)
342 stw r7, VCPU_SHARED_MAS6(r11)
343 lwz r8, VCPU_HOST_MAS6(r4)
344 mtspr SPRN_MAS4, r6
345 stw r5, VCPU_SHARED_MAS7_3+0(r11)
346 mtspr SPRN_MAS6, r8
347 /* Enable MAS register updates via exception */
348 mfspr r3, SPRN_EPCR
349 rlwinm r3, r3, 0, ~SPRN_EPCR_DMIUH
350 mtspr SPRN_EPCR, r3
351 isync
352
353 /* Switch to kernel stack and jump to handler. */
354 PPC_LL r3, HOST_RUN(r1)
355 mr r5, r14 /* intno */
356 mr r14, r4 /* Save vcpu pointer. */
357 bl kvmppc_handle_exit
358
359 /* Restore vcpu pointer and the nonvolatiles we used. */
360 mr r4, r14
361 PPC_LL r14, VCPU_GPR(r14)(r4)
362
363 andi. r5, r3, RESUME_FLAG_NV
364 beq skip_nv_load
365 PPC_LL r15, VCPU_GPR(r15)(r4)
366 PPC_LL r16, VCPU_GPR(r16)(r4)
367 PPC_LL r17, VCPU_GPR(r17)(r4)
368 PPC_LL r18, VCPU_GPR(r18)(r4)
369 PPC_LL r19, VCPU_GPR(r19)(r4)
370 PPC_LL r20, VCPU_GPR(r20)(r4)
371 PPC_LL r21, VCPU_GPR(r21)(r4)
372 PPC_LL r22, VCPU_GPR(r22)(r4)
373 PPC_LL r23, VCPU_GPR(r23)(r4)
374 PPC_LL r24, VCPU_GPR(r24)(r4)
375 PPC_LL r25, VCPU_GPR(r25)(r4)
376 PPC_LL r26, VCPU_GPR(r26)(r4)
377 PPC_LL r27, VCPU_GPR(r27)(r4)
378 PPC_LL r28, VCPU_GPR(r28)(r4)
379 PPC_LL r29, VCPU_GPR(r29)(r4)
380 PPC_LL r30, VCPU_GPR(r30)(r4)
381 PPC_LL r31, VCPU_GPR(r31)(r4)
382skip_nv_load:
383 /* Should we return to the guest? */
384 andi. r5, r3, RESUME_FLAG_HOST
385 beq lightweight_exit
386
387 srawi r3, r3, 2 /* Shift -ERR back down. */
388
389heavyweight_exit:
390 /* Not returning to guest. */
391 PPC_LL r5, HOST_STACK_LR(r1)
392 lwz r6, HOST_CR(r1)
393
394 /*
395 * We already saved guest volatile register state; now save the
396 * non-volatiles.
397 */
398
399 PPC_STL r15, VCPU_GPR(r15)(r4)
400 PPC_STL r16, VCPU_GPR(r16)(r4)
401 PPC_STL r17, VCPU_GPR(r17)(r4)
402 PPC_STL r18, VCPU_GPR(r18)(r4)
403 PPC_STL r19, VCPU_GPR(r19)(r4)
404 PPC_STL r20, VCPU_GPR(r20)(r4)
405 PPC_STL r21, VCPU_GPR(r21)(r4)
406 PPC_STL r22, VCPU_GPR(r22)(r4)
407 PPC_STL r23, VCPU_GPR(r23)(r4)
408 PPC_STL r24, VCPU_GPR(r24)(r4)
409 PPC_STL r25, VCPU_GPR(r25)(r4)
410 PPC_STL r26, VCPU_GPR(r26)(r4)
411 PPC_STL r27, VCPU_GPR(r27)(r4)
412 PPC_STL r28, VCPU_GPR(r28)(r4)
413 PPC_STL r29, VCPU_GPR(r29)(r4)
414 PPC_STL r30, VCPU_GPR(r30)(r4)
415 PPC_STL r31, VCPU_GPR(r31)(r4)
416
417 /* Load host non-volatile register state from host stack. */
418 PPC_LL r14, HOST_NV_GPR(r14)(r1)
419 PPC_LL r15, HOST_NV_GPR(r15)(r1)
420 PPC_LL r16, HOST_NV_GPR(r16)(r1)
421 PPC_LL r17, HOST_NV_GPR(r17)(r1)
422 PPC_LL r18, HOST_NV_GPR(r18)(r1)
423 PPC_LL r19, HOST_NV_GPR(r19)(r1)
424 PPC_LL r20, HOST_NV_GPR(r20)(r1)
425 PPC_LL r21, HOST_NV_GPR(r21)(r1)
426 PPC_LL r22, HOST_NV_GPR(r22)(r1)
427 PPC_LL r23, HOST_NV_GPR(r23)(r1)
428 PPC_LL r24, HOST_NV_GPR(r24)(r1)
429 PPC_LL r25, HOST_NV_GPR(r25)(r1)
430 PPC_LL r26, HOST_NV_GPR(r26)(r1)
431 PPC_LL r27, HOST_NV_GPR(r27)(r1)
432 PPC_LL r28, HOST_NV_GPR(r28)(r1)
433 PPC_LL r29, HOST_NV_GPR(r29)(r1)
434 PPC_LL r30, HOST_NV_GPR(r30)(r1)
435 PPC_LL r31, HOST_NV_GPR(r31)(r1)
436
437 /* Return to kvm_vcpu_run(). */
438 mtlr r5
439 mtcr r6
440 addi r1, r1, HOST_STACK_SIZE
441 /* r3 still contains the return code from kvmppc_handle_exit(). */
442 blr
443
444/* Registers:
445 * r3: kvm_run pointer
446 * r4: vcpu pointer
447 */
448_GLOBAL(__kvmppc_vcpu_run)
449 stwu r1, -HOST_STACK_SIZE(r1)
450 PPC_STL r1, VCPU_HOST_STACK(r4) /* Save stack pointer to vcpu. */
451
452 /* Save host state to stack. */
453 PPC_STL r3, HOST_RUN(r1)
454 mflr r3
455 mfcr r5
456 PPC_STL r3, HOST_STACK_LR(r1)
457
458 stw r5, HOST_CR(r1)
459
460 /* Save host non-volatile register state to stack. */
461 PPC_STL r14, HOST_NV_GPR(r14)(r1)
462 PPC_STL r15, HOST_NV_GPR(r15)(r1)
463 PPC_STL r16, HOST_NV_GPR(r16)(r1)
464 PPC_STL r17, HOST_NV_GPR(r17)(r1)
465 PPC_STL r18, HOST_NV_GPR(r18)(r1)
466 PPC_STL r19, HOST_NV_GPR(r19)(r1)
467 PPC_STL r20, HOST_NV_GPR(r20)(r1)
468 PPC_STL r21, HOST_NV_GPR(r21)(r1)
469 PPC_STL r22, HOST_NV_GPR(r22)(r1)
470 PPC_STL r23, HOST_NV_GPR(r23)(r1)
471 PPC_STL r24, HOST_NV_GPR(r24)(r1)
472 PPC_STL r25, HOST_NV_GPR(r25)(r1)
473 PPC_STL r26, HOST_NV_GPR(r26)(r1)
474 PPC_STL r27, HOST_NV_GPR(r27)(r1)
475 PPC_STL r28, HOST_NV_GPR(r28)(r1)
476 PPC_STL r29, HOST_NV_GPR(r29)(r1)
477 PPC_STL r30, HOST_NV_GPR(r30)(r1)
478 PPC_STL r31, HOST_NV_GPR(r31)(r1)
479
480 /* Load guest non-volatiles. */
481 PPC_LL r14, VCPU_GPR(r14)(r4)
482 PPC_LL r15, VCPU_GPR(r15)(r4)
483 PPC_LL r16, VCPU_GPR(r16)(r4)
484 PPC_LL r17, VCPU_GPR(r17)(r4)
485 PPC_LL r18, VCPU_GPR(r18)(r4)
486 PPC_LL r19, VCPU_GPR(r19)(r4)
487 PPC_LL r20, VCPU_GPR(r20)(r4)
488 PPC_LL r21, VCPU_GPR(r21)(r4)
489 PPC_LL r22, VCPU_GPR(r22)(r4)
490 PPC_LL r23, VCPU_GPR(r23)(r4)
491 PPC_LL r24, VCPU_GPR(r24)(r4)
492 PPC_LL r25, VCPU_GPR(r25)(r4)
493 PPC_LL r26, VCPU_GPR(r26)(r4)
494 PPC_LL r27, VCPU_GPR(r27)(r4)
495 PPC_LL r28, VCPU_GPR(r28)(r4)
496 PPC_LL r29, VCPU_GPR(r29)(r4)
497 PPC_LL r30, VCPU_GPR(r30)(r4)
498 PPC_LL r31, VCPU_GPR(r31)(r4)
499
500
501lightweight_exit:
502 PPC_STL r2, HOST_R2(r1)
503
504 mfspr r3, SPRN_PID
505 stw r3, VCPU_HOST_PID(r4)
506 lwz r3, VCPU_GUEST_PID(r4)
507 mtspr SPRN_PID, r3
508
509 PPC_LL r11, VCPU_SHARED(r4)
510 /* Disable MAS register updates via exception */
511 mfspr r3, SPRN_EPCR
512 oris r3, r3, SPRN_EPCR_DMIUH@h
513 mtspr SPRN_EPCR, r3
514 isync
515 /* Save host mas4 and mas6 and load guest MAS registers */
516 mfspr r3, SPRN_MAS4
517 stw r3, VCPU_HOST_MAS4(r4)
518 mfspr r3, SPRN_MAS6
519 stw r3, VCPU_HOST_MAS6(r4)
520 lwz r3, VCPU_SHARED_MAS0(r11)
521 lwz r5, VCPU_SHARED_MAS1(r11)
522 PPC_LD(r6, VCPU_SHARED_MAS2, r11)
523 lwz r7, VCPU_SHARED_MAS7_3+4(r11)
524 lwz r8, VCPU_SHARED_MAS4(r11)
525 mtspr SPRN_MAS0, r3
526 mtspr SPRN_MAS1, r5
527 mtspr SPRN_MAS2, r6
528 mtspr SPRN_MAS3, r7
529 mtspr SPRN_MAS4, r8
530 lwz r3, VCPU_SHARED_MAS6(r11)
531 lwz r5, VCPU_SHARED_MAS7_3+0(r11)
532 mtspr SPRN_MAS6, r3
533 mtspr SPRN_MAS7, r5
534
535 /*
536 * Host interrupt handlers may have clobbered these guest-readable
537 * SPRGs, so we need to reload them here with the guest's values.
538 */
539 lwz r3, VCPU_VRSAVE(r4)
540 PPC_LD(r5, VCPU_SHARED_SPRG4, r11)
541 mtspr SPRN_VRSAVE, r3
542 PPC_LD(r6, VCPU_SHARED_SPRG5, r11)
543 mtspr SPRN_SPRG4W, r5
544 PPC_LD(r7, VCPU_SHARED_SPRG6, r11)
545 mtspr SPRN_SPRG5W, r6
546 PPC_LD(r8, VCPU_SHARED_SPRG7, r11)
547 mtspr SPRN_SPRG6W, r7
548 mtspr SPRN_SPRG7W, r8
549
550 /* Load some guest volatiles. */
551 PPC_LL r3, VCPU_LR(r4)
552 PPC_LL r5, VCPU_XER(r4)
553 PPC_LL r6, VCPU_CTR(r4)
554 lwz r7, VCPU_CR(r4)
555 PPC_LL r8, VCPU_PC(r4)
556 PPC_LD(r9, VCPU_SHARED_MSR, r11)
557 PPC_LL r0, VCPU_GPR(r0)(r4)
558 PPC_LL r1, VCPU_GPR(r1)(r4)
559 PPC_LL r2, VCPU_GPR(r2)(r4)
560 PPC_LL r10, VCPU_GPR(r10)(r4)
561 PPC_LL r11, VCPU_GPR(r11)(r4)
562 PPC_LL r12, VCPU_GPR(r12)(r4)
563 PPC_LL r13, VCPU_GPR(r13)(r4)
564 mtlr r3
565 mtxer r5
566 mtctr r6
567 mtsrr0 r8
568 mtsrr1 r9
569
570#ifdef CONFIG_KVM_EXIT_TIMING
571 /* save enter time */
5721:
573 mfspr r6, SPRN_TBRU
574 mfspr r9, SPRN_TBRL
575 mfspr r8, SPRN_TBRU
576 cmpw r8, r6
577 stw r9, VCPU_TIMING_LAST_ENTER_TBL(r4)
578 bne 1b
579 stw r8, VCPU_TIMING_LAST_ENTER_TBU(r4)
580#endif
581
582 /*
583 * Don't execute any instruction which can change CR after
584 * below instruction.
585 */
586 mtcr r7
587
588 /* Finish loading guest volatiles and jump to guest. */
589 PPC_LL r5, VCPU_GPR(r5)(r4)
590 PPC_LL r6, VCPU_GPR(r6)(r4)
591 PPC_LL r7, VCPU_GPR(r7)(r4)
592 PPC_LL r8, VCPU_GPR(r8)(r4)
593 PPC_LL r9, VCPU_GPR(r9)(r4)
594
595 PPC_LL r3, VCPU_GPR(r3)(r4)
596 PPC_LL r4, VCPU_GPR(r4)(r4)
597 rfi
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index ddcd896fa2f..b479ed77c51 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -20,11 +20,282 @@
20#include <asm/reg.h> 20#include <asm/reg.h>
21#include <asm/cputable.h> 21#include <asm/cputable.h>
22#include <asm/tlbflush.h> 22#include <asm/tlbflush.h>
23#include <asm/kvm_e500.h>
24#include <asm/kvm_ppc.h> 23#include <asm/kvm_ppc.h>
25 24
25#include "../mm/mmu_decl.h"
26#include "booke.h" 26#include "booke.h"
27#include "e500_tlb.h" 27#include "e500.h"
28
29struct id {
30 unsigned long val;
31 struct id **pentry;
32};
33
34#define NUM_TIDS 256
35
36/*
37 * This table provide mappings from:
38 * (guestAS,guestTID,guestPR) --> ID of physical cpu
39 * guestAS [0..1]
40 * guestTID [0..255]
41 * guestPR [0..1]
42 * ID [1..255]
43 * Each vcpu keeps one vcpu_id_table.
44 */
45struct vcpu_id_table {
46 struct id id[2][NUM_TIDS][2];
47};
48
49/*
50 * This table provide reversed mappings of vcpu_id_table:
51 * ID --> address of vcpu_id_table item.
52 * Each physical core has one pcpu_id_table.
53 */
54struct pcpu_id_table {
55 struct id *entry[NUM_TIDS];
56};
57
58static DEFINE_PER_CPU(struct pcpu_id_table, pcpu_sids);
59
60/* This variable keeps last used shadow ID on local core.
61 * The valid range of shadow ID is [1..255] */
62static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid);
63
64/*
65 * Allocate a free shadow id and setup a valid sid mapping in given entry.
66 * A mapping is only valid when vcpu_id_table and pcpu_id_table are match.
67 *
68 * The caller must have preemption disabled, and keep it that way until
69 * it has finished with the returned shadow id (either written into the
70 * TLB or arch.shadow_pid, or discarded).
71 */
72static inline int local_sid_setup_one(struct id *entry)
73{
74 unsigned long sid;
75 int ret = -1;
76
77 sid = ++(__get_cpu_var(pcpu_last_used_sid));
78 if (sid < NUM_TIDS) {
79 __get_cpu_var(pcpu_sids).entry[sid] = entry;
80 entry->val = sid;
81 entry->pentry = &__get_cpu_var(pcpu_sids).entry[sid];
82 ret = sid;
83 }
84
85 /*
86 * If sid == NUM_TIDS, we've run out of sids. We return -1, and
87 * the caller will invalidate everything and start over.
88 *
89 * sid > NUM_TIDS indicates a race, which we disable preemption to
90 * avoid.
91 */
92 WARN_ON(sid > NUM_TIDS);
93
94 return ret;
95}
96
97/*
98 * Check if given entry contain a valid shadow id mapping.
99 * An ID mapping is considered valid only if
100 * both vcpu and pcpu know this mapping.
101 *
102 * The caller must have preemption disabled, and keep it that way until
103 * it has finished with the returned shadow id (either written into the
104 * TLB or arch.shadow_pid, or discarded).
105 */
106static inline int local_sid_lookup(struct id *entry)
107{
108 if (entry && entry->val != 0 &&
109 __get_cpu_var(pcpu_sids).entry[entry->val] == entry &&
110 entry->pentry == &__get_cpu_var(pcpu_sids).entry[entry->val])
111 return entry->val;
112 return -1;
113}
114
115/* Invalidate all id mappings on local core -- call with preempt disabled */
116static inline void local_sid_destroy_all(void)
117{
118 __get_cpu_var(pcpu_last_used_sid) = 0;
119 memset(&__get_cpu_var(pcpu_sids), 0, sizeof(__get_cpu_var(pcpu_sids)));
120}
121
122static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500)
123{
124 vcpu_e500->idt = kzalloc(sizeof(struct vcpu_id_table), GFP_KERNEL);
125 return vcpu_e500->idt;
126}
127
128static void kvmppc_e500_id_table_free(struct kvmppc_vcpu_e500 *vcpu_e500)
129{
130 kfree(vcpu_e500->idt);
131 vcpu_e500->idt = NULL;
132}
133
134/* Map guest pid to shadow.
135 * We use PID to keep shadow of current guest non-zero PID,
136 * and use PID1 to keep shadow of guest zero PID.
137 * So that guest tlbe with TID=0 can be accessed at any time */
138static void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *vcpu_e500)
139{
140 preempt_disable();
141 vcpu_e500->vcpu.arch.shadow_pid = kvmppc_e500_get_sid(vcpu_e500,
142 get_cur_as(&vcpu_e500->vcpu),
143 get_cur_pid(&vcpu_e500->vcpu),
144 get_cur_pr(&vcpu_e500->vcpu), 1);
145 vcpu_e500->vcpu.arch.shadow_pid1 = kvmppc_e500_get_sid(vcpu_e500,
146 get_cur_as(&vcpu_e500->vcpu), 0,
147 get_cur_pr(&vcpu_e500->vcpu), 1);
148 preempt_enable();
149}
150
151/* Invalidate all mappings on vcpu */
152static void kvmppc_e500_id_table_reset_all(struct kvmppc_vcpu_e500 *vcpu_e500)
153{
154 memset(vcpu_e500->idt, 0, sizeof(struct vcpu_id_table));
155
156 /* Update shadow pid when mappings are changed */
157 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
158}
159
160/* Invalidate one ID mapping on vcpu */
161static inline void kvmppc_e500_id_table_reset_one(
162 struct kvmppc_vcpu_e500 *vcpu_e500,
163 int as, int pid, int pr)
164{
165 struct vcpu_id_table *idt = vcpu_e500->idt;
166
167 BUG_ON(as >= 2);
168 BUG_ON(pid >= NUM_TIDS);
169 BUG_ON(pr >= 2);
170
171 idt->id[as][pid][pr].val = 0;
172 idt->id[as][pid][pr].pentry = NULL;
173
174 /* Update shadow pid when mappings are changed */
175 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
176}
177
178/*
179 * Map guest (vcpu,AS,ID,PR) to physical core shadow id.
180 * This function first lookup if a valid mapping exists,
181 * if not, then creates a new one.
182 *
183 * The caller must have preemption disabled, and keep it that way until
184 * it has finished with the returned shadow id (either written into the
185 * TLB or arch.shadow_pid, or discarded).
186 */
187unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
188 unsigned int as, unsigned int gid,
189 unsigned int pr, int avoid_recursion)
190{
191 struct vcpu_id_table *idt = vcpu_e500->idt;
192 int sid;
193
194 BUG_ON(as >= 2);
195 BUG_ON(gid >= NUM_TIDS);
196 BUG_ON(pr >= 2);
197
198 sid = local_sid_lookup(&idt->id[as][gid][pr]);
199
200 while (sid <= 0) {
201 /* No mapping yet */
202 sid = local_sid_setup_one(&idt->id[as][gid][pr]);
203 if (sid <= 0) {
204 _tlbil_all();
205 local_sid_destroy_all();
206 }
207
208 /* Update shadow pid when mappings are changed */
209 if (!avoid_recursion)
210 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
211 }
212
213 return sid;
214}
215
216unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu,
217 struct kvm_book3e_206_tlb_entry *gtlbe)
218{
219 return kvmppc_e500_get_sid(to_e500(vcpu), get_tlb_ts(gtlbe),
220 get_tlb_tid(gtlbe), get_cur_pr(vcpu), 0);
221}
222
223void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
224{
225 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
226
227 if (vcpu->arch.pid != pid) {
228 vcpu_e500->pid[0] = vcpu->arch.pid = pid;
229 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
230 }
231}
232
233/* gtlbe must not be mapped by more than one host tlbe */
234void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
235 struct kvm_book3e_206_tlb_entry *gtlbe)
236{
237 struct vcpu_id_table *idt = vcpu_e500->idt;
238 unsigned int pr, tid, ts, pid;
239 u32 val, eaddr;
240 unsigned long flags;
241
242 ts = get_tlb_ts(gtlbe);
243 tid = get_tlb_tid(gtlbe);
244
245 preempt_disable();
246
247 /* One guest ID may be mapped to two shadow IDs */
248 for (pr = 0; pr < 2; pr++) {
249 /*
250 * The shadow PID can have a valid mapping on at most one
251 * host CPU. In the common case, it will be valid on this
252 * CPU, in which case we do a local invalidation of the
253 * specific address.
254 *
255 * If the shadow PID is not valid on the current host CPU,
256 * we invalidate the entire shadow PID.
257 */
258 pid = local_sid_lookup(&idt->id[ts][tid][pr]);
259 if (pid <= 0) {
260 kvmppc_e500_id_table_reset_one(vcpu_e500, ts, tid, pr);
261 continue;
262 }
263
264 /*
265 * The guest is invalidating a 4K entry which is in a PID
266 * that has a valid shadow mapping on this host CPU. We
267 * search host TLB to invalidate it's shadow TLB entry,
268 * similar to __tlbil_va except that we need to look in AS1.
269 */
270 val = (pid << MAS6_SPID_SHIFT) | MAS6_SAS;
271 eaddr = get_tlb_eaddr(gtlbe);
272
273 local_irq_save(flags);
274
275 mtspr(SPRN_MAS6, val);
276 asm volatile("tlbsx 0, %[eaddr]" : : [eaddr] "r" (eaddr));
277 val = mfspr(SPRN_MAS1);
278 if (val & MAS1_VALID) {
279 mtspr(SPRN_MAS1, val & ~MAS1_VALID);
280 asm volatile("tlbwe");
281 }
282
283 local_irq_restore(flags);
284 }
285
286 preempt_enable();
287}
288
289void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500)
290{
291 kvmppc_e500_id_table_reset_all(vcpu_e500);
292}
293
294void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
295{
296 /* Recalc shadow pid since MSR changes */
297 kvmppc_e500_recalc_shadow_pid(to_e500(vcpu));
298}
28 299
29void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) 300void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
30{ 301{
@@ -36,17 +307,20 @@ void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
36 307
37void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 308void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
38{ 309{
39 kvmppc_e500_tlb_load(vcpu, cpu); 310 kvmppc_booke_vcpu_load(vcpu, cpu);
311
312 /* Shadow PID may be expired on local core */
313 kvmppc_e500_recalc_shadow_pid(to_e500(vcpu));
40} 314}
41 315
42void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) 316void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
43{ 317{
44 kvmppc_e500_tlb_put(vcpu);
45
46#ifdef CONFIG_SPE 318#ifdef CONFIG_SPE
47 if (vcpu->arch.shadow_msr & MSR_SPE) 319 if (vcpu->arch.shadow_msr & MSR_SPE)
48 kvmppc_vcpu_disable_spe(vcpu); 320 kvmppc_vcpu_disable_spe(vcpu);
49#endif 321#endif
322
323 kvmppc_booke_vcpu_put(vcpu);
50} 324}
51 325
52int kvmppc_core_check_processor_compat(void) 326int kvmppc_core_check_processor_compat(void)
@@ -61,6 +335,23 @@ int kvmppc_core_check_processor_compat(void)
61 return r; 335 return r;
62} 336}
63 337
338static void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
339{
340 struct kvm_book3e_206_tlb_entry *tlbe;
341
342 /* Insert large initial mapping for guest. */
343 tlbe = get_entry(vcpu_e500, 1, 0);
344 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M);
345 tlbe->mas2 = 0;
346 tlbe->mas7_3 = E500_TLB_SUPER_PERM_MASK;
347
348 /* 4K map for serial output. Used by kernel wrapper. */
349 tlbe = get_entry(vcpu_e500, 1, 1);
350 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K);
351 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
352 tlbe->mas7_3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
353}
354
64int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) 355int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
65{ 356{
66 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 357 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -76,32 +367,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
76 return 0; 367 return 0;
77} 368}
78 369
79/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
80int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
81 struct kvm_translation *tr)
82{
83 int index;
84 gva_t eaddr;
85 u8 pid;
86 u8 as;
87
88 eaddr = tr->linear_address;
89 pid = (tr->linear_address >> 32) & 0xff;
90 as = (tr->linear_address >> 40) & 0x1;
91
92 index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
93 if (index < 0) {
94 tr->valid = 0;
95 return 0;
96 }
97
98 tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
99 /* XXX what does "writeable" and "usermode" even mean? */
100 tr->valid = 1;
101
102 return 0;
103}
104
105void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 370void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
106{ 371{
107 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 372 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -115,19 +380,6 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
115 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0; 380 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
116 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar; 381 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
117 382
118 sregs->u.e.mas0 = vcpu->arch.shared->mas0;
119 sregs->u.e.mas1 = vcpu->arch.shared->mas1;
120 sregs->u.e.mas2 = vcpu->arch.shared->mas2;
121 sregs->u.e.mas7_3 = vcpu->arch.shared->mas7_3;
122 sregs->u.e.mas4 = vcpu->arch.shared->mas4;
123 sregs->u.e.mas6 = vcpu->arch.shared->mas6;
124
125 sregs->u.e.mmucfg = mfspr(SPRN_MMUCFG);
126 sregs->u.e.tlbcfg[0] = vcpu_e500->tlb0cfg;
127 sregs->u.e.tlbcfg[1] = vcpu_e500->tlb1cfg;
128 sregs->u.e.tlbcfg[2] = 0;
129 sregs->u.e.tlbcfg[3] = 0;
130
131 sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]; 383 sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
132 sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]; 384 sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
133 sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]; 385 sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
@@ -135,11 +387,13 @@ void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
135 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]; 387 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
136 388
137 kvmppc_get_sregs_ivor(vcpu, sregs); 389 kvmppc_get_sregs_ivor(vcpu, sregs);
390 kvmppc_get_sregs_e500_tlb(vcpu, sregs);
138} 391}
139 392
140int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 393int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
141{ 394{
142 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 395 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
396 int ret;
143 397
144 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) { 398 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
145 vcpu_e500->svr = sregs->u.e.impl.fsl.svr; 399 vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
@@ -147,14 +401,9 @@ int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
147 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar; 401 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
148 } 402 }
149 403
150 if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) { 404 ret = kvmppc_set_sregs_e500_tlb(vcpu, sregs);
151 vcpu->arch.shared->mas0 = sregs->u.e.mas0; 405 if (ret < 0)
152 vcpu->arch.shared->mas1 = sregs->u.e.mas1; 406 return ret;
153 vcpu->arch.shared->mas2 = sregs->u.e.mas2;
154 vcpu->arch.shared->mas7_3 = sregs->u.e.mas7_3;
155 vcpu->arch.shared->mas4 = sregs->u.e.mas4;
156 vcpu->arch.shared->mas6 = sregs->u.e.mas6;
157 }
158 407
159 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR)) 408 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
160 return 0; 409 return 0;
@@ -193,9 +442,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
193 if (err) 442 if (err)
194 goto free_vcpu; 443 goto free_vcpu;
195 444
445 if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL)
446 goto uninit_vcpu;
447
196 err = kvmppc_e500_tlb_init(vcpu_e500); 448 err = kvmppc_e500_tlb_init(vcpu_e500);
197 if (err) 449 if (err)
198 goto uninit_vcpu; 450 goto uninit_id;
199 451
200 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); 452 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
201 if (!vcpu->arch.shared) 453 if (!vcpu->arch.shared)
@@ -205,6 +457,8 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
205 457
206uninit_tlb: 458uninit_tlb:
207 kvmppc_e500_tlb_uninit(vcpu_e500); 459 kvmppc_e500_tlb_uninit(vcpu_e500);
460uninit_id:
461 kvmppc_e500_id_table_free(vcpu_e500);
208uninit_vcpu: 462uninit_vcpu:
209 kvm_vcpu_uninit(vcpu); 463 kvm_vcpu_uninit(vcpu);
210free_vcpu: 464free_vcpu:
@@ -218,11 +472,21 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
218 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 472 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
219 473
220 free_page((unsigned long)vcpu->arch.shared); 474 free_page((unsigned long)vcpu->arch.shared);
221 kvm_vcpu_uninit(vcpu);
222 kvmppc_e500_tlb_uninit(vcpu_e500); 475 kvmppc_e500_tlb_uninit(vcpu_e500);
476 kvmppc_e500_id_table_free(vcpu_e500);
477 kvm_vcpu_uninit(vcpu);
223 kmem_cache_free(kvm_vcpu_cache, vcpu_e500); 478 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
224} 479}
225 480
481int kvmppc_core_init_vm(struct kvm *kvm)
482{
483 return 0;
484}
485
486void kvmppc_core_destroy_vm(struct kvm *kvm)
487{
488}
489
226static int __init kvmppc_e500_init(void) 490static int __init kvmppc_e500_init(void)
227{ 491{
228 int r, i; 492 int r, i;
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h
new file mode 100644
index 00000000000..aa8b81428bf
--- /dev/null
+++ b/arch/powerpc/kvm/e500.h
@@ -0,0 +1,306 @@
1/*
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Yu Liu <yu.liu@freescale.com>
5 * Scott Wood <scottwood@freescale.com>
6 * Ashish Kalra <ashish.kalra@freescale.com>
7 * Varun Sethi <varun.sethi@freescale.com>
8 *
9 * Description:
10 * This file is based on arch/powerpc/kvm/44x_tlb.h and
11 * arch/powerpc/include/asm/kvm_44x.h by Hollis Blanchard <hollisb@us.ibm.com>,
12 * Copyright IBM Corp. 2007-2008
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License, version 2, as
16 * published by the Free Software Foundation.
17 */
18
19#ifndef KVM_E500_H
20#define KVM_E500_H
21
22#include <linux/kvm_host.h>
23#include <asm/mmu-book3e.h>
24#include <asm/tlb.h>
25
26#define E500_PID_NUM 3
27#define E500_TLB_NUM 2
28
29#define E500_TLB_VALID 1
30#define E500_TLB_DIRTY 2
31#define E500_TLB_BITMAP 4
32
33struct tlbe_ref {
34 pfn_t pfn;
35 unsigned int flags; /* E500_TLB_* */
36};
37
38struct tlbe_priv {
39 struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */
40};
41
42#ifdef CONFIG_KVM_E500V2
43struct vcpu_id_table;
44#endif
45
46struct kvmppc_e500_tlb_params {
47 int entries, ways, sets;
48};
49
50struct kvmppc_vcpu_e500 {
51 struct kvm_vcpu vcpu;
52
53 /* Unmodified copy of the guest's TLB -- shared with host userspace. */
54 struct kvm_book3e_206_tlb_entry *gtlb_arch;
55
56 /* Starting entry number in gtlb_arch[] */
57 int gtlb_offset[E500_TLB_NUM];
58
59 /* KVM internal information associated with each guest TLB entry */
60 struct tlbe_priv *gtlb_priv[E500_TLB_NUM];
61
62 struct kvmppc_e500_tlb_params gtlb_params[E500_TLB_NUM];
63
64 unsigned int gtlb_nv[E500_TLB_NUM];
65
66 /*
67 * information associated with each host TLB entry --
68 * TLB1 only for now. If/when guest TLB1 entries can be
69 * mapped with host TLB0, this will be used for that too.
70 *
71 * We don't want to use this for guest TLB0 because then we'd
72 * have the overhead of doing the translation again even if
73 * the entry is still in the guest TLB (e.g. we swapped out
74 * and back, and our host TLB entries got evicted).
75 */
76 struct tlbe_ref *tlb_refs[E500_TLB_NUM];
77 unsigned int host_tlb1_nv;
78
79 u32 svr;
80 u32 l1csr0;
81 u32 l1csr1;
82 u32 hid0;
83 u32 hid1;
84 u64 mcar;
85
86 struct page **shared_tlb_pages;
87 int num_shared_tlb_pages;
88
89 u64 *g2h_tlb1_map;
90 unsigned int *h2g_tlb1_rmap;
91
92 /* Minimum and maximum address mapped my TLB1 */
93 unsigned long tlb1_min_eaddr;
94 unsigned long tlb1_max_eaddr;
95
96#ifdef CONFIG_KVM_E500V2
97 u32 pid[E500_PID_NUM];
98
99 /* vcpu id table */
100 struct vcpu_id_table *idt;
101#endif
102};
103
104static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
105{
106 return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
107}
108
109
110/* This geometry is the legacy default -- can be overridden by userspace */
111#define KVM_E500_TLB0_WAY_SIZE 128
112#define KVM_E500_TLB0_WAY_NUM 2
113
114#define KVM_E500_TLB0_SIZE (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
115#define KVM_E500_TLB1_SIZE 16
116
117#define index_of(tlbsel, esel) (((tlbsel) << 16) | ((esel) & 0xFFFF))
118#define tlbsel_of(index) ((index) >> 16)
119#define esel_of(index) ((index) & 0xFFFF)
120
121#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
122#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
123#define MAS2_ATTRIB_MASK \
124 (MAS2_X0 | MAS2_X1)
125#define MAS3_ATTRIB_MASK \
126 (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
127 | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)
128
129int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500,
130 ulong value);
131int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu);
132int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu);
133int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb);
134int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb);
135int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb);
136int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500);
137void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500);
138
139void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
140int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
141
142
143#ifdef CONFIG_KVM_E500V2
144unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
145 unsigned int as, unsigned int gid,
146 unsigned int pr, int avoid_recursion);
147#endif
148
149/* TLB helper functions */
150static inline unsigned int
151get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe)
152{
153 return (tlbe->mas1 >> 7) & 0x1f;
154}
155
156static inline gva_t get_tlb_eaddr(const struct kvm_book3e_206_tlb_entry *tlbe)
157{
158 return tlbe->mas2 & 0xfffff000;
159}
160
161static inline u64 get_tlb_bytes(const struct kvm_book3e_206_tlb_entry *tlbe)
162{
163 unsigned int pgsize = get_tlb_size(tlbe);
164 return 1ULL << 10 << pgsize;
165}
166
167static inline gva_t get_tlb_end(const struct kvm_book3e_206_tlb_entry *tlbe)
168{
169 u64 bytes = get_tlb_bytes(tlbe);
170 return get_tlb_eaddr(tlbe) + bytes - 1;
171}
172
173static inline u64 get_tlb_raddr(const struct kvm_book3e_206_tlb_entry *tlbe)
174{
175 return tlbe->mas7_3 & ~0xfffULL;
176}
177
178static inline unsigned int
179get_tlb_tid(const struct kvm_book3e_206_tlb_entry *tlbe)
180{
181 return (tlbe->mas1 >> 16) & 0xff;
182}
183
184static inline unsigned int
185get_tlb_ts(const struct kvm_book3e_206_tlb_entry *tlbe)
186{
187 return (tlbe->mas1 >> 12) & 0x1;
188}
189
190static inline unsigned int
191get_tlb_v(const struct kvm_book3e_206_tlb_entry *tlbe)
192{
193 return (tlbe->mas1 >> 31) & 0x1;
194}
195
196static inline unsigned int
197get_tlb_iprot(const struct kvm_book3e_206_tlb_entry *tlbe)
198{
199 return (tlbe->mas1 >> 30) & 0x1;
200}
201
202static inline unsigned int
203get_tlb_tsize(const struct kvm_book3e_206_tlb_entry *tlbe)
204{
205 return (tlbe->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
206}
207
208static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
209{
210 return vcpu->arch.pid & 0xff;
211}
212
213static inline unsigned int get_cur_as(struct kvm_vcpu *vcpu)
214{
215 return !!(vcpu->arch.shared->msr & (MSR_IS | MSR_DS));
216}
217
218static inline unsigned int get_cur_pr(struct kvm_vcpu *vcpu)
219{
220 return !!(vcpu->arch.shared->msr & MSR_PR);
221}
222
223static inline unsigned int get_cur_spid(const struct kvm_vcpu *vcpu)
224{
225 return (vcpu->arch.shared->mas6 >> 16) & 0xff;
226}
227
228static inline unsigned int get_cur_sas(const struct kvm_vcpu *vcpu)
229{
230 return vcpu->arch.shared->mas6 & 0x1;
231}
232
233static inline unsigned int get_tlb_tlbsel(const struct kvm_vcpu *vcpu)
234{
235 /*
236 * Manual says that tlbsel has 2 bits wide.
237 * Since we only have two TLBs, only lower bit is used.
238 */
239 return (vcpu->arch.shared->mas0 >> 28) & 0x1;
240}
241
242static inline unsigned int get_tlb_nv_bit(const struct kvm_vcpu *vcpu)
243{
244 return vcpu->arch.shared->mas0 & 0xfff;
245}
246
247static inline unsigned int get_tlb_esel_bit(const struct kvm_vcpu *vcpu)
248{
249 return (vcpu->arch.shared->mas0 >> 16) & 0xfff;
250}
251
252static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
253 const struct kvm_book3e_206_tlb_entry *tlbe)
254{
255 gpa_t gpa;
256
257 if (!get_tlb_v(tlbe))
258 return 0;
259
260#ifndef CONFIG_KVM_BOOKE_HV
261 /* Does it match current guest AS? */
262 /* XXX what about IS != DS? */
263 if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
264 return 0;
265#endif
266
267 gpa = get_tlb_raddr(tlbe);
268 if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
269 /* Mapping is not for RAM. */
270 return 0;
271
272 return 1;
273}
274
275static inline struct kvm_book3e_206_tlb_entry *get_entry(
276 struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, int entry)
277{
278 int offset = vcpu_e500->gtlb_offset[tlbsel];
279 return &vcpu_e500->gtlb_arch[offset + entry];
280}
281
282void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
283 struct kvm_book3e_206_tlb_entry *gtlbe);
284void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500);
285
286#ifdef CONFIG_KVM_BOOKE_HV
287#define kvmppc_e500_get_tlb_stid(vcpu, gtlbe) get_tlb_tid(gtlbe)
288#define get_tlbmiss_tid(vcpu) get_cur_pid(vcpu)
289#define get_tlb_sts(gtlbe) (gtlbe->mas1 & MAS1_TS)
290#else
291unsigned int kvmppc_e500_get_tlb_stid(struct kvm_vcpu *vcpu,
292 struct kvm_book3e_206_tlb_entry *gtlbe);
293
294static inline unsigned int get_tlbmiss_tid(struct kvm_vcpu *vcpu)
295{
296 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
297 unsigned int tidseld = (vcpu->arch.shared->mas4 >> 16) & 0xf;
298
299 return vcpu_e500->pid[tidseld];
300}
301
302/* Force TS=1 for all guest mappings. */
303#define get_tlb_sts(gtlbe) (MAS1_TS)
304#endif /* !BOOKE_HV */
305
306#endif /* KVM_E500_H */
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 6d0b2bd54fb..8b99e076dc8 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -14,27 +14,96 @@
14 14
15#include <asm/kvm_ppc.h> 15#include <asm/kvm_ppc.h>
16#include <asm/disassemble.h> 16#include <asm/disassemble.h>
17#include <asm/kvm_e500.h> 17#include <asm/dbell.h>
18 18
19#include "booke.h" 19#include "booke.h"
20#include "e500_tlb.h" 20#include "e500.h"
21 21
22#define XOP_MSGSND 206
23#define XOP_MSGCLR 238
22#define XOP_TLBIVAX 786 24#define XOP_TLBIVAX 786
23#define XOP_TLBSX 914 25#define XOP_TLBSX 914
24#define XOP_TLBRE 946 26#define XOP_TLBRE 946
25#define XOP_TLBWE 978 27#define XOP_TLBWE 978
28#define XOP_TLBILX 18
29
30#ifdef CONFIG_KVM_E500MC
31static int dbell2prio(ulong param)
32{
33 int msg = param & PPC_DBELL_TYPE_MASK;
34 int prio = -1;
35
36 switch (msg) {
37 case PPC_DBELL_TYPE(PPC_DBELL):
38 prio = BOOKE_IRQPRIO_DBELL;
39 break;
40 case PPC_DBELL_TYPE(PPC_DBELL_CRIT):
41 prio = BOOKE_IRQPRIO_DBELL_CRIT;
42 break;
43 default:
44 break;
45 }
46
47 return prio;
48}
49
50static int kvmppc_e500_emul_msgclr(struct kvm_vcpu *vcpu, int rb)
51{
52 ulong param = vcpu->arch.gpr[rb];
53 int prio = dbell2prio(param);
54
55 if (prio < 0)
56 return EMULATE_FAIL;
57
58 clear_bit(prio, &vcpu->arch.pending_exceptions);
59 return EMULATE_DONE;
60}
61
62static int kvmppc_e500_emul_msgsnd(struct kvm_vcpu *vcpu, int rb)
63{
64 ulong param = vcpu->arch.gpr[rb];
65 int prio = dbell2prio(rb);
66 int pir = param & PPC_DBELL_PIR_MASK;
67 int i;
68 struct kvm_vcpu *cvcpu;
69
70 if (prio < 0)
71 return EMULATE_FAIL;
72
73 kvm_for_each_vcpu(i, cvcpu, vcpu->kvm) {
74 int cpir = cvcpu->arch.shared->pir;
75 if ((param & PPC_DBELL_MSG_BRDCAST) || (cpir == pir)) {
76 set_bit(prio, &cvcpu->arch.pending_exceptions);
77 kvm_vcpu_kick(cvcpu);
78 }
79 }
80
81 return EMULATE_DONE;
82}
83#endif
26 84
27int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, 85int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
28 unsigned int inst, int *advance) 86 unsigned int inst, int *advance)
29{ 87{
30 int emulated = EMULATE_DONE; 88 int emulated = EMULATE_DONE;
31 int ra; 89 int ra = get_ra(inst);
32 int rb; 90 int rb = get_rb(inst);
91 int rt = get_rt(inst);
33 92
34 switch (get_op(inst)) { 93 switch (get_op(inst)) {
35 case 31: 94 case 31:
36 switch (get_xop(inst)) { 95 switch (get_xop(inst)) {
37 96
97#ifdef CONFIG_KVM_E500MC
98 case XOP_MSGSND:
99 emulated = kvmppc_e500_emul_msgsnd(vcpu, rb);
100 break;
101
102 case XOP_MSGCLR:
103 emulated = kvmppc_e500_emul_msgclr(vcpu, rb);
104 break;
105#endif
106
38 case XOP_TLBRE: 107 case XOP_TLBRE:
39 emulated = kvmppc_e500_emul_tlbre(vcpu); 108 emulated = kvmppc_e500_emul_tlbre(vcpu);
40 break; 109 break;
@@ -44,13 +113,14 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
44 break; 113 break;
45 114
46 case XOP_TLBSX: 115 case XOP_TLBSX:
47 rb = get_rb(inst);
48 emulated = kvmppc_e500_emul_tlbsx(vcpu,rb); 116 emulated = kvmppc_e500_emul_tlbsx(vcpu,rb);
49 break; 117 break;
50 118
119 case XOP_TLBILX:
120 emulated = kvmppc_e500_emul_tlbilx(vcpu, rt, ra, rb);
121 break;
122
51 case XOP_TLBIVAX: 123 case XOP_TLBIVAX:
52 ra = get_ra(inst);
53 rb = get_rb(inst);
54 emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb); 124 emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb);
55 break; 125 break;
56 126
@@ -70,52 +140,63 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
70 return emulated; 140 return emulated;
71} 141}
72 142
73int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs) 143int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
74{ 144{
75 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 145 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
76 int emulated = EMULATE_DONE; 146 int emulated = EMULATE_DONE;
77 ulong spr_val = kvmppc_get_gpr(vcpu, rs);
78 147
79 switch (sprn) { 148 switch (sprn) {
149#ifndef CONFIG_KVM_BOOKE_HV
80 case SPRN_PID: 150 case SPRN_PID:
81 kvmppc_set_pid(vcpu, spr_val); 151 kvmppc_set_pid(vcpu, spr_val);
82 break; 152 break;
83 case SPRN_PID1: 153 case SPRN_PID1:
84 if (spr_val != 0) 154 if (spr_val != 0)
85 return EMULATE_FAIL; 155 return EMULATE_FAIL;
86 vcpu_e500->pid[1] = spr_val; break; 156 vcpu_e500->pid[1] = spr_val;
157 break;
87 case SPRN_PID2: 158 case SPRN_PID2:
88 if (spr_val != 0) 159 if (spr_val != 0)
89 return EMULATE_FAIL; 160 return EMULATE_FAIL;
90 vcpu_e500->pid[2] = spr_val; break; 161 vcpu_e500->pid[2] = spr_val;
162 break;
91 case SPRN_MAS0: 163 case SPRN_MAS0:
92 vcpu->arch.shared->mas0 = spr_val; break; 164 vcpu->arch.shared->mas0 = spr_val;
165 break;
93 case SPRN_MAS1: 166 case SPRN_MAS1:
94 vcpu->arch.shared->mas1 = spr_val; break; 167 vcpu->arch.shared->mas1 = spr_val;
168 break;
95 case SPRN_MAS2: 169 case SPRN_MAS2:
96 vcpu->arch.shared->mas2 = spr_val; break; 170 vcpu->arch.shared->mas2 = spr_val;
171 break;
97 case SPRN_MAS3: 172 case SPRN_MAS3:
98 vcpu->arch.shared->mas7_3 &= ~(u64)0xffffffff; 173 vcpu->arch.shared->mas7_3 &= ~(u64)0xffffffff;
99 vcpu->arch.shared->mas7_3 |= spr_val; 174 vcpu->arch.shared->mas7_3 |= spr_val;
100 break; 175 break;
101 case SPRN_MAS4: 176 case SPRN_MAS4:
102 vcpu->arch.shared->mas4 = spr_val; break; 177 vcpu->arch.shared->mas4 = spr_val;
178 break;
103 case SPRN_MAS6: 179 case SPRN_MAS6:
104 vcpu->arch.shared->mas6 = spr_val; break; 180 vcpu->arch.shared->mas6 = spr_val;
181 break;
105 case SPRN_MAS7: 182 case SPRN_MAS7:
106 vcpu->arch.shared->mas7_3 &= (u64)0xffffffff; 183 vcpu->arch.shared->mas7_3 &= (u64)0xffffffff;
107 vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32; 184 vcpu->arch.shared->mas7_3 |= (u64)spr_val << 32;
108 break; 185 break;
186#endif
109 case SPRN_L1CSR0: 187 case SPRN_L1CSR0:
110 vcpu_e500->l1csr0 = spr_val; 188 vcpu_e500->l1csr0 = spr_val;
111 vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC); 189 vcpu_e500->l1csr0 &= ~(L1CSR0_DCFI | L1CSR0_CLFC);
112 break; 190 break;
113 case SPRN_L1CSR1: 191 case SPRN_L1CSR1:
114 vcpu_e500->l1csr1 = spr_val; break; 192 vcpu_e500->l1csr1 = spr_val;
193 break;
115 case SPRN_HID0: 194 case SPRN_HID0:
116 vcpu_e500->hid0 = spr_val; break; 195 vcpu_e500->hid0 = spr_val;
196 break;
117 case SPRN_HID1: 197 case SPRN_HID1:
118 vcpu_e500->hid1 = spr_val; break; 198 vcpu_e500->hid1 = spr_val;
199 break;
119 200
120 case SPRN_MMUCSR0: 201 case SPRN_MMUCSR0:
121 emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500, 202 emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
@@ -135,81 +216,112 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
135 case SPRN_IVOR35: 216 case SPRN_IVOR35:
136 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val; 217 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = spr_val;
137 break; 218 break;
138 219#ifdef CONFIG_KVM_BOOKE_HV
220 case SPRN_IVOR36:
221 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] = spr_val;
222 break;
223 case SPRN_IVOR37:
224 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] = spr_val;
225 break;
226#endif
139 default: 227 default:
140 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs); 228 emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, spr_val);
141 } 229 }
142 230
143 return emulated; 231 return emulated;
144} 232}
145 233
146int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt) 234int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val)
147{ 235{
148 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 236 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
149 int emulated = EMULATE_DONE; 237 int emulated = EMULATE_DONE;
150 unsigned long val;
151 238
152 switch (sprn) { 239 switch (sprn) {
240#ifndef CONFIG_KVM_BOOKE_HV
153 case SPRN_PID: 241 case SPRN_PID:
154 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[0]); break; 242 *spr_val = vcpu_e500->pid[0];
243 break;
155 case SPRN_PID1: 244 case SPRN_PID1:
156 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[1]); break; 245 *spr_val = vcpu_e500->pid[1];
246 break;
157 case SPRN_PID2: 247 case SPRN_PID2:
158 kvmppc_set_gpr(vcpu, rt, vcpu_e500->pid[2]); break; 248 *spr_val = vcpu_e500->pid[2];
249 break;
159 case SPRN_MAS0: 250 case SPRN_MAS0:
160 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas0); break; 251 *spr_val = vcpu->arch.shared->mas0;
252 break;
161 case SPRN_MAS1: 253 case SPRN_MAS1:
162 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas1); break; 254 *spr_val = vcpu->arch.shared->mas1;
255 break;
163 case SPRN_MAS2: 256 case SPRN_MAS2:
164 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas2); break; 257 *spr_val = vcpu->arch.shared->mas2;
258 break;
165 case SPRN_MAS3: 259 case SPRN_MAS3:
166 val = (u32)vcpu->arch.shared->mas7_3; 260 *spr_val = (u32)vcpu->arch.shared->mas7_3;
167 kvmppc_set_gpr(vcpu, rt, val);
168 break; 261 break;
169 case SPRN_MAS4: 262 case SPRN_MAS4:
170 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas4); break; 263 *spr_val = vcpu->arch.shared->mas4;
264 break;
171 case SPRN_MAS6: 265 case SPRN_MAS6:
172 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->mas6); break; 266 *spr_val = vcpu->arch.shared->mas6;
267 break;
173 case SPRN_MAS7: 268 case SPRN_MAS7:
174 val = vcpu->arch.shared->mas7_3 >> 32; 269 *spr_val = vcpu->arch.shared->mas7_3 >> 32;
175 kvmppc_set_gpr(vcpu, rt, val);
176 break; 270 break;
271#endif
177 case SPRN_TLB0CFG: 272 case SPRN_TLB0CFG:
178 kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb0cfg); break; 273 *spr_val = vcpu->arch.tlbcfg[0];
274 break;
179 case SPRN_TLB1CFG: 275 case SPRN_TLB1CFG:
180 kvmppc_set_gpr(vcpu, rt, vcpu_e500->tlb1cfg); break; 276 *spr_val = vcpu->arch.tlbcfg[1];
277 break;
181 case SPRN_L1CSR0: 278 case SPRN_L1CSR0:
182 kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr0); break; 279 *spr_val = vcpu_e500->l1csr0;
280 break;
183 case SPRN_L1CSR1: 281 case SPRN_L1CSR1:
184 kvmppc_set_gpr(vcpu, rt, vcpu_e500->l1csr1); break; 282 *spr_val = vcpu_e500->l1csr1;
283 break;
185 case SPRN_HID0: 284 case SPRN_HID0:
186 kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break; 285 *spr_val = vcpu_e500->hid0;
286 break;
187 case SPRN_HID1: 287 case SPRN_HID1:
188 kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break; 288 *spr_val = vcpu_e500->hid1;
289 break;
189 case SPRN_SVR: 290 case SPRN_SVR:
190 kvmppc_set_gpr(vcpu, rt, vcpu_e500->svr); break; 291 *spr_val = vcpu_e500->svr;
292 break;
191 293
192 case SPRN_MMUCSR0: 294 case SPRN_MMUCSR0:
193 kvmppc_set_gpr(vcpu, rt, 0); break; 295 *spr_val = 0;
296 break;
194 297
195 case SPRN_MMUCFG: 298 case SPRN_MMUCFG:
196 kvmppc_set_gpr(vcpu, rt, mfspr(SPRN_MMUCFG)); break; 299 *spr_val = vcpu->arch.mmucfg;
300 break;
197 301
198 /* extra exceptions */ 302 /* extra exceptions */
199 case SPRN_IVOR32: 303 case SPRN_IVOR32:
200 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL]); 304 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
201 break; 305 break;
202 case SPRN_IVOR33: 306 case SPRN_IVOR33:
203 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA]); 307 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
204 break; 308 break;
205 case SPRN_IVOR34: 309 case SPRN_IVOR34:
206 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND]); 310 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
207 break; 311 break;
208 case SPRN_IVOR35: 312 case SPRN_IVOR35:
209 kvmppc_set_gpr(vcpu, rt, vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR]); 313 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
314 break;
315#ifdef CONFIG_KVM_BOOKE_HV
316 case SPRN_IVOR36:
317 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL];
318 break;
319 case SPRN_IVOR37:
320 *spr_val = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT];
210 break; 321 break;
322#endif
211 default: 323 default:
212 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt); 324 emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, spr_val);
213 } 325 }
214 326
215 return emulated; 327 return emulated;
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 6e53e4164de..c510fc96130 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -2,6 +2,9 @@
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved. 2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 * 3 *
4 * Author: Yu Liu, yu.liu@freescale.com 4 * Author: Yu Liu, yu.liu@freescale.com
5 * Scott Wood, scottwood@freescale.com
6 * Ashish Kalra, ashish.kalra@freescale.com
7 * Varun Sethi, varun.sethi@freescale.com
5 * 8 *
6 * Description: 9 * Description:
7 * This file is based on arch/powerpc/kvm/44x_tlb.c, 10 * This file is based on arch/powerpc/kvm/44x_tlb.c,
@@ -26,210 +29,15 @@
26#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
27#include <linux/hugetlb.h> 30#include <linux/hugetlb.h>
28#include <asm/kvm_ppc.h> 31#include <asm/kvm_ppc.h>
29#include <asm/kvm_e500.h>
30 32
31#include "../mm/mmu_decl.h" 33#include "e500.h"
32#include "e500_tlb.h"
33#include "trace.h" 34#include "trace.h"
34#include "timing.h" 35#include "timing.h"
35 36
36#define to_htlb1_esel(esel) (host_tlb_params[1].entries - (esel) - 1) 37#define to_htlb1_esel(esel) (host_tlb_params[1].entries - (esel) - 1)
37 38
38struct id {
39 unsigned long val;
40 struct id **pentry;
41};
42
43#define NUM_TIDS 256
44
45/*
46 * This table provide mappings from:
47 * (guestAS,guestTID,guestPR) --> ID of physical cpu
48 * guestAS [0..1]
49 * guestTID [0..255]
50 * guestPR [0..1]
51 * ID [1..255]
52 * Each vcpu keeps one vcpu_id_table.
53 */
54struct vcpu_id_table {
55 struct id id[2][NUM_TIDS][2];
56};
57
58/*
59 * This table provide reversed mappings of vcpu_id_table:
60 * ID --> address of vcpu_id_table item.
61 * Each physical core has one pcpu_id_table.
62 */
63struct pcpu_id_table {
64 struct id *entry[NUM_TIDS];
65};
66
67static DEFINE_PER_CPU(struct pcpu_id_table, pcpu_sids);
68
69/* This variable keeps last used shadow ID on local core.
70 * The valid range of shadow ID is [1..255] */
71static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid);
72
73static struct kvmppc_e500_tlb_params host_tlb_params[E500_TLB_NUM]; 39static struct kvmppc_e500_tlb_params host_tlb_params[E500_TLB_NUM];
74 40
75static struct kvm_book3e_206_tlb_entry *get_entry(
76 struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, int entry)
77{
78 int offset = vcpu_e500->gtlb_offset[tlbsel];
79 return &vcpu_e500->gtlb_arch[offset + entry];
80}
81
82/*
83 * Allocate a free shadow id and setup a valid sid mapping in given entry.
84 * A mapping is only valid when vcpu_id_table and pcpu_id_table are match.
85 *
86 * The caller must have preemption disabled, and keep it that way until
87 * it has finished with the returned shadow id (either written into the
88 * TLB or arch.shadow_pid, or discarded).
89 */
90static inline int local_sid_setup_one(struct id *entry)
91{
92 unsigned long sid;
93 int ret = -1;
94
95 sid = ++(__get_cpu_var(pcpu_last_used_sid));
96 if (sid < NUM_TIDS) {
97 __get_cpu_var(pcpu_sids).entry[sid] = entry;
98 entry->val = sid;
99 entry->pentry = &__get_cpu_var(pcpu_sids).entry[sid];
100 ret = sid;
101 }
102
103 /*
104 * If sid == NUM_TIDS, we've run out of sids. We return -1, and
105 * the caller will invalidate everything and start over.
106 *
107 * sid > NUM_TIDS indicates a race, which we disable preemption to
108 * avoid.
109 */
110 WARN_ON(sid > NUM_TIDS);
111
112 return ret;
113}
114
115/*
116 * Check if given entry contain a valid shadow id mapping.
117 * An ID mapping is considered valid only if
118 * both vcpu and pcpu know this mapping.
119 *
120 * The caller must have preemption disabled, and keep it that way until
121 * it has finished with the returned shadow id (either written into the
122 * TLB or arch.shadow_pid, or discarded).
123 */
124static inline int local_sid_lookup(struct id *entry)
125{
126 if (entry && entry->val != 0 &&
127 __get_cpu_var(pcpu_sids).entry[entry->val] == entry &&
128 entry->pentry == &__get_cpu_var(pcpu_sids).entry[entry->val])
129 return entry->val;
130 return -1;
131}
132
133/* Invalidate all id mappings on local core -- call with preempt disabled */
134static inline void local_sid_destroy_all(void)
135{
136 __get_cpu_var(pcpu_last_used_sid) = 0;
137 memset(&__get_cpu_var(pcpu_sids), 0, sizeof(__get_cpu_var(pcpu_sids)));
138}
139
140static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500)
141{
142 vcpu_e500->idt = kzalloc(sizeof(struct vcpu_id_table), GFP_KERNEL);
143 return vcpu_e500->idt;
144}
145
146static void kvmppc_e500_id_table_free(struct kvmppc_vcpu_e500 *vcpu_e500)
147{
148 kfree(vcpu_e500->idt);
149}
150
151/* Invalidate all mappings on vcpu */
152static void kvmppc_e500_id_table_reset_all(struct kvmppc_vcpu_e500 *vcpu_e500)
153{
154 memset(vcpu_e500->idt, 0, sizeof(struct vcpu_id_table));
155
156 /* Update shadow pid when mappings are changed */
157 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
158}
159
160/* Invalidate one ID mapping on vcpu */
161static inline void kvmppc_e500_id_table_reset_one(
162 struct kvmppc_vcpu_e500 *vcpu_e500,
163 int as, int pid, int pr)
164{
165 struct vcpu_id_table *idt = vcpu_e500->idt;
166
167 BUG_ON(as >= 2);
168 BUG_ON(pid >= NUM_TIDS);
169 BUG_ON(pr >= 2);
170
171 idt->id[as][pid][pr].val = 0;
172 idt->id[as][pid][pr].pentry = NULL;
173
174 /* Update shadow pid when mappings are changed */
175 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
176}
177
178/*
179 * Map guest (vcpu,AS,ID,PR) to physical core shadow id.
180 * This function first lookup if a valid mapping exists,
181 * if not, then creates a new one.
182 *
183 * The caller must have preemption disabled, and keep it that way until
184 * it has finished with the returned shadow id (either written into the
185 * TLB or arch.shadow_pid, or discarded).
186 */
187static unsigned int kvmppc_e500_get_sid(struct kvmppc_vcpu_e500 *vcpu_e500,
188 unsigned int as, unsigned int gid,
189 unsigned int pr, int avoid_recursion)
190{
191 struct vcpu_id_table *idt = vcpu_e500->idt;
192 int sid;
193
194 BUG_ON(as >= 2);
195 BUG_ON(gid >= NUM_TIDS);
196 BUG_ON(pr >= 2);
197
198 sid = local_sid_lookup(&idt->id[as][gid][pr]);
199
200 while (sid <= 0) {
201 /* No mapping yet */
202 sid = local_sid_setup_one(&idt->id[as][gid][pr]);
203 if (sid <= 0) {
204 _tlbil_all();
205 local_sid_destroy_all();
206 }
207
208 /* Update shadow pid when mappings are changed */
209 if (!avoid_recursion)
210 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
211 }
212
213 return sid;
214}
215
216/* Map guest pid to shadow.
217 * We use PID to keep shadow of current guest non-zero PID,
218 * and use PID1 to keep shadow of guest zero PID.
219 * So that guest tlbe with TID=0 can be accessed at any time */
220void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *vcpu_e500)
221{
222 preempt_disable();
223 vcpu_e500->vcpu.arch.shadow_pid = kvmppc_e500_get_sid(vcpu_e500,
224 get_cur_as(&vcpu_e500->vcpu),
225 get_cur_pid(&vcpu_e500->vcpu),
226 get_cur_pr(&vcpu_e500->vcpu), 1);
227 vcpu_e500->vcpu.arch.shadow_pid1 = kvmppc_e500_get_sid(vcpu_e500,
228 get_cur_as(&vcpu_e500->vcpu), 0,
229 get_cur_pr(&vcpu_e500->vcpu), 1);
230 preempt_enable();
231}
232
233static inline unsigned int gtlb0_get_next_victim( 41static inline unsigned int gtlb0_get_next_victim(
234 struct kvmppc_vcpu_e500 *vcpu_e500) 42 struct kvmppc_vcpu_e500 *vcpu_e500)
235{ 43{
@@ -258,6 +66,7 @@ static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
258 /* Mask off reserved bits. */ 66 /* Mask off reserved bits. */
259 mas3 &= MAS3_ATTRIB_MASK; 67 mas3 &= MAS3_ATTRIB_MASK;
260 68
69#ifndef CONFIG_KVM_BOOKE_HV
261 if (!usermode) { 70 if (!usermode) {
262 /* Guest is in supervisor mode, 71 /* Guest is in supervisor mode,
263 * so we need to translate guest 72 * so we need to translate guest
@@ -265,8 +74,9 @@ static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
265 mas3 &= ~E500_TLB_USER_PERM_MASK; 74 mas3 &= ~E500_TLB_USER_PERM_MASK;
266 mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1; 75 mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1;
267 } 76 }
268 77 mas3 |= E500_TLB_SUPER_PERM_MASK;
269 return mas3 | E500_TLB_SUPER_PERM_MASK; 78#endif
79 return mas3;
270} 80}
271 81
272static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode) 82static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
@@ -292,7 +102,16 @@ static inline void __write_host_tlbe(struct kvm_book3e_206_tlb_entry *stlbe,
292 mtspr(SPRN_MAS2, (unsigned long)stlbe->mas2); 102 mtspr(SPRN_MAS2, (unsigned long)stlbe->mas2);
293 mtspr(SPRN_MAS3, (u32)stlbe->mas7_3); 103 mtspr(SPRN_MAS3, (u32)stlbe->mas7_3);
294 mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32)); 104 mtspr(SPRN_MAS7, (u32)(stlbe->mas7_3 >> 32));
105#ifdef CONFIG_KVM_BOOKE_HV
106 mtspr(SPRN_MAS8, stlbe->mas8);
107#endif
295 asm volatile("isync; tlbwe" : : : "memory"); 108 asm volatile("isync; tlbwe" : : : "memory");
109
110#ifdef CONFIG_KVM_BOOKE_HV
111 /* Must clear mas8 for other host tlbwe's */
112 mtspr(SPRN_MAS8, 0);
113 isync();
114#endif
296 local_irq_restore(flags); 115 local_irq_restore(flags);
297 116
298 trace_kvm_booke206_stlb_write(mas0, stlbe->mas8, stlbe->mas1, 117 trace_kvm_booke206_stlb_write(mas0, stlbe->mas8, stlbe->mas1,
@@ -337,6 +156,7 @@ static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
337 } 156 }
338} 157}
339 158
159#ifdef CONFIG_KVM_E500V2
340void kvmppc_map_magic(struct kvm_vcpu *vcpu) 160void kvmppc_map_magic(struct kvm_vcpu *vcpu)
341{ 161{
342 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 162 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -361,75 +181,41 @@ void kvmppc_map_magic(struct kvm_vcpu *vcpu)
361 __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index)); 181 __write_host_tlbe(&magic, MAS0_TLBSEL(1) | MAS0_ESEL(tlbcam_index));
362 preempt_enable(); 182 preempt_enable();
363} 183}
364 184#endif
365void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
366{
367 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
368
369 /* Shadow PID may be expired on local core */
370 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
371}
372
373void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu)
374{
375}
376 185
377static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, 186static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500,
378 int tlbsel, int esel) 187 int tlbsel, int esel)
379{ 188{
380 struct kvm_book3e_206_tlb_entry *gtlbe = 189 struct kvm_book3e_206_tlb_entry *gtlbe =
381 get_entry(vcpu_e500, tlbsel, esel); 190 get_entry(vcpu_e500, tlbsel, esel);
382 struct vcpu_id_table *idt = vcpu_e500->idt;
383 unsigned int pr, tid, ts, pid;
384 u32 val, eaddr;
385 unsigned long flags;
386
387 ts = get_tlb_ts(gtlbe);
388 tid = get_tlb_tid(gtlbe);
389
390 preempt_disable();
391
392 /* One guest ID may be mapped to two shadow IDs */
393 for (pr = 0; pr < 2; pr++) {
394 /*
395 * The shadow PID can have a valid mapping on at most one
396 * host CPU. In the common case, it will be valid on this
397 * CPU, in which case (for TLB0) we do a local invalidation
398 * of the specific address.
399 *
400 * If the shadow PID is not valid on the current host CPU, or
401 * if we're invalidating a TLB1 entry, we invalidate the
402 * entire shadow PID.
403 */
404 if (tlbsel == 1 ||
405 (pid = local_sid_lookup(&idt->id[ts][tid][pr])) <= 0) {
406 kvmppc_e500_id_table_reset_one(vcpu_e500, ts, tid, pr);
407 continue;
408 }
409 191
410 /* 192 if (tlbsel == 1 &&
411 * The guest is invalidating a TLB0 entry which is in a PID 193 vcpu_e500->gtlb_priv[1][esel].ref.flags & E500_TLB_BITMAP) {
412 * that has a valid shadow mapping on this host CPU. We 194 u64 tmp = vcpu_e500->g2h_tlb1_map[esel];
413 * search host TLB0 to invalidate it's shadow TLB entry, 195 int hw_tlb_indx;
414 * similar to __tlbil_va except that we need to look in AS1. 196 unsigned long flags;
415 */
416 val = (pid << MAS6_SPID_SHIFT) | MAS6_SAS;
417 eaddr = get_tlb_eaddr(gtlbe);
418 197
419 local_irq_save(flags); 198 local_irq_save(flags);
420 199 while (tmp) {
421 mtspr(SPRN_MAS6, val); 200 hw_tlb_indx = __ilog2_u64(tmp & -tmp);
422 asm volatile("tlbsx 0, %[eaddr]" : : [eaddr] "r" (eaddr)); 201 mtspr(SPRN_MAS0,
423 val = mfspr(SPRN_MAS1); 202 MAS0_TLBSEL(1) |
424 if (val & MAS1_VALID) { 203 MAS0_ESEL(to_htlb1_esel(hw_tlb_indx)));
425 mtspr(SPRN_MAS1, val & ~MAS1_VALID); 204 mtspr(SPRN_MAS1, 0);
426 asm volatile("tlbwe"); 205 asm volatile("tlbwe");
206 vcpu_e500->h2g_tlb1_rmap[hw_tlb_indx] = 0;
207 tmp &= tmp - 1;
427 } 208 }
428 209 mb();
210 vcpu_e500->g2h_tlb1_map[esel] = 0;
211 vcpu_e500->gtlb_priv[1][esel].ref.flags &= ~E500_TLB_BITMAP;
429 local_irq_restore(flags); 212 local_irq_restore(flags);
213
214 return;
430 } 215 }
431 216
432 preempt_enable(); 217 /* Guest tlbe is backed by at most one host tlbe per shadow pid. */
218 kvmppc_e500_tlbil_one(vcpu_e500, gtlbe);
433} 219}
434 220
435static int tlb0_set_base(gva_t addr, int sets, int ways) 221static int tlb0_set_base(gva_t addr, int sets, int ways)
@@ -475,6 +261,9 @@ static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
475 set_base = gtlb0_set_base(vcpu_e500, eaddr); 261 set_base = gtlb0_set_base(vcpu_e500, eaddr);
476 size = vcpu_e500->gtlb_params[0].ways; 262 size = vcpu_e500->gtlb_params[0].ways;
477 } else { 263 } else {
264 if (eaddr < vcpu_e500->tlb1_min_eaddr ||
265 eaddr > vcpu_e500->tlb1_max_eaddr)
266 return -1;
478 set_base = 0; 267 set_base = 0;
479 } 268 }
480 269
@@ -530,6 +319,16 @@ static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)
530 } 319 }
531} 320}
532 321
322static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500)
323{
324 if (vcpu_e500->g2h_tlb1_map)
325 memset(vcpu_e500->g2h_tlb1_map,
326 sizeof(u64) * vcpu_e500->gtlb_params[1].entries, 0);
327 if (vcpu_e500->h2g_tlb1_rmap)
328 memset(vcpu_e500->h2g_tlb1_rmap,
329 sizeof(unsigned int) * host_tlb_params[1].entries, 0);
330}
331
533static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) 332static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500)
534{ 333{
535 int tlbsel = 0; 334 int tlbsel = 0;
@@ -547,7 +346,7 @@ static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500)
547 int stlbsel = 1; 346 int stlbsel = 1;
548 int i; 347 int i;
549 348
550 kvmppc_e500_id_table_reset_all(vcpu_e500); 349 kvmppc_e500_tlbil_all(vcpu_e500);
551 350
552 for (i = 0; i < host_tlb_params[stlbsel].entries; i++) { 351 for (i = 0; i < host_tlb_params[stlbsel].entries; i++) {
553 struct tlbe_ref *ref = 352 struct tlbe_ref *ref =
@@ -562,19 +361,18 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
562 unsigned int eaddr, int as) 361 unsigned int eaddr, int as)
563{ 362{
564 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 363 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
565 unsigned int victim, pidsel, tsized; 364 unsigned int victim, tsized;
566 int tlbsel; 365 int tlbsel;
567 366
568 /* since we only have two TLBs, only lower bit is used. */ 367 /* since we only have two TLBs, only lower bit is used. */
569 tlbsel = (vcpu->arch.shared->mas4 >> 28) & 0x1; 368 tlbsel = (vcpu->arch.shared->mas4 >> 28) & 0x1;
570 victim = (tlbsel == 0) ? gtlb0_get_next_victim(vcpu_e500) : 0; 369 victim = (tlbsel == 0) ? gtlb0_get_next_victim(vcpu_e500) : 0;
571 pidsel = (vcpu->arch.shared->mas4 >> 16) & 0xf;
572 tsized = (vcpu->arch.shared->mas4 >> 7) & 0x1f; 370 tsized = (vcpu->arch.shared->mas4 >> 7) & 0x1f;
573 371
574 vcpu->arch.shared->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) 372 vcpu->arch.shared->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
575 | MAS0_NV(vcpu_e500->gtlb_nv[tlbsel]); 373 | MAS0_NV(vcpu_e500->gtlb_nv[tlbsel]);
576 vcpu->arch.shared->mas1 = MAS1_VALID | (as ? MAS1_TS : 0) 374 vcpu->arch.shared->mas1 = MAS1_VALID | (as ? MAS1_TS : 0)
577 | MAS1_TID(vcpu_e500->pid[pidsel]) 375 | MAS1_TID(get_tlbmiss_tid(vcpu))
578 | MAS1_TSIZE(tsized); 376 | MAS1_TSIZE(tsized);
579 vcpu->arch.shared->mas2 = (eaddr & MAS2_EPN) 377 vcpu->arch.shared->mas2 = (eaddr & MAS2_EPN)
580 | (vcpu->arch.shared->mas4 & MAS2_ATTRIB_MASK); 378 | (vcpu->arch.shared->mas4 & MAS2_ATTRIB_MASK);
@@ -586,23 +384,26 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
586 384
587/* TID must be supplied by the caller */ 385/* TID must be supplied by the caller */
588static inline void kvmppc_e500_setup_stlbe( 386static inline void kvmppc_e500_setup_stlbe(
589 struct kvmppc_vcpu_e500 *vcpu_e500, 387 struct kvm_vcpu *vcpu,
590 struct kvm_book3e_206_tlb_entry *gtlbe, 388 struct kvm_book3e_206_tlb_entry *gtlbe,
591 int tsize, struct tlbe_ref *ref, u64 gvaddr, 389 int tsize, struct tlbe_ref *ref, u64 gvaddr,
592 struct kvm_book3e_206_tlb_entry *stlbe) 390 struct kvm_book3e_206_tlb_entry *stlbe)
593{ 391{
594 pfn_t pfn = ref->pfn; 392 pfn_t pfn = ref->pfn;
393 u32 pr = vcpu->arch.shared->msr & MSR_PR;
595 394
596 BUG_ON(!(ref->flags & E500_TLB_VALID)); 395 BUG_ON(!(ref->flags & E500_TLB_VALID));
597 396
598 /* Force TS=1 IPROT=0 for all guest mappings. */ 397 /* Force IPROT=0 for all guest mappings. */
599 stlbe->mas1 = MAS1_TSIZE(tsize) | MAS1_TS | MAS1_VALID; 398 stlbe->mas1 = MAS1_TSIZE(tsize) | get_tlb_sts(gtlbe) | MAS1_VALID;
600 stlbe->mas2 = (gvaddr & MAS2_EPN) 399 stlbe->mas2 = (gvaddr & MAS2_EPN) |
601 | e500_shadow_mas2_attrib(gtlbe->mas2, 400 e500_shadow_mas2_attrib(gtlbe->mas2, pr);
602 vcpu_e500->vcpu.arch.shared->msr & MSR_PR); 401 stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) |
603 stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) 402 e500_shadow_mas3_attrib(gtlbe->mas7_3, pr);
604 | e500_shadow_mas3_attrib(gtlbe->mas7_3, 403
605 vcpu_e500->vcpu.arch.shared->msr & MSR_PR); 404#ifdef CONFIG_KVM_BOOKE_HV
405 stlbe->mas8 = MAS8_TGS | vcpu->kvm->arch.lpid;
406#endif
606} 407}
607 408
608static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, 409static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -736,7 +537,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
736 kvmppc_e500_ref_release(ref); 537 kvmppc_e500_ref_release(ref);
737 kvmppc_e500_ref_setup(ref, gtlbe, pfn); 538 kvmppc_e500_ref_setup(ref, gtlbe, pfn);
738 539
739 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, tsize, ref, gvaddr, stlbe); 540 kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize,
541 ref, gvaddr, stlbe);
740} 542}
741 543
742/* XXX only map the one-one case, for now use TLB0 */ 544/* XXX only map the one-one case, for now use TLB0 */
@@ -760,7 +562,7 @@ static void kvmppc_e500_tlb0_map(struct kvmppc_vcpu_e500 *vcpu_e500,
760/* XXX for both one-one and one-to-many , for now use TLB1 */ 562/* XXX for both one-one and one-to-many , for now use TLB1 */
761static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, 563static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
762 u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, 564 u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe,
763 struct kvm_book3e_206_tlb_entry *stlbe) 565 struct kvm_book3e_206_tlb_entry *stlbe, int esel)
764{ 566{
765 struct tlbe_ref *ref; 567 struct tlbe_ref *ref;
766 unsigned int victim; 568 unsigned int victim;
@@ -773,15 +575,74 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
773 ref = &vcpu_e500->tlb_refs[1][victim]; 575 ref = &vcpu_e500->tlb_refs[1][victim];
774 kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, ref); 576 kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, ref);
775 577
578 vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << victim;
579 vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP;
580 if (vcpu_e500->h2g_tlb1_rmap[victim]) {
581 unsigned int idx = vcpu_e500->h2g_tlb1_rmap[victim];
582 vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << victim);
583 }
584 vcpu_e500->h2g_tlb1_rmap[victim] = esel;
585
776 return victim; 586 return victim;
777} 587}
778 588
779void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) 589static void kvmppc_recalc_tlb1map_range(struct kvmppc_vcpu_e500 *vcpu_e500)
590{
591 int size = vcpu_e500->gtlb_params[1].entries;
592 unsigned int offset;
593 gva_t eaddr;
594 int i;
595
596 vcpu_e500->tlb1_min_eaddr = ~0UL;
597 vcpu_e500->tlb1_max_eaddr = 0;
598 offset = vcpu_e500->gtlb_offset[1];
599
600 for (i = 0; i < size; i++) {
601 struct kvm_book3e_206_tlb_entry *tlbe =
602 &vcpu_e500->gtlb_arch[offset + i];
603
604 if (!get_tlb_v(tlbe))
605 continue;
606
607 eaddr = get_tlb_eaddr(tlbe);
608 vcpu_e500->tlb1_min_eaddr =
609 min(vcpu_e500->tlb1_min_eaddr, eaddr);
610
611 eaddr = get_tlb_end(tlbe);
612 vcpu_e500->tlb1_max_eaddr =
613 max(vcpu_e500->tlb1_max_eaddr, eaddr);
614 }
615}
616
617static int kvmppc_need_recalc_tlb1map_range(struct kvmppc_vcpu_e500 *vcpu_e500,
618 struct kvm_book3e_206_tlb_entry *gtlbe)
780{ 619{
620 unsigned long start, end, size;
621
622 size = get_tlb_bytes(gtlbe);
623 start = get_tlb_eaddr(gtlbe) & ~(size - 1);
624 end = start + size - 1;
625
626 return vcpu_e500->tlb1_min_eaddr == start ||
627 vcpu_e500->tlb1_max_eaddr == end;
628}
629
630/* This function is supposed to be called for a adding a new valid tlb entry */
631static void kvmppc_set_tlb1map_range(struct kvm_vcpu *vcpu,
632 struct kvm_book3e_206_tlb_entry *gtlbe)
633{
634 unsigned long start, end, size;
781 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 635 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
782 636
783 /* Recalc shadow pid since MSR changes */ 637 if (!get_tlb_v(gtlbe))
784 kvmppc_e500_recalc_shadow_pid(vcpu_e500); 638 return;
639
640 size = get_tlb_bytes(gtlbe);
641 start = get_tlb_eaddr(gtlbe) & ~(size - 1);
642 end = start + size - 1;
643
644 vcpu_e500->tlb1_min_eaddr = min(vcpu_e500->tlb1_min_eaddr, start);
645 vcpu_e500->tlb1_max_eaddr = max(vcpu_e500->tlb1_max_eaddr, end);
785} 646}
786 647
787static inline int kvmppc_e500_gtlbe_invalidate( 648static inline int kvmppc_e500_gtlbe_invalidate(
@@ -794,6 +655,9 @@ static inline int kvmppc_e500_gtlbe_invalidate(
794 if (unlikely(get_tlb_iprot(gtlbe))) 655 if (unlikely(get_tlb_iprot(gtlbe)))
795 return -1; 656 return -1;
796 657
658 if (tlbsel == 1 && kvmppc_need_recalc_tlb1map_range(vcpu_e500, gtlbe))
659 kvmppc_recalc_tlb1map_range(vcpu_e500);
660
797 gtlbe->mas1 = 0; 661 gtlbe->mas1 = 0;
798 662
799 return 0; 663 return 0;
@@ -811,7 +675,7 @@ int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500, ulong value)
811 kvmppc_e500_gtlbe_invalidate(vcpu_e500, 1, esel); 675 kvmppc_e500_gtlbe_invalidate(vcpu_e500, 1, esel);
812 676
813 /* Invalidate all vcpu id mappings */ 677 /* Invalidate all vcpu id mappings */
814 kvmppc_e500_id_table_reset_all(vcpu_e500); 678 kvmppc_e500_tlbil_all(vcpu_e500);
815 679
816 return EMULATE_DONE; 680 return EMULATE_DONE;
817} 681}
@@ -844,7 +708,59 @@ int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb)
844 } 708 }
845 709
846 /* Invalidate all vcpu id mappings */ 710 /* Invalidate all vcpu id mappings */
847 kvmppc_e500_id_table_reset_all(vcpu_e500); 711 kvmppc_e500_tlbil_all(vcpu_e500);
712
713 return EMULATE_DONE;
714}
715
716static void tlbilx_all(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel,
717 int pid, int rt)
718{
719 struct kvm_book3e_206_tlb_entry *tlbe;
720 int tid, esel;
721
722 /* invalidate all entries */
723 for (esel = 0; esel < vcpu_e500->gtlb_params[tlbsel].entries; esel++) {
724 tlbe = get_entry(vcpu_e500, tlbsel, esel);
725 tid = get_tlb_tid(tlbe);
726 if (rt == 0 || tid == pid) {
727 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
728 kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
729 }
730 }
731}
732
733static void tlbilx_one(struct kvmppc_vcpu_e500 *vcpu_e500, int pid,
734 int ra, int rb)
735{
736 int tlbsel, esel;
737 gva_t ea;
738
739 ea = kvmppc_get_gpr(&vcpu_e500->vcpu, rb);
740 if (ra)
741 ea += kvmppc_get_gpr(&vcpu_e500->vcpu, ra);
742
743 for (tlbsel = 0; tlbsel < 2; tlbsel++) {
744 esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, -1);
745 if (esel >= 0) {
746 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
747 kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
748 break;
749 }
750 }
751}
752
753int kvmppc_e500_emul_tlbilx(struct kvm_vcpu *vcpu, int rt, int ra, int rb)
754{
755 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
756 int pid = get_cur_spid(vcpu);
757
758 if (rt == 0 || rt == 1) {
759 tlbilx_all(vcpu_e500, 0, pid, rt);
760 tlbilx_all(vcpu_e500, 1, pid, rt);
761 } else if (rt == 3) {
762 tlbilx_one(vcpu_e500, pid, ra, rb);
763 }
848 764
849 return EMULATE_DONE; 765 return EMULATE_DONE;
850} 766}
@@ -929,9 +845,7 @@ static void write_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
929 int stid; 845 int stid;
930 846
931 preempt_disable(); 847 preempt_disable();
932 stid = kvmppc_e500_get_sid(vcpu_e500, get_tlb_ts(gtlbe), 848 stid = kvmppc_e500_get_tlb_stid(&vcpu_e500->vcpu, gtlbe);
933 get_tlb_tid(gtlbe),
934 get_cur_pr(&vcpu_e500->vcpu), 0);
935 849
936 stlbe->mas1 |= MAS1_TID(stid); 850 stlbe->mas1 |= MAS1_TID(stid);
937 write_host_tlbe(vcpu_e500, stlbsel, sesel, stlbe); 851 write_host_tlbe(vcpu_e500, stlbsel, sesel, stlbe);
@@ -941,16 +855,21 @@ static void write_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
941int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu) 855int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
942{ 856{
943 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 857 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
944 struct kvm_book3e_206_tlb_entry *gtlbe; 858 struct kvm_book3e_206_tlb_entry *gtlbe, stlbe;
945 int tlbsel, esel; 859 int tlbsel, esel, stlbsel, sesel;
860 int recal = 0;
946 861
947 tlbsel = get_tlb_tlbsel(vcpu); 862 tlbsel = get_tlb_tlbsel(vcpu);
948 esel = get_tlb_esel(vcpu, tlbsel); 863 esel = get_tlb_esel(vcpu, tlbsel);
949 864
950 gtlbe = get_entry(vcpu_e500, tlbsel, esel); 865 gtlbe = get_entry(vcpu_e500, tlbsel, esel);
951 866
952 if (get_tlb_v(gtlbe)) 867 if (get_tlb_v(gtlbe)) {
953 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel); 868 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
869 if ((tlbsel == 1) &&
870 kvmppc_need_recalc_tlb1map_range(vcpu_e500, gtlbe))
871 recal = 1;
872 }
954 873
955 gtlbe->mas1 = vcpu->arch.shared->mas1; 874 gtlbe->mas1 = vcpu->arch.shared->mas1;
956 gtlbe->mas2 = vcpu->arch.shared->mas2; 875 gtlbe->mas2 = vcpu->arch.shared->mas2;
@@ -959,10 +878,20 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
959 trace_kvm_booke206_gtlb_write(vcpu->arch.shared->mas0, gtlbe->mas1, 878 trace_kvm_booke206_gtlb_write(vcpu->arch.shared->mas0, gtlbe->mas1,
960 gtlbe->mas2, gtlbe->mas7_3); 879 gtlbe->mas2, gtlbe->mas7_3);
961 880
881 if (tlbsel == 1) {
882 /*
883 * If a valid tlb1 entry is overwritten then recalculate the
884 * min/max TLB1 map address range otherwise no need to look
885 * in tlb1 array.
886 */
887 if (recal)
888 kvmppc_recalc_tlb1map_range(vcpu_e500);
889 else
890 kvmppc_set_tlb1map_range(vcpu, gtlbe);
891 }
892
962 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */ 893 /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
963 if (tlbe_is_host_safe(vcpu, gtlbe)) { 894 if (tlbe_is_host_safe(vcpu, gtlbe)) {
964 struct kvm_book3e_206_tlb_entry stlbe;
965 int stlbsel, sesel;
966 u64 eaddr; 895 u64 eaddr;
967 u64 raddr; 896 u64 raddr;
968 897
@@ -989,7 +918,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
989 * are mapped on the fly. */ 918 * are mapped on the fly. */
990 stlbsel = 1; 919 stlbsel = 1;
991 sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr, 920 sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr,
992 raddr >> PAGE_SHIFT, gtlbe, &stlbe); 921 raddr >> PAGE_SHIFT, gtlbe, &stlbe, esel);
993 break; 922 break;
994 923
995 default: 924 default:
@@ -1003,6 +932,48 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
1003 return EMULATE_DONE; 932 return EMULATE_DONE;
1004} 933}
1005 934
935static int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
936 gva_t eaddr, unsigned int pid, int as)
937{
938 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
939 int esel, tlbsel;
940
941 for (tlbsel = 0; tlbsel < 2; tlbsel++) {
942 esel = kvmppc_e500_tlb_index(vcpu_e500, eaddr, tlbsel, pid, as);
943 if (esel >= 0)
944 return index_of(tlbsel, esel);
945 }
946
947 return -1;
948}
949
950/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
951int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
952 struct kvm_translation *tr)
953{
954 int index;
955 gva_t eaddr;
956 u8 pid;
957 u8 as;
958
959 eaddr = tr->linear_address;
960 pid = (tr->linear_address >> 32) & 0xff;
961 as = (tr->linear_address >> 40) & 0x1;
962
963 index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
964 if (index < 0) {
965 tr->valid = 0;
966 return 0;
967 }
968
969 tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
970 /* XXX what does "writeable" and "usermode" even mean? */
971 tr->valid = 1;
972
973 return 0;
974}
975
976
1006int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr) 977int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
1007{ 978{
1008 unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS); 979 unsigned int as = !!(vcpu->arch.shared->msr & MSR_IS);
@@ -1066,7 +1037,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
1066 sesel = 0; /* unused */ 1037 sesel = 0; /* unused */
1067 priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; 1038 priv = &vcpu_e500->gtlb_priv[tlbsel][esel];
1068 1039
1069 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, BOOK3E_PAGESZ_4K, 1040 kvmppc_e500_setup_stlbe(vcpu, gtlbe, BOOK3E_PAGESZ_4K,
1070 &priv->ref, eaddr, &stlbe); 1041 &priv->ref, eaddr, &stlbe);
1071 break; 1042 break;
1072 1043
@@ -1075,7 +1046,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
1075 1046
1076 stlbsel = 1; 1047 stlbsel = 1;
1077 sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr, gfn, 1048 sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr, gfn,
1078 gtlbe, &stlbe); 1049 gtlbe, &stlbe, esel);
1079 break; 1050 break;
1080 } 1051 }
1081 1052
@@ -1087,52 +1058,13 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
1087 write_stlbe(vcpu_e500, gtlbe, &stlbe, stlbsel, sesel); 1058 write_stlbe(vcpu_e500, gtlbe, &stlbe, stlbsel, sesel);
1088} 1059}
1089 1060
1090int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
1091 gva_t eaddr, unsigned int pid, int as)
1092{
1093 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
1094 int esel, tlbsel;
1095
1096 for (tlbsel = 0; tlbsel < 2; tlbsel++) {
1097 esel = kvmppc_e500_tlb_index(vcpu_e500, eaddr, tlbsel, pid, as);
1098 if (esel >= 0)
1099 return index_of(tlbsel, esel);
1100 }
1101
1102 return -1;
1103}
1104
1105void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
1106{
1107 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
1108
1109 if (vcpu->arch.pid != pid) {
1110 vcpu_e500->pid[0] = vcpu->arch.pid = pid;
1111 kvmppc_e500_recalc_shadow_pid(vcpu_e500);
1112 }
1113}
1114
1115void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
1116{
1117 struct kvm_book3e_206_tlb_entry *tlbe;
1118
1119 /* Insert large initial mapping for guest. */
1120 tlbe = get_entry(vcpu_e500, 1, 0);
1121 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M);
1122 tlbe->mas2 = 0;
1123 tlbe->mas7_3 = E500_TLB_SUPER_PERM_MASK;
1124
1125 /* 4K map for serial output. Used by kernel wrapper. */
1126 tlbe = get_entry(vcpu_e500, 1, 1);
1127 tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K);
1128 tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
1129 tlbe->mas7_3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
1130}
1131
1132static void free_gtlb(struct kvmppc_vcpu_e500 *vcpu_e500) 1061static void free_gtlb(struct kvmppc_vcpu_e500 *vcpu_e500)
1133{ 1062{
1134 int i; 1063 int i;
1135 1064
1065 clear_tlb1_bitmap(vcpu_e500);
1066 kfree(vcpu_e500->g2h_tlb1_map);
1067
1136 clear_tlb_refs(vcpu_e500); 1068 clear_tlb_refs(vcpu_e500);
1137 kfree(vcpu_e500->gtlb_priv[0]); 1069 kfree(vcpu_e500->gtlb_priv[0]);
1138 kfree(vcpu_e500->gtlb_priv[1]); 1070 kfree(vcpu_e500->gtlb_priv[1]);
@@ -1155,6 +1087,36 @@ static void free_gtlb(struct kvmppc_vcpu_e500 *vcpu_e500)
1155 vcpu_e500->gtlb_arch = NULL; 1087 vcpu_e500->gtlb_arch = NULL;
1156} 1088}
1157 1089
1090void kvmppc_get_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
1091{
1092 sregs->u.e.mas0 = vcpu->arch.shared->mas0;
1093 sregs->u.e.mas1 = vcpu->arch.shared->mas1;
1094 sregs->u.e.mas2 = vcpu->arch.shared->mas2;
1095 sregs->u.e.mas7_3 = vcpu->arch.shared->mas7_3;
1096 sregs->u.e.mas4 = vcpu->arch.shared->mas4;
1097 sregs->u.e.mas6 = vcpu->arch.shared->mas6;
1098
1099 sregs->u.e.mmucfg = vcpu->arch.mmucfg;
1100 sregs->u.e.tlbcfg[0] = vcpu->arch.tlbcfg[0];
1101 sregs->u.e.tlbcfg[1] = vcpu->arch.tlbcfg[1];
1102 sregs->u.e.tlbcfg[2] = 0;
1103 sregs->u.e.tlbcfg[3] = 0;
1104}
1105
1106int kvmppc_set_sregs_e500_tlb(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
1107{
1108 if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) {
1109 vcpu->arch.shared->mas0 = sregs->u.e.mas0;
1110 vcpu->arch.shared->mas1 = sregs->u.e.mas1;
1111 vcpu->arch.shared->mas2 = sregs->u.e.mas2;
1112 vcpu->arch.shared->mas7_3 = sregs->u.e.mas7_3;
1113 vcpu->arch.shared->mas4 = sregs->u.e.mas4;
1114 vcpu->arch.shared->mas6 = sregs->u.e.mas6;
1115 }
1116
1117 return 0;
1118}
1119
1158int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, 1120int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
1159 struct kvm_config_tlb *cfg) 1121 struct kvm_config_tlb *cfg)
1160{ 1122{
@@ -1163,6 +1125,7 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
1163 char *virt; 1125 char *virt;
1164 struct page **pages; 1126 struct page **pages;
1165 struct tlbe_priv *privs[2] = {}; 1127 struct tlbe_priv *privs[2] = {};
1128 u64 *g2h_bitmap = NULL;
1166 size_t array_len; 1129 size_t array_len;
1167 u32 sets; 1130 u32 sets;
1168 int num_pages, ret, i; 1131 int num_pages, ret, i;
@@ -1224,10 +1187,16 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
1224 if (!privs[0] || !privs[1]) 1187 if (!privs[0] || !privs[1])
1225 goto err_put_page; 1188 goto err_put_page;
1226 1189
1190 g2h_bitmap = kzalloc(sizeof(u64) * params.tlb_sizes[1],
1191 GFP_KERNEL);
1192 if (!g2h_bitmap)
1193 goto err_put_page;
1194
1227 free_gtlb(vcpu_e500); 1195 free_gtlb(vcpu_e500);
1228 1196
1229 vcpu_e500->gtlb_priv[0] = privs[0]; 1197 vcpu_e500->gtlb_priv[0] = privs[0];
1230 vcpu_e500->gtlb_priv[1] = privs[1]; 1198 vcpu_e500->gtlb_priv[1] = privs[1];
1199 vcpu_e500->g2h_tlb1_map = g2h_bitmap;
1231 1200
1232 vcpu_e500->gtlb_arch = (struct kvm_book3e_206_tlb_entry *) 1201 vcpu_e500->gtlb_arch = (struct kvm_book3e_206_tlb_entry *)
1233 (virt + (cfg->array & (PAGE_SIZE - 1))); 1202 (virt + (cfg->array & (PAGE_SIZE - 1)));
@@ -1238,14 +1207,16 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
1238 vcpu_e500->gtlb_offset[0] = 0; 1207 vcpu_e500->gtlb_offset[0] = 0;
1239 vcpu_e500->gtlb_offset[1] = params.tlb_sizes[0]; 1208 vcpu_e500->gtlb_offset[1] = params.tlb_sizes[0];
1240 1209
1241 vcpu_e500->tlb0cfg &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); 1210 vcpu->arch.mmucfg = mfspr(SPRN_MMUCFG) & ~MMUCFG_LPIDSIZE;
1211
1212 vcpu->arch.tlbcfg[0] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
1242 if (params.tlb_sizes[0] <= 2048) 1213 if (params.tlb_sizes[0] <= 2048)
1243 vcpu_e500->tlb0cfg |= params.tlb_sizes[0]; 1214 vcpu->arch.tlbcfg[0] |= params.tlb_sizes[0];
1244 vcpu_e500->tlb0cfg |= params.tlb_ways[0] << TLBnCFG_ASSOC_SHIFT; 1215 vcpu->arch.tlbcfg[0] |= params.tlb_ways[0] << TLBnCFG_ASSOC_SHIFT;
1245 1216
1246 vcpu_e500->tlb1cfg &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); 1217 vcpu->arch.tlbcfg[1] &= ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
1247 vcpu_e500->tlb1cfg |= params.tlb_sizes[1]; 1218 vcpu->arch.tlbcfg[1] |= params.tlb_sizes[1];
1248 vcpu_e500->tlb1cfg |= params.tlb_ways[1] << TLBnCFG_ASSOC_SHIFT; 1219 vcpu->arch.tlbcfg[1] |= params.tlb_ways[1] << TLBnCFG_ASSOC_SHIFT;
1249 1220
1250 vcpu_e500->shared_tlb_pages = pages; 1221 vcpu_e500->shared_tlb_pages = pages;
1251 vcpu_e500->num_shared_tlb_pages = num_pages; 1222 vcpu_e500->num_shared_tlb_pages = num_pages;
@@ -1256,6 +1227,7 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu,
1256 vcpu_e500->gtlb_params[1].ways = params.tlb_sizes[1]; 1227 vcpu_e500->gtlb_params[1].ways = params.tlb_sizes[1];
1257 vcpu_e500->gtlb_params[1].sets = 1; 1228 vcpu_e500->gtlb_params[1].sets = 1;
1258 1229
1230 kvmppc_recalc_tlb1map_range(vcpu_e500);
1259 return 0; 1231 return 0;
1260 1232
1261err_put_page: 1233err_put_page:
@@ -1274,13 +1246,14 @@ int kvm_vcpu_ioctl_dirty_tlb(struct kvm_vcpu *vcpu,
1274 struct kvm_dirty_tlb *dirty) 1246 struct kvm_dirty_tlb *dirty)
1275{ 1247{
1276 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 1248 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
1277 1249 kvmppc_recalc_tlb1map_range(vcpu_e500);
1278 clear_tlb_refs(vcpu_e500); 1250 clear_tlb_refs(vcpu_e500);
1279 return 0; 1251 return 0;
1280} 1252}
1281 1253
1282int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500) 1254int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
1283{ 1255{
1256 struct kvm_vcpu *vcpu = &vcpu_e500->vcpu;
1284 int entry_size = sizeof(struct kvm_book3e_206_tlb_entry); 1257 int entry_size = sizeof(struct kvm_book3e_206_tlb_entry);
1285 int entries = KVM_E500_TLB0_SIZE + KVM_E500_TLB1_SIZE; 1258 int entries = KVM_E500_TLB0_SIZE + KVM_E500_TLB1_SIZE;
1286 1259
@@ -1357,22 +1330,32 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
1357 if (!vcpu_e500->gtlb_priv[1]) 1330 if (!vcpu_e500->gtlb_priv[1])
1358 goto err; 1331 goto err;
1359 1332
1360 if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) 1333 vcpu_e500->g2h_tlb1_map = kzalloc(sizeof(unsigned int) *
1334 vcpu_e500->gtlb_params[1].entries,
1335 GFP_KERNEL);
1336 if (!vcpu_e500->g2h_tlb1_map)
1337 goto err;
1338
1339 vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) *
1340 host_tlb_params[1].entries,
1341 GFP_KERNEL);
1342 if (!vcpu_e500->h2g_tlb1_rmap)
1361 goto err; 1343 goto err;
1362 1344
1363 /* Init TLB configuration register */ 1345 /* Init TLB configuration register */
1364 vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & 1346 vcpu->arch.tlbcfg[0] = mfspr(SPRN_TLB0CFG) &
1365 ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); 1347 ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
1366 vcpu_e500->tlb0cfg |= vcpu_e500->gtlb_params[0].entries; 1348 vcpu->arch.tlbcfg[0] |= vcpu_e500->gtlb_params[0].entries;
1367 vcpu_e500->tlb0cfg |= 1349 vcpu->arch.tlbcfg[0] |=
1368 vcpu_e500->gtlb_params[0].ways << TLBnCFG_ASSOC_SHIFT; 1350 vcpu_e500->gtlb_params[0].ways << TLBnCFG_ASSOC_SHIFT;
1369 1351
1370 vcpu_e500->tlb1cfg = mfspr(SPRN_TLB1CFG) & 1352 vcpu->arch.tlbcfg[1] = mfspr(SPRN_TLB1CFG) &
1371 ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC); 1353 ~(TLBnCFG_N_ENTRY | TLBnCFG_ASSOC);
1372 vcpu_e500->tlb0cfg |= vcpu_e500->gtlb_params[1].entries; 1354 vcpu->arch.tlbcfg[1] |= vcpu_e500->gtlb_params[1].entries;
1373 vcpu_e500->tlb0cfg |= 1355 vcpu->arch.tlbcfg[1] |=
1374 vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT; 1356 vcpu_e500->gtlb_params[1].ways << TLBnCFG_ASSOC_SHIFT;
1375 1357
1358 kvmppc_recalc_tlb1map_range(vcpu_e500);
1376 return 0; 1359 return 0;
1377 1360
1378err: 1361err:
@@ -1385,8 +1368,7 @@ err:
1385void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) 1368void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500)
1386{ 1369{
1387 free_gtlb(vcpu_e500); 1370 free_gtlb(vcpu_e500);
1388 kvmppc_e500_id_table_free(vcpu_e500); 1371 kfree(vcpu_e500->h2g_tlb1_rmap);
1389
1390 kfree(vcpu_e500->tlb_refs[0]); 1372 kfree(vcpu_e500->tlb_refs[0]);
1391 kfree(vcpu_e500->tlb_refs[1]); 1373 kfree(vcpu_e500->tlb_refs[1]);
1392} 1374}
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
deleted file mode 100644
index 5c6d2d7bf05..00000000000
--- a/arch/powerpc/kvm/e500_tlb.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Yu Liu, yu.liu@freescale.com
5 *
6 * Description:
7 * This file is based on arch/powerpc/kvm/44x_tlb.h,
8 * by Hollis Blanchard <hollisb@us.ibm.com>.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __KVM_E500_TLB_H__
16#define __KVM_E500_TLB_H__
17
18#include <linux/kvm_host.h>
19#include <asm/mmu-book3e.h>
20#include <asm/tlb.h>
21#include <asm/kvm_e500.h>
22
23/* This geometry is the legacy default -- can be overridden by userspace */
24#define KVM_E500_TLB0_WAY_SIZE 128
25#define KVM_E500_TLB0_WAY_NUM 2
26
27#define KVM_E500_TLB0_SIZE (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
28#define KVM_E500_TLB1_SIZE 16
29
30#define index_of(tlbsel, esel) (((tlbsel) << 16) | ((esel) & 0xFFFF))
31#define tlbsel_of(index) ((index) >> 16)
32#define esel_of(index) ((index) & 0xFFFF)
33
34#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
35#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
36#define MAS2_ATTRIB_MASK \
37 (MAS2_X0 | MAS2_X1)
38#define MAS3_ATTRIB_MASK \
39 (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
40 | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)
41
42extern void kvmppc_dump_tlbs(struct kvm_vcpu *);
43extern int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *, ulong);
44extern int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *);
45extern int kvmppc_e500_emul_tlbre(struct kvm_vcpu *);
46extern int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *, int, int);
47extern int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *, int);
48extern int kvmppc_e500_tlb_search(struct kvm_vcpu *, gva_t, unsigned int, int);
49extern void kvmppc_e500_tlb_put(struct kvm_vcpu *);
50extern void kvmppc_e500_tlb_load(struct kvm_vcpu *, int);
51extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *);
52extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *);
53extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
54extern void kvmppc_e500_recalc_shadow_pid(struct kvmppc_vcpu_e500 *);
55
56/* TLB helper functions */
57static inline unsigned int
58get_tlb_size(const struct kvm_book3e_206_tlb_entry *tlbe)
59{
60 return (tlbe->mas1 >> 7) & 0x1f;
61}
62
63static inline gva_t get_tlb_eaddr(const struct kvm_book3e_206_tlb_entry *tlbe)
64{
65 return tlbe->mas2 & 0xfffff000;
66}
67
68static inline u64 get_tlb_bytes(const struct kvm_book3e_206_tlb_entry *tlbe)
69{
70 unsigned int pgsize = get_tlb_size(tlbe);
71 return 1ULL << 10 << pgsize;
72}
73
74static inline gva_t get_tlb_end(const struct kvm_book3e_206_tlb_entry *tlbe)
75{
76 u64 bytes = get_tlb_bytes(tlbe);
77 return get_tlb_eaddr(tlbe) + bytes - 1;
78}
79
80static inline u64 get_tlb_raddr(const struct kvm_book3e_206_tlb_entry *tlbe)
81{
82 return tlbe->mas7_3 & ~0xfffULL;
83}
84
85static inline unsigned int
86get_tlb_tid(const struct kvm_book3e_206_tlb_entry *tlbe)
87{
88 return (tlbe->mas1 >> 16) & 0xff;
89}
90
91static inline unsigned int
92get_tlb_ts(const struct kvm_book3e_206_tlb_entry *tlbe)
93{
94 return (tlbe->mas1 >> 12) & 0x1;
95}
96
97static inline unsigned int
98get_tlb_v(const struct kvm_book3e_206_tlb_entry *tlbe)
99{
100 return (tlbe->mas1 >> 31) & 0x1;
101}
102
103static inline unsigned int
104get_tlb_iprot(const struct kvm_book3e_206_tlb_entry *tlbe)
105{
106 return (tlbe->mas1 >> 30) & 0x1;
107}
108
109static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
110{
111 return vcpu->arch.pid & 0xff;
112}
113
114static inline unsigned int get_cur_as(struct kvm_vcpu *vcpu)
115{
116 return !!(vcpu->arch.shared->msr & (MSR_IS | MSR_DS));
117}
118
119static inline unsigned int get_cur_pr(struct kvm_vcpu *vcpu)
120{
121 return !!(vcpu->arch.shared->msr & MSR_PR);
122}
123
124static inline unsigned int get_cur_spid(const struct kvm_vcpu *vcpu)
125{
126 return (vcpu->arch.shared->mas6 >> 16) & 0xff;
127}
128
129static inline unsigned int get_cur_sas(const struct kvm_vcpu *vcpu)
130{
131 return vcpu->arch.shared->mas6 & 0x1;
132}
133
134static inline unsigned int get_tlb_tlbsel(const struct kvm_vcpu *vcpu)
135{
136 /*
137 * Manual says that tlbsel has 2 bits wide.
138 * Since we only have two TLBs, only lower bit is used.
139 */
140 return (vcpu->arch.shared->mas0 >> 28) & 0x1;
141}
142
143static inline unsigned int get_tlb_nv_bit(const struct kvm_vcpu *vcpu)
144{
145 return vcpu->arch.shared->mas0 & 0xfff;
146}
147
148static inline unsigned int get_tlb_esel_bit(const struct kvm_vcpu *vcpu)
149{
150 return (vcpu->arch.shared->mas0 >> 16) & 0xfff;
151}
152
153static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
154 const struct kvm_book3e_206_tlb_entry *tlbe)
155{
156 gpa_t gpa;
157
158 if (!get_tlb_v(tlbe))
159 return 0;
160
161 /* Does it match current guest AS? */
162 /* XXX what about IS != DS? */
163 if (get_tlb_ts(tlbe) != !!(vcpu->arch.shared->msr & MSR_IS))
164 return 0;
165
166 gpa = get_tlb_raddr(tlbe);
167 if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
168 /* Mapping is not for RAM. */
169 return 0;
170
171 return 1;
172}
173
174#endif /* __KVM_E500_TLB_H__ */
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
new file mode 100644
index 00000000000..fe6c1de6b70
--- /dev/null
+++ b/arch/powerpc/kvm/e500mc.c
@@ -0,0 +1,342 @@
1/*
2 * Copyright (C) 2010 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Varun Sethi, <varun.sethi@freescale.com>
5 *
6 * Description:
7 * This file is derived from arch/powerpc/kvm/e500.c,
8 * by Yu Liu <yu.liu@freescale.com>.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License, version 2, as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kvm_host.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include <linux/export.h>
19
20#include <asm/reg.h>
21#include <asm/cputable.h>
22#include <asm/tlbflush.h>
23#include <asm/kvm_ppc.h>
24#include <asm/dbell.h>
25
26#include "booke.h"
27#include "e500.h"
28
29void kvmppc_set_pending_interrupt(struct kvm_vcpu *vcpu, enum int_class type)
30{
31 enum ppc_dbell dbell_type;
32 unsigned long tag;
33
34 switch (type) {
35 case INT_CLASS_NONCRIT:
36 dbell_type = PPC_G_DBELL;
37 break;
38 case INT_CLASS_CRIT:
39 dbell_type = PPC_G_DBELL_CRIT;
40 break;
41 case INT_CLASS_MC:
42 dbell_type = PPC_G_DBELL_MC;
43 break;
44 default:
45 WARN_ONCE(1, "%s: unknown int type %d\n", __func__, type);
46 return;
47 }
48
49
50 tag = PPC_DBELL_LPID(vcpu->kvm->arch.lpid) | vcpu->vcpu_id;
51 mb();
52 ppc_msgsnd(dbell_type, 0, tag);
53}
54
55/* gtlbe must not be mapped by more than one host tlb entry */
56void kvmppc_e500_tlbil_one(struct kvmppc_vcpu_e500 *vcpu_e500,
57 struct kvm_book3e_206_tlb_entry *gtlbe)
58{
59 unsigned int tid, ts;
60 u32 val, eaddr, lpid;
61 unsigned long flags;
62
63 ts = get_tlb_ts(gtlbe);
64 tid = get_tlb_tid(gtlbe);
65 lpid = vcpu_e500->vcpu.kvm->arch.lpid;
66
67 /* We search the host TLB to invalidate its shadow TLB entry */
68 val = (tid << 16) | ts;
69 eaddr = get_tlb_eaddr(gtlbe);
70
71 local_irq_save(flags);
72
73 mtspr(SPRN_MAS6, val);
74 mtspr(SPRN_MAS5, MAS5_SGS | lpid);
75
76 asm volatile("tlbsx 0, %[eaddr]\n" : : [eaddr] "r" (eaddr));
77 val = mfspr(SPRN_MAS1);
78 if (val & MAS1_VALID) {
79 mtspr(SPRN_MAS1, val & ~MAS1_VALID);
80 asm volatile("tlbwe");
81 }
82 mtspr(SPRN_MAS5, 0);
83 /* NOTE: tlbsx also updates mas8, so clear it for host tlbwe */
84 mtspr(SPRN_MAS8, 0);
85 isync();
86
87 local_irq_restore(flags);
88}
89
90void kvmppc_e500_tlbil_all(struct kvmppc_vcpu_e500 *vcpu_e500)
91{
92 unsigned long flags;
93
94 local_irq_save(flags);
95 mtspr(SPRN_MAS5, MAS5_SGS | vcpu_e500->vcpu.kvm->arch.lpid);
96 asm volatile("tlbilxlpid");
97 mtspr(SPRN_MAS5, 0);
98 local_irq_restore(flags);
99}
100
101void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
102{
103 vcpu->arch.pid = pid;
104}
105
106void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
107{
108}
109
110void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
111{
112 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
113
114 kvmppc_booke_vcpu_load(vcpu, cpu);
115
116 mtspr(SPRN_LPID, vcpu->kvm->arch.lpid);
117 mtspr(SPRN_EPCR, vcpu->arch.shadow_epcr);
118 mtspr(SPRN_GPIR, vcpu->vcpu_id);
119 mtspr(SPRN_MSRP, vcpu->arch.shadow_msrp);
120 mtspr(SPRN_EPLC, vcpu->arch.eplc);
121 mtspr(SPRN_EPSC, vcpu->arch.epsc);
122
123 mtspr(SPRN_GIVPR, vcpu->arch.ivpr);
124 mtspr(SPRN_GIVOR2, vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE]);
125 mtspr(SPRN_GIVOR8, vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL]);
126 mtspr(SPRN_GSPRG0, (unsigned long)vcpu->arch.shared->sprg0);
127 mtspr(SPRN_GSPRG1, (unsigned long)vcpu->arch.shared->sprg1);
128 mtspr(SPRN_GSPRG2, (unsigned long)vcpu->arch.shared->sprg2);
129 mtspr(SPRN_GSPRG3, (unsigned long)vcpu->arch.shared->sprg3);
130
131 mtspr(SPRN_GSRR0, vcpu->arch.shared->srr0);
132 mtspr(SPRN_GSRR1, vcpu->arch.shared->srr1);
133
134 mtspr(SPRN_GEPR, vcpu->arch.epr);
135 mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
136 mtspr(SPRN_GESR, vcpu->arch.shared->esr);
137
138 if (vcpu->arch.oldpir != mfspr(SPRN_PIR))
139 kvmppc_e500_tlbil_all(vcpu_e500);
140
141 kvmppc_load_guest_fp(vcpu);
142}
143
144void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
145{
146 vcpu->arch.eplc = mfspr(SPRN_EPLC);
147 vcpu->arch.epsc = mfspr(SPRN_EPSC);
148
149 vcpu->arch.shared->sprg0 = mfspr(SPRN_GSPRG0);
150 vcpu->arch.shared->sprg1 = mfspr(SPRN_GSPRG1);
151 vcpu->arch.shared->sprg2 = mfspr(SPRN_GSPRG2);
152 vcpu->arch.shared->sprg3 = mfspr(SPRN_GSPRG3);
153
154 vcpu->arch.shared->srr0 = mfspr(SPRN_GSRR0);
155 vcpu->arch.shared->srr1 = mfspr(SPRN_GSRR1);
156
157 vcpu->arch.epr = mfspr(SPRN_GEPR);
158 vcpu->arch.shared->dar = mfspr(SPRN_GDEAR);
159 vcpu->arch.shared->esr = mfspr(SPRN_GESR);
160
161 vcpu->arch.oldpir = mfspr(SPRN_PIR);
162
163 kvmppc_booke_vcpu_put(vcpu);
164}
165
166int kvmppc_core_check_processor_compat(void)
167{
168 int r;
169
170 if (strcmp(cur_cpu_spec->cpu_name, "e500mc") == 0)
171 r = 0;
172 else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
173 r = 0;
174 else
175 r = -ENOTSUPP;
176
177 return r;
178}
179
180int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
181{
182 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
183
184 vcpu->arch.shadow_epcr = SPRN_EPCR_DSIGS | SPRN_EPCR_DGTMI | \
185 SPRN_EPCR_DUVD;
186 vcpu->arch.shadow_msrp = MSRP_UCLEP | MSRP_DEP | MSRP_PMMP;
187 vcpu->arch.eplc = EPC_EGS | (vcpu->kvm->arch.lpid << EPC_ELPID_SHIFT);
188 vcpu->arch.epsc = vcpu->arch.eplc;
189
190 vcpu->arch.pvr = mfspr(SPRN_PVR);
191 vcpu_e500->svr = mfspr(SPRN_SVR);
192
193 vcpu->arch.cpu_type = KVM_CPU_E500MC;
194
195 return 0;
196}
197
198void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
199{
200 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
201
202 sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_PM |
203 KVM_SREGS_E_PC;
204 sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
205
206 sregs->u.e.impl.fsl.features = 0;
207 sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
208 sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
209 sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
210
211 kvmppc_get_sregs_e500_tlb(vcpu, sregs);
212
213 sregs->u.e.ivor_high[3] =
214 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
215 sregs->u.e.ivor_high[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL];
216 sregs->u.e.ivor_high[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT];
217
218 kvmppc_get_sregs_ivor(vcpu, sregs);
219}
220
221int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
222{
223 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
224 int ret;
225
226 if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
227 vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
228 vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
229 vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
230 }
231
232 ret = kvmppc_set_sregs_e500_tlb(vcpu, sregs);
233 if (ret < 0)
234 return ret;
235
236 if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
237 return 0;
238
239 if (sregs->u.e.features & KVM_SREGS_E_PM) {
240 vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
241 sregs->u.e.ivor_high[3];
242 }
243
244 if (sregs->u.e.features & KVM_SREGS_E_PC) {
245 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL] =
246 sregs->u.e.ivor_high[4];
247 vcpu->arch.ivor[BOOKE_IRQPRIO_DBELL_CRIT] =
248 sregs->u.e.ivor_high[5];
249 }
250
251 return kvmppc_set_sregs_ivor(vcpu, sregs);
252}
253
254struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
255{
256 struct kvmppc_vcpu_e500 *vcpu_e500;
257 struct kvm_vcpu *vcpu;
258 int err;
259
260 vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
261 if (!vcpu_e500) {
262 err = -ENOMEM;
263 goto out;
264 }
265 vcpu = &vcpu_e500->vcpu;
266
267 /* Invalid PIR value -- this LPID dosn't have valid state on any cpu */
268 vcpu->arch.oldpir = 0xffffffff;
269
270 err = kvm_vcpu_init(vcpu, kvm, id);
271 if (err)
272 goto free_vcpu;
273
274 err = kvmppc_e500_tlb_init(vcpu_e500);
275 if (err)
276 goto uninit_vcpu;
277
278 vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
279 if (!vcpu->arch.shared)
280 goto uninit_tlb;
281
282 return vcpu;
283
284uninit_tlb:
285 kvmppc_e500_tlb_uninit(vcpu_e500);
286uninit_vcpu:
287 kvm_vcpu_uninit(vcpu);
288
289free_vcpu:
290 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
291out:
292 return ERR_PTR(err);
293}
294
295void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
296{
297 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
298
299 free_page((unsigned long)vcpu->arch.shared);
300 kvmppc_e500_tlb_uninit(vcpu_e500);
301 kvm_vcpu_uninit(vcpu);
302 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
303}
304
305int kvmppc_core_init_vm(struct kvm *kvm)
306{
307 int lpid;
308
309 lpid = kvmppc_alloc_lpid();
310 if (lpid < 0)
311 return lpid;
312
313 kvm->arch.lpid = lpid;
314 return 0;
315}
316
317void kvmppc_core_destroy_vm(struct kvm *kvm)
318{
319 kvmppc_free_lpid(kvm->arch.lpid);
320}
321
322static int __init kvmppc_e500mc_init(void)
323{
324 int r;
325
326 r = kvmppc_booke_init();
327 if (r)
328 return r;
329
330 kvmppc_init_lpid(64);
331 kvmppc_claim_lpid(0); /* host */
332
333 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), 0, THIS_MODULE);
334}
335
336static void __exit kvmppc_e500mc_exit(void)
337{
338 kvmppc_booke_exit();
339}
340
341module_init(kvmppc_e500mc_init);
342module_exit(kvmppc_e500mc_exit);
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 968f4010188..f90e86dea7a 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -23,6 +23,7 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/kvm_host.h> 25#include <linux/kvm_host.h>
26#include <linux/clockchips.h>
26 27
27#include <asm/reg.h> 28#include <asm/reg.h>
28#include <asm/time.h> 29#include <asm/time.h>
@@ -35,7 +36,9 @@
35#define OP_TRAP 3 36#define OP_TRAP 3
36#define OP_TRAP_64 2 37#define OP_TRAP_64 2
37 38
39#define OP_31_XOP_TRAP 4
38#define OP_31_XOP_LWZX 23 40#define OP_31_XOP_LWZX 23
41#define OP_31_XOP_TRAP_64 68
39#define OP_31_XOP_LBZX 87 42#define OP_31_XOP_LBZX 87
40#define OP_31_XOP_STWX 151 43#define OP_31_XOP_STWX 151
41#define OP_31_XOP_STBX 215 44#define OP_31_XOP_STBX 215
@@ -102,8 +105,12 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
102 */ 105 */
103 106
104 dec_time = vcpu->arch.dec; 107 dec_time = vcpu->arch.dec;
105 dec_time *= 1000; 108 /*
106 do_div(dec_time, tb_ticks_per_usec); 109 * Guest timebase ticks at the same frequency as host decrementer.
110 * So use the host decrementer calculations for decrementer emulation.
111 */
112 dec_time = dec_time << decrementer_clockevent.shift;
113 do_div(dec_time, decrementer_clockevent.mult);
107 dec_nsec = do_div(dec_time, NSEC_PER_SEC); 114 dec_nsec = do_div(dec_time, NSEC_PER_SEC);
108 hrtimer_start(&vcpu->arch.dec_timer, 115 hrtimer_start(&vcpu->arch.dec_timer,
109 ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL); 116 ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
@@ -141,14 +148,13 @@ u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
141int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) 148int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
142{ 149{
143 u32 inst = kvmppc_get_last_inst(vcpu); 150 u32 inst = kvmppc_get_last_inst(vcpu);
144 u32 ea; 151 int ra = get_ra(inst);
145 int ra; 152 int rs = get_rs(inst);
146 int rb; 153 int rt = get_rt(inst);
147 int rs; 154 int sprn = get_sprn(inst);
148 int rt;
149 int sprn;
150 enum emulation_result emulated = EMULATE_DONE; 155 enum emulation_result emulated = EMULATE_DONE;
151 int advance = 1; 156 int advance = 1;
157 ulong spr_val = 0;
152 158
153 /* this default type might be overwritten by subcategories */ 159 /* this default type might be overwritten by subcategories */
154 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS); 160 kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
@@ -170,173 +176,143 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
170 case 31: 176 case 31:
171 switch (get_xop(inst)) { 177 switch (get_xop(inst)) {
172 178
179 case OP_31_XOP_TRAP:
180#ifdef CONFIG_64BIT
181 case OP_31_XOP_TRAP_64:
182#endif
183#ifdef CONFIG_PPC_BOOK3S
184 kvmppc_core_queue_program(vcpu, SRR1_PROGTRAP);
185#else
186 kvmppc_core_queue_program(vcpu,
187 vcpu->arch.shared->esr | ESR_PTR);
188#endif
189 advance = 0;
190 break;
173 case OP_31_XOP_LWZX: 191 case OP_31_XOP_LWZX:
174 rt = get_rt(inst);
175 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 192 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
176 break; 193 break;
177 194
178 case OP_31_XOP_LBZX: 195 case OP_31_XOP_LBZX:
179 rt = get_rt(inst);
180 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 196 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
181 break; 197 break;
182 198
183 case OP_31_XOP_LBZUX: 199 case OP_31_XOP_LBZUX:
184 rt = get_rt(inst);
185 ra = get_ra(inst);
186 rb = get_rb(inst);
187
188 ea = kvmppc_get_gpr(vcpu, rb);
189 if (ra)
190 ea += kvmppc_get_gpr(vcpu, ra);
191
192 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 200 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
193 kvmppc_set_gpr(vcpu, ra, ea); 201 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
194 break; 202 break;
195 203
196 case OP_31_XOP_STWX: 204 case OP_31_XOP_STWX:
197 rs = get_rs(inst);
198 emulated = kvmppc_handle_store(run, vcpu, 205 emulated = kvmppc_handle_store(run, vcpu,
199 kvmppc_get_gpr(vcpu, rs), 206 kvmppc_get_gpr(vcpu, rs),
200 4, 1); 207 4, 1);
201 break; 208 break;
202 209
203 case OP_31_XOP_STBX: 210 case OP_31_XOP_STBX:
204 rs = get_rs(inst);
205 emulated = kvmppc_handle_store(run, vcpu, 211 emulated = kvmppc_handle_store(run, vcpu,
206 kvmppc_get_gpr(vcpu, rs), 212 kvmppc_get_gpr(vcpu, rs),
207 1, 1); 213 1, 1);
208 break; 214 break;
209 215
210 case OP_31_XOP_STBUX: 216 case OP_31_XOP_STBUX:
211 rs = get_rs(inst);
212 ra = get_ra(inst);
213 rb = get_rb(inst);
214
215 ea = kvmppc_get_gpr(vcpu, rb);
216 if (ra)
217 ea += kvmppc_get_gpr(vcpu, ra);
218
219 emulated = kvmppc_handle_store(run, vcpu, 217 emulated = kvmppc_handle_store(run, vcpu,
220 kvmppc_get_gpr(vcpu, rs), 218 kvmppc_get_gpr(vcpu, rs),
221 1, 1); 219 1, 1);
222 kvmppc_set_gpr(vcpu, rs, ea); 220 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
223 break; 221 break;
224 222
225 case OP_31_XOP_LHAX: 223 case OP_31_XOP_LHAX:
226 rt = get_rt(inst);
227 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); 224 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
228 break; 225 break;
229 226
230 case OP_31_XOP_LHZX: 227 case OP_31_XOP_LHZX:
231 rt = get_rt(inst);
232 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 228 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
233 break; 229 break;
234 230
235 case OP_31_XOP_LHZUX: 231 case OP_31_XOP_LHZUX:
236 rt = get_rt(inst);
237 ra = get_ra(inst);
238 rb = get_rb(inst);
239
240 ea = kvmppc_get_gpr(vcpu, rb);
241 if (ra)
242 ea += kvmppc_get_gpr(vcpu, ra);
243
244 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 232 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
245 kvmppc_set_gpr(vcpu, ra, ea); 233 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
246 break; 234 break;
247 235
248 case OP_31_XOP_MFSPR: 236 case OP_31_XOP_MFSPR:
249 sprn = get_sprn(inst);
250 rt = get_rt(inst);
251
252 switch (sprn) { 237 switch (sprn) {
253 case SPRN_SRR0: 238 case SPRN_SRR0:
254 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr0); 239 spr_val = vcpu->arch.shared->srr0;
255 break; 240 break;
256 case SPRN_SRR1: 241 case SPRN_SRR1:
257 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->srr1); 242 spr_val = vcpu->arch.shared->srr1;
258 break; 243 break;
259 case SPRN_PVR: 244 case SPRN_PVR:
260 kvmppc_set_gpr(vcpu, rt, vcpu->arch.pvr); break; 245 spr_val = vcpu->arch.pvr;
246 break;
261 case SPRN_PIR: 247 case SPRN_PIR:
262 kvmppc_set_gpr(vcpu, rt, vcpu->vcpu_id); break; 248 spr_val = vcpu->vcpu_id;
249 break;
263 case SPRN_MSSSR0: 250 case SPRN_MSSSR0:
264 kvmppc_set_gpr(vcpu, rt, 0); break; 251 spr_val = 0;
252 break;
265 253
266 /* Note: mftb and TBRL/TBWL are user-accessible, so 254 /* Note: mftb and TBRL/TBWL are user-accessible, so
267 * the guest can always access the real TB anyways. 255 * the guest can always access the real TB anyways.
268 * In fact, we probably will never see these traps. */ 256 * In fact, we probably will never see these traps. */
269 case SPRN_TBWL: 257 case SPRN_TBWL:
270 kvmppc_set_gpr(vcpu, rt, get_tb() >> 32); break; 258 spr_val = get_tb() >> 32;
259 break;
271 case SPRN_TBWU: 260 case SPRN_TBWU:
272 kvmppc_set_gpr(vcpu, rt, get_tb()); break; 261 spr_val = get_tb();
262 break;
273 263
274 case SPRN_SPRG0: 264 case SPRN_SPRG0:
275 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg0); 265 spr_val = vcpu->arch.shared->sprg0;
276 break; 266 break;
277 case SPRN_SPRG1: 267 case SPRN_SPRG1:
278 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg1); 268 spr_val = vcpu->arch.shared->sprg1;
279 break; 269 break;
280 case SPRN_SPRG2: 270 case SPRN_SPRG2:
281 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg2); 271 spr_val = vcpu->arch.shared->sprg2;
282 break; 272 break;
283 case SPRN_SPRG3: 273 case SPRN_SPRG3:
284 kvmppc_set_gpr(vcpu, rt, vcpu->arch.shared->sprg3); 274 spr_val = vcpu->arch.shared->sprg3;
285 break; 275 break;
286 /* Note: SPRG4-7 are user-readable, so we don't get 276 /* Note: SPRG4-7 are user-readable, so we don't get
287 * a trap. */ 277 * a trap. */
288 278
289 case SPRN_DEC: 279 case SPRN_DEC:
290 { 280 spr_val = kvmppc_get_dec(vcpu, get_tb());
291 kvmppc_set_gpr(vcpu, rt,
292 kvmppc_get_dec(vcpu, get_tb()));
293 break; 281 break;
294 }
295 default: 282 default:
296 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn, rt); 283 emulated = kvmppc_core_emulate_mfspr(vcpu, sprn,
297 if (emulated == EMULATE_FAIL) { 284 &spr_val);
298 printk("mfspr: unknown spr %x\n", sprn); 285 if (unlikely(emulated == EMULATE_FAIL)) {
299 kvmppc_set_gpr(vcpu, rt, 0); 286 printk(KERN_INFO "mfspr: unknown spr "
287 "0x%x\n", sprn);
300 } 288 }
301 break; 289 break;
302 } 290 }
291 kvmppc_set_gpr(vcpu, rt, spr_val);
303 kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS); 292 kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
304 break; 293 break;
305 294
306 case OP_31_XOP_STHX: 295 case OP_31_XOP_STHX:
307 rs = get_rs(inst);
308 ra = get_ra(inst);
309 rb = get_rb(inst);
310
311 emulated = kvmppc_handle_store(run, vcpu, 296 emulated = kvmppc_handle_store(run, vcpu,
312 kvmppc_get_gpr(vcpu, rs), 297 kvmppc_get_gpr(vcpu, rs),
313 2, 1); 298 2, 1);
314 break; 299 break;
315 300
316 case OP_31_XOP_STHUX: 301 case OP_31_XOP_STHUX:
317 rs = get_rs(inst);
318 ra = get_ra(inst);
319 rb = get_rb(inst);
320
321 ea = kvmppc_get_gpr(vcpu, rb);
322 if (ra)
323 ea += kvmppc_get_gpr(vcpu, ra);
324
325 emulated = kvmppc_handle_store(run, vcpu, 302 emulated = kvmppc_handle_store(run, vcpu,
326 kvmppc_get_gpr(vcpu, rs), 303 kvmppc_get_gpr(vcpu, rs),
327 2, 1); 304 2, 1);
328 kvmppc_set_gpr(vcpu, ra, ea); 305 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
329 break; 306 break;
330 307
331 case OP_31_XOP_MTSPR: 308 case OP_31_XOP_MTSPR:
332 sprn = get_sprn(inst); 309 spr_val = kvmppc_get_gpr(vcpu, rs);
333 rs = get_rs(inst);
334 switch (sprn) { 310 switch (sprn) {
335 case SPRN_SRR0: 311 case SPRN_SRR0:
336 vcpu->arch.shared->srr0 = kvmppc_get_gpr(vcpu, rs); 312 vcpu->arch.shared->srr0 = spr_val;
337 break; 313 break;
338 case SPRN_SRR1: 314 case SPRN_SRR1:
339 vcpu->arch.shared->srr1 = kvmppc_get_gpr(vcpu, rs); 315 vcpu->arch.shared->srr1 = spr_val;
340 break; 316 break;
341 317
342 /* XXX We need to context-switch the timebase for 318 /* XXX We need to context-switch the timebase for
@@ -347,27 +323,29 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
347 case SPRN_MSSSR0: break; 323 case SPRN_MSSSR0: break;
348 324
349 case SPRN_DEC: 325 case SPRN_DEC:
350 vcpu->arch.dec = kvmppc_get_gpr(vcpu, rs); 326 vcpu->arch.dec = spr_val;
351 kvmppc_emulate_dec(vcpu); 327 kvmppc_emulate_dec(vcpu);
352 break; 328 break;
353 329
354 case SPRN_SPRG0: 330 case SPRN_SPRG0:
355 vcpu->arch.shared->sprg0 = kvmppc_get_gpr(vcpu, rs); 331 vcpu->arch.shared->sprg0 = spr_val;
356 break; 332 break;
357 case SPRN_SPRG1: 333 case SPRN_SPRG1:
358 vcpu->arch.shared->sprg1 = kvmppc_get_gpr(vcpu, rs); 334 vcpu->arch.shared->sprg1 = spr_val;
359 break; 335 break;
360 case SPRN_SPRG2: 336 case SPRN_SPRG2:
361 vcpu->arch.shared->sprg2 = kvmppc_get_gpr(vcpu, rs); 337 vcpu->arch.shared->sprg2 = spr_val;
362 break; 338 break;
363 case SPRN_SPRG3: 339 case SPRN_SPRG3:
364 vcpu->arch.shared->sprg3 = kvmppc_get_gpr(vcpu, rs); 340 vcpu->arch.shared->sprg3 = spr_val;
365 break; 341 break;
366 342
367 default: 343 default:
368 emulated = kvmppc_core_emulate_mtspr(vcpu, sprn, rs); 344 emulated = kvmppc_core_emulate_mtspr(vcpu, sprn,
345 spr_val);
369 if (emulated == EMULATE_FAIL) 346 if (emulated == EMULATE_FAIL)
370 printk("mtspr: unknown spr %x\n", sprn); 347 printk(KERN_INFO "mtspr: unknown spr "
348 "0x%x\n", sprn);
371 break; 349 break;
372 } 350 }
373 kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS); 351 kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
@@ -382,7 +360,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
382 break; 360 break;
383 361
384 case OP_31_XOP_LWBRX: 362 case OP_31_XOP_LWBRX:
385 rt = get_rt(inst);
386 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0); 363 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
387 break; 364 break;
388 365
@@ -390,25 +367,16 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
390 break; 367 break;
391 368
392 case OP_31_XOP_STWBRX: 369 case OP_31_XOP_STWBRX:
393 rs = get_rs(inst);
394 ra = get_ra(inst);
395 rb = get_rb(inst);
396
397 emulated = kvmppc_handle_store(run, vcpu, 370 emulated = kvmppc_handle_store(run, vcpu,
398 kvmppc_get_gpr(vcpu, rs), 371 kvmppc_get_gpr(vcpu, rs),
399 4, 0); 372 4, 0);
400 break; 373 break;
401 374
402 case OP_31_XOP_LHBRX: 375 case OP_31_XOP_LHBRX:
403 rt = get_rt(inst);
404 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0); 376 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
405 break; 377 break;
406 378
407 case OP_31_XOP_STHBRX: 379 case OP_31_XOP_STHBRX:
408 rs = get_rs(inst);
409 ra = get_ra(inst);
410 rb = get_rb(inst);
411
412 emulated = kvmppc_handle_store(run, vcpu, 380 emulated = kvmppc_handle_store(run, vcpu,
413 kvmppc_get_gpr(vcpu, rs), 381 kvmppc_get_gpr(vcpu, rs),
414 2, 0); 382 2, 0);
@@ -421,99 +389,78 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
421 break; 389 break;
422 390
423 case OP_LWZ: 391 case OP_LWZ:
424 rt = get_rt(inst);
425 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 392 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
426 break; 393 break;
427 394
428 case OP_LWZU: 395 case OP_LWZU:
429 ra = get_ra(inst);
430 rt = get_rt(inst);
431 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); 396 emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
432 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 397 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
433 break; 398 break;
434 399
435 case OP_LBZ: 400 case OP_LBZ:
436 rt = get_rt(inst);
437 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 401 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
438 break; 402 break;
439 403
440 case OP_LBZU: 404 case OP_LBZU:
441 ra = get_ra(inst);
442 rt = get_rt(inst);
443 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); 405 emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
444 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 406 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
445 break; 407 break;
446 408
447 case OP_STW: 409 case OP_STW:
448 rs = get_rs(inst);
449 emulated = kvmppc_handle_store(run, vcpu, 410 emulated = kvmppc_handle_store(run, vcpu,
450 kvmppc_get_gpr(vcpu, rs), 411 kvmppc_get_gpr(vcpu, rs),
451 4, 1); 412 4, 1);
452 break; 413 break;
453 414
454 case OP_STWU: 415 case OP_STWU:
455 ra = get_ra(inst);
456 rs = get_rs(inst);
457 emulated = kvmppc_handle_store(run, vcpu, 416 emulated = kvmppc_handle_store(run, vcpu,
458 kvmppc_get_gpr(vcpu, rs), 417 kvmppc_get_gpr(vcpu, rs),
459 4, 1); 418 4, 1);
460 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 419 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
461 break; 420 break;
462 421
463 case OP_STB: 422 case OP_STB:
464 rs = get_rs(inst);
465 emulated = kvmppc_handle_store(run, vcpu, 423 emulated = kvmppc_handle_store(run, vcpu,
466 kvmppc_get_gpr(vcpu, rs), 424 kvmppc_get_gpr(vcpu, rs),
467 1, 1); 425 1, 1);
468 break; 426 break;
469 427
470 case OP_STBU: 428 case OP_STBU:
471 ra = get_ra(inst);
472 rs = get_rs(inst);
473 emulated = kvmppc_handle_store(run, vcpu, 429 emulated = kvmppc_handle_store(run, vcpu,
474 kvmppc_get_gpr(vcpu, rs), 430 kvmppc_get_gpr(vcpu, rs),
475 1, 1); 431 1, 1);
476 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 432 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
477 break; 433 break;
478 434
479 case OP_LHZ: 435 case OP_LHZ:
480 rt = get_rt(inst);
481 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 436 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
482 break; 437 break;
483 438
484 case OP_LHZU: 439 case OP_LHZU:
485 ra = get_ra(inst);
486 rt = get_rt(inst);
487 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); 440 emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
488 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 441 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
489 break; 442 break;
490 443
491 case OP_LHA: 444 case OP_LHA:
492 rt = get_rt(inst);
493 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); 445 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
494 break; 446 break;
495 447
496 case OP_LHAU: 448 case OP_LHAU:
497 ra = get_ra(inst);
498 rt = get_rt(inst);
499 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); 449 emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
500 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 450 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
501 break; 451 break;
502 452
503 case OP_STH: 453 case OP_STH:
504 rs = get_rs(inst);
505 emulated = kvmppc_handle_store(run, vcpu, 454 emulated = kvmppc_handle_store(run, vcpu,
506 kvmppc_get_gpr(vcpu, rs), 455 kvmppc_get_gpr(vcpu, rs),
507 2, 1); 456 2, 1);
508 break; 457 break;
509 458
510 case OP_STHU: 459 case OP_STHU:
511 ra = get_ra(inst);
512 rs = get_rs(inst);
513 emulated = kvmppc_handle_store(run, vcpu, 460 emulated = kvmppc_handle_store(run, vcpu,
514 kvmppc_get_gpr(vcpu, rs), 461 kvmppc_get_gpr(vcpu, rs),
515 2, 1); 462 2, 1);
516 kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); 463 kvmppc_set_gpr(vcpu, ra, vcpu->arch.vaddr_accessed);
517 break; 464 break;
518 465
519 default: 466 default:
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 00d7e345b3f..1493c8de947 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -43,6 +43,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
43 v->requests; 43 v->requests;
44} 44}
45 45
46int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
47{
48 return 1;
49}
50
46int kvmppc_kvm_pv(struct kvm_vcpu *vcpu) 51int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
47{ 52{
48 int nr = kvmppc_get_gpr(vcpu, 11); 53 int nr = kvmppc_get_gpr(vcpu, 11);
@@ -74,7 +79,7 @@ int kvmppc_kvm_pv(struct kvm_vcpu *vcpu)
74 } 79 }
75 case HC_VENDOR_KVM | KVM_HC_FEATURES: 80 case HC_VENDOR_KVM | KVM_HC_FEATURES:
76 r = HC_EV_SUCCESS; 81 r = HC_EV_SUCCESS;
77#if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500) 82#if defined(CONFIG_PPC_BOOK3S) || defined(CONFIG_KVM_E500V2)
78 /* XXX Missing magic page on 44x */ 83 /* XXX Missing magic page on 44x */
79 r2 |= (1 << KVM_FEATURE_MAGIC_PAGE); 84 r2 |= (1 << KVM_FEATURE_MAGIC_PAGE);
80#endif 85#endif
@@ -109,6 +114,11 @@ int kvmppc_sanity_check(struct kvm_vcpu *vcpu)
109 goto out; 114 goto out;
110#endif 115#endif
111 116
117#ifdef CONFIG_KVM_BOOKE_HV
118 if (!cpu_has_feature(CPU_FTR_EMB_HV))
119 goto out;
120#endif
121
112 r = true; 122 r = true;
113 123
114out: 124out:
@@ -225,7 +235,7 @@ int kvm_dev_ioctl_check_extension(long ext)
225 case KVM_CAP_PPC_PAIRED_SINGLES: 235 case KVM_CAP_PPC_PAIRED_SINGLES:
226 case KVM_CAP_PPC_OSI: 236 case KVM_CAP_PPC_OSI:
227 case KVM_CAP_PPC_GET_PVINFO: 237 case KVM_CAP_PPC_GET_PVINFO:
228#ifdef CONFIG_KVM_E500 238#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
229 case KVM_CAP_SW_TLB: 239 case KVM_CAP_SW_TLB:
230#endif 240#endif
231 r = 1; 241 r = 1;
@@ -234,10 +244,12 @@ int kvm_dev_ioctl_check_extension(long ext)
234 r = KVM_COALESCED_MMIO_PAGE_OFFSET; 244 r = KVM_COALESCED_MMIO_PAGE_OFFSET;
235 break; 245 break;
236#endif 246#endif
237#ifdef CONFIG_KVM_BOOK3S_64_HV 247#ifdef CONFIG_PPC_BOOK3S_64
238 case KVM_CAP_SPAPR_TCE: 248 case KVM_CAP_SPAPR_TCE:
239 r = 1; 249 r = 1;
240 break; 250 break;
251#endif /* CONFIG_PPC_BOOK3S_64 */
252#ifdef CONFIG_KVM_BOOK3S_64_HV
241 case KVM_CAP_PPC_SMT: 253 case KVM_CAP_PPC_SMT:
242 r = threads_per_core; 254 r = threads_per_core;
243 break; 255 break;
@@ -267,6 +279,11 @@ int kvm_dev_ioctl_check_extension(long ext)
267 case KVM_CAP_MAX_VCPUS: 279 case KVM_CAP_MAX_VCPUS:
268 r = KVM_MAX_VCPUS; 280 r = KVM_MAX_VCPUS;
269 break; 281 break;
282#ifdef CONFIG_PPC_BOOK3S_64
283 case KVM_CAP_PPC_GET_SMMU_INFO:
284 r = 1;
285 break;
286#endif
270 default: 287 default:
271 r = 0; 288 r = 0;
272 break; 289 break;
@@ -588,21 +605,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
588 return r; 605 return r;
589} 606}
590 607
591void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
592{
593 int me;
594 int cpu = vcpu->cpu;
595
596 me = get_cpu();
597 if (waitqueue_active(vcpu->arch.wqp)) {
598 wake_up_interruptible(vcpu->arch.wqp);
599 vcpu->stat.halt_wakeup++;
600 } else if (cpu != me && cpu != -1) {
601 smp_send_reschedule(vcpu->cpu);
602 }
603 put_cpu();
604}
605
606int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq) 608int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
607{ 609{
608 if (irq->irq == KVM_INTERRUPT_UNSET) { 610 if (irq->irq == KVM_INTERRUPT_UNSET) {
@@ -611,6 +613,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
611 } 613 }
612 614
613 kvmppc_core_queue_external(vcpu, irq); 615 kvmppc_core_queue_external(vcpu, irq);
616
614 kvm_vcpu_kick(vcpu); 617 kvm_vcpu_kick(vcpu);
615 618
616 return 0; 619 return 0;
@@ -633,7 +636,7 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
633 r = 0; 636 r = 0;
634 vcpu->arch.papr_enabled = true; 637 vcpu->arch.papr_enabled = true;
635 break; 638 break;
636#ifdef CONFIG_KVM_E500 639#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
637 case KVM_CAP_SW_TLB: { 640 case KVM_CAP_SW_TLB: {
638 struct kvm_config_tlb cfg; 641 struct kvm_config_tlb cfg;
639 void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0]; 642 void __user *user_ptr = (void __user *)(uintptr_t)cap->args[0];
@@ -710,7 +713,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
710 break; 713 break;
711 } 714 }
712 715
713#ifdef CONFIG_KVM_E500 716#if defined(CONFIG_KVM_E500V2) || defined(CONFIG_KVM_E500MC)
714 case KVM_DIRTY_TLB: { 717 case KVM_DIRTY_TLB: {
715 struct kvm_dirty_tlb dirty; 718 struct kvm_dirty_tlb dirty;
716 r = -EFAULT; 719 r = -EFAULT;
@@ -720,7 +723,6 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
720 break; 723 break;
721 } 724 }
722#endif 725#endif
723
724 default: 726 default:
725 r = -EINVAL; 727 r = -EINVAL;
726 } 728 }
@@ -777,7 +779,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
777 779
778 break; 780 break;
779 } 781 }
780#ifdef CONFIG_KVM_BOOK3S_64_HV 782#ifdef CONFIG_PPC_BOOK3S_64
781 case KVM_CREATE_SPAPR_TCE: { 783 case KVM_CREATE_SPAPR_TCE: {
782 struct kvm_create_spapr_tce create_tce; 784 struct kvm_create_spapr_tce create_tce;
783 struct kvm *kvm = filp->private_data; 785 struct kvm *kvm = filp->private_data;
@@ -788,7 +790,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
788 r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); 790 r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
789 goto out; 791 goto out;
790 } 792 }
793#endif /* CONFIG_PPC_BOOK3S_64 */
791 794
795#ifdef CONFIG_KVM_BOOK3S_64_HV
792 case KVM_ALLOCATE_RMA: { 796 case KVM_ALLOCATE_RMA: {
793 struct kvm *kvm = filp->private_data; 797 struct kvm *kvm = filp->private_data;
794 struct kvm_allocate_rma rma; 798 struct kvm_allocate_rma rma;
@@ -800,6 +804,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
800 } 804 }
801#endif /* CONFIG_KVM_BOOK3S_64_HV */ 805#endif /* CONFIG_KVM_BOOK3S_64_HV */
802 806
807#ifdef CONFIG_PPC_BOOK3S_64
808 case KVM_PPC_GET_SMMU_INFO: {
809 struct kvm *kvm = filp->private_data;
810 struct kvm_ppc_smmu_info info;
811
812 memset(&info, 0, sizeof(info));
813 r = kvm_vm_ioctl_get_smmu_info(kvm, &info);
814 if (r >= 0 && copy_to_user(argp, &info, sizeof(info)))
815 r = -EFAULT;
816 break;
817 }
818#endif /* CONFIG_PPC_BOOK3S_64 */
803 default: 819 default:
804 r = -ENOTTY; 820 r = -ENOTTY;
805 } 821 }
@@ -808,6 +824,40 @@ out:
808 return r; 824 return r;
809} 825}
810 826
827static unsigned long lpid_inuse[BITS_TO_LONGS(KVMPPC_NR_LPIDS)];
828static unsigned long nr_lpids;
829
830long kvmppc_alloc_lpid(void)
831{
832 long lpid;
833
834 do {
835 lpid = find_first_zero_bit(lpid_inuse, KVMPPC_NR_LPIDS);
836 if (lpid >= nr_lpids) {
837 pr_err("%s: No LPIDs free\n", __func__);
838 return -ENOMEM;
839 }
840 } while (test_and_set_bit(lpid, lpid_inuse));
841
842 return lpid;
843}
844
845void kvmppc_claim_lpid(long lpid)
846{
847 set_bit(lpid, lpid_inuse);
848}
849
850void kvmppc_free_lpid(long lpid)
851{
852 clear_bit(lpid, lpid_inuse);
853}
854
855void kvmppc_init_lpid(unsigned long nr_lpids_param)
856{
857 nr_lpids = min_t(unsigned long, KVMPPC_NR_LPIDS, nr_lpids_param);
858 memset(lpid_inuse, 0, sizeof(lpid_inuse));
859}
860
811int kvm_arch_init(void *opaque) 861int kvm_arch_init(void *opaque)
812{ 862{
813 return 0; 863 return 0;
diff --git a/arch/powerpc/kvm/timing.h b/arch/powerpc/kvm/timing.h
index 8167d42a776..bf191e72b2d 100644
--- a/arch/powerpc/kvm/timing.h
+++ b/arch/powerpc/kvm/timing.h
@@ -93,6 +93,12 @@ static inline void kvmppc_account_exit_stat(struct kvm_vcpu *vcpu, int type)
93 case SIGNAL_EXITS: 93 case SIGNAL_EXITS:
94 vcpu->stat.signal_exits++; 94 vcpu->stat.signal_exits++;
95 break; 95 break;
96 case DBELL_EXITS:
97 vcpu->stat.dbell_exits++;
98 break;
99 case GDBELL_EXITS:
100 vcpu->stat.gdbell_exits++;
101 break;
96 } 102 }
97} 103}
98 104
diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S
index 455881a5563..093d6316435 100644
--- a/arch/powerpc/lib/string.S
+++ b/arch/powerpc/lib/string.S
@@ -160,48 +160,3 @@ _GLOBAL(__clear_user)
160 PPC_LONG 1b,91b 160 PPC_LONG 1b,91b
161 PPC_LONG 8b,92b 161 PPC_LONG 8b,92b
162 .text 162 .text
163
164_GLOBAL(__strncpy_from_user)
165 addi r6,r3,-1
166 addi r4,r4,-1
167 cmpwi 0,r5,0
168 beq 2f
169 mtctr r5
1701: lbzu r0,1(r4)
171 cmpwi 0,r0,0
172 stbu r0,1(r6)
173 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
174 beq 3f
1752: addi r6,r6,1
1763: subf r3,r3,r6
177 blr
17899: li r3,-EFAULT
179 blr
180
181 .section __ex_table,"a"
182 PPC_LONG 1b,99b
183 .text
184
185/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
186_GLOBAL(__strnlen_user)
187 addi r7,r3,-1
188 subf r6,r7,r5 /* top+1 - str */
189 cmplw 0,r4,r6
190 bge 0f
191 mr r6,r4
1920: mtctr r6 /* ctr = min(len, top - str) */
1931: lbzu r0,1(r7) /* get next byte */
194 cmpwi 0,r0,0
195 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
196 addi r7,r7,1
197 subf r3,r3,r7 /* number of bytes we have looked at */
198 beqlr /* return if we found a 0 byte */
199 cmpw 0,r3,r4 /* did we look at all len bytes? */
200 blt 99f /* if not, must have hit top */
201 addi r3,r4,1 /* return len + 1 to indicate no null found */
202 blr
20399: li r3,0 /* bad address, return 0 */
204 blr
205
206 .section __ex_table,"a"
207 PPC_LONG 1b,99b
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 1d75c92ea8f..66519d263da 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -151,7 +151,7 @@ static void
151spufs_evict_inode(struct inode *inode) 151spufs_evict_inode(struct inode *inode)
152{ 152{
153 struct spufs_inode_info *ei = SPUFS_I(inode); 153 struct spufs_inode_info *ei = SPUFS_I(inode);
154 end_writeback(inode); 154 clear_inode(inode);
155 if (ei->i_ctx) 155 if (ei->i_ctx)
156 put_spu_context(ei->i_ctx); 156 put_spu_context(ei->i_ctx);
157 if (ei->i_gang) 157 if (ei->i_gang)
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 6a2cb560e96..73dae8b9b77 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -115,7 +115,7 @@ static struct inode *hypfs_make_inode(struct super_block *sb, umode_t mode)
115 115
116static void hypfs_evict_inode(struct inode *inode) 116static void hypfs_evict_inode(struct inode *inode)
117{ 117{
118 end_writeback(inode); 118 clear_inode(inode);
119 kfree(inode->i_private); 119 kfree(inode->i_private);
120} 120}
121 121
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 96076676e22..bdcbe0f8dd7 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -52,4 +52,9 @@ struct kvm_sync_regs {
52 __u32 acrs[16]; /* access registers */ 52 __u32 acrs[16]; /* access registers */
53 __u64 crs[16]; /* control registers */ 53 __u64 crs[16]; /* control registers */
54}; 54};
55
56#define KVM_REG_S390_TODPR (KVM_REG_S390 | KVM_REG_SIZE_U32 | 0x1)
57#define KVM_REG_S390_EPOCHDIFF (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x2)
58#define KVM_REG_S390_CPU_TIMER (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x3)
59#define KVM_REG_S390_CLOCK_COMP (KVM_REG_S390 | KVM_REG_SIZE_U64 | 0x4)
55#endif 60#endif
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 7343872890a..dd17537b9a9 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -148,6 +148,7 @@ struct kvm_vcpu_stat {
148 u32 instruction_sigp_restart; 148 u32 instruction_sigp_restart;
149 u32 diagnose_10; 149 u32 diagnose_10;
150 u32 diagnose_44; 150 u32 diagnose_44;
151 u32 diagnose_9c;
151}; 152};
152 153
153struct kvm_s390_io_info { 154struct kvm_s390_io_info {
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index 6964db226f8..a9883296103 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -149,6 +149,11 @@ static inline unsigned int kvm_arch_para_features(void)
149 return 0; 149 return 0;
150} 150}
151 151
152static inline bool kvm_check_and_clear_guest_paused(void)
153{
154 return false;
155}
156
152#endif 157#endif
153 158
154#endif /* __S390_KVM_PARA_H */ 159#endif /* __S390_KVM_PARA_H */
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h
index fed7bee650a..bf238c55740 100644
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -48,6 +48,7 @@ int sclp_cpu_deconfigure(u8 cpu);
48void sclp_facilities_detect(void); 48void sclp_facilities_detect(void);
49unsigned long long sclp_get_rnmax(void); 49unsigned long long sclp_get_rnmax(void);
50unsigned long long sclp_get_rzm(void); 50unsigned long long sclp_get_rzm(void);
51u8 sclp_get_fac85(void);
51int sclp_sdias_blk_count(void); 52int sclp_sdias_blk_count(void);
52int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 53int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
53int sclp_chp_configure(struct chp_id chpid); 54int sclp_chp_configure(struct chp_id chpid);
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index a353f0ea45c..b23d9ac77df 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -47,9 +47,30 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu)
47{ 47{
48 VCPU_EVENT(vcpu, 5, "%s", "diag time slice end"); 48 VCPU_EVENT(vcpu, 5, "%s", "diag time slice end");
49 vcpu->stat.diagnose_44++; 49 vcpu->stat.diagnose_44++;
50 vcpu_put(vcpu); 50 kvm_vcpu_on_spin(vcpu);
51 yield(); 51 return 0;
52 vcpu_load(vcpu); 52}
53
54static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu)
55{
56 struct kvm *kvm = vcpu->kvm;
57 struct kvm_vcpu *tcpu;
58 int tid;
59 int i;
60
61 tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
62 vcpu->stat.diagnose_9c++;
63 VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d", tid);
64
65 if (tid == vcpu->vcpu_id)
66 return 0;
67
68 kvm_for_each_vcpu(i, tcpu, kvm)
69 if (tcpu->vcpu_id == tid) {
70 kvm_vcpu_yield_to(tcpu);
71 break;
72 }
73
53 return 0; 74 return 0;
54} 75}
55 76
@@ -89,6 +110,8 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
89 return diag_release_pages(vcpu); 110 return diag_release_pages(vcpu);
90 case 0x44: 111 case 0x44:
91 return __diag_time_slice_end(vcpu); 112 return __diag_time_slice_end(vcpu);
113 case 0x9c:
114 return __diag_time_slice_end_directed(vcpu);
92 case 0x308: 115 case 0x308:
93 return __diag_ipl_functions(vcpu); 116 return __diag_ipl_functions(vcpu);
94 default: 117 default:
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 361456577c6..979cbe55bf5 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -101,6 +101,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
101} 101}
102 102
103static intercept_handler_t instruction_handlers[256] = { 103static intercept_handler_t instruction_handlers[256] = {
104 [0x01] = kvm_s390_handle_01,
104 [0x83] = kvm_s390_handle_diag, 105 [0x83] = kvm_s390_handle_diag,
105 [0xae] = kvm_s390_handle_sigp, 106 [0xae] = kvm_s390_handle_sigp,
106 [0xb2] = kvm_s390_handle_b2, 107 [0xb2] = kvm_s390_handle_b2,
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 217ce44395a..664766d0c83 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -28,6 +28,7 @@
28#include <asm/pgtable.h> 28#include <asm/pgtable.h>
29#include <asm/nmi.h> 29#include <asm/nmi.h>
30#include <asm/switch_to.h> 30#include <asm/switch_to.h>
31#include <asm/sclp.h>
31#include "kvm-s390.h" 32#include "kvm-s390.h"
32#include "gaccess.h" 33#include "gaccess.h"
33 34
@@ -74,6 +75,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
74 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) }, 75 { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
75 { "diagnose_10", VCPU_STAT(diagnose_10) }, 76 { "diagnose_10", VCPU_STAT(diagnose_10) },
76 { "diagnose_44", VCPU_STAT(diagnose_44) }, 77 { "diagnose_44", VCPU_STAT(diagnose_44) },
78 { "diagnose_9c", VCPU_STAT(diagnose_9c) },
77 { NULL } 79 { NULL }
78}; 80};
79 81
@@ -133,8 +135,16 @@ int kvm_dev_ioctl_check_extension(long ext)
133 case KVM_CAP_S390_UCONTROL: 135 case KVM_CAP_S390_UCONTROL:
134#endif 136#endif
135 case KVM_CAP_SYNC_REGS: 137 case KVM_CAP_SYNC_REGS:
138 case KVM_CAP_ONE_REG:
136 r = 1; 139 r = 1;
137 break; 140 break;
141 case KVM_CAP_NR_VCPUS:
142 case KVM_CAP_MAX_VCPUS:
143 r = KVM_MAX_VCPUS;
144 break;
145 case KVM_CAP_S390_COW:
146 r = sclp_get_fac85() & 0x2;
147 break;
138 default: 148 default:
139 r = 0; 149 r = 0;
140 } 150 }
@@ -423,6 +433,71 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
423 return 0; 433 return 0;
424} 434}
425 435
436int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
437{
438 /* kvm common code refers to this, but never calls it */
439 BUG();
440 return 0;
441}
442
443static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
444 struct kvm_one_reg *reg)
445{
446 int r = -EINVAL;
447
448 switch (reg->id) {
449 case KVM_REG_S390_TODPR:
450 r = put_user(vcpu->arch.sie_block->todpr,
451 (u32 __user *)reg->addr);
452 break;
453 case KVM_REG_S390_EPOCHDIFF:
454 r = put_user(vcpu->arch.sie_block->epoch,
455 (u64 __user *)reg->addr);
456 break;
457 case KVM_REG_S390_CPU_TIMER:
458 r = put_user(vcpu->arch.sie_block->cputm,
459 (u64 __user *)reg->addr);
460 break;
461 case KVM_REG_S390_CLOCK_COMP:
462 r = put_user(vcpu->arch.sie_block->ckc,
463 (u64 __user *)reg->addr);
464 break;
465 default:
466 break;
467 }
468
469 return r;
470}
471
472static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
473 struct kvm_one_reg *reg)
474{
475 int r = -EINVAL;
476
477 switch (reg->id) {
478 case KVM_REG_S390_TODPR:
479 r = get_user(vcpu->arch.sie_block->todpr,
480 (u32 __user *)reg->addr);
481 break;
482 case KVM_REG_S390_EPOCHDIFF:
483 r = get_user(vcpu->arch.sie_block->epoch,
484 (u64 __user *)reg->addr);
485 break;
486 case KVM_REG_S390_CPU_TIMER:
487 r = get_user(vcpu->arch.sie_block->cputm,
488 (u64 __user *)reg->addr);
489 break;
490 case KVM_REG_S390_CLOCK_COMP:
491 r = get_user(vcpu->arch.sie_block->ckc,
492 (u64 __user *)reg->addr);
493 break;
494 default:
495 break;
496 }
497
498 return r;
499}
500
426static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) 501static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
427{ 502{
428 kvm_s390_vcpu_initial_reset(vcpu); 503 kvm_s390_vcpu_initial_reset(vcpu);
@@ -753,6 +828,18 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
753 case KVM_S390_INITIAL_RESET: 828 case KVM_S390_INITIAL_RESET:
754 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); 829 r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
755 break; 830 break;
831 case KVM_SET_ONE_REG:
832 case KVM_GET_ONE_REG: {
833 struct kvm_one_reg reg;
834 r = -EFAULT;
835 if (copy_from_user(&reg, argp, sizeof(reg)))
836 break;
837 if (ioctl == KVM_SET_ONE_REG)
838 r = kvm_arch_vcpu_ioctl_set_one_reg(vcpu, &reg);
839 else
840 r = kvm_arch_vcpu_ioctl_get_one_reg(vcpu, &reg);
841 break;
842 }
756#ifdef CONFIG_KVM_S390_UCONTROL 843#ifdef CONFIG_KVM_S390_UCONTROL
757 case KVM_S390_UCAS_MAP: { 844 case KVM_S390_UCAS_MAP: {
758 struct kvm_s390_ucas_mapping ucasmap; 845 struct kvm_s390_ucas_mapping ucasmap;
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index ff28f9d1c9e..2294377975e 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -79,6 +79,7 @@ int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
79/* implemented in priv.c */ 79/* implemented in priv.c */
80int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); 80int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
81int kvm_s390_handle_e5(struct kvm_vcpu *vcpu); 81int kvm_s390_handle_e5(struct kvm_vcpu *vcpu);
82int kvm_s390_handle_01(struct kvm_vcpu *vcpu);
82 83
83/* implemented in sigp.c */ 84/* implemented in sigp.c */
84int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); 85int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index e5a45dbd26a..68a6b2ed16b 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -380,3 +380,34 @@ int kvm_s390_handle_e5(struct kvm_vcpu *vcpu)
380 return -EOPNOTSUPP; 380 return -EOPNOTSUPP;
381} 381}
382 382
383static int handle_sckpf(struct kvm_vcpu *vcpu)
384{
385 u32 value;
386
387 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
388 return kvm_s390_inject_program_int(vcpu,
389 PGM_PRIVILEGED_OPERATION);
390
391 if (vcpu->run->s.regs.gprs[0] & 0x00000000ffff0000)
392 return kvm_s390_inject_program_int(vcpu,
393 PGM_SPECIFICATION);
394
395 value = vcpu->run->s.regs.gprs[0] & 0x000000000000ffff;
396 vcpu->arch.sie_block->todpr = value;
397
398 return 0;
399}
400
401static intercept_handler_t x01_handlers[256] = {
402 [0x07] = handle_sckpf,
403};
404
405int kvm_s390_handle_01(struct kvm_vcpu *vcpu)
406{
407 intercept_handler_t handler;
408
409 handler = x01_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
410 if (handler)
411 return handler(vcpu);
412 return -EOPNOTSUPP;
413}
diff --git a/arch/score/include/asm/kvm_para.h b/arch/score/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/score/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/sh/include/asm/kvm_para.h b/arch/sh/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/sh/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 15e9e05740d..83bd051754e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -35,6 +35,7 @@ config SPARC
35 select GENERIC_CMOS_UPDATE 35 select GENERIC_CMOS_UPDATE
36 select GENERIC_CLOCKEVENTS 36 select GENERIC_CLOCKEVENTS
37 select GENERIC_STRNCPY_FROM_USER 37 select GENERIC_STRNCPY_FROM_USER
38 select GENERIC_STRNLEN_USER
38 39
39config SPARC32 40config SPARC32
40 def_bool !64BIT 41 def_bool !64BIT
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 2c2e38821f6..67f83e0a0d6 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += div64.h
21generic-y += local64.h 21generic-y += local64.h
22generic-y += irq_regs.h 22generic-y += irq_regs.h
23generic-y += local.h 23generic-y += local.h
24generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/kvm_para.h b/arch/sparc/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/sparc/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 59586b57ef1..53a28dd59f5 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -16,6 +16,8 @@
16 16
17#ifndef __ASSEMBLY__ 17#ifndef __ASSEMBLY__
18 18
19#include <asm/processor.h>
20
19#define ARCH_HAS_SORT_EXTABLE 21#define ARCH_HAS_SORT_EXTABLE
20#define ARCH_HAS_SEARCH_EXTABLE 22#define ARCH_HAS_SEARCH_EXTABLE
21 23
@@ -304,24 +306,8 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n)
304 return n; 306 return n;
305} 307}
306 308
307extern long __strlen_user(const char __user *); 309extern __must_check long strlen_user(const char __user *str);
308extern long __strnlen_user(const char __user *, long len); 310extern __must_check long strnlen_user(const char __user *str, long n);
309
310static inline long strlen_user(const char __user *str)
311{
312 if (!access_ok(VERIFY_READ, str, 0))
313 return 0;
314 else
315 return __strlen_user(str);
316}
317
318static inline long strnlen_user(const char __user *str, long len)
319{
320 if (!access_ok(VERIFY_READ, str, 0))
321 return 0;
322 else
323 return __strnlen_user(str, len);
324}
325 311
326#endif /* __ASSEMBLY__ */ 312#endif /* __ASSEMBLY__ */
327 313
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index dcdfb89cbf3..7c831d848b4 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -17,6 +17,8 @@
17 17
18#ifndef __ASSEMBLY__ 18#ifndef __ASSEMBLY__
19 19
20#include <asm/processor.h>
21
20/* 22/*
21 * Sparc64 is segmented, though more like the M68K than the I386. 23 * Sparc64 is segmented, though more like the M68K than the I386.
22 * We use the secondary ASI to address user memory, which references a 24 * We use the secondary ASI to address user memory, which references a
@@ -257,11 +259,9 @@ extern unsigned long __must_check __clear_user(void __user *, unsigned long);
257 259
258#define clear_user __clear_user 260#define clear_user __clear_user
259 261
260extern long __strlen_user(const char __user *); 262extern __must_check long strlen_user(const char __user *str);
261extern long __strnlen_user(const char __user *, long len); 263extern __must_check long strnlen_user(const char __user *str, long n);
262 264
263#define strlen_user __strlen_user
264#define strnlen_user __strnlen_user
265#define __copy_to_user_inatomic ___copy_to_user 265#define __copy_to_user_inatomic ___copy_to_user
266#define __copy_from_user_inatomic ___copy_from_user 266#define __copy_from_user_inatomic ___copy_from_user
267 267
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 943d98dc4cd..dff4096f3de 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -10,7 +10,6 @@ lib-y += strlen.o
10lib-y += checksum_$(BITS).o 10lib-y += checksum_$(BITS).o
11lib-$(CONFIG_SPARC32) += blockops.o 11lib-$(CONFIG_SPARC32) += blockops.o
12lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o 12lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o
13lib-y += strlen_user_$(BITS).o
14lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o 13lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
15lib-$(CONFIG_SPARC32) += copy_user.o locks.o 14lib-$(CONFIG_SPARC32) += copy_user.o locks.o
16lib-$(CONFIG_SPARC64) += atomic_64.o 15lib-$(CONFIG_SPARC64) += atomic_64.o
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index 6b278abdb63..3b31218cafc 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -15,8 +15,6 @@
15 15
16/* string functions */ 16/* string functions */
17EXPORT_SYMBOL(strlen); 17EXPORT_SYMBOL(strlen);
18EXPORT_SYMBOL(__strlen_user);
19EXPORT_SYMBOL(__strnlen_user);
20EXPORT_SYMBOL(strncmp); 18EXPORT_SYMBOL(strncmp);
21 19
22/* mem* functions */ 20/* mem* functions */
diff --git a/arch/sparc/lib/strlen_user_32.S b/arch/sparc/lib/strlen_user_32.S
deleted file mode 100644
index 8c8a371df3c..00000000000
--- a/arch/sparc/lib/strlen_user_32.S
+++ /dev/null
@@ -1,109 +0,0 @@
1/* strlen_user.S: Sparc optimized strlen_user code
2 *
3 * Return length of string in userspace including terminating 0
4 * or 0 for error
5 *
6 * Copyright (C) 1991,1996 Free Software Foundation
7 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
8 * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 */
10
11#define LO_MAGIC 0x01010101
12#define HI_MAGIC 0x80808080
13
1410:
15 ldub [%o0], %o5
16 cmp %o5, 0
17 be 1f
18 add %o0, 1, %o0
19 andcc %o0, 3, %g0
20 be 4f
21 or %o4, %lo(HI_MAGIC), %o3
2211:
23 ldub [%o0], %o5
24 cmp %o5, 0
25 be 2f
26 add %o0, 1, %o0
27 andcc %o0, 3, %g0
28 be 5f
29 sethi %hi(LO_MAGIC), %o4
3012:
31 ldub [%o0], %o5
32 cmp %o5, 0
33 be 3f
34 add %o0, 1, %o0
35 b 13f
36 or %o4, %lo(LO_MAGIC), %o2
371:
38 retl
39 mov 1, %o0
402:
41 retl
42 mov 2, %o0
433:
44 retl
45 mov 3, %o0
46
47 .align 4
48 .global __strlen_user, __strnlen_user
49__strlen_user:
50 sethi %hi(32768), %o1
51__strnlen_user:
52 mov %o1, %g1
53 mov %o0, %o1
54 andcc %o0, 3, %g0
55 bne 10b
56 sethi %hi(HI_MAGIC), %o4
57 or %o4, %lo(HI_MAGIC), %o3
584:
59 sethi %hi(LO_MAGIC), %o4
605:
61 or %o4, %lo(LO_MAGIC), %o2
6213:
63 ld [%o0], %o5
642:
65 sub %o5, %o2, %o4
66 andcc %o4, %o3, %g0
67 bne 82f
68 add %o0, 4, %o0
69 sub %o0, %o1, %g2
7081: cmp %g2, %g1
71 blu 13b
72 mov %o0, %o4
73 ba,a 1f
74
75 /* Check every byte. */
7682: srl %o5, 24, %g5
77 andcc %g5, 0xff, %g0
78 be 1f
79 add %o0, -3, %o4
80 srl %o5, 16, %g5
81 andcc %g5, 0xff, %g0
82 be 1f
83 add %o4, 1, %o4
84 srl %o5, 8, %g5
85 andcc %g5, 0xff, %g0
86 be 1f
87 add %o4, 1, %o4
88 andcc %o5, 0xff, %g0
89 bne 81b
90 sub %o0, %o1, %g2
91
92 add %o4, 1, %o4
931:
94 retl
95 sub %o4, %o1, %o0
96
97 .section .fixup,#alloc,#execinstr
98 .align 4
999:
100 retl
101 clr %o0
102
103 .section __ex_table,#alloc
104 .align 4
105
106 .word 10b, 9b
107 .word 11b, 9b
108 .word 12b, 9b
109 .word 13b, 9b
diff --git a/arch/sparc/lib/strlen_user_64.S b/arch/sparc/lib/strlen_user_64.S
deleted file mode 100644
index c3df71fa492..00000000000
--- a/arch/sparc/lib/strlen_user_64.S
+++ /dev/null
@@ -1,97 +0,0 @@
1/* strlen_user.S: Sparc64 optimized strlen_user code
2 *
3 * Return length of string in userspace including terminating 0
4 * or 0 for error
5 *
6 * Copyright (C) 1991,1996 Free Software Foundation
7 * Copyright (C) 1996,1999 David S. Miller (davem@redhat.com)
8 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
9 */
10
11#include <linux/linkage.h>
12#include <asm/asi.h>
13
14#define LO_MAGIC 0x01010101
15#define HI_MAGIC 0x80808080
16
17 .align 4
18ENTRY(__strlen_user)
19 sethi %hi(32768), %o1
20ENTRY(__strnlen_user)
21 mov %o1, %g1
22 mov %o0, %o1
23 andcc %o0, 3, %g0
24 be,pt %icc, 9f
25 sethi %hi(HI_MAGIC), %o4
2610: lduba [%o0] %asi, %o5
27 brz,pn %o5, 21f
28 add %o0, 1, %o0
29 andcc %o0, 3, %g0
30 be,pn %icc, 4f
31 or %o4, %lo(HI_MAGIC), %o3
3211: lduba [%o0] %asi, %o5
33 brz,pn %o5, 22f
34 add %o0, 1, %o0
35 andcc %o0, 3, %g0
36 be,pt %icc, 13f
37 srl %o3, 7, %o2
3812: lduba [%o0] %asi, %o5
39 brz,pn %o5, 23f
40 add %o0, 1, %o0
41 ba,pt %icc, 2f
4215: lda [%o0] %asi, %o5
439: or %o4, %lo(HI_MAGIC), %o3
444: srl %o3, 7, %o2
4513: lda [%o0] %asi, %o5
462: sub %o5, %o2, %o4
47 andcc %o4, %o3, %g0
48 bne,pn %icc, 82f
49 add %o0, 4, %o0
50 sub %o0, %o1, %g2
5181: cmp %g2, %g1
52 blu,pt %icc, 13b
53 mov %o0, %o4
54 ba,a,pt %xcc, 1f
55
56 /* Check every byte. */
5782: srl %o5, 24, %g7
58 andcc %g7, 0xff, %g0
59 be,pn %icc, 1f
60 add %o0, -3, %o4
61 srl %o5, 16, %g7
62 andcc %g7, 0xff, %g0
63 be,pn %icc, 1f
64 add %o4, 1, %o4
65 srl %o5, 8, %g7
66 andcc %g7, 0xff, %g0
67 be,pn %icc, 1f
68 add %o4, 1, %o4
69 andcc %o5, 0xff, %g0
70 bne,pt %icc, 81b
71 sub %o0, %o1, %g2
72 add %o4, 1, %o4
731: retl
74 sub %o4, %o1, %o0
7521: retl
76 mov 1, %o0
7722: retl
78 mov 2, %o0
7923: retl
80 mov 3, %o0
81ENDPROC(__strlen_user)
82ENDPROC(__strnlen_user)
83
84 .section .fixup,#alloc,#execinstr
85 .align 4
8630:
87 retl
88 clr %o0
89
90 .section __ex_table,"a"
91 .align 4
92
93 .word 10b, 30b
94 .word 11b, 30b
95 .word 12b, 30b
96 .word 15b, 30b
97 .word 13b, 30b
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 6ad6219fc47..fe128816c44 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -48,6 +48,14 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK
48config SYS_SUPPORTS_HUGETLBFS 48config SYS_SUPPORTS_HUGETLBFS
49 def_bool y 49 def_bool y
50 50
51# Support for additional huge page sizes besides HPAGE_SIZE.
52# The software support is currently only present in the TILE-Gx
53# hypervisor. TILEPro in any case does not support page sizes
54# larger than the default HPAGE_SIZE.
55config HUGETLB_SUPER_PAGES
56 depends on HUGETLB_PAGE && TILEGX
57 def_bool y
58
51# FIXME: tilegx can implement a more efficient rwsem. 59# FIXME: tilegx can implement a more efficient rwsem.
52config RWSEM_GENERIC_SPINLOCK 60config RWSEM_GENERIC_SPINLOCK
53 def_bool y 61 def_bool y
@@ -107,16 +115,14 @@ config HVC_TILE
107 select HVC_DRIVER 115 select HVC_DRIVER
108 def_bool y 116 def_bool y
109 117
110# Please note: TILE-Gx support is not yet finalized; this is
111# the preliminary support. TILE-Gx drivers are only provided
112# with the alpha or beta test versions for Tilera customers.
113config TILEGX 118config TILEGX
114 depends on EXPERIMENTAL
115 bool "Building with TILE-Gx (64-bit) compiler and toolchain" 119 bool "Building with TILE-Gx (64-bit) compiler and toolchain"
116 120
121config TILEPRO
122 def_bool !TILEGX
123
117config 64BIT 124config 64BIT
118 depends on TILEGX 125 def_bool TILEGX
119 def_bool y
120 126
121config ARCH_DEFCONFIG 127config ARCH_DEFCONFIG
122 string 128 string
@@ -137,6 +143,31 @@ config NR_CPUS
137 smaller kernel memory footprint results from using a smaller 143 smaller kernel memory footprint results from using a smaller
138 value on chips with fewer tiles. 144 value on chips with fewer tiles.
139 145
146if TILEGX
147
148choice
149 prompt "Kernel page size"
150 default PAGE_SIZE_64KB
151 help
152 This lets you select the page size of the kernel. For best
153 performance on memory-intensive applications, a page size of 64KB
154 is recommended. For workloads involving many small files, many
155 connections, etc., it may be better to select 16KB, which uses
156 memory more efficiently at some cost in TLB performance.
157
158 Note that this option is TILE-Gx specific; currently
159 TILEPro page size is set by rebuilding the hypervisor.
160
161config PAGE_SIZE_16KB
162 bool "16KB"
163
164config PAGE_SIZE_64KB
165 bool "64KB"
166
167endchoice
168
169endif
170
140source "kernel/Kconfig.hz" 171source "kernel/Kconfig.hz"
141 172
142config KEXEC 173config KEXEC
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
index 9520bc5a4b7..e20b0a0b64a 100644
--- a/arch/tile/Makefile
+++ b/arch/tile/Makefile
@@ -34,7 +34,12 @@ LIBGCC_PATH := \
34 $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name) 34 $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
35 35
36# Provide the path to use for "make defconfig". 36# Provide the path to use for "make defconfig".
37KBUILD_DEFCONFIG := $(ARCH)_defconfig 37# We default to the newer TILE-Gx architecture if only "tile" is given.
38ifeq ($(ARCH),tile)
39 KBUILD_DEFCONFIG := tilegx_defconfig
40else
41 KBUILD_DEFCONFIG := $(ARCH)_defconfig
42endif
38 43
39# Used as a file extension when useful, e.g. head_$(BITS).o 44# Used as a file extension when useful, e.g. head_$(BITS).o
40# Not needed for (e.g.) "$(CC) -m32" since the compiler automatically 45# Not needed for (e.g.) "$(CC) -m32" since the compiler automatically
diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/arch/spr_def_32.h
index bbc1f4c924e..78bbce2fb19 100644
--- a/arch/tile/include/arch/spr_def_32.h
+++ b/arch/tile/include/arch/spr_def_32.h
@@ -65,6 +65,31 @@
65#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1 65#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
66#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4 66#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
67#define SPR_FAIL 0x4e09 67#define SPR_FAIL 0x4e09
68#define SPR_IDN_AVAIL_EN 0x3e05
69#define SPR_IDN_CA_DATA 0x0b00
70#define SPR_IDN_DATA_AVAIL 0x0b03
71#define SPR_IDN_DEADLOCK_TIMEOUT 0x3406
72#define SPR_IDN_DEMUX_CA_COUNT 0x0a05
73#define SPR_IDN_DEMUX_COUNT_0 0x0a06
74#define SPR_IDN_DEMUX_COUNT_1 0x0a07
75#define SPR_IDN_DEMUX_CTL 0x0a08
76#define SPR_IDN_DEMUX_QUEUE_SEL 0x0a0a
77#define SPR_IDN_DEMUX_STATUS 0x0a0b
78#define SPR_IDN_DEMUX_WRITE_FIFO 0x0a0c
79#define SPR_IDN_DIRECTION_PROTECT 0x2e05
80#define SPR_IDN_PENDING 0x0a0e
81#define SPR_IDN_REFILL_EN 0x0e05
82#define SPR_IDN_SP_FIFO_DATA 0x0a0f
83#define SPR_IDN_SP_FIFO_SEL 0x0a10
84#define SPR_IDN_SP_FREEZE 0x0a11
85#define SPR_IDN_SP_FREEZE__SP_FRZ_MASK 0x1
86#define SPR_IDN_SP_FREEZE__DEMUX_FRZ_MASK 0x2
87#define SPR_IDN_SP_FREEZE__NON_DEST_EXT_MASK 0x4
88#define SPR_IDN_SP_STATE 0x0a12
89#define SPR_IDN_TAG_0 0x0a13
90#define SPR_IDN_TAG_1 0x0a14
91#define SPR_IDN_TAG_VALID 0x0a15
92#define SPR_IDN_TILE_COORD 0x0a16
68#define SPR_INTCTRL_0_STATUS 0x4a07 93#define SPR_INTCTRL_0_STATUS 0x4a07
69#define SPR_INTCTRL_1_STATUS 0x4807 94#define SPR_INTCTRL_1_STATUS 0x4807
70#define SPR_INTCTRL_2_STATUS 0x4607 95#define SPR_INTCTRL_2_STATUS 0x4607
@@ -87,12 +112,36 @@
87#define SPR_INTERRUPT_MASK_SET_1_1 0x480e 112#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
88#define SPR_INTERRUPT_MASK_SET_2_0 0x460c 113#define SPR_INTERRUPT_MASK_SET_2_0 0x460c
89#define SPR_INTERRUPT_MASK_SET_2_1 0x460d 114#define SPR_INTERRUPT_MASK_SET_2_1 0x460d
115#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x6000
116#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x6001
117#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x6002
90#define SPR_MPL_DMA_CPL_SET_0 0x5800 118#define SPR_MPL_DMA_CPL_SET_0 0x5800
91#define SPR_MPL_DMA_CPL_SET_1 0x5801 119#define SPR_MPL_DMA_CPL_SET_1 0x5801
92#define SPR_MPL_DMA_CPL_SET_2 0x5802 120#define SPR_MPL_DMA_CPL_SET_2 0x5802
93#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800 121#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
94#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801 122#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
95#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802 123#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802
124#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
125#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
126#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
127#define SPR_MPL_IDN_AVAIL_SET_0 0x3e00
128#define SPR_MPL_IDN_AVAIL_SET_1 0x3e01
129#define SPR_MPL_IDN_AVAIL_SET_2 0x3e02
130#define SPR_MPL_IDN_CA_SET_0 0x3a00
131#define SPR_MPL_IDN_CA_SET_1 0x3a01
132#define SPR_MPL_IDN_CA_SET_2 0x3a02
133#define SPR_MPL_IDN_COMPLETE_SET_0 0x1200
134#define SPR_MPL_IDN_COMPLETE_SET_1 0x1201
135#define SPR_MPL_IDN_COMPLETE_SET_2 0x1202
136#define SPR_MPL_IDN_FIREWALL_SET_0 0x2e00
137#define SPR_MPL_IDN_FIREWALL_SET_1 0x2e01
138#define SPR_MPL_IDN_FIREWALL_SET_2 0x2e02
139#define SPR_MPL_IDN_REFILL_SET_0 0x0e00
140#define SPR_MPL_IDN_REFILL_SET_1 0x0e01
141#define SPR_MPL_IDN_REFILL_SET_2 0x0e02
142#define SPR_MPL_IDN_TIMER_SET_0 0x3400
143#define SPR_MPL_IDN_TIMER_SET_1 0x3401
144#define SPR_MPL_IDN_TIMER_SET_2 0x3402
96#define SPR_MPL_INTCTRL_0_SET_0 0x4a00 145#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
97#define SPR_MPL_INTCTRL_0_SET_1 0x4a01 146#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
98#define SPR_MPL_INTCTRL_0_SET_2 0x4a02 147#define SPR_MPL_INTCTRL_0_SET_2 0x4a02
@@ -102,6 +151,9 @@
102#define SPR_MPL_INTCTRL_2_SET_0 0x4600 151#define SPR_MPL_INTCTRL_2_SET_0 0x4600
103#define SPR_MPL_INTCTRL_2_SET_1 0x4601 152#define SPR_MPL_INTCTRL_2_SET_1 0x4601
104#define SPR_MPL_INTCTRL_2_SET_2 0x4602 153#define SPR_MPL_INTCTRL_2_SET_2 0x4602
154#define SPR_MPL_PERF_COUNT_SET_0 0x4200
155#define SPR_MPL_PERF_COUNT_SET_1 0x4201
156#define SPR_MPL_PERF_COUNT_SET_2 0x4202
105#define SPR_MPL_SN_ACCESS_SET_0 0x0800 157#define SPR_MPL_SN_ACCESS_SET_0 0x0800
106#define SPR_MPL_SN_ACCESS_SET_1 0x0801 158#define SPR_MPL_SN_ACCESS_SET_1 0x0801
107#define SPR_MPL_SN_ACCESS_SET_2 0x0802 159#define SPR_MPL_SN_ACCESS_SET_2 0x0802
@@ -181,6 +233,7 @@
181#define SPR_UDN_DEMUX_STATUS 0x0c0d 233#define SPR_UDN_DEMUX_STATUS 0x0c0d
182#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e 234#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e
183#define SPR_UDN_DIRECTION_PROTECT 0x3005 235#define SPR_UDN_DIRECTION_PROTECT 0x3005
236#define SPR_UDN_PENDING 0x0c10
184#define SPR_UDN_REFILL_EN 0x1005 237#define SPR_UDN_REFILL_EN 0x1005
185#define SPR_UDN_SP_FIFO_DATA 0x0c11 238#define SPR_UDN_SP_FIFO_DATA 0x0c11
186#define SPR_UDN_SP_FIFO_SEL 0x0c12 239#define SPR_UDN_SP_FIFO_SEL 0x0c12
@@ -195,6 +248,9 @@
195#define SPR_UDN_TAG_3 0x0c18 248#define SPR_UDN_TAG_3 0x0c18
196#define SPR_UDN_TAG_VALID 0x0c19 249#define SPR_UDN_TAG_VALID 0x0c19
197#define SPR_UDN_TILE_COORD 0x0c1a 250#define SPR_UDN_TILE_COORD 0x0c1a
251#define SPR_WATCH_CTL 0x4209
252#define SPR_WATCH_MASK 0x420a
253#define SPR_WATCH_VAL 0x420b
198 254
199#endif /* !defined(__ARCH_SPR_DEF_H__) */ 255#endif /* !defined(__ARCH_SPR_DEF_H__) */
200 256
diff --git a/arch/tile/include/arch/spr_def_64.h b/arch/tile/include/arch/spr_def_64.h
index cd3e5f95d5f..0da86faa337 100644
--- a/arch/tile/include/arch/spr_def_64.h
+++ b/arch/tile/include/arch/spr_def_64.h
@@ -52,6 +52,13 @@
52#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1 52#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
53#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4 53#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
54#define SPR_FAIL 0x2707 54#define SPR_FAIL 0x2707
55#define SPR_IDN_AVAIL_EN 0x1a05
56#define SPR_IDN_DATA_AVAIL 0x0a80
57#define SPR_IDN_DEADLOCK_TIMEOUT 0x1806
58#define SPR_IDN_DEMUX_COUNT_0 0x0a05
59#define SPR_IDN_DEMUX_COUNT_1 0x0a06
60#define SPR_IDN_DIRECTION_PROTECT 0x1405
61#define SPR_IDN_PENDING 0x0a08
55#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1 62#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
56#define SPR_INTCTRL_0_STATUS 0x2505 63#define SPR_INTCTRL_0_STATUS 0x2505
57#define SPR_INTCTRL_1_STATUS 0x2405 64#define SPR_INTCTRL_1_STATUS 0x2405
@@ -88,9 +95,27 @@
88#define SPR_IPI_MASK_SET_0 0x1f0a 95#define SPR_IPI_MASK_SET_0 0x1f0a
89#define SPR_IPI_MASK_SET_1 0x1e0a 96#define SPR_IPI_MASK_SET_1 0x1e0a
90#define SPR_IPI_MASK_SET_2 0x1d0a 97#define SPR_IPI_MASK_SET_2 0x1d0a
98#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x2100
99#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x2101
100#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x2102
91#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700 101#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
92#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701 102#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
93#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702 103#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
104#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
105#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
106#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
107#define SPR_MPL_IDN_AVAIL_SET_0 0x1a00
108#define SPR_MPL_IDN_AVAIL_SET_1 0x1a01
109#define SPR_MPL_IDN_AVAIL_SET_2 0x1a02
110#define SPR_MPL_IDN_COMPLETE_SET_0 0x0500
111#define SPR_MPL_IDN_COMPLETE_SET_1 0x0501
112#define SPR_MPL_IDN_COMPLETE_SET_2 0x0502
113#define SPR_MPL_IDN_FIREWALL_SET_0 0x1400
114#define SPR_MPL_IDN_FIREWALL_SET_1 0x1401
115#define SPR_MPL_IDN_FIREWALL_SET_2 0x1402
116#define SPR_MPL_IDN_TIMER_SET_0 0x1800
117#define SPR_MPL_IDN_TIMER_SET_1 0x1801
118#define SPR_MPL_IDN_TIMER_SET_2 0x1802
94#define SPR_MPL_INTCTRL_0_SET_0 0x2500 119#define SPR_MPL_INTCTRL_0_SET_0 0x2500
95#define SPR_MPL_INTCTRL_0_SET_1 0x2501 120#define SPR_MPL_INTCTRL_0_SET_1 0x2501
96#define SPR_MPL_INTCTRL_0_SET_2 0x2502 121#define SPR_MPL_INTCTRL_0_SET_2 0x2502
@@ -100,6 +125,21 @@
100#define SPR_MPL_INTCTRL_2_SET_0 0x2300 125#define SPR_MPL_INTCTRL_2_SET_0 0x2300
101#define SPR_MPL_INTCTRL_2_SET_1 0x2301 126#define SPR_MPL_INTCTRL_2_SET_1 0x2301
102#define SPR_MPL_INTCTRL_2_SET_2 0x2302 127#define SPR_MPL_INTCTRL_2_SET_2 0x2302
128#define SPR_MPL_IPI_0 0x1f04
129#define SPR_MPL_IPI_0_SET_0 0x1f00
130#define SPR_MPL_IPI_0_SET_1 0x1f01
131#define SPR_MPL_IPI_0_SET_2 0x1f02
132#define SPR_MPL_IPI_1 0x1e04
133#define SPR_MPL_IPI_1_SET_0 0x1e00
134#define SPR_MPL_IPI_1_SET_1 0x1e01
135#define SPR_MPL_IPI_1_SET_2 0x1e02
136#define SPR_MPL_IPI_2 0x1d04
137#define SPR_MPL_IPI_2_SET_0 0x1d00
138#define SPR_MPL_IPI_2_SET_1 0x1d01
139#define SPR_MPL_IPI_2_SET_2 0x1d02
140#define SPR_MPL_PERF_COUNT_SET_0 0x2000
141#define SPR_MPL_PERF_COUNT_SET_1 0x2001
142#define SPR_MPL_PERF_COUNT_SET_2 0x2002
103#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00 143#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
104#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01 144#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
105#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02 145#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
@@ -167,6 +207,9 @@
167#define SPR_UDN_DEMUX_COUNT_2 0x0b07 207#define SPR_UDN_DEMUX_COUNT_2 0x0b07
168#define SPR_UDN_DEMUX_COUNT_3 0x0b08 208#define SPR_UDN_DEMUX_COUNT_3 0x0b08
169#define SPR_UDN_DIRECTION_PROTECT 0x1505 209#define SPR_UDN_DIRECTION_PROTECT 0x1505
210#define SPR_UDN_PENDING 0x0b0a
211#define SPR_WATCH_MASK 0x200a
212#define SPR_WATCH_VAL 0x200b
170 213
171#endif /* !defined(__ARCH_SPR_DEF_H__) */ 214#endif /* !defined(__ARCH_SPR_DEF_H__) */
172 215
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 0bb42642343..143473e3a0b 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
2 2
3header-y += ../arch/ 3header-y += ../arch/
4 4
5header-y += cachectl.h
5header-y += ucontext.h 6header-y += ucontext.h
6header-y += hardwall.h 7header-y += hardwall.h
7 8
@@ -21,7 +22,6 @@ generic-y += ipcbuf.h
21generic-y += irq_regs.h 22generic-y += irq_regs.h
22generic-y += kdebug.h 23generic-y += kdebug.h
23generic-y += local.h 24generic-y += local.h
24generic-y += module.h
25generic-y += msgbuf.h 25generic-y += msgbuf.h
26generic-y += mutex.h 26generic-y += mutex.h
27generic-y += param.h 27generic-y += param.h
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
index 54d1da826f9..e7fb5cfb959 100644
--- a/arch/tile/include/asm/atomic_32.h
+++ b/arch/tile/include/asm/atomic_32.h
@@ -303,7 +303,14 @@ void __init_atomic_per_cpu(void);
303void __atomic_fault_unlock(int *lock_ptr); 303void __atomic_fault_unlock(int *lock_ptr);
304#endif 304#endif
305 305
306/* Return a pointer to the lock for the given address. */
307int *__atomic_hashed_lock(volatile void *v);
308
306/* Private helper routines in lib/atomic_asm_32.S */ 309/* Private helper routines in lib/atomic_asm_32.S */
310struct __get_user {
311 unsigned long val;
312 int err;
313};
307extern struct __get_user __atomic_cmpxchg(volatile int *p, 314extern struct __get_user __atomic_cmpxchg(volatile int *p,
308 int *lock, int o, int n); 315 int *lock, int o, int n);
309extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n); 316extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n);
@@ -319,6 +326,9 @@ extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
319extern u64 __atomic64_xchg_add_unless(volatile u64 *p, 326extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
320 int *lock, u64 o, u64 n); 327 int *lock, u64 o, u64 n);
321 328
329/* Return failure from the atomic wrappers. */
330struct __get_user __atomic_bad_address(int __user *addr);
331
322#endif /* !__ASSEMBLY__ */ 332#endif /* !__ASSEMBLY__ */
323 333
324#endif /* _ASM_TILE_ATOMIC_32_H */ 334#endif /* _ASM_TILE_ATOMIC_32_H */
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
index 16f1fa51fea..bd186c4eaa5 100644
--- a/arch/tile/include/asm/bitops.h
+++ b/arch/tile/include/asm/bitops.h
@@ -77,6 +77,11 @@ static inline int ffs(int x)
77 return __builtin_ffs(x); 77 return __builtin_ffs(x);
78} 78}
79 79
80static inline int fls64(__u64 w)
81{
82 return (sizeof(__u64) * 8) - __builtin_clzll(w);
83}
84
80/** 85/**
81 * fls - find last set bit in word 86 * fls - find last set bit in word
82 * @x: the word to search 87 * @x: the word to search
@@ -90,12 +95,7 @@ static inline int ffs(int x)
90 */ 95 */
91static inline int fls(int x) 96static inline int fls(int x)
92{ 97{
93 return (sizeof(int) * 8) - __builtin_clz(x); 98 return fls64((unsigned int) x);
94}
95
96static inline int fls64(__u64 w)
97{
98 return (sizeof(__u64) * 8) - __builtin_clzll(w);
99} 99}
100 100
101static inline unsigned int __arch_hweight32(unsigned int w) 101static inline unsigned int __arch_hweight32(unsigned int w)
diff --git a/arch/tile/include/asm/byteorder.h b/arch/tile/include/asm/byteorder.h
index 9558416d578..fb72ecf4921 100644
--- a/arch/tile/include/asm/byteorder.h
+++ b/arch/tile/include/asm/byteorder.h
@@ -1 +1,21 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#if defined (__BIG_ENDIAN__)
16#include <linux/byteorder/big_endian.h>
17#elif defined (__LITTLE_ENDIAN__)
1#include <linux/byteorder/little_endian.h> 18#include <linux/byteorder/little_endian.h>
19#else
20#error "__BIG_ENDIAN__ or __LITTLE_ENDIAN__ must be defined."
21#endif
diff --git a/arch/tile/include/asm/cachectl.h b/arch/tile/include/asm/cachectl.h
new file mode 100644
index 00000000000..af4c9f9154d
--- /dev/null
+++ b/arch/tile/include/asm/cachectl.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _ASM_TILE_CACHECTL_H
16#define _ASM_TILE_CACHECTL_H
17
18/*
19 * Options for cacheflush system call.
20 *
21 * The ICACHE flush is performed on all cores currently running the
22 * current process's address space. The intent is for user
23 * applications to be able to modify code, invoke the system call,
24 * then allow arbitrary other threads in the same address space to see
25 * the newly-modified code. Passing a length of CHIP_L1I_CACHE_SIZE()
26 * or more invalidates the entire icache on all cores in the address
27 * spaces. (Note: currently this option invalidates the entire icache
28 * regardless of the requested address and length, but we may choose
29 * to honor the arguments at some point.)
30 *
31 * Flush and invalidation of memory can normally be performed with the
32 * __insn_flush(), __insn_inv(), and __insn_finv() instructions from
33 * userspace. The DCACHE option to the system call allows userspace
34 * to flush the entire L1+L2 data cache from the core. In this case,
35 * the address and length arguments are not used. The DCACHE flush is
36 * restricted to the current core, not all cores in the address space.
37 */
38#define ICACHE (1<<0) /* invalidate L1 instruction cache */
39#define DCACHE (1<<1) /* flush and invalidate data cache */
40#define BCACHE (ICACHE|DCACHE) /* flush both caches */
41
42#endif /* _ASM_TILE_CACHECTL_H */
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index 4b4b28969a6..69adc08d36a 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -242,9 +242,6 @@ long compat_sys_fallocate(int fd, int mode,
242long compat_sys_sched_rr_get_interval(compat_pid_t pid, 242long compat_sys_sched_rr_get_interval(compat_pid_t pid,
243 struct compat_timespec __user *interval); 243 struct compat_timespec __user *interval);
244 244
245/* Tilera Linux syscalls that don't have "compat" versions. */
246#define compat_sys_flush_cache sys_flush_cache
247
248/* These are the intvec_64.S trampolines. */ 245/* These are the intvec_64.S trampolines. */
249long _compat_sys_execve(const char __user *path, 246long _compat_sys_execve(const char __user *path,
250 const compat_uptr_t __user *argv, 247 const compat_uptr_t __user *argv,
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index 623a6bb741c..d16d006d660 100644
--- a/arch/tile/include/asm/elf.h
+++ b/arch/tile/include/asm/elf.h
@@ -44,7 +44,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
44#else 44#else
45#define ELF_CLASS ELFCLASS32 45#define ELF_CLASS ELFCLASS32
46#endif 46#endif
47#ifdef __BIG_ENDIAN__
48#define ELF_DATA ELFDATA2MSB
49#else
47#define ELF_DATA ELFDATA2LSB 50#define ELF_DATA ELFDATA2LSB
51#endif
48 52
49/* 53/*
50 * There seems to be a bug in how compat_binfmt_elf.c works: it 54 * There seems to be a bug in how compat_binfmt_elf.c works: it
@@ -59,6 +63,7 @@ enum { ELF_ARCH = CHIP_ELF_TYPE() };
59 */ 63 */
60#define elf_check_arch(x) \ 64#define elf_check_arch(x) \
61 ((x)->e_ident[EI_CLASS] == ELF_CLASS && \ 65 ((x)->e_ident[EI_CLASS] == ELF_CLASS && \
66 (x)->e_ident[EI_DATA] == ELF_DATA && \
62 (x)->e_machine == CHIP_ELF_TYPE()) 67 (x)->e_machine == CHIP_ELF_TYPE())
63 68
64/* The module loader only handles a few relocation types. */ 69/* The module loader only handles a few relocation types. */
diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h
index d03ec124a59..5909ac3d721 100644
--- a/arch/tile/include/asm/futex.h
+++ b/arch/tile/include/asm/futex.h
@@ -28,29 +28,81 @@
28#include <linux/futex.h> 28#include <linux/futex.h>
29#include <linux/uaccess.h> 29#include <linux/uaccess.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <asm/atomic.h>
31 32
32extern struct __get_user futex_set(u32 __user *v, int i); 33/*
33extern struct __get_user futex_add(u32 __user *v, int n); 34 * Support macros for futex operations. Do not use these macros directly.
34extern struct __get_user futex_or(u32 __user *v, int n); 35 * They assume "ret", "val", "oparg", and "uaddr" in the lexical context.
35extern struct __get_user futex_andn(u32 __user *v, int n); 36 * __futex_cmpxchg() additionally assumes "oldval".
36extern struct __get_user futex_cmpxchg(u32 __user *v, int o, int n); 37 */
38
39#ifdef __tilegx__
40
41#define __futex_asm(OP) \
42 asm("1: {" #OP " %1, %3, %4; movei %0, 0 }\n" \
43 ".pushsection .fixup,\"ax\"\n" \
44 "0: { movei %0, %5; j 9f }\n" \
45 ".section __ex_table,\"a\"\n" \
46 ".quad 1b, 0b\n" \
47 ".popsection\n" \
48 "9:" \
49 : "=r" (ret), "=r" (val), "+m" (*(uaddr)) \
50 : "r" (uaddr), "r" (oparg), "i" (-EFAULT))
51
52#define __futex_set() __futex_asm(exch4)
53#define __futex_add() __futex_asm(fetchadd4)
54#define __futex_or() __futex_asm(fetchor4)
55#define __futex_andn() ({ oparg = ~oparg; __futex_asm(fetchand4); })
56#define __futex_cmpxchg() \
57 ({ __insn_mtspr(SPR_CMPEXCH_VALUE, oldval); __futex_asm(cmpexch4); })
58
59#define __futex_xor() \
60 ({ \
61 u32 oldval, n = oparg; \
62 if ((ret = __get_user(oldval, uaddr)) == 0) { \
63 do { \
64 oparg = oldval ^ n; \
65 __futex_cmpxchg(); \
66 } while (ret == 0 && oldval != val); \
67 } \
68 })
69
70/* No need to prefetch, since the atomic ops go to the home cache anyway. */
71#define __futex_prolog()
37 72
38#ifndef __tilegx__
39extern struct __get_user futex_xor(u32 __user *v, int n);
40#else 73#else
41static inline struct __get_user futex_xor(u32 __user *uaddr, int n) 74
42{ 75#define __futex_call(FN) \
43 struct __get_user asm_ret = __get_user_4(uaddr); 76 { \
44 if (!asm_ret.err) { 77 struct __get_user gu = FN((u32 __force *)uaddr, lock, oparg); \
45 int oldval, newval; 78 val = gu.val; \
46 do { 79 ret = gu.err; \
47 oldval = asm_ret.val;
48 newval = oldval ^ n;
49 asm_ret = futex_cmpxchg(uaddr, oldval, newval);
50 } while (asm_ret.err == 0 && oldval != asm_ret.val);
51 } 80 }
52 return asm_ret; 81
53} 82#define __futex_set() __futex_call(__atomic_xchg)
83#define __futex_add() __futex_call(__atomic_xchg_add)
84#define __futex_or() __futex_call(__atomic_or)
85#define __futex_andn() __futex_call(__atomic_andn)
86#define __futex_xor() __futex_call(__atomic_xor)
87
88#define __futex_cmpxchg() \
89 { \
90 struct __get_user gu = __atomic_cmpxchg((u32 __force *)uaddr, \
91 lock, oldval, oparg); \
92 val = gu.val; \
93 ret = gu.err; \
94 }
95
96/*
97 * Find the lock pointer for the atomic calls to use, and issue a
98 * prefetch to the user address to bring it into cache. Similar to
99 * __atomic_setup(), but we can't do a read into the L1 since it might
100 * fault; instead we do a prefetch into the L2.
101 */
102#define __futex_prolog() \
103 int *lock; \
104 __insn_prefetch(uaddr); \
105 lock = __atomic_hashed_lock((int __force *)uaddr)
54#endif 106#endif
55 107
56static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) 108static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
@@ -59,8 +111,12 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
59 int cmp = (encoded_op >> 24) & 15; 111 int cmp = (encoded_op >> 24) & 15;
60 int oparg = (encoded_op << 8) >> 20; 112 int oparg = (encoded_op << 8) >> 20;
61 int cmparg = (encoded_op << 20) >> 20; 113 int cmparg = (encoded_op << 20) >> 20;
62 int ret; 114 int uninitialized_var(val), ret;
63 struct __get_user asm_ret; 115
116 __futex_prolog();
117
118 /* The 32-bit futex code makes this assumption, so validate it here. */
119 BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
64 120
65 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 121 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
66 oparg = 1 << oparg; 122 oparg = 1 << oparg;
@@ -71,46 +127,45 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
71 pagefault_disable(); 127 pagefault_disable();
72 switch (op) { 128 switch (op) {
73 case FUTEX_OP_SET: 129 case FUTEX_OP_SET:
74 asm_ret = futex_set(uaddr, oparg); 130 __futex_set();
75 break; 131 break;
76 case FUTEX_OP_ADD: 132 case FUTEX_OP_ADD:
77 asm_ret = futex_add(uaddr, oparg); 133 __futex_add();
78 break; 134 break;
79 case FUTEX_OP_OR: 135 case FUTEX_OP_OR:
80 asm_ret = futex_or(uaddr, oparg); 136 __futex_or();
81 break; 137 break;
82 case FUTEX_OP_ANDN: 138 case FUTEX_OP_ANDN:
83 asm_ret = futex_andn(uaddr, oparg); 139 __futex_andn();
84 break; 140 break;
85 case FUTEX_OP_XOR: 141 case FUTEX_OP_XOR:
86 asm_ret = futex_xor(uaddr, oparg); 142 __futex_xor();
87 break; 143 break;
88 default: 144 default:
89 asm_ret.err = -ENOSYS; 145 ret = -ENOSYS;
146 break;
90 } 147 }
91 pagefault_enable(); 148 pagefault_enable();
92 149
93 ret = asm_ret.err;
94
95 if (!ret) { 150 if (!ret) {
96 switch (cmp) { 151 switch (cmp) {
97 case FUTEX_OP_CMP_EQ: 152 case FUTEX_OP_CMP_EQ:
98 ret = (asm_ret.val == cmparg); 153 ret = (val == cmparg);
99 break; 154 break;
100 case FUTEX_OP_CMP_NE: 155 case FUTEX_OP_CMP_NE:
101 ret = (asm_ret.val != cmparg); 156 ret = (val != cmparg);
102 break; 157 break;
103 case FUTEX_OP_CMP_LT: 158 case FUTEX_OP_CMP_LT:
104 ret = (asm_ret.val < cmparg); 159 ret = (val < cmparg);
105 break; 160 break;
106 case FUTEX_OP_CMP_GE: 161 case FUTEX_OP_CMP_GE:
107 ret = (asm_ret.val >= cmparg); 162 ret = (val >= cmparg);
108 break; 163 break;
109 case FUTEX_OP_CMP_LE: 164 case FUTEX_OP_CMP_LE:
110 ret = (asm_ret.val <= cmparg); 165 ret = (val <= cmparg);
111 break; 166 break;
112 case FUTEX_OP_CMP_GT: 167 case FUTEX_OP_CMP_GT:
113 ret = (asm_ret.val > cmparg); 168 ret = (val > cmparg);
114 break; 169 break;
115 default: 170 default:
116 ret = -ENOSYS; 171 ret = -ENOSYS;
@@ -120,22 +175,20 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
120} 175}
121 176
122static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, 177static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
123 u32 oldval, u32 newval) 178 u32 oldval, u32 oparg)
124{ 179{
125 struct __get_user asm_ret; 180 int ret, val;
181
182 __futex_prolog();
126 183
127 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) 184 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
128 return -EFAULT; 185 return -EFAULT;
129 186
130 asm_ret = futex_cmpxchg(uaddr, oldval, newval); 187 __futex_cmpxchg();
131 *uval = asm_ret.val;
132 return asm_ret.err;
133}
134 188
135#ifndef __tilegx__ 189 *uval = val;
136/* Return failure from the atomic wrappers. */ 190 return ret;
137struct __get_user __atomic_bad_address(int __user *addr); 191}
138#endif
139 192
140#endif /* !__ASSEMBLY__ */ 193#endif /* !__ASSEMBLY__ */
141 194
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h
index 2ac422848c7..47514a58d68 100644
--- a/arch/tile/include/asm/hardwall.h
+++ b/arch/tile/include/asm/hardwall.h
@@ -11,12 +11,14 @@
11 * NON INFRINGEMENT. See the GNU General Public License for 11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details. 12 * more details.
13 * 13 *
14 * Provide methods for the HARDWALL_FILE for accessing the UDN. 14 * Provide methods for access control of per-cpu resources like
15 * UDN, IDN, or IPI.
15 */ 16 */
16 17
17#ifndef _ASM_TILE_HARDWALL_H 18#ifndef _ASM_TILE_HARDWALL_H
18#define _ASM_TILE_HARDWALL_H 19#define _ASM_TILE_HARDWALL_H
19 20
21#include <arch/chip.h>
20#include <linux/ioctl.h> 22#include <linux/ioctl.h>
21 23
22#define HARDWALL_IOCTL_BASE 0xa2 24#define HARDWALL_IOCTL_BASE 0xa2
@@ -24,8 +26,9 @@
24/* 26/*
25 * The HARDWALL_CREATE() ioctl is a macro with a "size" argument. 27 * The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
26 * The resulting ioctl value is passed to the kernel in conjunction 28 * The resulting ioctl value is passed to the kernel in conjunction
27 * with a pointer to a little-endian bitmask of cpus, which must be 29 * with a pointer to a standard kernel bitmask of cpus.
28 * physically in a rectangular configuration on the chip. 30 * For network resources (UDN or IDN) the bitmask must physically
31 * represent a rectangular configuration on the chip.
29 * The "size" is the number of bytes of cpu mask data. 32 * The "size" is the number of bytes of cpu mask data.
30 */ 33 */
31#define _HARDWALL_CREATE 1 34#define _HARDWALL_CREATE 1
@@ -44,13 +47,7 @@
44#define HARDWALL_GET_ID \ 47#define HARDWALL_GET_ID \
45 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID) 48 _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
46 49
47#ifndef __KERNEL__ 50#ifdef __KERNEL__
48
49/* This is the canonical name expected by userspace. */
50#define HARDWALL_FILE "/dev/hardwall"
51
52#else
53
54/* /proc hooks for hardwall. */ 51/* /proc hooks for hardwall. */
55struct proc_dir_entry; 52struct proc_dir_entry;
56#ifdef CONFIG_HARDWALL 53#ifdef CONFIG_HARDWALL
@@ -59,7 +56,6 @@ int proc_pid_hardwall(struct task_struct *task, char *buffer);
59#else 56#else
60static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {} 57static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
61#endif 58#endif
62
63#endif 59#endif
64 60
65#endif /* _ASM_TILE_HARDWALL_H */ 61#endif /* _ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index d396d180516..b2042380a5a 100644
--- a/arch/tile/include/asm/hugetlb.h
+++ b/arch/tile/include/asm/hugetlb.h
@@ -106,4 +106,25 @@ static inline void arch_release_hugepage(struct page *page)
106{ 106{
107} 107}
108 108
109#ifdef CONFIG_HUGETLB_SUPER_PAGES
110static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
111 struct page *page, int writable)
112{
113 size_t pagesize = huge_page_size(hstate_vma(vma));
114 if (pagesize != PUD_SIZE && pagesize != PMD_SIZE)
115 entry = pte_mksuper(entry);
116 return entry;
117}
118#define arch_make_huge_pte arch_make_huge_pte
119
120/* Sizes to scale up page size for PTEs with HV_PTE_SUPER bit. */
121enum {
122 HUGE_SHIFT_PGDIR = 0,
123 HUGE_SHIFT_PMD = 1,
124 HUGE_SHIFT_PAGE = 2,
125 HUGE_SHIFT_ENTRIES
126};
127extern int huge_shift[HUGE_SHIFT_ENTRIES];
128#endif
129
109#endif /* _ASM_TILE_HUGETLB_H */ 130#endif /* _ASM_TILE_HUGETLB_H */
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
index 5db0ce54284..b4e96fef2cf 100644
--- a/arch/tile/include/asm/irqflags.h
+++ b/arch/tile/include/asm/irqflags.h
@@ -28,10 +28,10 @@
28 */ 28 */
29#if CHIP_HAS_AUX_PERF_COUNTERS() 29#if CHIP_HAS_AUX_PERF_COUNTERS()
30#define LINUX_MASKABLE_INTERRUPTS_HI \ 30#define LINUX_MASKABLE_INTERRUPTS_HI \
31 (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT))) 31 (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT)))
32#else 32#else
33#define LINUX_MASKABLE_INTERRUPTS_HI \ 33#define LINUX_MASKABLE_INTERRUPTS_HI \
34 (~(INT_MASK_HI(INT_PERF_COUNT))) 34 (~(INT_MASK_HI(INT_PERF_COUNT)))
35#endif 35#endif
36 36
37#else 37#else
@@ -90,6 +90,14 @@
90 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, (unsigned long)(__m)); \ 90 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, (unsigned long)(__m)); \
91 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, (unsigned long)(__m>>32)); \ 91 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, (unsigned long)(__m>>32)); \
92} while (0) 92} while (0)
93#define interrupt_mask_save_mask() \
94 (__insn_mfspr(SPR_INTERRUPT_MASK_SET_K_0) | \
95 (((unsigned long long)__insn_mfspr(SPR_INTERRUPT_MASK_SET_K_1))<<32))
96#define interrupt_mask_restore_mask(mask) do { \
97 unsigned long long __m = (mask); \
98 __insn_mtspr(SPR_INTERRUPT_MASK_K_0, (unsigned long)(__m)); \
99 __insn_mtspr(SPR_INTERRUPT_MASK_K_1, (unsigned long)(__m>>32)); \
100} while (0)
93#else 101#else
94#define interrupt_mask_set(n) \ 102#define interrupt_mask_set(n) \
95 __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (1UL << (n))) 103 __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (1UL << (n)))
@@ -101,6 +109,10 @@
101 __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (mask)) 109 __insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (mask))
102#define interrupt_mask_reset_mask(mask) \ 110#define interrupt_mask_reset_mask(mask) \
103 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (mask)) 111 __insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (mask))
112#define interrupt_mask_save_mask() \
113 __insn_mfspr(SPR_INTERRUPT_MASK_K)
114#define interrupt_mask_restore_mask(mask) \
115 __insn_mtspr(SPR_INTERRUPT_MASK_K, (mask))
104#endif 116#endif
105 117
106/* 118/*
@@ -122,7 +134,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
122 134
123/* Disable all interrupts, including NMIs. */ 135/* Disable all interrupts, including NMIs. */
124#define arch_local_irq_disable_all() \ 136#define arch_local_irq_disable_all() \
125 interrupt_mask_set_mask(-1UL) 137 interrupt_mask_set_mask(-1ULL)
126 138
127/* Re-enable all maskable interrupts. */ 139/* Re-enable all maskable interrupts. */
128#define arch_local_irq_enable() \ 140#define arch_local_irq_enable() \
@@ -179,7 +191,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
179#ifdef __tilegx__ 191#ifdef __tilegx__
180 192
181#if INT_MEM_ERROR != 0 193#if INT_MEM_ERROR != 0
182# error Fix IRQ_DISABLED() macro 194# error Fix IRQS_DISABLED() macro
183#endif 195#endif
184 196
185/* Return 0 or 1 to indicate whether interrupts are currently disabled. */ 197/* Return 0 or 1 to indicate whether interrupts are currently disabled. */
@@ -207,9 +219,10 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
207 mtspr SPR_INTERRUPT_MASK_SET_K, tmp 219 mtspr SPR_INTERRUPT_MASK_SET_K, tmp
208 220
209/* Enable interrupts. */ 221/* Enable interrupts. */
210#define IRQ_ENABLE(tmp0, tmp1) \ 222#define IRQ_ENABLE_LOAD(tmp0, tmp1) \
211 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \ 223 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
212 ld tmp0, tmp0; \ 224 ld tmp0, tmp0
225#define IRQ_ENABLE_APPLY(tmp0, tmp1) \
213 mtspr SPR_INTERRUPT_MASK_RESET_K, tmp0 226 mtspr SPR_INTERRUPT_MASK_RESET_K, tmp0
214 227
215#else /* !__tilegx__ */ 228#else /* !__tilegx__ */
@@ -253,17 +266,22 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
253 mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp 266 mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp
254 267
255/* Enable interrupts. */ 268/* Enable interrupts. */
256#define IRQ_ENABLE(tmp0, tmp1) \ 269#define IRQ_ENABLE_LOAD(tmp0, tmp1) \
257 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \ 270 GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
258 { \ 271 { \
259 lw tmp0, tmp0; \ 272 lw tmp0, tmp0; \
260 addi tmp1, tmp0, 4 \ 273 addi tmp1, tmp0, 4 \
261 }; \ 274 }; \
262 lw tmp1, tmp1; \ 275 lw tmp1, tmp1
276#define IRQ_ENABLE_APPLY(tmp0, tmp1) \
263 mtspr SPR_INTERRUPT_MASK_RESET_K_0, tmp0; \ 277 mtspr SPR_INTERRUPT_MASK_RESET_K_0, tmp0; \
264 mtspr SPR_INTERRUPT_MASK_RESET_K_1, tmp1 278 mtspr SPR_INTERRUPT_MASK_RESET_K_1, tmp1
265#endif 279#endif
266 280
281#define IRQ_ENABLE(tmp0, tmp1) \
282 IRQ_ENABLE_LOAD(tmp0, tmp1); \
283 IRQ_ENABLE_APPLY(tmp0, tmp1)
284
267/* 285/*
268 * Do the CPU's IRQ-state tracing from assembly code. We call a 286 * Do the CPU's IRQ-state tracing from assembly code. We call a
269 * C function, but almost everywhere we do, we don't mind clobbering 287 * C function, but almost everywhere we do, we don't mind clobbering
diff --git a/arch/tile/include/asm/kexec.h b/arch/tile/include/asm/kexec.h
index c11a6cc73bb..fc98ccfc98a 100644
--- a/arch/tile/include/asm/kexec.h
+++ b/arch/tile/include/asm/kexec.h
@@ -19,12 +19,24 @@
19 19
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22#ifndef __tilegx__
22/* Maximum physical address we can use pages from. */ 23/* Maximum physical address we can use pages from. */
23#define KEXEC_SOURCE_MEMORY_LIMIT TASK_SIZE 24#define KEXEC_SOURCE_MEMORY_LIMIT TASK_SIZE
24/* Maximum address we can reach in physical address mode. */ 25/* Maximum address we can reach in physical address mode. */
25#define KEXEC_DESTINATION_MEMORY_LIMIT TASK_SIZE 26#define KEXEC_DESTINATION_MEMORY_LIMIT TASK_SIZE
26/* Maximum address we can use for the control code buffer. */ 27/* Maximum address we can use for the control code buffer. */
27#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE 28#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
29#else
30/* We need to limit the memory below PGDIR_SIZE since
31 * we only setup page table for [0, PGDIR_SIZE) before final kexec.
32 */
33/* Maximum physical address we can use pages from. */
34#define KEXEC_SOURCE_MEMORY_LIMIT PGDIR_SIZE
35/* Maximum address we can reach in physical address mode. */
36#define KEXEC_DESTINATION_MEMORY_LIMIT PGDIR_SIZE
37/* Maximum address we can use for the control code buffer. */
38#define KEXEC_CONTROL_MEMORY_LIMIT PGDIR_SIZE
39#endif
28 40
29#define KEXEC_CONTROL_PAGE_SIZE PAGE_SIZE 41#define KEXEC_CONTROL_PAGE_SIZE PAGE_SIZE
30 42
diff --git a/arch/tile/include/asm/kvm_para.h b/arch/tile/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/tile/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/tile/include/asm/mmu.h b/arch/tile/include/asm/mmu.h
index 92f94c77b6e..e2c78909679 100644
--- a/arch/tile/include/asm/mmu.h
+++ b/arch/tile/include/asm/mmu.h
@@ -21,7 +21,7 @@ struct mm_context {
21 * Written under the mmap_sem semaphore; read without the 21 * Written under the mmap_sem semaphore; read without the
22 * semaphore but atomically, but it is conservatively set. 22 * semaphore but atomically, but it is conservatively set.
23 */ 23 */
24 unsigned int priority_cached; 24 unsigned long priority_cached;
25}; 25};
26 26
27typedef struct mm_context mm_context_t; 27typedef struct mm_context mm_context_t;
diff --git a/arch/tile/include/asm/mmu_context.h b/arch/tile/include/asm/mmu_context.h
index 15fb2464112..37f0b741dee 100644
--- a/arch/tile/include/asm/mmu_context.h
+++ b/arch/tile/include/asm/mmu_context.h
@@ -30,11 +30,15 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
30 return 0; 30 return 0;
31} 31}
32 32
33/* Note that arch/tile/kernel/head.S also calls hv_install_context() */ 33/*
34 * Note that arch/tile/kernel/head_NN.S and arch/tile/mm/migrate_NN.S
35 * also call hv_install_context().
36 */
34static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot) 37static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot)
35{ 38{
36 /* FIXME: DIRECTIO should not always be set. FIXME. */ 39 /* FIXME: DIRECTIO should not always be set. FIXME. */
37 int rc = hv_install_context(__pa(pgdir), prot, asid, HV_CTX_DIRECTIO); 40 int rc = hv_install_context(__pa(pgdir), prot, asid,
41 HV_CTX_DIRECTIO | CTX_PAGE_FLAG);
38 if (rc < 0) 42 if (rc < 0)
39 panic("hv_install_context failed: %d", rc); 43 panic("hv_install_context failed: %d", rc);
40} 44}
diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h
new file mode 100644
index 00000000000..44ed07ccd3d
--- /dev/null
+++ b/arch/tile/include/asm/module.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 */
14
15#ifndef _ASM_TILE_MODULE_H
16#define _ASM_TILE_MODULE_H
17
18#include <arch/chip.h>
19
20#include <asm-generic/module.h>
21
22/* We can't use modules built with different page sizes. */
23#if defined(CONFIG_PAGE_SIZE_16KB)
24# define MODULE_PGSZ " 16KB"
25#elif defined(CONFIG_PAGE_SIZE_64KB)
26# define MODULE_PGSZ " 64KB"
27#else
28# define MODULE_PGSZ ""
29#endif
30
31/* We don't really support no-SMP so tag if someone tries. */
32#ifdef CONFIG_SMP
33#define MODULE_NOSMP ""
34#else
35#define MODULE_NOSMP " nosmp"
36#endif
37
38#define MODULE_ARCH_VERMAGIC CHIP_ARCH_NAME MODULE_PGSZ MODULE_NOSMP
39
40#endif /* _ASM_TILE_MODULE_H */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index db93518fac0..9d9131e5c55 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -20,8 +20,17 @@
20#include <arch/chip.h> 20#include <arch/chip.h>
21 21
22/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ 22/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
23#define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL 23#if defined(CONFIG_PAGE_SIZE_16KB)
24#define HPAGE_SHIFT HV_LOG2_PAGE_SIZE_LARGE 24#define PAGE_SHIFT 14
25#define CTX_PAGE_FLAG HV_CTX_PG_SM_16K
26#elif defined(CONFIG_PAGE_SIZE_64KB)
27#define PAGE_SHIFT 16
28#define CTX_PAGE_FLAG HV_CTX_PG_SM_64K
29#else
30#define PAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_SMALL
31#define CTX_PAGE_FLAG 0
32#endif
33#define HPAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_LARGE
25 34
26#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) 35#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
27#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) 36#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
@@ -78,8 +87,7 @@ typedef HV_PTE pgprot_t;
78/* 87/*
79 * User L2 page tables are managed as one L2 page table per page, 88 * User L2 page tables are managed as one L2 page table per page,
80 * because we use the page allocator for them. This keeps the allocation 89 * because we use the page allocator for them. This keeps the allocation
81 * simple and makes it potentially useful to implement HIGHPTE at some point. 90 * simple, but it's also inefficient, since L2 page tables are much smaller
82 * However, it's also inefficient, since L2 page tables are much smaller
83 * than pages (currently 2KB vs 64KB). So we should revisit this. 91 * than pages (currently 2KB vs 64KB). So we should revisit this.
84 */ 92 */
85typedef struct page *pgtable_t; 93typedef struct page *pgtable_t;
@@ -128,7 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size)
128 136
129#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 137#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
130 138
131#define HUGE_MAX_HSTATE 2 139#define HUGE_MAX_HSTATE 6
132 140
133#ifdef CONFIG_HUGETLB_PAGE 141#ifdef CONFIG_HUGETLB_PAGE
134#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA 142#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h
index e919c0bdc22..1b902508b66 100644
--- a/arch/tile/include/asm/pgalloc.h
+++ b/arch/tile/include/asm/pgalloc.h
@@ -19,24 +19,24 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/mmzone.h> 20#include <linux/mmzone.h>
21#include <asm/fixmap.h> 21#include <asm/fixmap.h>
22#include <asm/page.h>
22#include <hv/hypervisor.h> 23#include <hv/hypervisor.h>
23 24
24/* Bits for the size of the second-level page table. */ 25/* Bits for the size of the second-level page table. */
25#define L2_KERNEL_PGTABLE_SHIFT \ 26#define L2_KERNEL_PGTABLE_SHIFT _HV_LOG2_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
26 (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL + HV_LOG2_PTE_SIZE) 27
28/* How big is a kernel L2 page table? */
29#define L2_KERNEL_PGTABLE_SIZE (1UL << L2_KERNEL_PGTABLE_SHIFT)
27 30
28/* We currently allocate user L2 page tables by page (unlike kernel L2s). */ 31/* We currently allocate user L2 page tables by page (unlike kernel L2s). */
29#if L2_KERNEL_PGTABLE_SHIFT < HV_LOG2_PAGE_SIZE_SMALL 32#if L2_KERNEL_PGTABLE_SHIFT < PAGE_SHIFT
30#define L2_USER_PGTABLE_SHIFT HV_LOG2_PAGE_SIZE_SMALL 33#define L2_USER_PGTABLE_SHIFT PAGE_SHIFT
31#else 34#else
32#define L2_USER_PGTABLE_SHIFT L2_KERNEL_PGTABLE_SHIFT 35#define L2_USER_PGTABLE_SHIFT L2_KERNEL_PGTABLE_SHIFT
33#endif 36#endif
34 37
35/* How many pages do we need, as an "order", for a user L2 page table? */ 38/* How many pages do we need, as an "order", for a user L2 page table? */
36#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - HV_LOG2_PAGE_SIZE_SMALL) 39#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - PAGE_SHIFT)
37
38/* How big is a kernel L2 page table? */
39#define L2_KERNEL_PGTABLE_SIZE (1 << L2_KERNEL_PGTABLE_SHIFT)
40 40
41static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) 41static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
42{ 42{
@@ -50,14 +50,14 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
50static inline void pmd_populate_kernel(struct mm_struct *mm, 50static inline void pmd_populate_kernel(struct mm_struct *mm,
51 pmd_t *pmd, pte_t *ptep) 51 pmd_t *pmd, pte_t *ptep)
52{ 52{
53 set_pmd(pmd, ptfn_pmd(__pa(ptep) >> HV_LOG2_PAGE_TABLE_ALIGN, 53 set_pmd(pmd, ptfn_pmd(HV_CPA_TO_PTFN(__pa(ptep)),
54 __pgprot(_PAGE_PRESENT))); 54 __pgprot(_PAGE_PRESENT)));
55} 55}
56 56
57static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 57static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
58 pgtable_t page) 58 pgtable_t page)
59{ 59{
60 set_pmd(pmd, ptfn_pmd(HV_PFN_TO_PTFN(page_to_pfn(page)), 60 set_pmd(pmd, ptfn_pmd(HV_CPA_TO_PTFN(PFN_PHYS(page_to_pfn(page))),
61 __pgprot(_PAGE_PRESENT))); 61 __pgprot(_PAGE_PRESENT)));
62} 62}
63 63
@@ -68,8 +68,20 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
68extern pgd_t *pgd_alloc(struct mm_struct *mm); 68extern pgd_t *pgd_alloc(struct mm_struct *mm);
69extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); 69extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
70 70
71extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address); 71extern pgtable_t pgtable_alloc_one(struct mm_struct *mm, unsigned long address,
72extern void pte_free(struct mm_struct *mm, struct page *pte); 72 int order);
73extern void pgtable_free(struct mm_struct *mm, struct page *pte, int order);
74
75static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
76 unsigned long address)
77{
78 return pgtable_alloc_one(mm, address, L2_USER_PGTABLE_ORDER);
79}
80
81static inline void pte_free(struct mm_struct *mm, struct page *pte)
82{
83 pgtable_free(mm, pte, L2_USER_PGTABLE_ORDER);
84}
73 85
74#define pmd_pgtable(pmd) pmd_page(pmd) 86#define pmd_pgtable(pmd) pmd_page(pmd)
75 87
@@ -85,8 +97,13 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
85 pte_free(mm, virt_to_page(pte)); 97 pte_free(mm, virt_to_page(pte));
86} 98}
87 99
88extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte, 100extern void __pgtable_free_tlb(struct mmu_gather *tlb, struct page *pte,
89 unsigned long address); 101 unsigned long address, int order);
102static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
103 unsigned long address)
104{
105 __pgtable_free_tlb(tlb, pte, address, L2_USER_PGTABLE_ORDER);
106}
90 107
91#define check_pgt_cache() do { } while (0) 108#define check_pgt_cache() do { } while (0)
92 109
@@ -104,19 +121,44 @@ void shatter_pmd(pmd_t *pmd);
104void shatter_huge_page(unsigned long addr); 121void shatter_huge_page(unsigned long addr);
105 122
106#ifdef __tilegx__ 123#ifdef __tilegx__
107/* We share a single page allocator for both L1 and L2 page tables. */ 124
108#if HV_L1_SIZE != HV_L2_SIZE
109# error Rework assumption that L1 and L2 page tables are same size.
110#endif
111#define L1_USER_PGTABLE_ORDER L2_USER_PGTABLE_ORDER
112#define pud_populate(mm, pud, pmd) \ 125#define pud_populate(mm, pud, pmd) \
113 pmd_populate_kernel((mm), (pmd_t *)(pud), (pte_t *)(pmd)) 126 pmd_populate_kernel((mm), (pmd_t *)(pud), (pte_t *)(pmd))
114#define pmd_alloc_one(mm, addr) \ 127
115 ((pmd_t *)page_to_virt(pte_alloc_one((mm), (addr)))) 128/* Bits for the size of the L1 (intermediate) page table. */
116#define pmd_free(mm, pmdp) \ 129#define L1_KERNEL_PGTABLE_SHIFT _HV_LOG2_L1_SIZE(HPAGE_SHIFT)
117 pte_free((mm), virt_to_page(pmdp)) 130
118#define __pmd_free_tlb(tlb, pmdp, address) \ 131/* How big is a kernel L2 page table? */
119 __pte_free_tlb((tlb), virt_to_page(pmdp), (address)) 132#define L1_KERNEL_PGTABLE_SIZE (1UL << L1_KERNEL_PGTABLE_SHIFT)
133
134/* We currently allocate L1 page tables by page. */
135#if L1_KERNEL_PGTABLE_SHIFT < PAGE_SHIFT
136#define L1_USER_PGTABLE_SHIFT PAGE_SHIFT
137#else
138#define L1_USER_PGTABLE_SHIFT L1_KERNEL_PGTABLE_SHIFT
120#endif 139#endif
121 140
141/* How many pages do we need, as an "order", for an L1 page table? */
142#define L1_USER_PGTABLE_ORDER (L1_USER_PGTABLE_SHIFT - PAGE_SHIFT)
143
144static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
145{
146 struct page *p = pgtable_alloc_one(mm, address, L1_USER_PGTABLE_ORDER);
147 return (pmd_t *)page_to_virt(p);
148}
149
150static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
151{
152 pgtable_free(mm, virt_to_page(pmdp), L1_USER_PGTABLE_ORDER);
153}
154
155static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
156 unsigned long address)
157{
158 __pgtable_free_tlb(tlb, virt_to_page(pmdp), address,
159 L1_USER_PGTABLE_ORDER);
160}
161
162#endif /* __tilegx__ */
163
122#endif /* _ASM_TILE_PGALLOC_H */ 164#endif /* _ASM_TILE_PGALLOC_H */
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
index 67490910774..73b1a4c9ad0 100644
--- a/arch/tile/include/asm/pgtable.h
+++ b/arch/tile/include/asm/pgtable.h
@@ -27,8 +27,10 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/pfn.h>
30#include <asm/processor.h> 31#include <asm/processor.h>
31#include <asm/fixmap.h> 32#include <asm/fixmap.h>
33#include <asm/page.h>
32 34
33struct mm_struct; 35struct mm_struct;
34struct vm_area_struct; 36struct vm_area_struct;
@@ -69,6 +71,7 @@ extern void set_page_homes(void);
69 71
70#define _PAGE_PRESENT HV_PTE_PRESENT 72#define _PAGE_PRESENT HV_PTE_PRESENT
71#define _PAGE_HUGE_PAGE HV_PTE_PAGE 73#define _PAGE_HUGE_PAGE HV_PTE_PAGE
74#define _PAGE_SUPER_PAGE HV_PTE_SUPER
72#define _PAGE_READABLE HV_PTE_READABLE 75#define _PAGE_READABLE HV_PTE_READABLE
73#define _PAGE_WRITABLE HV_PTE_WRITABLE 76#define _PAGE_WRITABLE HV_PTE_WRITABLE
74#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE 77#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE
@@ -85,6 +88,7 @@ extern void set_page_homes(void);
85#define _PAGE_ALL (\ 88#define _PAGE_ALL (\
86 _PAGE_PRESENT | \ 89 _PAGE_PRESENT | \
87 _PAGE_HUGE_PAGE | \ 90 _PAGE_HUGE_PAGE | \
91 _PAGE_SUPER_PAGE | \
88 _PAGE_READABLE | \ 92 _PAGE_READABLE | \
89 _PAGE_WRITABLE | \ 93 _PAGE_WRITABLE | \
90 _PAGE_EXECUTABLE | \ 94 _PAGE_EXECUTABLE | \
@@ -162,7 +166,7 @@ extern void set_page_homes(void);
162 (pgprot_t) { ((oldprot).val & ~_PAGE_ALL) | (newprot).val } 166 (pgprot_t) { ((oldprot).val & ~_PAGE_ALL) | (newprot).val }
163 167
164/* Just setting the PFN to zero suffices. */ 168/* Just setting the PFN to zero suffices. */
165#define pte_pgprot(x) hv_pte_set_pfn((x), 0) 169#define pte_pgprot(x) hv_pte_set_pa((x), 0)
166 170
167/* 171/*
168 * For PTEs and PDEs, we must clear the Present bit first when 172 * For PTEs and PDEs, we must clear the Present bit first when
@@ -187,6 +191,7 @@ static inline void __pte_clear(pte_t *ptep)
187 * Undefined behaviour if not.. 191 * Undefined behaviour if not..
188 */ 192 */
189#define pte_present hv_pte_get_present 193#define pte_present hv_pte_get_present
194#define pte_mknotpresent hv_pte_clear_present
190#define pte_user hv_pte_get_user 195#define pte_user hv_pte_get_user
191#define pte_read hv_pte_get_readable 196#define pte_read hv_pte_get_readable
192#define pte_dirty hv_pte_get_dirty 197#define pte_dirty hv_pte_get_dirty
@@ -194,6 +199,7 @@ static inline void __pte_clear(pte_t *ptep)
194#define pte_write hv_pte_get_writable 199#define pte_write hv_pte_get_writable
195#define pte_exec hv_pte_get_executable 200#define pte_exec hv_pte_get_executable
196#define pte_huge hv_pte_get_page 201#define pte_huge hv_pte_get_page
202#define pte_super hv_pte_get_super
197#define pte_rdprotect hv_pte_clear_readable 203#define pte_rdprotect hv_pte_clear_readable
198#define pte_exprotect hv_pte_clear_executable 204#define pte_exprotect hv_pte_clear_executable
199#define pte_mkclean hv_pte_clear_dirty 205#define pte_mkclean hv_pte_clear_dirty
@@ -206,6 +212,7 @@ static inline void __pte_clear(pte_t *ptep)
206#define pte_mkyoung hv_pte_set_accessed 212#define pte_mkyoung hv_pte_set_accessed
207#define pte_mkwrite hv_pte_set_writable 213#define pte_mkwrite hv_pte_set_writable
208#define pte_mkhuge hv_pte_set_page 214#define pte_mkhuge hv_pte_set_page
215#define pte_mksuper hv_pte_set_super
209 216
210#define pte_special(pte) 0 217#define pte_special(pte) 0
211#define pte_mkspecial(pte) (pte) 218#define pte_mkspecial(pte) (pte)
@@ -261,7 +268,7 @@ static inline int pte_none(pte_t pte)
261 268
262static inline unsigned long pte_pfn(pte_t pte) 269static inline unsigned long pte_pfn(pte_t pte)
263{ 270{
264 return hv_pte_get_pfn(pte); 271 return PFN_DOWN(hv_pte_get_pa(pte));
265} 272}
266 273
267/* Set or get the remote cache cpu in a pgprot with remote caching. */ 274/* Set or get the remote cache cpu in a pgprot with remote caching. */
@@ -270,7 +277,7 @@ extern int get_remote_cache_cpu(pgprot_t prot);
270 277
271static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) 278static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
272{ 279{
273 return hv_pte_set_pfn(prot, pfn); 280 return hv_pte_set_pa(prot, PFN_PHYS(pfn));
274} 281}
275 282
276/* Support for priority mappings. */ 283/* Support for priority mappings. */
@@ -312,7 +319,7 @@ extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next);
312 */ 319 */
313static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 320static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
314{ 321{
315 return pfn_pte(hv_pte_get_pfn(pte), newprot); 322 return pfn_pte(pte_pfn(pte), newprot);
316} 323}
317 324
318/* 325/*
@@ -335,13 +342,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
335 */ 342 */
336#define pgd_offset_k(address) pgd_offset(&init_mm, address) 343#define pgd_offset_k(address) pgd_offset(&init_mm, address)
337 344
338#if defined(CONFIG_HIGHPTE)
339extern pte_t *pte_offset_map(pmd_t *, unsigned long address);
340#define pte_unmap(pte) kunmap_atomic(pte)
341#else
342#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) 345#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
343#define pte_unmap(pte) do { } while (0) 346#define pte_unmap(pte) do { } while (0)
344#endif
345 347
346/* Clear a non-executable kernel PTE and flush it from the TLB. */ 348/* Clear a non-executable kernel PTE and flush it from the TLB. */
347#define kpte_clear_flush(ptep, vaddr) \ 349#define kpte_clear_flush(ptep, vaddr) \
@@ -410,6 +412,46 @@ static inline unsigned long pmd_index(unsigned long address)
410 return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); 412 return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
411} 413}
412 414
415#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
416static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
417 unsigned long address,
418 pmd_t *pmdp)
419{
420 return ptep_test_and_clear_young(vma, address, pmdp_ptep(pmdp));
421}
422
423#define __HAVE_ARCH_PMDP_SET_WRPROTECT
424static inline void pmdp_set_wrprotect(struct mm_struct *mm,
425 unsigned long address, pmd_t *pmdp)
426{
427 ptep_set_wrprotect(mm, address, pmdp_ptep(pmdp));
428}
429
430
431#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
432static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
433 unsigned long address,
434 pmd_t *pmdp)
435{
436 return pte_pmd(ptep_get_and_clear(mm, address, pmdp_ptep(pmdp)));
437}
438
439static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
440{
441 set_pte(pmdp_ptep(pmdp), pmd_pte(pmdval));
442}
443
444#define set_pmd_at(mm, addr, pmdp, pmdval) __set_pmd(pmdp, pmdval)
445
446/* Create a pmd from a PTFN. */
447static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
448{
449 return pte_pmd(hv_pte_set_ptfn(prot, ptfn));
450}
451
452/* Return the page-table frame number (ptfn) that a pmd_t points at. */
453#define pmd_ptfn(pmd) hv_pte_get_ptfn(pmd_pte(pmd))
454
413/* 455/*
414 * A given kernel pmd_t maps to a specific virtual address (either a 456 * A given kernel pmd_t maps to a specific virtual address (either a
415 * kernel huge page or a kernel pte_t table). Since kernel pte_t 457 * kernel huge page or a kernel pte_t table). Since kernel pte_t
@@ -430,7 +472,48 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
430 * OK for pte_lockptr(), since we just end up with potentially one 472 * OK for pte_lockptr(), since we just end up with potentially one
431 * lock being used for several pte_t arrays. 473 * lock being used for several pte_t arrays.
432 */ 474 */
433#define pmd_page(pmd) pfn_to_page(HV_PTFN_TO_PFN(pmd_ptfn(pmd))) 475#define pmd_page(pmd) pfn_to_page(PFN_DOWN(HV_PTFN_TO_CPA(pmd_ptfn(pmd))))
476
477static inline void pmd_clear(pmd_t *pmdp)
478{
479 __pte_clear(pmdp_ptep(pmdp));
480}
481
482#define pmd_mknotpresent(pmd) pte_pmd(pte_mknotpresent(pmd_pte(pmd)))
483#define pmd_young(pmd) pte_young(pmd_pte(pmd))
484#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
485#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
486#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
487#define pmd_write(pmd) pte_write(pmd_pte(pmd))
488#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
489#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
490#define pmd_huge_page(pmd) pte_huge(pmd_pte(pmd))
491#define pmd_mkhuge(pmd) pte_pmd(pte_mkhuge(pmd_pte(pmd)))
492#define __HAVE_ARCH_PMD_WRITE
493
494#define pfn_pmd(pfn, pgprot) pte_pmd(pfn_pte((pfn), (pgprot)))
495#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
496#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot))
497
498static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
499{
500 return pfn_pmd(pmd_pfn(pmd), newprot);
501}
502
503#ifdef CONFIG_TRANSPARENT_HUGEPAGE
504#define has_transparent_hugepage() 1
505#define pmd_trans_huge pmd_huge_page
506
507static inline pmd_t pmd_mksplitting(pmd_t pmd)
508{
509 return pte_pmd(hv_pte_set_client2(pmd_pte(pmd)));
510}
511
512static inline int pmd_trans_splitting(pmd_t pmd)
513{
514 return hv_pte_get_client2(pmd_pte(pmd));
515}
516#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
434 517
435/* 518/*
436 * The pte page can be thought of an array like this: pte_t[PTRS_PER_PTE] 519 * The pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
@@ -448,17 +531,13 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
448 return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address); 531 return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
449} 532}
450 533
451static inline int pmd_huge_page(pmd_t pmd)
452{
453 return pmd_val(pmd) & _PAGE_HUGE_PAGE;
454}
455
456#include <asm-generic/pgtable.h> 534#include <asm-generic/pgtable.h>
457 535
458/* Support /proc/NN/pgtable API. */ 536/* Support /proc/NN/pgtable API. */
459struct seq_file; 537struct seq_file;
460int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm, 538int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
461 unsigned long vaddr, pte_t *ptep, void **datap); 539 unsigned long vaddr, unsigned long pagesize,
540 pte_t *ptep, void **datap);
462 541
463#endif /* !__ASSEMBLY__ */ 542#endif /* !__ASSEMBLY__ */
464 543
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h
index 9f98529761f..4ce4a7a99c2 100644
--- a/arch/tile/include/asm/pgtable_32.h
+++ b/arch/tile/include/asm/pgtable_32.h
@@ -20,11 +20,12 @@
20 * The level-1 index is defined by the huge page size. A PGD is composed 20 * The level-1 index is defined by the huge page size. A PGD is composed
21 * of PTRS_PER_PGD pgd_t's and is the top level of the page table. 21 * of PTRS_PER_PGD pgd_t's and is the top level of the page table.
22 */ 22 */
23#define PGDIR_SHIFT HV_LOG2_PAGE_SIZE_LARGE 23#define PGDIR_SHIFT HPAGE_SHIFT
24#define PGDIR_SIZE HV_PAGE_SIZE_LARGE 24#define PGDIR_SIZE HPAGE_SIZE
25#define PGDIR_MASK (~(PGDIR_SIZE-1)) 25#define PGDIR_MASK (~(PGDIR_SIZE-1))
26#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) 26#define PTRS_PER_PGD _HV_L1_ENTRIES(HPAGE_SHIFT)
27#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t)) 27#define PGD_INDEX(va) _HV_L1_INDEX(va, HPAGE_SHIFT)
28#define SIZEOF_PGD _HV_L1_SIZE(HPAGE_SHIFT)
28 29
29/* 30/*
30 * The level-2 index is defined by the difference between the huge 31 * The level-2 index is defined by the difference between the huge
@@ -33,8 +34,9 @@
33 * Note that the hypervisor docs use PTE for what we call pte_t, so 34 * Note that the hypervisor docs use PTE for what we call pte_t, so
34 * this nomenclature is somewhat confusing. 35 * this nomenclature is somewhat confusing.
35 */ 36 */
36#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) 37#define PTRS_PER_PTE _HV_L2_ENTRIES(HPAGE_SHIFT, PAGE_SHIFT)
37#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t)) 38#define PTE_INDEX(va) _HV_L2_INDEX(va, HPAGE_SHIFT, PAGE_SHIFT)
39#define SIZEOF_PTE _HV_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
38 40
39#ifndef __ASSEMBLY__ 41#ifndef __ASSEMBLY__
40 42
@@ -111,24 +113,14 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
111 return pte; 113 return pte;
112} 114}
113 115
114static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval) 116/*
115{ 117 * pmds are wrappers around pgds, which are the same as ptes.
116 set_pte(&pmdp->pud.pgd, pmdval.pud.pgd); 118 * It's often convenient to "cast" back and forth and use the pte methods,
117} 119 * which are the methods supplied by the hypervisor.
118 120 */
119/* Create a pmd from a PTFN. */ 121#define pmd_pte(pmd) ((pmd).pud.pgd)
120static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) 122#define pmdp_ptep(pmdp) (&(pmdp)->pud.pgd)
121{ 123#define pte_pmd(pte) ((pmd_t){ { (pte) } })
122 return (pmd_t){ { hv_pte_set_ptfn(prot, ptfn) } };
123}
124
125/* Return the page-table frame number (ptfn) that a pmd_t points at. */
126#define pmd_ptfn(pmd) hv_pte_get_ptfn((pmd).pud.pgd)
127
128static inline void pmd_clear(pmd_t *pmdp)
129{
130 __pte_clear(&pmdp->pud.pgd);
131}
132 124
133#endif /* __ASSEMBLY__ */ 125#endif /* __ASSEMBLY__ */
134 126
diff --git a/arch/tile/include/asm/pgtable_64.h b/arch/tile/include/asm/pgtable_64.h
index fd80328523b..2492fa5478e 100644
--- a/arch/tile/include/asm/pgtable_64.h
+++ b/arch/tile/include/asm/pgtable_64.h
@@ -21,17 +21,19 @@
21#define PGDIR_SIZE HV_L1_SPAN 21#define PGDIR_SIZE HV_L1_SPAN
22#define PGDIR_MASK (~(PGDIR_SIZE-1)) 22#define PGDIR_MASK (~(PGDIR_SIZE-1))
23#define PTRS_PER_PGD HV_L0_ENTRIES 23#define PTRS_PER_PGD HV_L0_ENTRIES
24#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t)) 24#define PGD_INDEX(va) HV_L0_INDEX(va)
25#define SIZEOF_PGD HV_L0_SIZE
25 26
26/* 27/*
27 * The level-1 index is defined by the huge page size. A PMD is composed 28 * The level-1 index is defined by the huge page size. A PMD is composed
28 * of PTRS_PER_PMD pgd_t's and is the middle level of the page table. 29 * of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
29 */ 30 */
30#define PMD_SHIFT HV_LOG2_PAGE_SIZE_LARGE 31#define PMD_SHIFT HPAGE_SHIFT
31#define PMD_SIZE HV_PAGE_SIZE_LARGE 32#define PMD_SIZE HPAGE_SIZE
32#define PMD_MASK (~(PMD_SIZE-1)) 33#define PMD_MASK (~(PMD_SIZE-1))
33#define PTRS_PER_PMD (1 << (PGDIR_SHIFT - PMD_SHIFT)) 34#define PTRS_PER_PMD _HV_L1_ENTRIES(HPAGE_SHIFT)
34#define SIZEOF_PMD (PTRS_PER_PMD * sizeof(pmd_t)) 35#define PMD_INDEX(va) _HV_L1_INDEX(va, HPAGE_SHIFT)
36#define SIZEOF_PMD _HV_L1_SIZE(HPAGE_SHIFT)
35 37
36/* 38/*
37 * The level-2 index is defined by the difference between the huge 39 * The level-2 index is defined by the difference between the huge
@@ -40,17 +42,19 @@
40 * Note that the hypervisor docs use PTE for what we call pte_t, so 42 * Note that the hypervisor docs use PTE for what we call pte_t, so
41 * this nomenclature is somewhat confusing. 43 * this nomenclature is somewhat confusing.
42 */ 44 */
43#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) 45#define PTRS_PER_PTE _HV_L2_ENTRIES(HPAGE_SHIFT, PAGE_SHIFT)
44#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t)) 46#define PTE_INDEX(va) _HV_L2_INDEX(va, HPAGE_SHIFT, PAGE_SHIFT)
47#define SIZEOF_PTE _HV_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
45 48
46/* 49/*
47 * Align the vmalloc area to an L2 page table, and leave a guard page 50 * Align the vmalloc area to an L2 page table. Omit guard pages at
48 * at the beginning and end. The vmalloc code also puts in an internal 51 * the beginning and end for simplicity (particularly in the per-cpu
52 * memory allocation code). The vmalloc code puts in an internal
49 * guard page between each allocation. 53 * guard page between each allocation.
50 */ 54 */
51#define _VMALLOC_END HUGE_VMAP_BASE 55#define _VMALLOC_END HUGE_VMAP_BASE
52#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE) 56#define VMALLOC_END _VMALLOC_END
53#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE) 57#define VMALLOC_START _VMALLOC_START
54 58
55#define HUGE_VMAP_END (HUGE_VMAP_BASE + PGDIR_SIZE) 59#define HUGE_VMAP_END (HUGE_VMAP_BASE + PGDIR_SIZE)
56 60
@@ -98,7 +102,7 @@ static inline int pud_bad(pud_t pud)
98 * A pud_t points to a pmd_t array. Since we can have multiple per 102 * A pud_t points to a pmd_t array. Since we can have multiple per
99 * page, we don't have a one-to-one mapping of pud_t's to pages. 103 * page, we don't have a one-to-one mapping of pud_t's to pages.
100 */ 104 */
101#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud))) 105#define pud_page(pud) pfn_to_page(PFN_DOWN(HV_PTFN_TO_CPA(pud_ptfn(pud))))
102 106
103static inline unsigned long pud_index(unsigned long address) 107static inline unsigned long pud_index(unsigned long address)
104{ 108{
@@ -108,28 +112,6 @@ static inline unsigned long pud_index(unsigned long address)
108#define pmd_offset(pud, address) \ 112#define pmd_offset(pud, address) \
109 ((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address)) 113 ((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
110 114
111static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
112{
113 set_pte(pmdp, pmdval);
114}
115
116/* Create a pmd from a PTFN and pgprot. */
117static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
118{
119 return hv_pte_set_ptfn(prot, ptfn);
120}
121
122/* Return the page-table frame number (ptfn) that a pmd_t points at. */
123static inline unsigned long pmd_ptfn(pmd_t pmd)
124{
125 return hv_pte_get_ptfn(pmd);
126}
127
128static inline void pmd_clear(pmd_t *pmdp)
129{
130 __pte_clear(pmdp);
131}
132
133/* Normalize an address to having the correct high bits set. */ 115/* Normalize an address to having the correct high bits set. */
134#define pgd_addr_normalize pgd_addr_normalize 116#define pgd_addr_normalize pgd_addr_normalize
135static inline unsigned long pgd_addr_normalize(unsigned long addr) 117static inline unsigned long pgd_addr_normalize(unsigned long addr)
@@ -170,6 +152,13 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
170 return hv_pte(__insn_exch(&ptep->val, 0UL)); 152 return hv_pte(__insn_exch(&ptep->val, 0UL));
171} 153}
172 154
155/*
156 * pmds are the same as pgds and ptes, so converting is a no-op.
157 */
158#define pmd_pte(pmd) (pmd)
159#define pmdp_ptep(pmdp) (pmdp)
160#define pte_pmd(pte) (pte)
161
173#endif /* __ASSEMBLY__ */ 162#endif /* __ASSEMBLY__ */
174 163
175#endif /* _ASM_TILE_PGTABLE_64_H */ 164#endif /* _ASM_TILE_PGTABLE_64_H */
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index 15cd8a4a06c..8c4dd9ff91e 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -76,6 +76,17 @@ struct async_tlb {
76 76
77#ifdef CONFIG_HARDWALL 77#ifdef CONFIG_HARDWALL
78struct hardwall_info; 78struct hardwall_info;
79struct hardwall_task {
80 /* Which hardwall is this task tied to? (or NULL if none) */
81 struct hardwall_info *info;
82 /* Chains this task into the list at info->task_head. */
83 struct list_head list;
84};
85#ifdef __tilepro__
86#define HARDWALL_TYPES 1 /* udn */
87#else
88#define HARDWALL_TYPES 3 /* udn, idn, and ipi */
89#endif
79#endif 90#endif
80 91
81struct thread_struct { 92struct thread_struct {
@@ -116,10 +127,8 @@ struct thread_struct {
116 unsigned long dstream_pf; 127 unsigned long dstream_pf;
117#endif 128#endif
118#ifdef CONFIG_HARDWALL 129#ifdef CONFIG_HARDWALL
119 /* Is this task tied to an activated hardwall? */ 130 /* Hardwall information for various resources. */
120 struct hardwall_info *hardwall; 131 struct hardwall_task hardwall[HARDWALL_TYPES];
121 /* Chains this task into the list at hardwall->list. */
122 struct list_head hardwall_list;
123#endif 132#endif
124#if CHIP_HAS_TILE_DMA() 133#if CHIP_HAS_TILE_DMA()
125 /* Async DMA TLB fault information */ 134 /* Async DMA TLB fault information */
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
index e58613e0752..c67eb70ea78 100644
--- a/arch/tile/include/asm/setup.h
+++ b/arch/tile/include/asm/setup.h
@@ -41,15 +41,15 @@ void restrict_dma_mpls(void);
41#ifdef CONFIG_HARDWALL 41#ifdef CONFIG_HARDWALL
42/* User-level network management functions */ 42/* User-level network management functions */
43void reset_network_state(void); 43void reset_network_state(void);
44void grant_network_mpls(void);
45void restrict_network_mpls(void);
46struct task_struct; 44struct task_struct;
47int hardwall_deactivate(struct task_struct *task); 45void hardwall_switch_tasks(struct task_struct *prev, struct task_struct *next);
46void hardwall_deactivate_all(struct task_struct *task);
47int hardwall_ipi_valid(int cpu);
48 48
49/* Hook hardwall code into changes in affinity. */ 49/* Hook hardwall code into changes in affinity. */
50#define arch_set_cpus_allowed(p, new_mask) do { \ 50#define arch_set_cpus_allowed(p, new_mask) do { \
51 if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \ 51 if (!cpumask_equal(&p->cpus_allowed, new_mask)) \
52 hardwall_deactivate(p); \ 52 hardwall_deactivate_all(p); \
53} while (0) 53} while (0)
54#endif 54#endif
55 55
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h
index 3b5507c31ea..06f0464cfed 100644
--- a/arch/tile/include/asm/syscalls.h
+++ b/arch/tile/include/asm/syscalls.h
@@ -43,7 +43,8 @@ long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
43 u32 len, int advice); 43 u32 len, int advice);
44int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi, 44int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
45 u32 len_lo, u32 len_hi, int advice); 45 u32 len_lo, u32 len_hi, int advice);
46long sys_flush_cache(void); 46long sys_cacheflush(unsigned long addr, unsigned long len,
47 unsigned long flags);
47#ifndef __tilegx__ /* No mmap() in the 32-bit kernel. */ 48#ifndef __tilegx__ /* No mmap() in the 32-bit kernel. */
48#define sys_mmap sys_mmap 49#define sys_mmap sys_mmap
49#endif 50#endif
diff --git a/arch/tile/include/asm/tlbflush.h b/arch/tile/include/asm/tlbflush.h
index 96199d214fb..dcf91b25a1e 100644
--- a/arch/tile/include/asm/tlbflush.h
+++ b/arch/tile/include/asm/tlbflush.h
@@ -38,16 +38,11 @@ DECLARE_PER_CPU(int, current_asid);
38/* The hypervisor tells us what ASIDs are available to us. */ 38/* The hypervisor tells us what ASIDs are available to us. */
39extern int min_asid, max_asid; 39extern int min_asid, max_asid;
40 40
41static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
42{
43 return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
44}
45
46/* Pass as vma pointer for non-executable mapping, if no vma available. */ 41/* Pass as vma pointer for non-executable mapping, if no vma available. */
47#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL) 42#define FLUSH_NONEXEC ((struct vm_area_struct *)-1UL)
48 43
49/* Flush a single user page on this cpu. */ 44/* Flush a single user page on this cpu. */
50static inline void local_flush_tlb_page(const struct vm_area_struct *vma, 45static inline void local_flush_tlb_page(struct vm_area_struct *vma,
51 unsigned long addr, 46 unsigned long addr,
52 unsigned long page_size) 47 unsigned long page_size)
53{ 48{
@@ -60,7 +55,7 @@ static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
60} 55}
61 56
62/* Flush range of user pages on this cpu. */ 57/* Flush range of user pages on this cpu. */
63static inline void local_flush_tlb_pages(const struct vm_area_struct *vma, 58static inline void local_flush_tlb_pages(struct vm_area_struct *vma,
64 unsigned long addr, 59 unsigned long addr,
65 unsigned long page_size, 60 unsigned long page_size,
66 unsigned long len) 61 unsigned long len)
@@ -117,10 +112,10 @@ extern void flush_tlb_all(void);
117extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 112extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
118extern void flush_tlb_current_task(void); 113extern void flush_tlb_current_task(void);
119extern void flush_tlb_mm(struct mm_struct *); 114extern void flush_tlb_mm(struct mm_struct *);
120extern void flush_tlb_page(const struct vm_area_struct *, unsigned long); 115extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
121extern void flush_tlb_page_mm(const struct vm_area_struct *, 116extern void flush_tlb_page_mm(struct vm_area_struct *,
122 struct mm_struct *, unsigned long); 117 struct mm_struct *, unsigned long);
123extern void flush_tlb_range(const struct vm_area_struct *, 118extern void flush_tlb_range(struct vm_area_struct *,
124 unsigned long start, unsigned long end); 119 unsigned long start, unsigned long end);
125 120
126#define flush_tlb() flush_tlb_current_task() 121#define flush_tlb() flush_tlb_current_task()
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
index ef34d2caa5b..c3dd275f25e 100644
--- a/arch/tile/include/asm/uaccess.h
+++ b/arch/tile/include/asm/uaccess.h
@@ -114,45 +114,75 @@ struct exception_table_entry {
114extern int fixup_exception(struct pt_regs *regs); 114extern int fixup_exception(struct pt_regs *regs);
115 115
116/* 116/*
117 * We return the __get_user_N function results in a structure, 117 * Support macros for __get_user().
118 * thus in r0 and r1. If "err" is zero, "val" is the result 118 *
119 * of the read; otherwise, "err" is -EFAULT. 119 * Implementation note: The "case 8" logic of casting to the type of
120 * 120 * the result of subtracting the value from itself is basically a way
121 * We rarely need 8-byte values on a 32-bit architecture, but 121 * of keeping all integer types the same, but casting any pointers to
122 * we size the structure to accommodate. In practice, for the 122 * ptrdiff_t, i.e. also an integer type. This way there are no
123 * the smaller reads, we can zero the high word for free, and 123 * questionable casts seen by the compiler on an ILP32 platform.
124 * the caller will ignore it by virtue of casting anyway. 124 *
125 * Note that __get_user() and __put_user() assume proper alignment.
125 */ 126 */
126struct __get_user {
127 unsigned long long val;
128 int err;
129};
130 127
131/* 128#ifdef __LP64__
132 * FIXME: we should express these as inline extended assembler, since 129#define _ASM_PTR ".quad"
133 * they're fundamentally just a variable dereference and some 130#else
134 * supporting exception_table gunk. Note that (a la i386) we can 131#define _ASM_PTR ".long"
135 * extend the copy_to_user and copy_from_user routines to call into 132#endif
136 * such extended assembler routines, though we will have to use a 133
137 * different return code in that case (1, 2, or 4, rather than -EFAULT). 134#define __get_user_asm(OP, x, ptr, ret) \
138 */ 135 asm volatile("1: {" #OP " %1, %2; movei %0, 0 }\n" \
139extern struct __get_user __get_user_1(const void __user *); 136 ".pushsection .fixup,\"ax\"\n" \
140extern struct __get_user __get_user_2(const void __user *); 137 "0: { movei %1, 0; movei %0, %3 }\n" \
141extern struct __get_user __get_user_4(const void __user *); 138 "j 9f\n" \
142extern struct __get_user __get_user_8(const void __user *); 139 ".section __ex_table,\"a\"\n" \
143extern int __put_user_1(long, void __user *); 140 _ASM_PTR " 1b, 0b\n" \
144extern int __put_user_2(long, void __user *); 141 ".popsection\n" \
145extern int __put_user_4(long, void __user *); 142 "9:" \
146extern int __put_user_8(long long, void __user *); 143 : "=r" (ret), "=r" (x) \
147 144 : "r" (ptr), "i" (-EFAULT))
148/* Unimplemented routines to cause linker failures */ 145
149extern struct __get_user __get_user_bad(void); 146#ifdef __tilegx__
150extern int __put_user_bad(void); 147#define __get_user_1(x, ptr, ret) __get_user_asm(ld1u, x, ptr, ret)
148#define __get_user_2(x, ptr, ret) __get_user_asm(ld2u, x, ptr, ret)
149#define __get_user_4(x, ptr, ret) __get_user_asm(ld4u, x, ptr, ret)
150#define __get_user_8(x, ptr, ret) __get_user_asm(ld, x, ptr, ret)
151#else
152#define __get_user_1(x, ptr, ret) __get_user_asm(lb_u, x, ptr, ret)
153#define __get_user_2(x, ptr, ret) __get_user_asm(lh_u, x, ptr, ret)
154#define __get_user_4(x, ptr, ret) __get_user_asm(lw, x, ptr, ret)
155#ifdef __LITTLE_ENDIAN
156#define __lo32(a, b) a
157#define __hi32(a, b) b
158#else
159#define __lo32(a, b) b
160#define __hi32(a, b) a
161#endif
162#define __get_user_8(x, ptr, ret) \
163 ({ \
164 unsigned int __a, __b; \
165 asm volatile("1: { lw %1, %3; addi %2, %3, 4 }\n" \
166 "2: { lw %2, %2; movei %0, 0 }\n" \
167 ".pushsection .fixup,\"ax\"\n" \
168 "0: { movei %1, 0; movei %2, 0 }\n" \
169 "{ movei %0, %4; j 9f }\n" \
170 ".section __ex_table,\"a\"\n" \
171 ".word 1b, 0b\n" \
172 ".word 2b, 0b\n" \
173 ".popsection\n" \
174 "9:" \
175 : "=r" (ret), "=r" (__a), "=&r" (__b) \
176 : "r" (ptr), "i" (-EFAULT)); \
177 (x) = (__typeof(x))(__typeof((x)-(x))) \
178 (((u64)__hi32(__a, __b) << 32) | \
179 __lo32(__a, __b)); \
180 })
181#endif
182
183extern int __get_user_bad(void)
184 __attribute__((warning("sizeof __get_user argument not 1, 2, 4 or 8")));
151 185
152/*
153 * Careful: we have to cast the result to the type of the pointer
154 * for sign reasons.
155 */
156/** 186/**
157 * __get_user: - Get a simple variable from user space, with less checking. 187 * __get_user: - Get a simple variable from user space, with less checking.
158 * @x: Variable to store result. 188 * @x: Variable to store result.
@@ -174,30 +204,62 @@ extern int __put_user_bad(void);
174 * function. 204 * function.
175 */ 205 */
176#define __get_user(x, ptr) \ 206#define __get_user(x, ptr) \
177({ struct __get_user __ret; \ 207 ({ \
178 __typeof__(*(ptr)) const __user *__gu_addr = (ptr); \ 208 int __ret; \
179 __chk_user_ptr(__gu_addr); \ 209 __chk_user_ptr(ptr); \
180 switch (sizeof(*(__gu_addr))) { \ 210 switch (sizeof(*(ptr))) { \
181 case 1: \ 211 case 1: __get_user_1(x, ptr, __ret); break; \
182 __ret = __get_user_1(__gu_addr); \ 212 case 2: __get_user_2(x, ptr, __ret); break; \
183 break; \ 213 case 4: __get_user_4(x, ptr, __ret); break; \
184 case 2: \ 214 case 8: __get_user_8(x, ptr, __ret); break; \
185 __ret = __get_user_2(__gu_addr); \ 215 default: __ret = __get_user_bad(); break; \
186 break; \ 216 } \
187 case 4: \ 217 __ret; \
188 __ret = __get_user_4(__gu_addr); \ 218 })
189 break; \ 219
190 case 8: \ 220/* Support macros for __put_user(). */
191 __ret = __get_user_8(__gu_addr); \ 221
192 break; \ 222#define __put_user_asm(OP, x, ptr, ret) \
193 default: \ 223 asm volatile("1: {" #OP " %1, %2; movei %0, 0 }\n" \
194 __ret = __get_user_bad(); \ 224 ".pushsection .fixup,\"ax\"\n" \
195 break; \ 225 "0: { movei %0, %3; j 9f }\n" \
196 } \ 226 ".section __ex_table,\"a\"\n" \
197 (x) = (__typeof__(*__gu_addr)) (__typeof__(*__gu_addr - *__gu_addr)) \ 227 _ASM_PTR " 1b, 0b\n" \
198 __ret.val; \ 228 ".popsection\n" \
199 __ret.err; \ 229 "9:" \
200}) 230 : "=r" (ret) \
231 : "r" (ptr), "r" (x), "i" (-EFAULT))
232
233#ifdef __tilegx__
234#define __put_user_1(x, ptr, ret) __put_user_asm(st1, x, ptr, ret)
235#define __put_user_2(x, ptr, ret) __put_user_asm(st2, x, ptr, ret)
236#define __put_user_4(x, ptr, ret) __put_user_asm(st4, x, ptr, ret)
237#define __put_user_8(x, ptr, ret) __put_user_asm(st, x, ptr, ret)
238#else
239#define __put_user_1(x, ptr, ret) __put_user_asm(sb, x, ptr, ret)
240#define __put_user_2(x, ptr, ret) __put_user_asm(sh, x, ptr, ret)
241#define __put_user_4(x, ptr, ret) __put_user_asm(sw, x, ptr, ret)
242#define __put_user_8(x, ptr, ret) \
243 ({ \
244 u64 __x = (__typeof((x)-(x)))(x); \
245 int __lo = (int) __x, __hi = (int) (__x >> 32); \
246 asm volatile("1: { sw %1, %2; addi %0, %1, 4 }\n" \
247 "2: { sw %0, %3; movei %0, 0 }\n" \
248 ".pushsection .fixup,\"ax\"\n" \
249 "0: { movei %0, %4; j 9f }\n" \
250 ".section __ex_table,\"a\"\n" \
251 ".word 1b, 0b\n" \
252 ".word 2b, 0b\n" \
253 ".popsection\n" \
254 "9:" \
255 : "=&r" (ret) \
256 : "r" (ptr), "r" (__lo32(__lo, __hi)), \
257 "r" (__hi32(__lo, __hi)), "i" (-EFAULT)); \
258 })
259#endif
260
261extern int __put_user_bad(void)
262 __attribute__((warning("sizeof __put_user argument not 1, 2, 4 or 8")));
201 263
202/** 264/**
203 * __put_user: - Write a simple value into user space, with less checking. 265 * __put_user: - Write a simple value into user space, with less checking.
@@ -217,39 +279,19 @@ extern int __put_user_bad(void);
217 * function. 279 * function.
218 * 280 *
219 * Returns zero on success, or -EFAULT on error. 281 * Returns zero on success, or -EFAULT on error.
220 *
221 * Implementation note: The "case 8" logic of casting to the type of
222 * the result of subtracting the value from itself is basically a way
223 * of keeping all integer types the same, but casting any pointers to
224 * ptrdiff_t, i.e. also an integer type. This way there are no
225 * questionable casts seen by the compiler on an ILP32 platform.
226 */ 282 */
227#define __put_user(x, ptr) \ 283#define __put_user(x, ptr) \
228({ \ 284({ \
229 int __pu_err = 0; \ 285 int __ret; \
230 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ 286 __chk_user_ptr(ptr); \
231 typeof(*__pu_addr) __pu_val = (x); \ 287 switch (sizeof(*(ptr))) { \
232 __chk_user_ptr(__pu_addr); \ 288 case 1: __put_user_1(x, ptr, __ret); break; \
233 switch (sizeof(__pu_val)) { \ 289 case 2: __put_user_2(x, ptr, __ret); break; \
234 case 1: \ 290 case 4: __put_user_4(x, ptr, __ret); break; \
235 __pu_err = __put_user_1((long)__pu_val, __pu_addr); \ 291 case 8: __put_user_8(x, ptr, __ret); break; \
236 break; \ 292 default: __ret = __put_user_bad(); break; \
237 case 2: \
238 __pu_err = __put_user_2((long)__pu_val, __pu_addr); \
239 break; \
240 case 4: \
241 __pu_err = __put_user_4((long)__pu_val, __pu_addr); \
242 break; \
243 case 8: \
244 __pu_err = \
245 __put_user_8((__typeof__(__pu_val - __pu_val))__pu_val,\
246 __pu_addr); \
247 break; \
248 default: \
249 __pu_err = __put_user_bad(); \
250 break; \
251 } \ 293 } \
252 __pu_err; \ 294 __ret; \
253}) 295})
254 296
255/* 297/*
@@ -378,7 +420,7 @@ static inline unsigned long __must_check copy_from_user(void *to,
378/** 420/**
379 * __copy_in_user() - copy data within user space, with less checking. 421 * __copy_in_user() - copy data within user space, with less checking.
380 * @to: Destination address, in user space. 422 * @to: Destination address, in user space.
381 * @from: Source address, in kernel space. 423 * @from: Source address, in user space.
382 * @n: Number of bytes to copy. 424 * @n: Number of bytes to copy.
383 * 425 *
384 * Context: User context only. This function may sleep. 426 * Context: User context only. This function may sleep.
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h
index f70bf1c541f..a017246ca0c 100644
--- a/arch/tile/include/asm/unistd.h
+++ b/arch/tile/include/asm/unistd.h
@@ -24,8 +24,8 @@
24#include <asm-generic/unistd.h> 24#include <asm-generic/unistd.h>
25 25
26/* Additional Tilera-specific syscalls. */ 26/* Additional Tilera-specific syscalls. */
27#define __NR_flush_cache (__NR_arch_specific_syscall + 1) 27#define __NR_cacheflush (__NR_arch_specific_syscall + 1)
28__SYSCALL(__NR_flush_cache, sys_flush_cache) 28__SYSCALL(__NR_cacheflush, sys_cacheflush)
29 29
30#ifndef __tilegx__ 30#ifndef __tilegx__
31/* "Fast" syscalls provide atomic support for 32-bit chips. */ 31/* "Fast" syscalls provide atomic support for 32-bit chips. */
diff --git a/arch/tile/include/hv/drv_xgbe_intf.h b/arch/tile/include/hv/drv_xgbe_intf.h
index f13188ac281..2a20b266d94 100644
--- a/arch/tile/include/hv/drv_xgbe_intf.h
+++ b/arch/tile/include/hv/drv_xgbe_intf.h
@@ -460,7 +460,7 @@ typedef void* lepp_comp_t;
460 * linux's "MAX_SKB_FRAGS", and presumably over-estimates by one, for 460 * linux's "MAX_SKB_FRAGS", and presumably over-estimates by one, for
461 * our page size of exactly 65536. We add one for a "body" fragment. 461 * our page size of exactly 65536. We add one for a "body" fragment.
462 */ 462 */
463#define LEPP_MAX_FRAGS (65536 / HV_PAGE_SIZE_SMALL + 2 + 1) 463#define LEPP_MAX_FRAGS (65536 / HV_DEFAULT_PAGE_SIZE_SMALL + 2 + 1)
464 464
465/** Total number of bytes needed for an lepp_tso_cmd_t. */ 465/** Total number of bytes needed for an lepp_tso_cmd_t. */
466#define LEPP_TSO_CMD_SIZE(num_frags, header_size) \ 466#define LEPP_TSO_CMD_SIZE(num_frags, header_size) \
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h
index 72ec1e972f1..ccd847e2347 100644
--- a/arch/tile/include/hv/hypervisor.h
+++ b/arch/tile/include/hv/hypervisor.h
@@ -17,8 +17,8 @@
17 * The hypervisor's public API. 17 * The hypervisor's public API.
18 */ 18 */
19 19
20#ifndef _TILE_HV_H 20#ifndef _HV_HV_H
21#define _TILE_HV_H 21#define _HV_HV_H
22 22
23#include <arch/chip.h> 23#include <arch/chip.h>
24 24
@@ -42,25 +42,45 @@
42 */ 42 */
43#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN) 43#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
44 44
45/** The log2 of the size of small pages, in bytes. This value should 45/** The log2 of the initial size of small pages, in bytes.
46 * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL). 46 * See HV_DEFAULT_PAGE_SIZE_SMALL.
47 */ 47 */
48#define HV_LOG2_PAGE_SIZE_SMALL 16 48#define HV_LOG2_DEFAULT_PAGE_SIZE_SMALL 16
49 49
50/** The size of small pages, in bytes. This value should be verified 50/** The initial size of small pages, in bytes. This value should be verified
51 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL). 51 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
52 * It may also be modified when installing a new context.
52 */ 53 */
53#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL) 54#define HV_DEFAULT_PAGE_SIZE_SMALL \
55 (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_SMALL)
54 56
55/** The log2 of the size of large pages, in bytes. This value should be 57/** The log2 of the initial size of large pages, in bytes.
56 * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE). 58 * See HV_DEFAULT_PAGE_SIZE_LARGE.
57 */ 59 */
58#define HV_LOG2_PAGE_SIZE_LARGE 24 60#define HV_LOG2_DEFAULT_PAGE_SIZE_LARGE 24
59 61
60/** The size of large pages, in bytes. This value should be verified 62/** The initial size of large pages, in bytes. This value should be verified
61 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE). 63 * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
64 * It may also be modified when installing a new context.
62 */ 65 */
63#define HV_PAGE_SIZE_LARGE (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_LARGE) 66#define HV_DEFAULT_PAGE_SIZE_LARGE \
67 (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_LARGE)
68
69#if CHIP_VA_WIDTH() > 32
70
71/** The log2 of the initial size of jumbo pages, in bytes.
72 * See HV_DEFAULT_PAGE_SIZE_JUMBO.
73 */
74#define HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO 32
75
76/** The initial size of jumbo pages, in bytes. This value should
77 * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO).
78 * It may also be modified when installing a new context.
79 */
80#define HV_DEFAULT_PAGE_SIZE_JUMBO \
81 (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO)
82
83#endif
64 84
65/** The log2 of the granularity at which page tables must be aligned; 85/** The log2 of the granularity at which page tables must be aligned;
66 * in other words, the CPA for a page table must have this many zero 86 * in other words, the CPA for a page table must have this many zero
@@ -280,8 +300,11 @@
280#define HV_DISPATCH_GET_IPI_PTE 56 300#define HV_DISPATCH_GET_IPI_PTE 56
281#endif 301#endif
282 302
303/** hv_set_pte_super_shift */
304#define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57
305
283/** One more than the largest dispatch value */ 306/** One more than the largest dispatch value */
284#define _HV_DISPATCH_END 57 307#define _HV_DISPATCH_END 58
285 308
286 309
287#ifndef __ASSEMBLER__ 310#ifndef __ASSEMBLER__
@@ -401,7 +424,18 @@ typedef enum {
401 * that the temperature has hit an upper limit and is no longer being 424 * that the temperature has hit an upper limit and is no longer being
402 * accurately tracked. 425 * accurately tracked.
403 */ 426 */
404 HV_SYSCONF_BOARD_TEMP = 6 427 HV_SYSCONF_BOARD_TEMP = 6,
428
429 /** Legal page size bitmask for hv_install_context().
430 * For example, if 16KB and 64KB small pages are supported,
431 * it would return "HV_CTX_PG_SM_16K | HV_CTX_PG_SM_64K".
432 */
433 HV_SYSCONF_VALID_PAGE_SIZES = 7,
434
435 /** The size of jumbo pages, in bytes.
436 * If no jumbo pages are available, zero will be returned.
437 */
438 HV_SYSCONF_PAGE_SIZE_JUMBO = 8,
405 439
406} HV_SysconfQuery; 440} HV_SysconfQuery;
407 441
@@ -474,7 +508,19 @@ typedef enum {
474 HV_CONFSTR_SWITCH_CONTROL = 14, 508 HV_CONFSTR_SWITCH_CONTROL = 14,
475 509
476 /** Chip revision level. */ 510 /** Chip revision level. */
477 HV_CONFSTR_CHIP_REV = 15 511 HV_CONFSTR_CHIP_REV = 15,
512
513 /** CPU module part number. */
514 HV_CONFSTR_CPUMOD_PART_NUM = 16,
515
516 /** CPU module serial number. */
517 HV_CONFSTR_CPUMOD_SERIAL_NUM = 17,
518
519 /** CPU module revision level. */
520 HV_CONFSTR_CPUMOD_REV = 18,
521
522 /** Human-readable CPU module description. */
523 HV_CONFSTR_CPUMOD_DESC = 19
478 524
479} HV_ConfstrQuery; 525} HV_ConfstrQuery;
480 526
@@ -494,11 +540,16 @@ int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
494/** Tile coordinate */ 540/** Tile coordinate */
495typedef struct 541typedef struct
496{ 542{
543#ifndef __BIG_ENDIAN__
497 /** X coordinate, relative to supervisor's top-left coordinate */ 544 /** X coordinate, relative to supervisor's top-left coordinate */
498 int x; 545 int x;
499 546
500 /** Y coordinate, relative to supervisor's top-left coordinate */ 547 /** Y coordinate, relative to supervisor's top-left coordinate */
501 int y; 548 int y;
549#else
550 int y;
551 int x;
552#endif
502} HV_Coord; 553} HV_Coord;
503 554
504 555
@@ -649,6 +700,12 @@ void hv_set_rtc(HV_RTCTime time);
649 * new page table does not need to contain any mapping for the 700 * new page table does not need to contain any mapping for the
650 * hv_install_context address itself. 701 * hv_install_context address itself.
651 * 702 *
703 * At most one HV_CTX_PG_SM_* flag may be specified in "flags";
704 * if multiple flags are specified, HV_EINVAL is returned.
705 * Specifying none of the flags results in using the default page size.
706 * All cores participating in a given client must request the same
707 * page size, or the results are undefined.
708 *
652 * @param page_table Root of the page table. 709 * @param page_table Root of the page table.
653 * @param access PTE providing info on how to read the page table. This 710 * @param access PTE providing info on how to read the page table. This
654 * value must be consistent between multiple tiles sharing a page table, 711 * value must be consistent between multiple tiles sharing a page table,
@@ -667,8 +724,36 @@ int hv_install_context(HV_PhysAddr page_table, HV_PTE access, HV_ASID asid,
667#define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from 724#define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from
668 PL0. */ 725 PL0. */
669 726
727#define HV_CTX_PG_SM_4K 0x10 /**< Use 4K small pages, if available. */
728#define HV_CTX_PG_SM_16K 0x20 /**< Use 16K small pages, if available. */
729#define HV_CTX_PG_SM_64K 0x40 /**< Use 64K small pages, if available. */
730#define HV_CTX_PG_SM_MASK 0xf0 /**< Mask of all possible small pages. */
731
670#ifndef __ASSEMBLER__ 732#ifndef __ASSEMBLER__
671 733
734
735/** Set the number of pages ganged together by HV_PTE_SUPER at a
736 * particular level of the page table.
737 *
738 * The current TILE-Gx hardware only supports powers of four
739 * (i.e. log2_count must be a multiple of two), and the requested
740 * "super" page size must be less than the span of the next level in
741 * the page table. The largest size that can be requested is 64GB.
742 *
743 * The shift value is initially "0" for all page table levels,
744 * indicating that the HV_PTE_SUPER bit is effectively ignored.
745 *
746 * If you change the count from one non-zero value to another, the
747 * hypervisor will flush the entire TLB and TSB to avoid confusion.
748 *
749 * @param level Page table level (0, 1, or 2)
750 * @param log2_count Base-2 log of the number of pages to gang together,
751 * i.e. how much to shift left the base page size for the super page size.
752 * @return Zero on success, or a hypervisor error code on failure.
753 */
754int hv_set_pte_super_shift(int level, int log2_count);
755
756
672/** Value returned from hv_inquire_context(). */ 757/** Value returned from hv_inquire_context(). */
673typedef struct 758typedef struct
674{ 759{
@@ -986,8 +1071,13 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
986/** A range of ASID values. */ 1071/** A range of ASID values. */
987typedef struct 1072typedef struct
988{ 1073{
1074#ifndef __BIG_ENDIAN__
989 HV_ASID start; /**< First ASID in the range. */ 1075 HV_ASID start; /**< First ASID in the range. */
990 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1076 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1077#else
1078 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1079 HV_ASID start; /**< First ASID in the range. */
1080#endif
991} HV_ASIDRange; 1081} HV_ASIDRange;
992 1082
993/** Returns information about a range of ASIDs. 1083/** Returns information about a range of ASIDs.
@@ -1238,11 +1328,14 @@ HV_Errno hv_set_command_line(HV_VirtAddr buf, int length);
1238 * with the existing priority pages) or "red/black" (if they don't). 1328 * with the existing priority pages) or "red/black" (if they don't).
1239 * The bitmask provides information on which parts of the cache 1329 * The bitmask provides information on which parts of the cache
1240 * have been used for pinned pages so far on this tile; if (1 << N) 1330 * have been used for pinned pages so far on this tile; if (1 << N)
1241 * appears in the bitmask, that indicates that a page has been marked 1331 * appears in the bitmask, that indicates that a 4KB region of the
1242 * "priority" whose PFN equals N, mod 8. 1332 * cache starting at (N * 4KB) is in use by a "priority" page.
1333 * The portion of cache used by a particular page can be computed
1334 * by taking the page's PA, modulo CHIP_L2_CACHE_SIZE(), and setting
1335 * all the "4KB" bits corresponding to the actual page size.
1243 * @param bitmask A bitmap of priority page set values 1336 * @param bitmask A bitmap of priority page set values
1244 */ 1337 */
1245void hv_set_caching(unsigned int bitmask); 1338void hv_set_caching(unsigned long bitmask);
1246 1339
1247 1340
1248/** Zero out a specified number of pages. 1341/** Zero out a specified number of pages.
@@ -1308,6 +1401,7 @@ typedef enum
1308/** Message recipient. */ 1401/** Message recipient. */
1309typedef struct 1402typedef struct
1310{ 1403{
1404#ifndef __BIG_ENDIAN__
1311 /** X coordinate, relative to supervisor's top-left coordinate */ 1405 /** X coordinate, relative to supervisor's top-left coordinate */
1312 unsigned int x:11; 1406 unsigned int x:11;
1313 1407
@@ -1316,6 +1410,11 @@ typedef struct
1316 1410
1317 /** Status of this recipient */ 1411 /** Status of this recipient */
1318 HV_Recip_State state:10; 1412 HV_Recip_State state:10;
1413#else //__BIG_ENDIAN__
1414 HV_Recip_State state:10;
1415 unsigned int y:11;
1416 unsigned int x:11;
1417#endif
1319} HV_Recipient; 1418} HV_Recipient;
1320 1419
1321/** Send a message to a set of recipients. 1420/** Send a message to a set of recipients.
@@ -1851,12 +1950,12 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
1851#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */ 1950#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
1852#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */ 1951#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
1853#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */ 1952#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
1854 /* Bits 13-15 are reserved for 1953 /* Bits 13-14 are reserved for
1855 future use. */ 1954 future use. */
1955#define HV_PTE_INDEX_SUPER 15 /**< Pages ganged together for TLB */
1856#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */ 1956#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
1857#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */ 1957#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
1858 /* Bit 19 is reserved for 1958#define HV_PTE_INDEX_CLIENT2 19 /**< Page client state 2 */
1859 future use. */
1860#define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits 1959#define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits
1861 of word */ 1960 of word */
1862#define HV_PTE_LOTAR_BITS 12 /**< Number of bits in a LOTAR */ 1961#define HV_PTE_LOTAR_BITS 12 /**< Number of bits in a LOTAR */
@@ -1869,15 +1968,6 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
1869 of word */ 1968 of word */
1870#define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */ 1969#define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */
1871 1970
1872/** Position of the PFN field within the PTE (subset of the PTFN). */
1873#define HV_PTE_INDEX_PFN (HV_PTE_INDEX_PTFN + (HV_LOG2_PAGE_SIZE_SMALL - \
1874 HV_LOG2_PAGE_TABLE_ALIGN))
1875
1876/** Length of the PFN field within the PTE (subset of the PTFN). */
1877#define HV_PTE_INDEX_PFN_BITS (HV_PTE_INDEX_PTFN_BITS - \
1878 (HV_LOG2_PAGE_SIZE_SMALL - \
1879 HV_LOG2_PAGE_TABLE_ALIGN))
1880
1881/* 1971/*
1882 * Legal values for the PTE's mode field 1972 * Legal values for the PTE's mode field
1883 */ 1973 */
@@ -1957,7 +2047,10 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
1957 2047
1958/** Does this PTE map a page? 2048/** Does this PTE map a page?
1959 * 2049 *
1960 * If this bit is set in the level-1 page table, the entry should be 2050 * If this bit is set in a level-0 page table, the entry should be
2051 * interpreted as a level-2 page table entry mapping a jumbo page.
2052 *
2053 * If this bit is set in a level-1 page table, the entry should be
1961 * interpreted as a level-2 page table entry mapping a large page. 2054 * interpreted as a level-2 page table entry mapping a large page.
1962 * 2055 *
1963 * This bit should not be modified by the client while PRESENT is set, as 2056 * This bit should not be modified by the client while PRESENT is set, as
@@ -1967,6 +2060,18 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
1967 */ 2060 */
1968#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE) 2061#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)
1969 2062
2063/** Does this PTE implicitly reference multiple pages?
2064 *
2065 * If this bit is set in the page table (either in the level-2 page table,
2066 * or in a higher level page table in conjunction with the PAGE bit)
2067 * then the PTE specifies a range of contiguous pages, not a single page.
2068 * The hv_set_pte_super_shift() allows you to specify the count for
2069 * each level of the page table.
2070 *
2071 * Note: this bit is not supported on TILEPro systems.
2072 */
2073#define HV_PTE_SUPER (__HV_PTE_ONE << HV_PTE_INDEX_SUPER)
2074
1970/** Is this a global (non-ASID) mapping? 2075/** Is this a global (non-ASID) mapping?
1971 * 2076 *
1972 * If this bit is set, the translations established by this PTE will 2077 * If this bit is set, the translations established by this PTE will
@@ -2046,6 +2151,13 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
2046 */ 2151 */
2047#define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1) 2152#define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1)
2048 2153
2154/** Client-private bit in PTE.
2155 *
2156 * This bit is guaranteed not to be inspected or modified by the
2157 * hypervisor.
2158 */
2159#define HV_PTE_CLIENT2 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT2)
2160
2049/** Non-coherent (NC) bit in PTE. 2161/** Non-coherent (NC) bit in PTE.
2050 * 2162 *
2051 * If this bit is set, the mapping that is set up will be non-coherent 2163 * If this bit is set, the mapping that is set up will be non-coherent
@@ -2178,8 +2290,10 @@ hv_pte_clear_##name(HV_PTE pte) \
2178 */ 2290 */
2179_HV_BIT(present, PRESENT) 2291_HV_BIT(present, PRESENT)
2180_HV_BIT(page, PAGE) 2292_HV_BIT(page, PAGE)
2293_HV_BIT(super, SUPER)
2181_HV_BIT(client0, CLIENT0) 2294_HV_BIT(client0, CLIENT0)
2182_HV_BIT(client1, CLIENT1) 2295_HV_BIT(client1, CLIENT1)
2296_HV_BIT(client2, CLIENT2)
2183_HV_BIT(migrating, MIGRATING) 2297_HV_BIT(migrating, MIGRATING)
2184_HV_BIT(nc, NC) 2298_HV_BIT(nc, NC)
2185_HV_BIT(readable, READABLE) 2299_HV_BIT(readable, READABLE)
@@ -2222,40 +2336,11 @@ hv_pte_set_mode(HV_PTE pte, unsigned int val)
2222 * 2336 *
2223 * This field contains the upper bits of the CPA (client physical 2337 * This field contains the upper bits of the CPA (client physical
2224 * address) of the target page; the complete CPA is this field with 2338 * address) of the target page; the complete CPA is this field with
2225 * HV_LOG2_PAGE_SIZE_SMALL zero bits appended to it. 2339 * HV_LOG2_PAGE_TABLE_ALIGN zero bits appended to it.
2226 *
2227 * For PTEs in a level-1 page table where the Page bit is set, the
2228 * CPA must be aligned modulo the large page size.
2229 */
2230static __inline unsigned int
2231hv_pte_get_pfn(const HV_PTE pte)
2232{
2233 return pte.val >> HV_PTE_INDEX_PFN;
2234}
2235
2236
2237/** Set the page frame number into a PTE. See hv_pte_get_pfn. */
2238static __inline HV_PTE
2239hv_pte_set_pfn(HV_PTE pte, unsigned int val)
2240{
2241 /*
2242 * Note that the use of "PTFN" in the next line is intentional; we
2243 * don't want any garbage lower bits left in that field.
2244 */
2245 pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS) - 1) << HV_PTE_INDEX_PTFN);
2246 pte.val |= (__hv64) val << HV_PTE_INDEX_PFN;
2247 return pte;
2248}
2249
2250/** Get the page table frame number from the PTE.
2251 *
2252 * This field contains the upper bits of the CPA (client physical
2253 * address) of the target page table; the complete CPA is this field with
2254 * with HV_PAGE_TABLE_ALIGN zero bits appended to it.
2255 * 2340 *
2256 * For PTEs in a level-1 page table when the Page bit is not set, the 2341 * For all PTEs in the lowest-level page table, and for all PTEs with
2257 * CPA must be aligned modulo the sticter of HV_PAGE_TABLE_ALIGN and 2342 * the Page bit set in all page tables, the CPA must be aligned modulo
2258 * the level-2 page table size. 2343 * the relevant page size.
2259 */ 2344 */
2260static __inline unsigned long 2345static __inline unsigned long
2261hv_pte_get_ptfn(const HV_PTE pte) 2346hv_pte_get_ptfn(const HV_PTE pte)
@@ -2263,7 +2348,6 @@ hv_pte_get_ptfn(const HV_PTE pte)
2263 return pte.val >> HV_PTE_INDEX_PTFN; 2348 return pte.val >> HV_PTE_INDEX_PTFN;
2264} 2349}
2265 2350
2266
2267/** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */ 2351/** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */
2268static __inline HV_PTE 2352static __inline HV_PTE
2269hv_pte_set_ptfn(HV_PTE pte, unsigned long val) 2353hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
@@ -2273,6 +2357,20 @@ hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
2273 return pte; 2357 return pte;
2274} 2358}
2275 2359
2360/** Get the client physical address from the PTE. See hv_pte_set_ptfn. */
2361static __inline HV_PhysAddr
2362hv_pte_get_pa(const HV_PTE pte)
2363{
2364 return (__hv64) hv_pte_get_ptfn(pte) << HV_LOG2_PAGE_TABLE_ALIGN;
2365}
2366
2367/** Set the client physical address into a PTE. See hv_pte_get_ptfn. */
2368static __inline HV_PTE
2369hv_pte_set_pa(HV_PTE pte, HV_PhysAddr pa)
2370{
2371 return hv_pte_set_ptfn(pte, pa >> HV_LOG2_PAGE_TABLE_ALIGN);
2372}
2373
2276 2374
2277/** Get the remote tile caching this page. 2375/** Get the remote tile caching this page.
2278 * 2376 *
@@ -2308,28 +2406,20 @@ hv_pte_set_lotar(HV_PTE pte, unsigned int val)
2308 2406
2309#endif /* !__ASSEMBLER__ */ 2407#endif /* !__ASSEMBLER__ */
2310 2408
2311/** Converts a client physical address to a pfn. */
2312#define HV_CPA_TO_PFN(p) ((p) >> HV_LOG2_PAGE_SIZE_SMALL)
2313
2314/** Converts a pfn to a client physical address. */
2315#define HV_PFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_SIZE_SMALL)
2316
2317/** Converts a client physical address to a ptfn. */ 2409/** Converts a client physical address to a ptfn. */
2318#define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN) 2410#define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN)
2319 2411
2320/** Converts a ptfn to a client physical address. */ 2412/** Converts a ptfn to a client physical address. */
2321#define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN) 2413#define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN)
2322 2414
2323/** Converts a ptfn to a pfn. */
2324#define HV_PTFN_TO_PFN(p) \
2325 ((p) >> (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
2326
2327/** Converts a pfn to a ptfn. */
2328#define HV_PFN_TO_PTFN(p) \
2329 ((p) << (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
2330
2331#if CHIP_VA_WIDTH() > 32 2415#if CHIP_VA_WIDTH() > 32
2332 2416
2417/*
2418 * Note that we currently do not allow customizing the page size
2419 * of the L0 pages, but fix them at 4GB, so we do not use the
2420 * "_HV_xxx" nomenclature for the L0 macros.
2421 */
2422
2333/** Log number of HV_PTE entries in L0 page table */ 2423/** Log number of HV_PTE entries in L0 page table */
2334#define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN) 2424#define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN)
2335 2425
@@ -2359,69 +2449,104 @@ hv_pte_set_lotar(HV_PTE pte, unsigned int val)
2359#endif /* CHIP_VA_WIDTH() > 32 */ 2449#endif /* CHIP_VA_WIDTH() > 32 */
2360 2450
2361/** Log number of HV_PTE entries in L1 page table */ 2451/** Log number of HV_PTE entries in L1 page table */
2362#define HV_LOG2_L1_ENTRIES (HV_LOG2_L1_SPAN - HV_LOG2_PAGE_SIZE_LARGE) 2452#define _HV_LOG2_L1_ENTRIES(log2_page_size_large) \
2453 (HV_LOG2_L1_SPAN - log2_page_size_large)
2363 2454
2364/** Number of HV_PTE entries in L1 page table */ 2455/** Number of HV_PTE entries in L1 page table */
2365#define HV_L1_ENTRIES (1 << HV_LOG2_L1_ENTRIES) 2456#define _HV_L1_ENTRIES(log2_page_size_large) \
2457 (1 << _HV_LOG2_L1_ENTRIES(log2_page_size_large))
2366 2458
2367/** Log size of L1 page table in bytes */ 2459/** Log size of L1 page table in bytes */
2368#define HV_LOG2_L1_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L1_ENTRIES) 2460#define _HV_LOG2_L1_SIZE(log2_page_size_large) \
2461 (HV_LOG2_PTE_SIZE + _HV_LOG2_L1_ENTRIES(log2_page_size_large))
2369 2462
2370/** Size of L1 page table in bytes */ 2463/** Size of L1 page table in bytes */
2371#define HV_L1_SIZE (1 << HV_LOG2_L1_SIZE) 2464#define _HV_L1_SIZE(log2_page_size_large) \
2465 (1 << _HV_LOG2_L1_SIZE(log2_page_size_large))
2372 2466
2373/** Log number of HV_PTE entries in level-2 page table */ 2467/** Log number of HV_PTE entries in level-2 page table */
2374#define HV_LOG2_L2_ENTRIES (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL) 2468#define _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
2469 (log2_page_size_large - log2_page_size_small)
2375 2470
2376/** Number of HV_PTE entries in level-2 page table */ 2471/** Number of HV_PTE entries in level-2 page table */
2377#define HV_L2_ENTRIES (1 << HV_LOG2_L2_ENTRIES) 2472#define _HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
2473 (1 << _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
2378 2474
2379/** Log size of level-2 page table in bytes */ 2475/** Log size of level-2 page table in bytes */
2380#define HV_LOG2_L2_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L2_ENTRIES) 2476#define _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small) \
2477 (HV_LOG2_PTE_SIZE + \
2478 _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
2381 2479
2382/** Size of level-2 page table in bytes */ 2480/** Size of level-2 page table in bytes */
2383#define HV_L2_SIZE (1 << HV_LOG2_L2_SIZE) 2481#define _HV_L2_SIZE(log2_page_size_large, log2_page_size_small) \
2482 (1 << _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small))
2384 2483
2385#ifdef __ASSEMBLER__ 2484#ifdef __ASSEMBLER__
2386 2485
2387#if CHIP_VA_WIDTH() > 32 2486#if CHIP_VA_WIDTH() > 32
2388 2487
2389/** Index in L1 for a specific VA */ 2488/** Index in L1 for a specific VA */
2390#define HV_L1_INDEX(va) \ 2489#define _HV_L1_INDEX(va, log2_page_size_large) \
2391 (((va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1)) 2490 (((va) >> log2_page_size_large) & (_HV_L1_ENTRIES(log2_page_size_large) - 1))
2392 2491
2393#else /* CHIP_VA_WIDTH() > 32 */ 2492#else /* CHIP_VA_WIDTH() > 32 */
2394 2493
2395/** Index in L1 for a specific VA */ 2494/** Index in L1 for a specific VA */
2396#define HV_L1_INDEX(va) \ 2495#define _HV_L1_INDEX(va, log2_page_size_large) \
2397 (((va) >> HV_LOG2_PAGE_SIZE_LARGE)) 2496 (((va) >> log2_page_size_large))
2398 2497
2399#endif /* CHIP_VA_WIDTH() > 32 */ 2498#endif /* CHIP_VA_WIDTH() > 32 */
2400 2499
2401/** Index in level-2 page table for a specific VA */ 2500/** Index in level-2 page table for a specific VA */
2402#define HV_L2_INDEX(va) \ 2501#define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
2403 (((va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1)) 2502 (((va) >> log2_page_size_small) & \
2503 (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
2404 2504
2405#else /* __ASSEMBLER __ */ 2505#else /* __ASSEMBLER __ */
2406 2506
2407#if CHIP_VA_WIDTH() > 32 2507#if CHIP_VA_WIDTH() > 32
2408 2508
2409/** Index in L1 for a specific VA */ 2509/** Index in L1 for a specific VA */
2410#define HV_L1_INDEX(va) \ 2510#define _HV_L1_INDEX(va, log2_page_size_large) \
2411 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1)) 2511 (((HV_VirtAddr)(va) >> log2_page_size_large) & \
2512 (_HV_L1_ENTRIES(log2_page_size_large) - 1))
2412 2513
2413#else /* CHIP_VA_WIDTH() > 32 */ 2514#else /* CHIP_VA_WIDTH() > 32 */
2414 2515
2415/** Index in L1 for a specific VA */ 2516/** Index in L1 for a specific VA */
2416#define HV_L1_INDEX(va) \ 2517#define _HV_L1_INDEX(va, log2_page_size_large) \
2417 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE)) 2518 (((HV_VirtAddr)(va) >> log2_page_size_large))
2418 2519
2419#endif /* CHIP_VA_WIDTH() > 32 */ 2520#endif /* CHIP_VA_WIDTH() > 32 */
2420 2521
2421/** Index in level-2 page table for a specific VA */ 2522/** Index in level-2 page table for a specific VA */
2422#define HV_L2_INDEX(va) \ 2523#define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
2423 (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1)) 2524 (((HV_VirtAddr)(va) >> log2_page_size_small) & \
2525 (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
2424 2526
2425#endif /* __ASSEMBLER __ */ 2527#endif /* __ASSEMBLER __ */
2426 2528
2427#endif /* _TILE_HV_H */ 2529/** Position of the PFN field within the PTE (subset of the PTFN). */
2530#define _HV_PTE_INDEX_PFN(log2_page_size) \
2531 (HV_PTE_INDEX_PTFN + (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
2532
2533/** Length of the PFN field within the PTE (subset of the PTFN). */
2534#define _HV_PTE_INDEX_PFN_BITS(log2_page_size) \
2535 (HV_PTE_INDEX_PTFN_BITS - (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
2536
2537/** Converts a client physical address to a pfn. */
2538#define _HV_CPA_TO_PFN(p, log2_page_size) ((p) >> log2_page_size)
2539
2540/** Converts a pfn to a client physical address. */
2541#define _HV_PFN_TO_CPA(p, log2_page_size) \
2542 (((HV_PhysAddr)(p)) << log2_page_size)
2543
2544/** Converts a ptfn to a pfn. */
2545#define _HV_PTFN_TO_PFN(p, log2_page_size) \
2546 ((p) >> (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
2547
2548/** Converts a pfn to a ptfn. */
2549#define _HV_PFN_TO_PTFN(p, log2_page_size) \
2550 ((p) << (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
2551
2552#endif /* _HV_HV_H */
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
index 0d826faf8f3..5de99248d8d 100644
--- a/arch/tile/kernel/Makefile
+++ b/arch/tile/kernel/Makefile
@@ -9,10 +9,9 @@ obj-y := backtrace.o entry.o irq.o messaging.o \
9 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o 9 intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
10 10
11obj-$(CONFIG_HARDWALL) += hardwall.o 11obj-$(CONFIG_HARDWALL) += hardwall.o
12obj-$(CONFIG_TILEGX) += futex_64.o
13obj-$(CONFIG_COMPAT) += compat.o compat_signal.o 12obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
14obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o 13obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
15obj-$(CONFIG_MODULES) += module.o 14obj-$(CONFIG_MODULES) += module.o
16obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 15obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
17obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 16obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o
18obj-$(CONFIG_PCI) += pci.o 17obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index ec91568df88..133c4b56a99 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -100,8 +100,9 @@ STD_ENTRY(smp_nap)
100 */ 100 */
101STD_ENTRY(_cpu_idle) 101STD_ENTRY(_cpu_idle)
102 movei r1, 1 102 movei r1, 1
103 IRQ_ENABLE_LOAD(r2, r3)
103 mtspr INTERRUPT_CRITICAL_SECTION, r1 104 mtspr INTERRUPT_CRITICAL_SECTION, r1
104 IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */ 105 IRQ_ENABLE_APPLY(r2, r3) /* unmask, but still with ICS set */
105 mtspr INTERRUPT_CRITICAL_SECTION, zero 106 mtspr INTERRUPT_CRITICAL_SECTION, zero
106 .global _cpu_idle_nap 107 .global _cpu_idle_nap
107_cpu_idle_nap: 108_cpu_idle_nap:
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
index 8c41891aab3..20273ee37de 100644
--- a/arch/tile/kernel/hardwall.c
+++ b/arch/tile/kernel/hardwall.c
@@ -33,59 +33,157 @@
33 33
34 34
35/* 35/*
36 * This data structure tracks the rectangle data, etc., associated 36 * Implement a per-cpu "hardwall" resource class such as UDN or IPI.
37 * one-to-one with a "struct file *" from opening HARDWALL_FILE. 37 * We use "hardwall" nomenclature throughout for historical reasons.
38 * The lock here controls access to the list data structure as well as
39 * to the items on the list.
40 */
41struct hardwall_type {
42 int index;
43 int is_xdn;
44 int is_idn;
45 int disabled;
46 const char *name;
47 struct list_head list;
48 spinlock_t lock;
49 struct proc_dir_entry *proc_dir;
50};
51
52enum hardwall_index {
53 HARDWALL_UDN = 0,
54#ifndef __tilepro__
55 HARDWALL_IDN = 1,
56 HARDWALL_IPI = 2,
57#endif
58 _HARDWALL_TYPES
59};
60
61static struct hardwall_type hardwall_types[] = {
62 { /* user-space access to UDN */
63 0,
64 1,
65 0,
66 0,
67 "udn",
68 LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
69 __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock),
70 NULL
71 },
72#ifndef __tilepro__
73 { /* user-space access to IDN */
74 1,
75 1,
76 1,
77 1, /* disabled pending hypervisor support */
78 "idn",
79 LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
80 __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock),
81 NULL
82 },
83 { /* access to user-space IPI */
84 2,
85 0,
86 0,
87 0,
88 "ipi",
89 LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
90 __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock),
91 NULL
92 },
93#endif
94};
95
96/*
97 * This data structure tracks the cpu data, etc., associated
98 * one-to-one with a "struct file *" from opening a hardwall device file.
38 * Note that the file's private data points back to this structure. 99 * Note that the file's private data points back to this structure.
39 */ 100 */
40struct hardwall_info { 101struct hardwall_info {
41 struct list_head list; /* "rectangles" list */ 102 struct list_head list; /* for hardwall_types.list */
42 struct list_head task_head; /* head of tasks in this hardwall */ 103 struct list_head task_head; /* head of tasks in this hardwall */
43 struct cpumask cpumask; /* cpus in the rectangle */ 104 struct hardwall_type *type; /* type of this resource */
105 struct cpumask cpumask; /* cpus reserved */
106 int id; /* integer id for this hardwall */
107 int teardown_in_progress; /* are we tearing this one down? */
108
109 /* Remaining fields only valid for user-network resources. */
44 int ulhc_x; /* upper left hand corner x coord */ 110 int ulhc_x; /* upper left hand corner x coord */
45 int ulhc_y; /* upper left hand corner y coord */ 111 int ulhc_y; /* upper left hand corner y coord */
46 int width; /* rectangle width */ 112 int width; /* rectangle width */
47 int height; /* rectangle height */ 113 int height; /* rectangle height */
48 int id; /* integer id for this hardwall */ 114#if CHIP_HAS_REV1_XDN()
49 int teardown_in_progress; /* are we tearing this one down? */ 115 atomic_t xdn_pending_count; /* cores in phase 1 of drain */
116#endif
50}; 117};
51 118
52/* Currently allocated hardwall rectangles */
53static LIST_HEAD(rectangles);
54 119
55/* /proc/tile/hardwall */ 120/* /proc/tile/hardwall */
56static struct proc_dir_entry *hardwall_proc_dir; 121static struct proc_dir_entry *hardwall_proc_dir;
57 122
58/* Functions to manage files in /proc/tile/hardwall. */ 123/* Functions to manage files in /proc/tile/hardwall. */
59static void hardwall_add_proc(struct hardwall_info *rect); 124static void hardwall_add_proc(struct hardwall_info *);
60static void hardwall_remove_proc(struct hardwall_info *rect); 125static void hardwall_remove_proc(struct hardwall_info *);
61
62/*
63 * Guard changes to the hardwall data structures.
64 * This could be finer grained (e.g. one lock for the list of hardwall
65 * rectangles, then separate embedded locks for each one's list of tasks),
66 * but there are subtle correctness issues when trying to start with
67 * a task's "hardwall" pointer and lock the correct rectangle's embedded
68 * lock in the presence of a simultaneous deactivation, so it seems
69 * easier to have a single lock, given that none of these data
70 * structures are touched very frequently during normal operation.
71 */
72static DEFINE_SPINLOCK(hardwall_lock);
73 126
74/* Allow disabling UDN access. */ 127/* Allow disabling UDN access. */
75static int udn_disabled;
76static int __init noudn(char *str) 128static int __init noudn(char *str)
77{ 129{
78 pr_info("User-space UDN access is disabled\n"); 130 pr_info("User-space UDN access is disabled\n");
79 udn_disabled = 1; 131 hardwall_types[HARDWALL_UDN].disabled = 1;
80 return 0; 132 return 0;
81} 133}
82early_param("noudn", noudn); 134early_param("noudn", noudn);
83 135
136#ifndef __tilepro__
137/* Allow disabling IDN access. */
138static int __init noidn(char *str)
139{
140 pr_info("User-space IDN access is disabled\n");
141 hardwall_types[HARDWALL_IDN].disabled = 1;
142 return 0;
143}
144early_param("noidn", noidn);
145
146/* Allow disabling IPI access. */
147static int __init noipi(char *str)
148{
149 pr_info("User-space IPI access is disabled\n");
150 hardwall_types[HARDWALL_IPI].disabled = 1;
151 return 0;
152}
153early_param("noipi", noipi);
154#endif
155
84 156
85/* 157/*
86 * Low-level primitives 158 * Low-level primitives for UDN/IDN
87 */ 159 */
88 160
161#ifdef __tilepro__
162#define mtspr_XDN(hwt, name, val) \
163 do { (void)(hwt); __insn_mtspr(SPR_UDN_##name, (val)); } while (0)
164#define mtspr_MPL_XDN(hwt, name, val) \
165 do { (void)(hwt); __insn_mtspr(SPR_MPL_UDN_##name, (val)); } while (0)
166#define mfspr_XDN(hwt, name) \
167 ((void)(hwt), __insn_mfspr(SPR_UDN_##name))
168#else
169#define mtspr_XDN(hwt, name, val) \
170 do { \
171 if ((hwt)->is_idn) \
172 __insn_mtspr(SPR_IDN_##name, (val)); \
173 else \
174 __insn_mtspr(SPR_UDN_##name, (val)); \
175 } while (0)
176#define mtspr_MPL_XDN(hwt, name, val) \
177 do { \
178 if ((hwt)->is_idn) \
179 __insn_mtspr(SPR_MPL_IDN_##name, (val)); \
180 else \
181 __insn_mtspr(SPR_MPL_UDN_##name, (val)); \
182 } while (0)
183#define mfspr_XDN(hwt, name) \
184 ((hwt)->is_idn ? __insn_mfspr(SPR_IDN_##name) : __insn_mfspr(SPR_UDN_##name))
185#endif
186
89/* Set a CPU bit if the CPU is online. */ 187/* Set a CPU bit if the CPU is online. */
90#define cpu_online_set(cpu, dst) do { \ 188#define cpu_online_set(cpu, dst) do { \
91 if (cpu_online(cpu)) \ 189 if (cpu_online(cpu)) \
@@ -101,7 +199,7 @@ static int contains(struct hardwall_info *r, int x, int y)
101} 199}
102 200
103/* Compute the rectangle parameters and validate the cpumask. */ 201/* Compute the rectangle parameters and validate the cpumask. */
104static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask) 202static int check_rectangle(struct hardwall_info *r, struct cpumask *mask)
105{ 203{
106 int x, y, cpu, ulhc, lrhc; 204 int x, y, cpu, ulhc, lrhc;
107 205
@@ -114,8 +212,6 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
114 r->ulhc_y = cpu_y(ulhc); 212 r->ulhc_y = cpu_y(ulhc);
115 r->width = cpu_x(lrhc) - r->ulhc_x + 1; 213 r->width = cpu_x(lrhc) - r->ulhc_x + 1;
116 r->height = cpu_y(lrhc) - r->ulhc_y + 1; 214 r->height = cpu_y(lrhc) - r->ulhc_y + 1;
117 cpumask_copy(&r->cpumask, mask);
118 r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */
119 215
120 /* Width and height must be positive */ 216 /* Width and height must be positive */
121 if (r->width <= 0 || r->height <= 0) 217 if (r->width <= 0 || r->height <= 0)
@@ -128,7 +224,7 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
128 return -EINVAL; 224 return -EINVAL;
129 225
130 /* 226 /*
131 * Note that offline cpus can't be drained when this UDN 227 * Note that offline cpus can't be drained when this user network
132 * rectangle eventually closes. We used to detect this 228 * rectangle eventually closes. We used to detect this
133 * situation and print a warning, but it annoyed users and 229 * situation and print a warning, but it annoyed users and
134 * they ignored it anyway, so now we just return without a 230 * they ignored it anyway, so now we just return without a
@@ -137,16 +233,6 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
137 return 0; 233 return 0;
138} 234}
139 235
140/* Do the two given rectangles overlap on any cpu? */
141static int overlaps(struct hardwall_info *a, struct hardwall_info *b)
142{
143 return a->ulhc_x + a->width > b->ulhc_x && /* A not to the left */
144 b->ulhc_x + b->width > a->ulhc_x && /* B not to the left */
145 a->ulhc_y + a->height > b->ulhc_y && /* A not above */
146 b->ulhc_y + b->height > a->ulhc_y; /* B not above */
147}
148
149
150/* 236/*
151 * Hardware management of hardwall setup, teardown, trapping, 237 * Hardware management of hardwall setup, teardown, trapping,
152 * and enabling/disabling PL0 access to the networks. 238 * and enabling/disabling PL0 access to the networks.
@@ -157,23 +243,35 @@ enum direction_protect {
157 N_PROTECT = (1 << 0), 243 N_PROTECT = (1 << 0),
158 E_PROTECT = (1 << 1), 244 E_PROTECT = (1 << 1),
159 S_PROTECT = (1 << 2), 245 S_PROTECT = (1 << 2),
160 W_PROTECT = (1 << 3) 246 W_PROTECT = (1 << 3),
247 C_PROTECT = (1 << 4),
161}; 248};
162 249
163static void enable_firewall_interrupts(void) 250static inline int xdn_which_interrupt(struct hardwall_type *hwt)
251{
252#ifndef __tilepro__
253 if (hwt->is_idn)
254 return INT_IDN_FIREWALL;
255#endif
256 return INT_UDN_FIREWALL;
257}
258
259static void enable_firewall_interrupts(struct hardwall_type *hwt)
164{ 260{
165 arch_local_irq_unmask_now(INT_UDN_FIREWALL); 261 arch_local_irq_unmask_now(xdn_which_interrupt(hwt));
166} 262}
167 263
168static void disable_firewall_interrupts(void) 264static void disable_firewall_interrupts(struct hardwall_type *hwt)
169{ 265{
170 arch_local_irq_mask_now(INT_UDN_FIREWALL); 266 arch_local_irq_mask_now(xdn_which_interrupt(hwt));
171} 267}
172 268
173/* Set up hardwall on this cpu based on the passed hardwall_info. */ 269/* Set up hardwall on this cpu based on the passed hardwall_info. */
174static void hardwall_setup_ipi_func(void *info) 270static void hardwall_setup_func(void *info)
175{ 271{
176 struct hardwall_info *r = info; 272 struct hardwall_info *r = info;
273 struct hardwall_type *hwt = r->type;
274
177 int cpu = smp_processor_id(); 275 int cpu = smp_processor_id();
178 int x = cpu % smp_width; 276 int x = cpu % smp_width;
179 int y = cpu / smp_width; 277 int y = cpu / smp_width;
@@ -187,13 +285,12 @@ static void hardwall_setup_ipi_func(void *info)
187 if (y == r->ulhc_y + r->height - 1) 285 if (y == r->ulhc_y + r->height - 1)
188 bits |= S_PROTECT; 286 bits |= S_PROTECT;
189 BUG_ON(bits == 0); 287 BUG_ON(bits == 0);
190 __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, bits); 288 mtspr_XDN(hwt, DIRECTION_PROTECT, bits);
191 enable_firewall_interrupts(); 289 enable_firewall_interrupts(hwt);
192
193} 290}
194 291
195/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */ 292/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */
196static void hardwall_setup(struct hardwall_info *r) 293static void hardwall_protect_rectangle(struct hardwall_info *r)
197{ 294{
198 int x, y, cpu, delta; 295 int x, y, cpu, delta;
199 struct cpumask rect_cpus; 296 struct cpumask rect_cpus;
@@ -217,37 +314,50 @@ static void hardwall_setup(struct hardwall_info *r)
217 } 314 }
218 315
219 /* Then tell all the cpus to set up their protection SPR */ 316 /* Then tell all the cpus to set up their protection SPR */
220 on_each_cpu_mask(&rect_cpus, hardwall_setup_ipi_func, r, 1); 317 on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1);
221} 318}
222 319
223void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num) 320void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
224{ 321{
225 struct hardwall_info *rect; 322 struct hardwall_info *rect;
323 struct hardwall_type *hwt;
226 struct task_struct *p; 324 struct task_struct *p;
227 struct siginfo info; 325 struct siginfo info;
228 int x, y;
229 int cpu = smp_processor_id(); 326 int cpu = smp_processor_id();
230 int found_processes; 327 int found_processes;
231 unsigned long flags; 328 unsigned long flags;
232
233 struct pt_regs *old_regs = set_irq_regs(regs); 329 struct pt_regs *old_regs = set_irq_regs(regs);
330
234 irq_enter(); 331 irq_enter();
235 332
333 /* Figure out which network trapped. */
334 switch (fault_num) {
335#ifndef __tilepro__
336 case INT_IDN_FIREWALL:
337 hwt = &hardwall_types[HARDWALL_IDN];
338 break;
339#endif
340 case INT_UDN_FIREWALL:
341 hwt = &hardwall_types[HARDWALL_UDN];
342 break;
343 default:
344 BUG();
345 }
346 BUG_ON(hwt->disabled);
347
236 /* This tile trapped a network access; find the rectangle. */ 348 /* This tile trapped a network access; find the rectangle. */
237 x = cpu % smp_width; 349 spin_lock_irqsave(&hwt->lock, flags);
238 y = cpu / smp_width; 350 list_for_each_entry(rect, &hwt->list, list) {
239 spin_lock_irqsave(&hardwall_lock, flags); 351 if (cpumask_test_cpu(cpu, &rect->cpumask))
240 list_for_each_entry(rect, &rectangles, list) {
241 if (contains(rect, x, y))
242 break; 352 break;
243 } 353 }
244 354
245 /* 355 /*
246 * It shouldn't be possible not to find this cpu on the 356 * It shouldn't be possible not to find this cpu on the
247 * rectangle list, since only cpus in rectangles get hardwalled. 357 * rectangle list, since only cpus in rectangles get hardwalled.
248 * The hardwall is only removed after the UDN is drained. 358 * The hardwall is only removed after the user network is drained.
249 */ 359 */
250 BUG_ON(&rect->list == &rectangles); 360 BUG_ON(&rect->list == &hwt->list);
251 361
252 /* 362 /*
253 * If we already started teardown on this hardwall, don't worry; 363 * If we already started teardown on this hardwall, don't worry;
@@ -255,30 +365,32 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
255 * to quiesce. 365 * to quiesce.
256 */ 366 */
257 if (rect->teardown_in_progress) { 367 if (rect->teardown_in_progress) {
258 pr_notice("cpu %d: detected hardwall violation %#lx" 368 pr_notice("cpu %d: detected %s hardwall violation %#lx"
259 " while teardown already in progress\n", 369 " while teardown already in progress\n",
260 cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT)); 370 cpu, hwt->name,
371 (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
261 goto done; 372 goto done;
262 } 373 }
263 374
264 /* 375 /*
265 * Kill off any process that is activated in this rectangle. 376 * Kill off any process that is activated in this rectangle.
266 * We bypass security to deliver the signal, since it must be 377 * We bypass security to deliver the signal, since it must be
267 * one of the activated processes that generated the UDN 378 * one of the activated processes that generated the user network
268 * message that caused this trap, and all the activated 379 * message that caused this trap, and all the activated
269 * processes shared a single open file so are pretty tightly 380 * processes shared a single open file so are pretty tightly
270 * bound together from a security point of view to begin with. 381 * bound together from a security point of view to begin with.
271 */ 382 */
272 rect->teardown_in_progress = 1; 383 rect->teardown_in_progress = 1;
273 wmb(); /* Ensure visibility of rectangle before notifying processes. */ 384 wmb(); /* Ensure visibility of rectangle before notifying processes. */
274 pr_notice("cpu %d: detected hardwall violation %#lx...\n", 385 pr_notice("cpu %d: detected %s hardwall violation %#lx...\n",
275 cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT)); 386 cpu, hwt->name, (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
276 info.si_signo = SIGILL; 387 info.si_signo = SIGILL;
277 info.si_errno = 0; 388 info.si_errno = 0;
278 info.si_code = ILL_HARDWALL; 389 info.si_code = ILL_HARDWALL;
279 found_processes = 0; 390 found_processes = 0;
280 list_for_each_entry(p, &rect->task_head, thread.hardwall_list) { 391 list_for_each_entry(p, &rect->task_head,
281 BUG_ON(p->thread.hardwall != rect); 392 thread.hardwall[hwt->index].list) {
393 BUG_ON(p->thread.hardwall[hwt->index].info != rect);
282 if (!(p->flags & PF_EXITING)) { 394 if (!(p->flags & PF_EXITING)) {
283 found_processes = 1; 395 found_processes = 1;
284 pr_notice("hardwall: killing %d\n", p->pid); 396 pr_notice("hardwall: killing %d\n", p->pid);
@@ -289,7 +401,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
289 pr_notice("hardwall: no associated processes!\n"); 401 pr_notice("hardwall: no associated processes!\n");
290 402
291 done: 403 done:
292 spin_unlock_irqrestore(&hardwall_lock, flags); 404 spin_unlock_irqrestore(&hwt->lock, flags);
293 405
294 /* 406 /*
295 * We have to disable firewall interrupts now, or else when we 407 * We have to disable firewall interrupts now, or else when we
@@ -298,48 +410,87 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
298 * haven't yet drained the network, and that would allow packets 410 * haven't yet drained the network, and that would allow packets
299 * to cross out of the hardwall region. 411 * to cross out of the hardwall region.
300 */ 412 */
301 disable_firewall_interrupts(); 413 disable_firewall_interrupts(hwt);
302 414
303 irq_exit(); 415 irq_exit();
304 set_irq_regs(old_regs); 416 set_irq_regs(old_regs);
305} 417}
306 418
307/* Allow access from user space to the UDN. */ 419/* Allow access from user space to the user network. */
308void grant_network_mpls(void) 420void grant_hardwall_mpls(struct hardwall_type *hwt)
309{ 421{
310 __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_0, 1); 422#ifndef __tilepro__
311 __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_0, 1); 423 if (!hwt->is_xdn) {
312 __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_0, 1); 424 __insn_mtspr(SPR_MPL_IPI_0_SET_0, 1);
313 __insn_mtspr(SPR_MPL_UDN_TIMER_SET_0, 1); 425 return;
426 }
427#endif
428 mtspr_MPL_XDN(hwt, ACCESS_SET_0, 1);
429 mtspr_MPL_XDN(hwt, AVAIL_SET_0, 1);
430 mtspr_MPL_XDN(hwt, COMPLETE_SET_0, 1);
431 mtspr_MPL_XDN(hwt, TIMER_SET_0, 1);
314#if !CHIP_HAS_REV1_XDN() 432#if !CHIP_HAS_REV1_XDN()
315 __insn_mtspr(SPR_MPL_UDN_REFILL_SET_0, 1); 433 mtspr_MPL_XDN(hwt, REFILL_SET_0, 1);
316 __insn_mtspr(SPR_MPL_UDN_CA_SET_0, 1); 434 mtspr_MPL_XDN(hwt, CA_SET_0, 1);
317#endif 435#endif
318} 436}
319 437
320/* Deny access from user space to the UDN. */ 438/* Deny access from user space to the user network. */
321void restrict_network_mpls(void) 439void restrict_hardwall_mpls(struct hardwall_type *hwt)
322{ 440{
323 __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_1, 1); 441#ifndef __tilepro__
324 __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_1, 1); 442 if (!hwt->is_xdn) {
325 __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_1, 1); 443 __insn_mtspr(SPR_MPL_IPI_0_SET_1, 1);
326 __insn_mtspr(SPR_MPL_UDN_TIMER_SET_1, 1); 444 return;
445 }
446#endif
447 mtspr_MPL_XDN(hwt, ACCESS_SET_1, 1);
448 mtspr_MPL_XDN(hwt, AVAIL_SET_1, 1);
449 mtspr_MPL_XDN(hwt, COMPLETE_SET_1, 1);
450 mtspr_MPL_XDN(hwt, TIMER_SET_1, 1);
327#if !CHIP_HAS_REV1_XDN() 451#if !CHIP_HAS_REV1_XDN()
328 __insn_mtspr(SPR_MPL_UDN_REFILL_SET_1, 1); 452 mtspr_MPL_XDN(hwt, REFILL_SET_1, 1);
329 __insn_mtspr(SPR_MPL_UDN_CA_SET_1, 1); 453 mtspr_MPL_XDN(hwt, CA_SET_1, 1);
330#endif 454#endif
331} 455}
332 456
457/* Restrict or deny as necessary for the task we're switching to. */
458void hardwall_switch_tasks(struct task_struct *prev,
459 struct task_struct *next)
460{
461 int i;
462 for (i = 0; i < HARDWALL_TYPES; ++i) {
463 if (prev->thread.hardwall[i].info != NULL) {
464 if (next->thread.hardwall[i].info == NULL)
465 restrict_hardwall_mpls(&hardwall_types[i]);
466 } else if (next->thread.hardwall[i].info != NULL) {
467 grant_hardwall_mpls(&hardwall_types[i]);
468 }
469 }
470}
471
472/* Does this task have the right to IPI the given cpu? */
473int hardwall_ipi_valid(int cpu)
474{
475#ifdef __tilegx__
476 struct hardwall_info *info =
477 current->thread.hardwall[HARDWALL_IPI].info;
478 return info && cpumask_test_cpu(cpu, &info->cpumask);
479#else
480 return 0;
481#endif
482}
333 483
334/* 484/*
335 * Code to create, activate, deactivate, and destroy hardwall rectangles. 485 * Code to create, activate, deactivate, and destroy hardwall resources.
336 */ 486 */
337 487
338/* Create a hardwall for the given rectangle */ 488/* Create a hardwall for the given resource */
339static struct hardwall_info *hardwall_create( 489static struct hardwall_info *hardwall_create(struct hardwall_type *hwt,
340 size_t size, const unsigned char __user *bits) 490 size_t size,
491 const unsigned char __user *bits)
341{ 492{
342 struct hardwall_info *iter, *rect; 493 struct hardwall_info *iter, *info;
343 struct cpumask mask; 494 struct cpumask mask;
344 unsigned long flags; 495 unsigned long flags;
345 int rc; 496 int rc;
@@ -370,55 +521,62 @@ static struct hardwall_info *hardwall_create(
370 } 521 }
371 } 522 }
372 523
373 /* Allocate a new rectangle optimistically. */ 524 /* Allocate a new hardwall_info optimistically. */
374 rect = kmalloc(sizeof(struct hardwall_info), 525 info = kmalloc(sizeof(struct hardwall_info),
375 GFP_KERNEL | __GFP_ZERO); 526 GFP_KERNEL | __GFP_ZERO);
376 if (rect == NULL) 527 if (info == NULL)
377 return ERR_PTR(-ENOMEM); 528 return ERR_PTR(-ENOMEM);
378 INIT_LIST_HEAD(&rect->task_head); 529 INIT_LIST_HEAD(&info->task_head);
530 info->type = hwt;
379 531
380 /* Compute the rectangle size and validate that it's plausible. */ 532 /* Compute the rectangle size and validate that it's plausible. */
381 rc = setup_rectangle(rect, &mask); 533 cpumask_copy(&info->cpumask, &mask);
382 if (rc != 0) { 534 info->id = find_first_bit(cpumask_bits(&mask), nr_cpumask_bits);
383 kfree(rect); 535 if (hwt->is_xdn) {
384 return ERR_PTR(rc); 536 rc = check_rectangle(info, &mask);
537 if (rc != 0) {
538 kfree(info);
539 return ERR_PTR(rc);
540 }
385 } 541 }
386 542
387 /* Confirm it doesn't overlap and add it to the list. */ 543 /* Confirm it doesn't overlap and add it to the list. */
388 spin_lock_irqsave(&hardwall_lock, flags); 544 spin_lock_irqsave(&hwt->lock, flags);
389 list_for_each_entry(iter, &rectangles, list) { 545 list_for_each_entry(iter, &hwt->list, list) {
390 if (overlaps(iter, rect)) { 546 if (cpumask_intersects(&iter->cpumask, &info->cpumask)) {
391 spin_unlock_irqrestore(&hardwall_lock, flags); 547 spin_unlock_irqrestore(&hwt->lock, flags);
392 kfree(rect); 548 kfree(info);
393 return ERR_PTR(-EBUSY); 549 return ERR_PTR(-EBUSY);
394 } 550 }
395 } 551 }
396 list_add_tail(&rect->list, &rectangles); 552 list_add_tail(&info->list, &hwt->list);
397 spin_unlock_irqrestore(&hardwall_lock, flags); 553 spin_unlock_irqrestore(&hwt->lock, flags);
398 554
399 /* Set up appropriate hardwalling on all affected cpus. */ 555 /* Set up appropriate hardwalling on all affected cpus. */
400 hardwall_setup(rect); 556 if (hwt->is_xdn)
557 hardwall_protect_rectangle(info);
401 558
402 /* Create a /proc/tile/hardwall entry. */ 559 /* Create a /proc/tile/hardwall entry. */
403 hardwall_add_proc(rect); 560 hardwall_add_proc(info);
404 561
405 return rect; 562 return info;
406} 563}
407 564
408/* Activate a given hardwall on this cpu for this process. */ 565/* Activate a given hardwall on this cpu for this process. */
409static int hardwall_activate(struct hardwall_info *rect) 566static int hardwall_activate(struct hardwall_info *info)
410{ 567{
411 int cpu, x, y; 568 int cpu;
412 unsigned long flags; 569 unsigned long flags;
413 struct task_struct *p = current; 570 struct task_struct *p = current;
414 struct thread_struct *ts = &p->thread; 571 struct thread_struct *ts = &p->thread;
572 struct hardwall_type *hwt;
415 573
416 /* Require a rectangle. */ 574 /* Require a hardwall. */
417 if (rect == NULL) 575 if (info == NULL)
418 return -ENODATA; 576 return -ENODATA;
419 577
420 /* Not allowed to activate a rectangle that is being torn down. */ 578 /* Not allowed to activate a hardwall that is being torn down. */
421 if (rect->teardown_in_progress) 579 if (info->teardown_in_progress)
422 return -EINVAL; 580 return -EINVAL;
423 581
424 /* 582 /*
@@ -428,78 +586,87 @@ static int hardwall_activate(struct hardwall_info *rect)
428 if (cpumask_weight(&p->cpus_allowed) != 1) 586 if (cpumask_weight(&p->cpus_allowed) != 1)
429 return -EPERM; 587 return -EPERM;
430 588
431 /* Make sure we are bound to a cpu in this rectangle. */ 589 /* Make sure we are bound to a cpu assigned to this resource. */
432 cpu = smp_processor_id(); 590 cpu = smp_processor_id();
433 BUG_ON(cpumask_first(&p->cpus_allowed) != cpu); 591 BUG_ON(cpumask_first(&p->cpus_allowed) != cpu);
434 x = cpu_x(cpu); 592 if (!cpumask_test_cpu(cpu, &info->cpumask))
435 y = cpu_y(cpu);
436 if (!contains(rect, x, y))
437 return -EINVAL; 593 return -EINVAL;
438 594
439 /* If we are already bound to this hardwall, it's a no-op. */ 595 /* If we are already bound to this hardwall, it's a no-op. */
440 if (ts->hardwall) { 596 hwt = info->type;
441 BUG_ON(ts->hardwall != rect); 597 if (ts->hardwall[hwt->index].info) {
598 BUG_ON(ts->hardwall[hwt->index].info != info);
442 return 0; 599 return 0;
443 } 600 }
444 601
445 /* Success! This process gets to use the user networks on this cpu. */ 602 /* Success! This process gets to use the resource on this cpu. */
446 ts->hardwall = rect; 603 ts->hardwall[hwt->index].info = info;
447 spin_lock_irqsave(&hardwall_lock, flags); 604 spin_lock_irqsave(&hwt->lock, flags);
448 list_add(&ts->hardwall_list, &rect->task_head); 605 list_add(&ts->hardwall[hwt->index].list, &info->task_head);
449 spin_unlock_irqrestore(&hardwall_lock, flags); 606 spin_unlock_irqrestore(&hwt->lock, flags);
450 grant_network_mpls(); 607 grant_hardwall_mpls(hwt);
451 printk(KERN_DEBUG "Pid %d (%s) activated for hardwall: cpu %d\n", 608 printk(KERN_DEBUG "Pid %d (%s) activated for %s hardwall: cpu %d\n",
452 p->pid, p->comm, cpu); 609 p->pid, p->comm, hwt->name, cpu);
453 return 0; 610 return 0;
454} 611}
455 612
456/* 613/*
457 * Deactivate a task's hardwall. Must hold hardwall_lock. 614 * Deactivate a task's hardwall. Must hold lock for hardwall_type.
458 * This method may be called from free_task(), so we don't want to 615 * This method may be called from free_task(), so we don't want to
459 * rely on too many fields of struct task_struct still being valid. 616 * rely on too many fields of struct task_struct still being valid.
460 * We assume the cpus_allowed, pid, and comm fields are still valid. 617 * We assume the cpus_allowed, pid, and comm fields are still valid.
461 */ 618 */
462static void _hardwall_deactivate(struct task_struct *task) 619static void _hardwall_deactivate(struct hardwall_type *hwt,
620 struct task_struct *task)
463{ 621{
464 struct thread_struct *ts = &task->thread; 622 struct thread_struct *ts = &task->thread;
465 623
466 if (cpumask_weight(&task->cpus_allowed) != 1) { 624 if (cpumask_weight(&task->cpus_allowed) != 1) {
467 pr_err("pid %d (%s) releasing networks with" 625 pr_err("pid %d (%s) releasing %s hardwall with"
468 " an affinity mask containing %d cpus!\n", 626 " an affinity mask containing %d cpus!\n",
469 task->pid, task->comm, 627 task->pid, task->comm, hwt->name,
470 cpumask_weight(&task->cpus_allowed)); 628 cpumask_weight(&task->cpus_allowed));
471 BUG(); 629 BUG();
472 } 630 }
473 631
474 BUG_ON(ts->hardwall == NULL); 632 BUG_ON(ts->hardwall[hwt->index].info == NULL);
475 ts->hardwall = NULL; 633 ts->hardwall[hwt->index].info = NULL;
476 list_del(&ts->hardwall_list); 634 list_del(&ts->hardwall[hwt->index].list);
477 if (task == current) 635 if (task == current)
478 restrict_network_mpls(); 636 restrict_hardwall_mpls(hwt);
479} 637}
480 638
481/* Deactivate a task's hardwall. */ 639/* Deactivate a task's hardwall. */
482int hardwall_deactivate(struct task_struct *task) 640static int hardwall_deactivate(struct hardwall_type *hwt,
641 struct task_struct *task)
483{ 642{
484 unsigned long flags; 643 unsigned long flags;
485 int activated; 644 int activated;
486 645
487 spin_lock_irqsave(&hardwall_lock, flags); 646 spin_lock_irqsave(&hwt->lock, flags);
488 activated = (task->thread.hardwall != NULL); 647 activated = (task->thread.hardwall[hwt->index].info != NULL);
489 if (activated) 648 if (activated)
490 _hardwall_deactivate(task); 649 _hardwall_deactivate(hwt, task);
491 spin_unlock_irqrestore(&hardwall_lock, flags); 650 spin_unlock_irqrestore(&hwt->lock, flags);
492 651
493 if (!activated) 652 if (!activated)
494 return -EINVAL; 653 return -EINVAL;
495 654
496 printk(KERN_DEBUG "Pid %d (%s) deactivated for hardwall: cpu %d\n", 655 printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n",
497 task->pid, task->comm, smp_processor_id()); 656 task->pid, task->comm, hwt->name, smp_processor_id());
498 return 0; 657 return 0;
499} 658}
500 659
501/* Stop a UDN switch before draining the network. */ 660void hardwall_deactivate_all(struct task_struct *task)
502static void stop_udn_switch(void *ignored) 661{
662 int i;
663 for (i = 0; i < HARDWALL_TYPES; ++i)
664 if (task->thread.hardwall[i].info)
665 hardwall_deactivate(&hardwall_types[i], task);
666}
667
668/* Stop the switch before draining the network. */
669static void stop_xdn_switch(void *arg)
503{ 670{
504#if !CHIP_HAS_REV1_XDN() 671#if !CHIP_HAS_REV1_XDN()
505 /* Freeze the switch and the demux. */ 672 /* Freeze the switch and the demux. */
@@ -507,13 +674,71 @@ static void stop_udn_switch(void *ignored)
507 SPR_UDN_SP_FREEZE__SP_FRZ_MASK | 674 SPR_UDN_SP_FREEZE__SP_FRZ_MASK |
508 SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK | 675 SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK |
509 SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK); 676 SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK);
677#else
678 /*
679 * Drop all packets bound for the core or off the edge.
680 * We rely on the normal hardwall protection setup code
681 * to have set the low four bits to trigger firewall interrupts,
682 * and shift those bits up to trigger "drop on send" semantics,
683 * plus adding "drop on send to core" for all switches.
684 * In practice it seems the switches latch the DIRECTION_PROTECT
685 * SPR so they won't start dropping if they're already
686 * delivering the last message to the core, but it doesn't
687 * hurt to enable it here.
688 */
689 struct hardwall_type *hwt = arg;
690 unsigned long protect = mfspr_XDN(hwt, DIRECTION_PROTECT);
691 mtspr_XDN(hwt, DIRECTION_PROTECT, (protect | C_PROTECT) << 5);
510#endif 692#endif
511} 693}
512 694
695static void empty_xdn_demuxes(struct hardwall_type *hwt)
696{
697#ifndef __tilepro__
698 if (hwt->is_idn) {
699 while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 0))
700 (void) __tile_idn0_receive();
701 while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 1))
702 (void) __tile_idn1_receive();
703 return;
704 }
705#endif
706 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
707 (void) __tile_udn0_receive();
708 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
709 (void) __tile_udn1_receive();
710 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
711 (void) __tile_udn2_receive();
712 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
713 (void) __tile_udn3_receive();
714}
715
513/* Drain all the state from a stopped switch. */ 716/* Drain all the state from a stopped switch. */
514static void drain_udn_switch(void *ignored) 717static void drain_xdn_switch(void *arg)
515{ 718{
516#if !CHIP_HAS_REV1_XDN() 719 struct hardwall_info *info = arg;
720 struct hardwall_type *hwt = info->type;
721
722#if CHIP_HAS_REV1_XDN()
723 /*
724 * The switches have been configured to drop any messages
725 * destined for cores (or off the edge of the rectangle).
726 * But the current message may continue to be delivered,
727 * so we wait until all the cores have finished any pending
728 * messages before we stop draining.
729 */
730 int pending = mfspr_XDN(hwt, PENDING);
731 while (pending--) {
732 empty_xdn_demuxes(hwt);
733 if (hwt->is_idn)
734 __tile_idn_send(0);
735 else
736 __tile_udn_send(0);
737 }
738 atomic_dec(&info->xdn_pending_count);
739 while (atomic_read(&info->xdn_pending_count))
740 empty_xdn_demuxes(hwt);
741#else
517 int i; 742 int i;
518 int from_tile_words, ca_count; 743 int from_tile_words, ca_count;
519 744
@@ -533,15 +758,7 @@ static void drain_udn_switch(void *ignored)
533 (void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO); 758 (void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO);
534 759
535 /* Empty out demuxes. */ 760 /* Empty out demuxes. */
536 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0)) 761 empty_xdn_demuxes(hwt);
537 (void) __tile_udn0_receive();
538 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
539 (void) __tile_udn1_receive();
540 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
541 (void) __tile_udn2_receive();
542 while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
543 (void) __tile_udn3_receive();
544 BUG_ON((__insn_mfspr(SPR_UDN_DATA_AVAIL) & 0xF) != 0);
545 762
546 /* Empty out catch all. */ 763 /* Empty out catch all. */
547 ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT); 764 ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT);
@@ -563,21 +780,25 @@ static void drain_udn_switch(void *ignored)
563#endif 780#endif
564} 781}
565 782
566/* Reset random UDN state registers at boot up and during hardwall teardown. */ 783/* Reset random XDN state registers at boot up and during hardwall teardown. */
567void reset_network_state(void) 784static void reset_xdn_network_state(struct hardwall_type *hwt)
568{ 785{
569#if !CHIP_HAS_REV1_XDN() 786 if (hwt->disabled)
570 /* Reset UDN coordinates to their standard value */
571 unsigned int cpu = smp_processor_id();
572 unsigned int x = cpu % smp_width;
573 unsigned int y = cpu / smp_width;
574#endif
575
576 if (udn_disabled)
577 return; 787 return;
578 788
789 /* Clear out other random registers so we have a clean slate. */
790 mtspr_XDN(hwt, DIRECTION_PROTECT, 0);
791 mtspr_XDN(hwt, AVAIL_EN, 0);
792 mtspr_XDN(hwt, DEADLOCK_TIMEOUT, 0);
793
579#if !CHIP_HAS_REV1_XDN() 794#if !CHIP_HAS_REV1_XDN()
580 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7)); 795 /* Reset UDN coordinates to their standard value */
796 {
797 unsigned int cpu = smp_processor_id();
798 unsigned int x = cpu % smp_width;
799 unsigned int y = cpu / smp_width;
800 __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
801 }
581 802
582 /* Set demux tags to predefined values and enable them. */ 803 /* Set demux tags to predefined values and enable them. */
583 __insn_mtspr(SPR_UDN_TAG_VALID, 0xf); 804 __insn_mtspr(SPR_UDN_TAG_VALID, 0xf);
@@ -585,56 +806,50 @@ void reset_network_state(void)
585 __insn_mtspr(SPR_UDN_TAG_1, (1 << 1)); 806 __insn_mtspr(SPR_UDN_TAG_1, (1 << 1));
586 __insn_mtspr(SPR_UDN_TAG_2, (1 << 2)); 807 __insn_mtspr(SPR_UDN_TAG_2, (1 << 2));
587 __insn_mtspr(SPR_UDN_TAG_3, (1 << 3)); 808 __insn_mtspr(SPR_UDN_TAG_3, (1 << 3));
588#endif
589 809
590 /* Clear out other random registers so we have a clean slate. */ 810 /* Set other rev0 random registers to a clean state. */
591 __insn_mtspr(SPR_UDN_AVAIL_EN, 0);
592 __insn_mtspr(SPR_UDN_DEADLOCK_TIMEOUT, 0);
593#if !CHIP_HAS_REV1_XDN()
594 __insn_mtspr(SPR_UDN_REFILL_EN, 0); 811 __insn_mtspr(SPR_UDN_REFILL_EN, 0);
595 __insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0); 812 __insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0);
596 __insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0); 813 __insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0);
597#endif
598 814
599 /* Start the switch and demux. */ 815 /* Start the switch and demux. */
600#if !CHIP_HAS_REV1_XDN()
601 __insn_mtspr(SPR_UDN_SP_FREEZE, 0); 816 __insn_mtspr(SPR_UDN_SP_FREEZE, 0);
602#endif 817#endif
603} 818}
604 819
605/* Restart a UDN switch after draining. */ 820void reset_network_state(void)
606static void restart_udn_switch(void *ignored)
607{ 821{
608 reset_network_state(); 822 reset_xdn_network_state(&hardwall_types[HARDWALL_UDN]);
609 823#ifndef __tilepro__
610 /* Disable firewall interrupts. */ 824 reset_xdn_network_state(&hardwall_types[HARDWALL_IDN]);
611 __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, 0); 825#endif
612 disable_firewall_interrupts();
613} 826}
614 827
615/* Build a struct cpumask containing all valid tiles in bounding rectangle. */ 828/* Restart an XDN switch after draining. */
616static void fill_mask(struct hardwall_info *r, struct cpumask *result) 829static void restart_xdn_switch(void *arg)
617{ 830{
618 int x, y, cpu; 831 struct hardwall_type *hwt = arg;
619 832
620 cpumask_clear(result); 833#if CHIP_HAS_REV1_XDN()
834 /* One last drain step to avoid races with injection and draining. */
835 empty_xdn_demuxes(hwt);
836#endif
621 837
622 cpu = r->ulhc_y * smp_width + r->ulhc_x; 838 reset_xdn_network_state(hwt);
623 for (y = 0; y < r->height; ++y, cpu += smp_width - r->width) { 839
624 for (x = 0; x < r->width; ++x, ++cpu) 840 /* Disable firewall interrupts. */
625 cpu_online_set(cpu, result); 841 disable_firewall_interrupts(hwt);
626 }
627} 842}
628 843
629/* Last reference to a hardwall is gone, so clear the network. */ 844/* Last reference to a hardwall is gone, so clear the network. */
630static void hardwall_destroy(struct hardwall_info *rect) 845static void hardwall_destroy(struct hardwall_info *info)
631{ 846{
632 struct task_struct *task; 847 struct task_struct *task;
848 struct hardwall_type *hwt;
633 unsigned long flags; 849 unsigned long flags;
634 struct cpumask mask;
635 850
636 /* Make sure this file actually represents a rectangle. */ 851 /* Make sure this file actually represents a hardwall. */
637 if (rect == NULL) 852 if (info == NULL)
638 return; 853 return;
639 854
640 /* 855 /*
@@ -644,39 +859,53 @@ static void hardwall_destroy(struct hardwall_info *rect)
644 * deactivate any remaining tasks before freeing the 859 * deactivate any remaining tasks before freeing the
645 * hardwall_info object itself. 860 * hardwall_info object itself.
646 */ 861 */
647 spin_lock_irqsave(&hardwall_lock, flags); 862 hwt = info->type;
648 list_for_each_entry(task, &rect->task_head, thread.hardwall_list) 863 info->teardown_in_progress = 1;
649 _hardwall_deactivate(task); 864 spin_lock_irqsave(&hwt->lock, flags);
650 spin_unlock_irqrestore(&hardwall_lock, flags); 865 list_for_each_entry(task, &info->task_head,
651 866 thread.hardwall[hwt->index].list)
652 /* Drain the UDN. */ 867 _hardwall_deactivate(hwt, task);
653 printk(KERN_DEBUG "Clearing hardwall rectangle %dx%d %d,%d\n", 868 spin_unlock_irqrestore(&hwt->lock, flags);
654 rect->width, rect->height, rect->ulhc_x, rect->ulhc_y); 869
655 fill_mask(rect, &mask); 870 if (hwt->is_xdn) {
656 on_each_cpu_mask(&mask, stop_udn_switch, NULL, 1); 871 /* Configure the switches for draining the user network. */
657 on_each_cpu_mask(&mask, drain_udn_switch, NULL, 1); 872 printk(KERN_DEBUG
873 "Clearing %s hardwall rectangle %dx%d %d,%d\n",
874 hwt->name, info->width, info->height,
875 info->ulhc_x, info->ulhc_y);
876 on_each_cpu_mask(&info->cpumask, stop_xdn_switch, hwt, 1);
877
878 /* Drain the network. */
879#if CHIP_HAS_REV1_XDN()
880 atomic_set(&info->xdn_pending_count,
881 cpumask_weight(&info->cpumask));
882 on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 0);
883#else
884 on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 1);
885#endif
658 886
659 /* Restart switch and disable firewall. */ 887 /* Restart switch and disable firewall. */
660 on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1); 888 on_each_cpu_mask(&info->cpumask, restart_xdn_switch, hwt, 1);
889 }
661 890
662 /* Remove the /proc/tile/hardwall entry. */ 891 /* Remove the /proc/tile/hardwall entry. */
663 hardwall_remove_proc(rect); 892 hardwall_remove_proc(info);
664 893
665 /* Now free the rectangle from the list. */ 894 /* Now free the hardwall from the list. */
666 spin_lock_irqsave(&hardwall_lock, flags); 895 spin_lock_irqsave(&hwt->lock, flags);
667 BUG_ON(!list_empty(&rect->task_head)); 896 BUG_ON(!list_empty(&info->task_head));
668 list_del(&rect->list); 897 list_del(&info->list);
669 spin_unlock_irqrestore(&hardwall_lock, flags); 898 spin_unlock_irqrestore(&hwt->lock, flags);
670 kfree(rect); 899 kfree(info);
671} 900}
672 901
673 902
674static int hardwall_proc_show(struct seq_file *sf, void *v) 903static int hardwall_proc_show(struct seq_file *sf, void *v)
675{ 904{
676 struct hardwall_info *rect = sf->private; 905 struct hardwall_info *info = sf->private;
677 char buf[256]; 906 char buf[256];
678 907
679 int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask); 908 int rc = cpulist_scnprintf(buf, sizeof(buf), &info->cpumask);
680 buf[rc++] = '\n'; 909 buf[rc++] = '\n';
681 seq_write(sf, buf, rc); 910 seq_write(sf, buf, rc);
682 return 0; 911 return 0;
@@ -695,31 +924,45 @@ static const struct file_operations hardwall_proc_fops = {
695 .release = single_release, 924 .release = single_release,
696}; 925};
697 926
698static void hardwall_add_proc(struct hardwall_info *rect) 927static void hardwall_add_proc(struct hardwall_info *info)
699{ 928{
700 char buf[64]; 929 char buf[64];
701 snprintf(buf, sizeof(buf), "%d", rect->id); 930 snprintf(buf, sizeof(buf), "%d", info->id);
702 proc_create_data(buf, 0444, hardwall_proc_dir, 931 proc_create_data(buf, 0444, info->type->proc_dir,
703 &hardwall_proc_fops, rect); 932 &hardwall_proc_fops, info);
704} 933}
705 934
706static void hardwall_remove_proc(struct hardwall_info *rect) 935static void hardwall_remove_proc(struct hardwall_info *info)
707{ 936{
708 char buf[64]; 937 char buf[64];
709 snprintf(buf, sizeof(buf), "%d", rect->id); 938 snprintf(buf, sizeof(buf), "%d", info->id);
710 remove_proc_entry(buf, hardwall_proc_dir); 939 remove_proc_entry(buf, info->type->proc_dir);
711} 940}
712 941
713int proc_pid_hardwall(struct task_struct *task, char *buffer) 942int proc_pid_hardwall(struct task_struct *task, char *buffer)
714{ 943{
715 struct hardwall_info *rect = task->thread.hardwall; 944 int i;
716 return rect ? sprintf(buffer, "%d\n", rect->id) : 0; 945 int n = 0;
946 for (i = 0; i < HARDWALL_TYPES; ++i) {
947 struct hardwall_info *info = task->thread.hardwall[i].info;
948 if (info)
949 n += sprintf(&buffer[n], "%s: %d\n",
950 info->type->name, info->id);
951 }
952 return n;
717} 953}
718 954
719void proc_tile_hardwall_init(struct proc_dir_entry *root) 955void proc_tile_hardwall_init(struct proc_dir_entry *root)
720{ 956{
721 if (!udn_disabled) 957 int i;
722 hardwall_proc_dir = proc_mkdir("hardwall", root); 958 for (i = 0; i < HARDWALL_TYPES; ++i) {
959 struct hardwall_type *hwt = &hardwall_types[i];
960 if (hwt->disabled)
961 continue;
962 if (hardwall_proc_dir == NULL)
963 hardwall_proc_dir = proc_mkdir("hardwall", root);
964 hwt->proc_dir = proc_mkdir(hwt->name, hardwall_proc_dir);
965 }
723} 966}
724 967
725 968
@@ -729,34 +972,45 @@ void proc_tile_hardwall_init(struct proc_dir_entry *root)
729 972
730static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b) 973static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
731{ 974{
732 struct hardwall_info *rect = file->private_data; 975 struct hardwall_info *info = file->private_data;
976 int minor = iminor(file->f_mapping->host);
977 struct hardwall_type* hwt;
733 978
734 if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE) 979 if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE)
735 return -EINVAL; 980 return -EINVAL;
736 981
982 BUILD_BUG_ON(HARDWALL_TYPES != _HARDWALL_TYPES);
983 BUILD_BUG_ON(HARDWALL_TYPES !=
984 sizeof(hardwall_types)/sizeof(hardwall_types[0]));
985
986 if (minor < 0 || minor >= HARDWALL_TYPES)
987 return -EINVAL;
988 hwt = &hardwall_types[minor];
989 WARN_ON(info && hwt != info->type);
990
737 switch (_IOC_NR(a)) { 991 switch (_IOC_NR(a)) {
738 case _HARDWALL_CREATE: 992 case _HARDWALL_CREATE:
739 if (udn_disabled) 993 if (hwt->disabled)
740 return -ENOSYS; 994 return -ENOSYS;
741 if (rect != NULL) 995 if (info != NULL)
742 return -EALREADY; 996 return -EALREADY;
743 rect = hardwall_create(_IOC_SIZE(a), 997 info = hardwall_create(hwt, _IOC_SIZE(a),
744 (const unsigned char __user *)b); 998 (const unsigned char __user *)b);
745 if (IS_ERR(rect)) 999 if (IS_ERR(info))
746 return PTR_ERR(rect); 1000 return PTR_ERR(info);
747 file->private_data = rect; 1001 file->private_data = info;
748 return 0; 1002 return 0;
749 1003
750 case _HARDWALL_ACTIVATE: 1004 case _HARDWALL_ACTIVATE:
751 return hardwall_activate(rect); 1005 return hardwall_activate(info);
752 1006
753 case _HARDWALL_DEACTIVATE: 1007 case _HARDWALL_DEACTIVATE:
754 if (current->thread.hardwall != rect) 1008 if (current->thread.hardwall[hwt->index].info != info)
755 return -EINVAL; 1009 return -EINVAL;
756 return hardwall_deactivate(current); 1010 return hardwall_deactivate(hwt, current);
757 1011
758 case _HARDWALL_GET_ID: 1012 case _HARDWALL_GET_ID:
759 return rect ? rect->id : -EINVAL; 1013 return info ? info->id : -EINVAL;
760 1014
761 default: 1015 default:
762 return -EINVAL; 1016 return -EINVAL;
@@ -775,26 +1029,28 @@ static long hardwall_compat_ioctl(struct file *file,
775/* The user process closed the file; revoke access to user networks. */ 1029/* The user process closed the file; revoke access to user networks. */
776static int hardwall_flush(struct file *file, fl_owner_t owner) 1030static int hardwall_flush(struct file *file, fl_owner_t owner)
777{ 1031{
778 struct hardwall_info *rect = file->private_data; 1032 struct hardwall_info *info = file->private_data;
779 struct task_struct *task, *tmp; 1033 struct task_struct *task, *tmp;
780 unsigned long flags; 1034 unsigned long flags;
781 1035
782 if (rect) { 1036 if (info) {
783 /* 1037 /*
784 * NOTE: if multiple threads are activated on this hardwall 1038 * NOTE: if multiple threads are activated on this hardwall
785 * file, the other threads will continue having access to the 1039 * file, the other threads will continue having access to the
786 * UDN until they are context-switched out and back in again. 1040 * user network until they are context-switched out and back
1041 * in again.
787 * 1042 *
788 * NOTE: A NULL files pointer means the task is being torn 1043 * NOTE: A NULL files pointer means the task is being torn
789 * down, so in that case we also deactivate it. 1044 * down, so in that case we also deactivate it.
790 */ 1045 */
791 spin_lock_irqsave(&hardwall_lock, flags); 1046 struct hardwall_type *hwt = info->type;
792 list_for_each_entry_safe(task, tmp, &rect->task_head, 1047 spin_lock_irqsave(&hwt->lock, flags);
793 thread.hardwall_list) { 1048 list_for_each_entry_safe(task, tmp, &info->task_head,
1049 thread.hardwall[hwt->index].list) {
794 if (task->files == owner || task->files == NULL) 1050 if (task->files == owner || task->files == NULL)
795 _hardwall_deactivate(task); 1051 _hardwall_deactivate(hwt, task);
796 } 1052 }
797 spin_unlock_irqrestore(&hardwall_lock, flags); 1053 spin_unlock_irqrestore(&hwt->lock, flags);
798 } 1054 }
799 1055
800 return 0; 1056 return 0;
@@ -824,11 +1080,11 @@ static int __init dev_hardwall_init(void)
824 int rc; 1080 int rc;
825 dev_t dev; 1081 dev_t dev;
826 1082
827 rc = alloc_chrdev_region(&dev, 0, 1, "hardwall"); 1083 rc = alloc_chrdev_region(&dev, 0, HARDWALL_TYPES, "hardwall");
828 if (rc < 0) 1084 if (rc < 0)
829 return rc; 1085 return rc;
830 cdev_init(&hardwall_dev, &dev_hardwall_fops); 1086 cdev_init(&hardwall_dev, &dev_hardwall_fops);
831 rc = cdev_add(&hardwall_dev, dev, 1); 1087 rc = cdev_add(&hardwall_dev, dev, HARDWALL_TYPES);
832 if (rc < 0) 1088 if (rc < 0)
833 return rc; 1089 return rc;
834 1090
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
index 1a39b7c1c87..f71bfeeaf1a 100644
--- a/arch/tile/kernel/head_32.S
+++ b/arch/tile/kernel/head_32.S
@@ -69,7 +69,7 @@ ENTRY(_start)
69 } 69 }
70 { 70 {
71 moveli lr, lo16(1f) 71 moveli lr, lo16(1f)
72 move r5, zero 72 moveli r5, CTX_PAGE_FLAG
73 } 73 }
74 { 74 {
75 auli lr, lr, ha16(1f) 75 auli lr, lr, ha16(1f)
@@ -141,11 +141,11 @@ ENTRY(empty_zero_page)
141 141
142 .macro PTE va, cpa, bits1, no_org=0 142 .macro PTE va, cpa, bits1, no_org=0
143 .ifeq \no_org 143 .ifeq \no_org
144 .org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE 144 .org swapper_pg_dir + PGD_INDEX(\va) * HV_PTE_SIZE
145 .endif 145 .endif
146 .word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \ 146 .word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
147 (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) 147 (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
148 .word (\bits1) | (HV_CPA_TO_PFN(\cpa) << (HV_PTE_INDEX_PFN - 32)) 148 .word (\bits1) | (HV_CPA_TO_PTFN(\cpa) << (HV_PTE_INDEX_PTFN - 32))
149 .endm 149 .endm
150 150
151__PAGE_ALIGNED_DATA 151__PAGE_ALIGNED_DATA
@@ -166,7 +166,7 @@ ENTRY(swapper_pg_dir)
166 /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */ 166 /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
167 PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \ 167 PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \
168 (1 << (HV_PTE_INDEX_EXECUTABLE - 32)) 168 (1 << (HV_PTE_INDEX_EXECUTABLE - 32))
169 .org swapper_pg_dir + HV_L1_SIZE 169 .org swapper_pg_dir + PGDIR_SIZE
170 END(swapper_pg_dir) 170 END(swapper_pg_dir)
171 171
172 /* 172 /*
diff --git a/arch/tile/kernel/head_64.S b/arch/tile/kernel/head_64.S
index 6bc3a932fe4..f9a2734f7b8 100644
--- a/arch/tile/kernel/head_64.S
+++ b/arch/tile/kernel/head_64.S
@@ -114,7 +114,7 @@ ENTRY(_start)
114 shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET) 114 shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
115 } 115 }
116 { 116 {
117 move r3, zero 117 moveli r3, CTX_PAGE_FLAG
118 j hv_install_context 118 j hv_install_context
119 } 119 }
1201: 1201:
@@ -210,19 +210,19 @@ ENTRY(empty_zero_page)
210 .macro PTE cpa, bits1 210 .macro PTE cpa, bits1
211 .quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\ 211 .quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
212 HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\ 212 HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
213 (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN) 213 (\bits1) | (HV_CPA_TO_PTFN(\cpa) << HV_PTE_INDEX_PTFN)
214 .endm 214 .endm
215 215
216__PAGE_ALIGNED_DATA 216__PAGE_ALIGNED_DATA
217 .align PAGE_SIZE 217 .align PAGE_SIZE
218ENTRY(swapper_pg_dir) 218ENTRY(swapper_pg_dir)
219 .org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE 219 .org swapper_pg_dir + PGD_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
220.Lsv_data_pmd: 220.Lsv_data_pmd:
221 .quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */ 221 .quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
222 .org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE 222 .org swapper_pg_dir + PGD_INDEX(MEM_SV_START) * HV_PTE_SIZE
223.Lsv_code_pmd: 223.Lsv_code_pmd:
224 .quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */ 224 .quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
225 .org swapper_pg_dir + HV_L0_SIZE 225 .org swapper_pg_dir + SIZEOF_PGD
226 END(swapper_pg_dir) 226 END(swapper_pg_dir)
227 227
228 .align HV_PAGE_TABLE_ALIGN 228 .align HV_PAGE_TABLE_ALIGN
@@ -233,11 +233,11 @@ ENTRY(temp_data_pmd)
233 * permissions later. 233 * permissions later.
234 */ 234 */
235 .set addr, 0 235 .set addr, 0
236 .rept HV_L1_ENTRIES 236 .rept PTRS_PER_PMD
237 PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE 237 PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
238 .set addr, addr + HV_PAGE_SIZE_LARGE 238 .set addr, addr + HPAGE_SIZE
239 .endr 239 .endr
240 .org temp_data_pmd + HV_L1_SIZE 240 .org temp_data_pmd + SIZEOF_PMD
241 END(temp_data_pmd) 241 END(temp_data_pmd)
242 242
243 .align HV_PAGE_TABLE_ALIGN 243 .align HV_PAGE_TABLE_ALIGN
@@ -248,11 +248,11 @@ ENTRY(temp_code_pmd)
248 * permissions later. 248 * permissions later.
249 */ 249 */
250 .set addr, 0 250 .set addr, 0
251 .rept HV_L1_ENTRIES 251 .rept PTRS_PER_PMD
252 PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE 252 PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
253 .set addr, addr + HV_PAGE_SIZE_LARGE 253 .set addr, addr + HPAGE_SIZE
254 .endr 254 .endr
255 .org temp_code_pmd + HV_L1_SIZE 255 .org temp_code_pmd + SIZEOF_PMD
256 END(temp_code_pmd) 256 END(temp_code_pmd)
257 257
258 /* 258 /*
diff --git a/arch/tile/kernel/hvglue.lds b/arch/tile/kernel/hvglue.lds
index 2b7cd0a659a..d44c5a67a1e 100644
--- a/arch/tile/kernel/hvglue.lds
+++ b/arch/tile/kernel/hvglue.lds
@@ -55,4 +55,5 @@ hv_store_mapping = TEXT_OFFSET + 0x106a0;
55hv_inquire_realpa = TEXT_OFFSET + 0x106c0; 55hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
56hv_flush_all = TEXT_OFFSET + 0x106e0; 56hv_flush_all = TEXT_OFFSET + 0x106e0;
57hv_get_ipi_pte = TEXT_OFFSET + 0x10700; 57hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
58hv_glue_internals = TEXT_OFFSET + 0x10720; 58hv_set_pte_super_shift = TEXT_OFFSET + 0x10720;
59hv_glue_internals = TEXT_OFFSET + 0x10740;
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 30ae76e50c4..7c06d597ffd 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -220,7 +220,9 @@ intvec_\vecname:
220 * This routine saves just the first four registers, plus the 220 * This routine saves just the first four registers, plus the
221 * stack context so we can do proper backtracing right away, 221 * stack context so we can do proper backtracing right away,
222 * and defers to handle_interrupt to save the rest. 222 * and defers to handle_interrupt to save the rest.
223 * The backtracer needs pc, ex1, lr, sp, r52, and faultnum. 223 * The backtracer needs pc, ex1, lr, sp, r52, and faultnum,
224 * and needs sp set to its final location at the bottom of
225 * the stack frame.
224 */ 226 */
225 addli r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP) 227 addli r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP)
226 wh64 r0 /* cache line 7 */ 228 wh64 r0 /* cache line 7 */
@@ -450,23 +452,6 @@ intvec_\vecname:
450 push_reg r5, r52 452 push_reg r5, r52
451 st r52, r4 453 st r52, r4
452 454
453 /* Load tp with our per-cpu offset. */
454#ifdef CONFIG_SMP
455 {
456 mfspr r20, SPR_SYSTEM_SAVE_K_0
457 moveli r21, hw2_last(__per_cpu_offset)
458 }
459 {
460 shl16insli r21, r21, hw1(__per_cpu_offset)
461 bfextu r20, r20, 0, LOG2_THREAD_SIZE-1
462 }
463 shl16insli r21, r21, hw0(__per_cpu_offset)
464 shl3add r20, r20, r21
465 ld tp, r20
466#else
467 move tp, zero
468#endif
469
470 /* 455 /*
471 * If we will be returning to the kernel, we will need to 456 * If we will be returning to the kernel, we will need to
472 * reset the interrupt masks to the state they had before. 457 * reset the interrupt masks to the state they had before.
@@ -489,6 +474,44 @@ intvec_\vecname:
489 .endif 474 .endif
490 st r21, r32 475 st r21, r32
491 476
477 /*
478 * we've captured enough state to the stack (including in
479 * particular our EX_CONTEXT state) that we can now release
480 * the interrupt critical section and replace it with our
481 * standard "interrupts disabled" mask value. This allows
482 * synchronous interrupts (and profile interrupts) to punch
483 * through from this point onwards.
484 *
485 * It's important that no code before this point touch memory
486 * other than our own stack (to keep the invariant that this
487 * is all that gets touched under ICS), and that no code after
488 * this point reference any interrupt-specific SPR, in particular
489 * the EX_CONTEXT_K_ values.
490 */
491 .ifc \function,handle_nmi
492 IRQ_DISABLE_ALL(r20)
493 .else
494 IRQ_DISABLE(r20, r21)
495 .endif
496 mtspr INTERRUPT_CRITICAL_SECTION, zero
497
498 /* Load tp with our per-cpu offset. */
499#ifdef CONFIG_SMP
500 {
501 mfspr r20, SPR_SYSTEM_SAVE_K_0
502 moveli r21, hw2_last(__per_cpu_offset)
503 }
504 {
505 shl16insli r21, r21, hw1(__per_cpu_offset)
506 bfextu r20, r20, 0, LOG2_THREAD_SIZE-1
507 }
508 shl16insli r21, r21, hw0(__per_cpu_offset)
509 shl3add r20, r20, r21
510 ld tp, r20
511#else
512 move tp, zero
513#endif
514
492#ifdef __COLLECT_LINKER_FEEDBACK__ 515#ifdef __COLLECT_LINKER_FEEDBACK__
493 /* 516 /*
494 * Notify the feedback routines that we were in the 517 * Notify the feedback routines that we were in the
@@ -513,21 +536,6 @@ intvec_\vecname:
513#endif 536#endif
514 537
515 /* 538 /*
516 * we've captured enough state to the stack (including in
517 * particular our EX_CONTEXT state) that we can now release
518 * the interrupt critical section and replace it with our
519 * standard "interrupts disabled" mask value. This allows
520 * synchronous interrupts (and profile interrupts) to punch
521 * through from this point onwards.
522 */
523 .ifc \function,handle_nmi
524 IRQ_DISABLE_ALL(r20)
525 .else
526 IRQ_DISABLE(r20, r21)
527 .endif
528 mtspr INTERRUPT_CRITICAL_SECTION, zero
529
530 /*
531 * Prepare the first 256 stack bytes to be rapidly accessible 539 * Prepare the first 256 stack bytes to be rapidly accessible
532 * without having to fetch the background data. 540 * without having to fetch the background data.
533 */ 541 */
@@ -736,9 +744,10 @@ STD_ENTRY(interrupt_return)
736 beqzt r30, .Lrestore_regs 744 beqzt r30, .Lrestore_regs
737 j 3f 745 j 3f
7382: TRACE_IRQS_ON 7462: TRACE_IRQS_ON
747 IRQ_ENABLE_LOAD(r20, r21)
739 movei r0, 1 748 movei r0, 1
740 mtspr INTERRUPT_CRITICAL_SECTION, r0 749 mtspr INTERRUPT_CRITICAL_SECTION, r0
741 IRQ_ENABLE(r20, r21) 750 IRQ_ENABLE_APPLY(r20, r21)
742 beqzt r30, .Lrestore_regs 751 beqzt r30, .Lrestore_regs
7433: 7523:
744 753
@@ -755,7 +764,6 @@ STD_ENTRY(interrupt_return)
755 * that will save some cycles if this turns out to be a syscall. 764 * that will save some cycles if this turns out to be a syscall.
756 */ 765 */
757.Lrestore_regs: 766.Lrestore_regs:
758 FEEDBACK_REENTER(interrupt_return) /* called from elsewhere */
759 767
760 /* 768 /*
761 * Rotate so we have one high bit and one low bit to test. 769 * Rotate so we have one high bit and one low bit to test.
@@ -1249,7 +1257,7 @@ STD_ENTRY(fill_ra_stack)
1249 int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign 1257 int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
1250 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault 1258 int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
1251 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault 1259 int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
1252 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr 1260 int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap
1253 int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap 1261 int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
1254 int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt 1262 int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
1255 int_hand INT_IDN_TIMER, IDN_TIMER, bad_intr 1263 int_hand INT_IDN_TIMER, IDN_TIMER, bad_intr
diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c
index 6255f2eab11..f0b54a93471 100644
--- a/arch/tile/kernel/machine_kexec.c
+++ b/arch/tile/kernel/machine_kexec.c
@@ -31,6 +31,8 @@
31#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
32#include <asm/cacheflush.h> 32#include <asm/cacheflush.h>
33#include <asm/checksum.h> 33#include <asm/checksum.h>
34#include <asm/tlbflush.h>
35#include <asm/homecache.h>
34#include <hv/hypervisor.h> 36#include <hv/hypervisor.h>
35 37
36 38
@@ -222,11 +224,22 @@ struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order)
222 return alloc_pages_node(0, gfp_mask, order); 224 return alloc_pages_node(0, gfp_mask, order);
223} 225}
224 226
227/*
228 * Address range in which pa=va mapping is set in setup_quasi_va_is_pa().
229 * For tilepro, PAGE_OFFSET is used since this is the largest possbile value
230 * for tilepro, while for tilegx, we limit it to entire middle level page
231 * table which we assume has been allocated and is undoubtedly large enough.
232 */
233#ifndef __tilegx__
234#define QUASI_VA_IS_PA_ADDR_RANGE PAGE_OFFSET
235#else
236#define QUASI_VA_IS_PA_ADDR_RANGE PGDIR_SIZE
237#endif
238
225static void setup_quasi_va_is_pa(void) 239static void setup_quasi_va_is_pa(void)
226{ 240{
227 HV_PTE *pgtable;
228 HV_PTE pte; 241 HV_PTE pte;
229 int i; 242 unsigned long i;
230 243
231 /* 244 /*
232 * Flush our TLB to prevent conflicts between the previous contents 245 * Flush our TLB to prevent conflicts between the previous contents
@@ -234,16 +247,22 @@ static void setup_quasi_va_is_pa(void)
234 */ 247 */
235 local_flush_tlb_all(); 248 local_flush_tlb_all();
236 249
237 /* setup VA is PA, at least up to PAGE_OFFSET */ 250 /*
238 251 * setup VA is PA, at least up to QUASI_VA_IS_PA_ADDR_RANGE.
239 pgtable = (HV_PTE *)current->mm->pgd; 252 * Note here we assume that level-1 page table is defined by
253 * HPAGE_SIZE.
254 */
240 pte = hv_pte(_PAGE_KERNEL | _PAGE_HUGE_PAGE); 255 pte = hv_pte(_PAGE_KERNEL | _PAGE_HUGE_PAGE);
241 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3); 256 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
242 257 for (i = 0; i < (QUASI_VA_IS_PA_ADDR_RANGE >> HPAGE_SHIFT); i++) {
243 for (i = 0; i < pgd_index(PAGE_OFFSET); i++) { 258 unsigned long vaddr = i << HPAGE_SHIFT;
259 pgd_t *pgd = pgd_offset(current->mm, vaddr);
260 pud_t *pud = pud_offset(pgd, vaddr);
261 pte_t *ptep = (pte_t *) pmd_offset(pud, vaddr);
244 unsigned long pfn = i << (HPAGE_SHIFT - PAGE_SHIFT); 262 unsigned long pfn = i << (HPAGE_SHIFT - PAGE_SHIFT);
263
245 if (pfn_valid(pfn)) 264 if (pfn_valid(pfn))
246 __set_pte(&pgtable[i], pfn_pte(pfn, pte)); 265 __set_pte(ptep, pfn_pte(pfn, pte));
247 } 266 }
248} 267}
249 268
@@ -251,6 +270,7 @@ static void setup_quasi_va_is_pa(void)
251void machine_kexec(struct kimage *image) 270void machine_kexec(struct kimage *image)
252{ 271{
253 void *reboot_code_buffer; 272 void *reboot_code_buffer;
273 pte_t *ptep;
254 void (*rnk)(unsigned long, void *, unsigned long) 274 void (*rnk)(unsigned long, void *, unsigned long)
255 __noreturn; 275 __noreturn;
256 276
@@ -266,8 +286,10 @@ void machine_kexec(struct kimage *image)
266 */ 286 */
267 homecache_change_page_home(image->control_code_page, 0, 287 homecache_change_page_home(image->control_code_page, 0,
268 smp_processor_id()); 288 smp_processor_id());
269 reboot_code_buffer = vmap(&image->control_code_page, 1, 0, 289 reboot_code_buffer = page_address(image->control_code_page);
270 __pgprot(_PAGE_KERNEL | _PAGE_EXECUTABLE)); 290 BUG_ON(reboot_code_buffer == NULL);
291 ptep = virt_to_pte(NULL, (unsigned long)reboot_code_buffer);
292 __set_pte(ptep, pte_mkexec(*ptep));
271 memcpy(reboot_code_buffer, relocate_new_kernel, 293 memcpy(reboot_code_buffer, relocate_new_kernel,
272 relocate_new_kernel_size); 294 relocate_new_kernel_size);
273 __flush_icache_range( 295 __flush_icache_range(
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
index 98d47692010..001cbfa10ac 100644
--- a/arch/tile/kernel/module.c
+++ b/arch/tile/kernel/module.c
@@ -159,7 +159,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
159 159
160 switch (ELF_R_TYPE(rel[i].r_info)) { 160 switch (ELF_R_TYPE(rel[i].r_info)) {
161 161
162#define MUNGE(func) (*location = ((*location & ~func(-1)) | func(value))) 162#ifdef __LITTLE_ENDIAN
163# define MUNGE(func) \
164 (*location = ((*location & ~func(-1)) | func(value)))
165#else
166/*
167 * Instructions are always little-endian, so when we read them as data,
168 * we have to swap them around before and after modifying them.
169 */
170# define MUNGE(func) \
171 (*location = swab64((swab64(*location) & ~func(-1)) | func(value)))
172#endif
163 173
164#ifndef __tilegx__ 174#ifndef __tilegx__
165 case R_TILE_32: 175 case R_TILE_32:
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c
index 446a7f52cc1..dafc447b512 100644
--- a/arch/tile/kernel/proc.c
+++ b/arch/tile/kernel/proc.c
@@ -22,6 +22,7 @@
22#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
23#include <linux/sysctl.h> 23#include <linux/sysctl.h>
24#include <linux/hardirq.h> 24#include <linux/hardirq.h>
25#include <linux/hugetlb.h>
25#include <linux/mman.h> 26#include <linux/mman.h>
26#include <asm/unaligned.h> 27#include <asm/unaligned.h>
27#include <asm/pgtable.h> 28#include <asm/pgtable.h>
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index f572c19c408..ba1023d8a02 100644
--- a/arch/tile/kernel/process.c
+++ b/arch/tile/kernel/process.c
@@ -128,10 +128,10 @@ void arch_release_thread_info(struct thread_info *info)
128 * Calling deactivate here just frees up the data structures. 128 * Calling deactivate here just frees up the data structures.
129 * If the task we're freeing held the last reference to a 129 * If the task we're freeing held the last reference to a
130 * hardwall fd, it would have been released prior to this point 130 * hardwall fd, it would have been released prior to this point
131 * anyway via exit_files(), and "hardwall" would be NULL by now. 131 * anyway via exit_files(), and the hardwall_task.info pointers
132 * would be NULL by now.
132 */ 133 */
133 if (info->task->thread.hardwall) 134 hardwall_deactivate_all(info->task);
134 hardwall_deactivate(info->task);
135#endif 135#endif
136 136
137 if (step_state) { 137 if (step_state) {
@@ -245,7 +245,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
245 245
246#ifdef CONFIG_HARDWALL 246#ifdef CONFIG_HARDWALL
247 /* New thread does not own any networks. */ 247 /* New thread does not own any networks. */
248 p->thread.hardwall = NULL; 248 memset(&p->thread.hardwall[0], 0,
249 sizeof(struct hardwall_task) * HARDWALL_TYPES);
249#endif 250#endif
250 251
251 252
@@ -515,12 +516,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
515 516
516#ifdef CONFIG_HARDWALL 517#ifdef CONFIG_HARDWALL
517 /* Enable or disable access to the network registers appropriately. */ 518 /* Enable or disable access to the network registers appropriately. */
518 if (prev->thread.hardwall != NULL) { 519 hardwall_switch_tasks(prev, next);
519 if (next->thread.hardwall == NULL)
520 restrict_network_mpls();
521 } else if (next->thread.hardwall != NULL) {
522 grant_network_mpls();
523 }
524#endif 520#endif
525 521
526 /* 522 /*
diff --git a/arch/tile/kernel/relocate_kernel.S b/arch/tile/kernel/relocate_kernel_32.S
index 010b418515f..010b418515f 100644
--- a/arch/tile/kernel/relocate_kernel.S
+++ b/arch/tile/kernel/relocate_kernel_32.S
diff --git a/arch/tile/kernel/relocate_kernel_64.S b/arch/tile/kernel/relocate_kernel_64.S
new file mode 100644
index 00000000000..1c09a4f5a4e
--- /dev/null
+++ b/arch/tile/kernel/relocate_kernel_64.S
@@ -0,0 +1,260 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * copy new kernel into place and then call hv_reexec
15 *
16 */
17
18#include <linux/linkage.h>
19#include <arch/chip.h>
20#include <asm/page.h>
21#include <hv/hypervisor.h>
22
23#undef RELOCATE_NEW_KERNEL_VERBOSE
24
25STD_ENTRY(relocate_new_kernel)
26
27 move r30, r0 /* page list */
28 move r31, r1 /* address of page we are on */
29 move r32, r2 /* start address of new kernel */
30
31 shrui r1, r1, PAGE_SHIFT
32 addi r1, r1, 1
33 shli sp, r1, PAGE_SHIFT
34 addi sp, sp, -8
35 /* we now have a stack (whether we need one or not) */
36
37 moveli r40, hw2_last(hv_console_putc)
38 shl16insli r40, r40, hw1(hv_console_putc)
39 shl16insli r40, r40, hw0(hv_console_putc)
40
41#ifdef RELOCATE_NEW_KERNEL_VERBOSE
42 moveli r0, 'r'
43 jalr r40
44
45 moveli r0, '_'
46 jalr r40
47
48 moveli r0, 'n'
49 jalr r40
50
51 moveli r0, '_'
52 jalr r40
53
54 moveli r0, 'k'
55 jalr r40
56
57 moveli r0, '\n'
58 jalr r40
59#endif
60
61 /*
62 * Throughout this code r30 is pointer to the element of page
63 * list we are working on.
64 *
65 * Normally we get to the next element of the page list by
66 * incrementing r30 by eight. The exception is if the element
67 * on the page list is an IND_INDIRECTION in which case we use
68 * the element with the low bits masked off as the new value
69 * of r30.
70 *
71 * To get this started, we need the value passed to us (which
72 * will always be an IND_INDIRECTION) in memory somewhere with
73 * r30 pointing at it. To do that, we push the value passed
74 * to us on the stack and make r30 point to it.
75 */
76
77 st sp, r30
78 move r30, sp
79 addi sp, sp, -16
80
81#if CHIP_HAS_CBOX_HOME_MAP()
82 /*
83 * On TILE-GX, we need to flush all tiles' caches, since we may
84 * have been doing hash-for-home caching there. Note that we
85 * must do this _after_ we're completely done modifying any memory
86 * other than our output buffer (which we know is locally cached).
87 * We want the caches to be fully clean when we do the reexec,
88 * because the hypervisor is going to do this flush again at that
89 * point, and we don't want that second flush to overwrite any memory.
90 */
91 {
92 move r0, zero /* cache_pa */
93 moveli r1, hw2_last(HV_FLUSH_EVICT_L2)
94 }
95 {
96 shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)
97 movei r2, -1 /* cache_cpumask; -1 means all client tiles */
98 }
99 {
100 shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2) /* cache_control */
101 move r3, zero /* tlb_va */
102 }
103 {
104 move r4, zero /* tlb_length */
105 move r5, zero /* tlb_pgsize */
106 }
107 {
108 move r6, zero /* tlb_cpumask */
109 move r7, zero /* asids */
110 }
111 {
112 moveli r20, hw2_last(hv_flush_remote)
113 move r8, zero /* asidcount */
114 }
115 shl16insli r20, r20, hw1(hv_flush_remote)
116 shl16insli r20, r20, hw0(hv_flush_remote)
117
118 jalr r20
119#endif
120
121 /* r33 is destination pointer, default to zero */
122
123 moveli r33, 0
124
125.Lloop: ld r10, r30
126
127 andi r9, r10, 0xf /* low 4 bits tell us what type it is */
128 xor r10, r10, r9 /* r10 is now value with low 4 bits stripped */
129
130 cmpeqi r0, r9, 0x1 /* IND_DESTINATION */
131 beqzt r0, .Ltry2
132
133 move r33, r10
134
135#ifdef RELOCATE_NEW_KERNEL_VERBOSE
136 moveli r0, 'd'
137 jalr r40
138#endif
139
140 addi r30, r30, 8
141 j .Lloop
142
143.Ltry2:
144 cmpeqi r0, r9, 0x2 /* IND_INDIRECTION */
145 beqzt r0, .Ltry4
146
147 move r30, r10
148
149#ifdef RELOCATE_NEW_KERNEL_VERBOSE
150 moveli r0, 'i'
151 jalr r40
152#endif
153
154 j .Lloop
155
156.Ltry4:
157 cmpeqi r0, r9, 0x4 /* IND_DONE */
158 beqzt r0, .Ltry8
159
160 mf
161
162#ifdef RELOCATE_NEW_KERNEL_VERBOSE
163 moveli r0, 'D'
164 jalr r40
165 moveli r0, '\n'
166 jalr r40
167#endif
168
169 move r0, r32
170
171 moveli r41, hw2_last(hv_reexec)
172 shl16insli r41, r41, hw1(hv_reexec)
173 shl16insli r41, r41, hw0(hv_reexec)
174
175 jalr r41
176
177 /* we should not get here */
178
179 moveli r0, '?'
180 jalr r40
181 moveli r0, '\n'
182 jalr r40
183
184 j .Lhalt
185
186.Ltry8: cmpeqi r0, r9, 0x8 /* IND_SOURCE */
187 beqz r0, .Lerr /* unknown type */
188
189 /* copy page at r10 to page at r33 */
190
191 move r11, r33
192
193 moveli r0, hw2_last(PAGE_SIZE)
194 shl16insli r0, r0, hw1(PAGE_SIZE)
195 shl16insli r0, r0, hw0(PAGE_SIZE)
196 add r33, r33, r0
197
198 /* copy word at r10 to word at r11 until r11 equals r33 */
199
200 /* We know page size must be multiple of 8, so we can unroll
201 * 8 times safely without any edge case checking.
202 *
203 * Issue a flush of the destination every 8 words to avoid
204 * incoherence when starting the new kernel. (Now this is
205 * just good paranoia because the hv_reexec call will also
206 * take care of this.)
207 */
208
2091:
210 { ld r0, r10; addi r10, r10, 8 }
211 { st r11, r0; addi r11, r11, 8 }
212 { ld r0, r10; addi r10, r10, 8 }
213 { st r11, r0; addi r11, r11, 8 }
214 { ld r0, r10; addi r10, r10, 8 }
215 { st r11, r0; addi r11, r11, 8 }
216 { ld r0, r10; addi r10, r10, 8 }
217 { st r11, r0; addi r11, r11, 8 }
218 { ld r0, r10; addi r10, r10, 8 }
219 { st r11, r0; addi r11, r11, 8 }
220 { ld r0, r10; addi r10, r10, 8 }
221 { st r11, r0; addi r11, r11, 8 }
222 { ld r0, r10; addi r10, r10, 8 }
223 { st r11, r0; addi r11, r11, 8 }
224 { ld r0, r10; addi r10, r10, 8 }
225 { st r11, r0 }
226 { flush r11 ; addi r11, r11, 8 }
227
228 cmpeq r0, r33, r11
229 beqzt r0, 1b
230
231#ifdef RELOCATE_NEW_KERNEL_VERBOSE
232 moveli r0, 's'
233 jalr r40
234#endif
235
236 addi r30, r30, 8
237 j .Lloop
238
239
240.Lerr: moveli r0, 'e'
241 jalr r40
242 moveli r0, 'r'
243 jalr r40
244 moveli r0, 'r'
245 jalr r40
246 moveli r0, '\n'
247 jalr r40
248.Lhalt:
249 moveli r41, hw2_last(hv_halt)
250 shl16insli r41, r41, hw1(hv_halt)
251 shl16insli r41, r41, hw0(hv_halt)
252
253 jalr r41
254 STD_ENDPROC(relocate_new_kernel)
255
256 .section .rodata,"a"
257
258 .globl relocate_new_kernel_size
259relocate_new_kernel_size:
260 .long .Lend_relocate_new_kernel - relocate_new_kernel
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index 98d80eb49dd..6098ccc59be 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -28,6 +28,7 @@
28#include <linux/highmem.h> 28#include <linux/highmem.h>
29#include <linux/smp.h> 29#include <linux/smp.h>
30#include <linux/timex.h> 30#include <linux/timex.h>
31#include <linux/hugetlb.h>
31#include <asm/setup.h> 32#include <asm/setup.h>
32#include <asm/sections.h> 33#include <asm/sections.h>
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
@@ -49,9 +50,6 @@ char chip_model[64] __write_once;
49struct pglist_data node_data[MAX_NUMNODES] __read_mostly; 50struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
50EXPORT_SYMBOL(node_data); 51EXPORT_SYMBOL(node_data);
51 52
52/* We only create bootmem data on node 0. */
53static bootmem_data_t __initdata node0_bdata;
54
55/* Information on the NUMA nodes that we compute early */ 53/* Information on the NUMA nodes that we compute early */
56unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES]; 54unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
57unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES]; 55unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
@@ -534,37 +532,96 @@ static void __init setup_memory(void)
534#endif 532#endif
535} 533}
536 534
537static void __init setup_bootmem_allocator(void) 535/*
536 * On 32-bit machines, we only put bootmem on the low controller,
537 * since PAs > 4GB can't be used in bootmem. In principle one could
538 * imagine, e.g., multiple 1 GB controllers all of which could support
539 * bootmem, but in practice using controllers this small isn't a
540 * particularly interesting scenario, so we just keep it simple and
541 * use only the first controller for bootmem on 32-bit machines.
542 */
543static inline int node_has_bootmem(int nid)
538{ 544{
539 unsigned long bootmap_size, first_alloc_pfn, last_alloc_pfn; 545#ifdef CONFIG_64BIT
546 return 1;
547#else
548 return nid == 0;
549#endif
550}
540 551
541 /* Provide a node 0 bdata. */ 552static inline unsigned long alloc_bootmem_pfn(int nid,
542 NODE_DATA(0)->bdata = &node0_bdata; 553 unsigned long size,
554 unsigned long goal)
555{
556 void *kva = __alloc_bootmem_node(NODE_DATA(nid), size,
557 PAGE_SIZE, goal);
558 unsigned long pfn = kaddr_to_pfn(kva);
559 BUG_ON(goal && PFN_PHYS(pfn) != goal);
560 return pfn;
561}
543 562
544#ifdef CONFIG_PCI 563static void __init setup_bootmem_allocator_node(int i)
545 /* Don't let boot memory alias the PCI region. */ 564{
546 last_alloc_pfn = min(max_low_pfn, pci_reserve_start_pfn); 565 unsigned long start, end, mapsize, mapstart;
566
567 if (node_has_bootmem(i)) {
568 NODE_DATA(i)->bdata = &bootmem_node_data[i];
569 } else {
570 /* Share controller zero's bdata for now. */
571 NODE_DATA(i)->bdata = &bootmem_node_data[0];
572 return;
573 }
574
575 /* Skip up to after the bss in node 0. */
576 start = (i == 0) ? min_low_pfn : node_start_pfn[i];
577
578 /* Only lowmem, if we're a HIGHMEM build. */
579#ifdef CONFIG_HIGHMEM
580 end = node_lowmem_end_pfn[i];
547#else 581#else
548 last_alloc_pfn = max_low_pfn; 582 end = node_end_pfn[i];
549#endif 583#endif
550 584
551 /* 585 /* No memory here. */
552 * Initialize the boot-time allocator (with low memory only): 586 if (end == start)
553 * The first argument says where to put the bitmap, and the 587 return;
554 * second says where the end of allocatable memory is. 588
555 */ 589 /* Figure out where the bootmem bitmap is located. */
556 bootmap_size = init_bootmem(min_low_pfn, last_alloc_pfn); 590 mapsize = bootmem_bootmap_pages(end - start);
591 if (i == 0) {
592 /* Use some space right before the heap on node 0. */
593 mapstart = start;
594 start += mapsize;
595 } else {
596 /* Allocate bitmap on node 0 to avoid page table issues. */
597 mapstart = alloc_bootmem_pfn(0, PFN_PHYS(mapsize), 0);
598 }
557 599
600 /* Initialize a node. */
601 init_bootmem_node(NODE_DATA(i), mapstart, start, end);
602
603 /* Free all the space back into the allocator. */
604 free_bootmem(PFN_PHYS(start), PFN_PHYS(end - start));
605
606#if defined(CONFIG_PCI)
558 /* 607 /*
559 * Let the bootmem allocator use all the space we've given it 608 * Throw away any memory aliased by the PCI region. FIXME: this
560 * except for its own bitmap. 609 * is a temporary hack to work around bug 10502, and needs to be
610 * fixed properly.
561 */ 611 */
562 first_alloc_pfn = min_low_pfn + PFN_UP(bootmap_size); 612 if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start)
563 if (first_alloc_pfn >= last_alloc_pfn) 613 reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn),
564 early_panic("Not enough memory on controller 0 for bootmem\n"); 614 PFN_PHYS(pci_reserve_end_pfn -
615 pci_reserve_start_pfn),
616 BOOTMEM_EXCLUSIVE);
617#endif
618}
565 619
566 free_bootmem(PFN_PHYS(first_alloc_pfn), 620static void __init setup_bootmem_allocator(void)
567 PFN_PHYS(last_alloc_pfn - first_alloc_pfn)); 621{
622 int i;
623 for (i = 0; i < MAX_NUMNODES; ++i)
624 setup_bootmem_allocator_node(i);
568 625
569#ifdef CONFIG_KEXEC 626#ifdef CONFIG_KEXEC
570 if (crashk_res.start != crashk_res.end) 627 if (crashk_res.start != crashk_res.end)
@@ -595,14 +652,6 @@ static int __init percpu_size(void)
595 return size; 652 return size;
596} 653}
597 654
598static inline unsigned long alloc_bootmem_pfn(int size, unsigned long goal)
599{
600 void *kva = __alloc_bootmem(size, PAGE_SIZE, goal);
601 unsigned long pfn = kaddr_to_pfn(kva);
602 BUG_ON(goal && PFN_PHYS(pfn) != goal);
603 return pfn;
604}
605
606static void __init zone_sizes_init(void) 655static void __init zone_sizes_init(void)
607{ 656{
608 unsigned long zones_size[MAX_NR_ZONES] = { 0 }; 657 unsigned long zones_size[MAX_NR_ZONES] = { 0 };
@@ -640,21 +689,22 @@ static void __init zone_sizes_init(void)
640 * though, there'll be no lowmem, so we just alloc_bootmem 689 * though, there'll be no lowmem, so we just alloc_bootmem
641 * the memmap. There will be no percpu memory either. 690 * the memmap. There will be no percpu memory either.
642 */ 691 */
643 if (__pfn_to_highbits(start) == 0) { 692 if (i != 0 && cpu_isset(i, isolnodes)) {
644 /* In low PAs, allocate via bootmem. */ 693 node_memmap_pfn[i] =
694 alloc_bootmem_pfn(0, memmap_size, 0);
695 BUG_ON(node_percpu[i] != 0);
696 } else if (node_has_bootmem(start)) {
645 unsigned long goal = 0; 697 unsigned long goal = 0;
646 node_memmap_pfn[i] = 698 node_memmap_pfn[i] =
647 alloc_bootmem_pfn(memmap_size, goal); 699 alloc_bootmem_pfn(i, memmap_size, 0);
648 if (kdata_huge) 700 if (kdata_huge)
649 goal = PFN_PHYS(lowmem_end) - node_percpu[i]; 701 goal = PFN_PHYS(lowmem_end) - node_percpu[i];
650 if (node_percpu[i]) 702 if (node_percpu[i])
651 node_percpu_pfn[i] = 703 node_percpu_pfn[i] =
652 alloc_bootmem_pfn(node_percpu[i], goal); 704 alloc_bootmem_pfn(i, node_percpu[i],
653 } else if (cpu_isset(i, isolnodes)) { 705 goal);
654 node_memmap_pfn[i] = alloc_bootmem_pfn(memmap_size, 0);
655 BUG_ON(node_percpu[i] != 0);
656 } else { 706 } else {
657 /* In high PAs, just reserve some pages. */ 707 /* In non-bootmem zones, just reserve some pages. */
658 node_memmap_pfn[i] = node_free_pfn[i]; 708 node_memmap_pfn[i] = node_free_pfn[i];
659 node_free_pfn[i] += PFN_UP(memmap_size); 709 node_free_pfn[i] += PFN_UP(memmap_size);
660 if (!kdata_huge) { 710 if (!kdata_huge) {
@@ -678,16 +728,9 @@ static void __init zone_sizes_init(void)
678 zones_size[ZONE_NORMAL] = end - start; 728 zones_size[ZONE_NORMAL] = end - start;
679#endif 729#endif
680 730
681 /* 731 /* Take zone metadata from controller 0 if we're isolnode. */
682 * Everyone shares node 0's bootmem allocator, but 732 if (node_isset(i, isolnodes))
683 * we use alloc_remap(), above, to put the actual 733 NODE_DATA(i)->bdata = &bootmem_node_data[0];
684 * struct page array on the individual controllers,
685 * which is most of the data that we actually care about.
686 * We can't place bootmem allocators on the other
687 * controllers since the bootmem allocator can only
688 * operate on 32-bit physical addresses.
689 */
690 NODE_DATA(i)->bdata = NODE_DATA(0)->bdata;
691 734
692 free_area_init_node(i, zones_size, start, NULL); 735 free_area_init_node(i, zones_size, start, NULL);
693 printk(KERN_DEBUG " Normal zone: %ld per-cpu pages\n", 736 printk(KERN_DEBUG " Normal zone: %ld per-cpu pages\n",
@@ -870,6 +913,22 @@ subsys_initcall(topology_init);
870 913
871#endif /* CONFIG_NUMA */ 914#endif /* CONFIG_NUMA */
872 915
916/*
917 * Initialize hugepage support on this cpu. We do this on all cores
918 * early in boot: before argument parsing for the boot cpu, and after
919 * argument parsing but before the init functions run on the secondaries.
920 * So the values we set up here in the hypervisor may be overridden on
921 * the boot cpu as arguments are parsed.
922 */
923static __cpuinit void init_super_pages(void)
924{
925#ifdef CONFIG_HUGETLB_SUPER_PAGES
926 int i;
927 for (i = 0; i < HUGE_SHIFT_ENTRIES; ++i)
928 hv_set_pte_super_shift(i, huge_shift[i]);
929#endif
930}
931
873/** 932/**
874 * setup_cpu() - Do all necessary per-cpu, tile-specific initialization. 933 * setup_cpu() - Do all necessary per-cpu, tile-specific initialization.
875 * @boot: Is this the boot cpu? 934 * @boot: Is this the boot cpu?
@@ -924,6 +983,8 @@ void __cpuinit setup_cpu(int boot)
924 /* Reset the network state on this cpu. */ 983 /* Reset the network state on this cpu. */
925 reset_network_state(); 984 reset_network_state();
926#endif 985#endif
986
987 init_super_pages();
927} 988}
928 989
929#ifdef CONFIG_BLK_DEV_INITRD 990#ifdef CONFIG_BLK_DEV_INITRD
@@ -1412,13 +1473,13 @@ void __init setup_per_cpu_areas(void)
1412 for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) { 1473 for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
1413 1474
1414 /* Update the vmalloc mapping and page home. */ 1475 /* Update the vmalloc mapping and page home. */
1415 pte_t *ptep = 1476 unsigned long addr = (unsigned long)ptr + i;
1416 virt_to_pte(NULL, (unsigned long)ptr + i); 1477 pte_t *ptep = virt_to_pte(NULL, addr);
1417 pte_t pte = *ptep; 1478 pte_t pte = *ptep;
1418 BUG_ON(pfn != pte_pfn(pte)); 1479 BUG_ON(pfn != pte_pfn(pte));
1419 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3); 1480 pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
1420 pte = set_remote_cache_cpu(pte, cpu); 1481 pte = set_remote_cache_cpu(pte, cpu);
1421 set_pte(ptep, pte); 1482 set_pte_at(&init_mm, addr, ptep, pte);
1422 1483
1423 /* Update the lowmem mapping for consistency. */ 1484 /* Update the lowmem mapping for consistency. */
1424 lowmem_va = (unsigned long)pfn_to_kaddr(pfn); 1485 lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
@@ -1431,7 +1492,7 @@ void __init setup_per_cpu_areas(void)
1431 BUG_ON(pte_huge(*ptep)); 1492 BUG_ON(pte_huge(*ptep));
1432 } 1493 }
1433 BUG_ON(pfn != pte_pfn(*ptep)); 1494 BUG_ON(pfn != pte_pfn(*ptep));
1434 set_pte(ptep, pte); 1495 set_pte_at(&init_mm, lowmem_va, ptep, pte);
1435 } 1496 }
1436 } 1497 }
1437 1498
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 89529c9f060..27742e87e25 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -172,9 +172,6 @@ static tile_bundle_bits rewrite_load_store_unaligned(
172 return (tilepro_bundle_bits) 0; 172 return (tilepro_bundle_bits) 0;
173 } 173 }
174 174
175#ifndef __LITTLE_ENDIAN
176# error We assume little-endian representation with copy_xx_user size 2 here
177#endif
178 /* Handle unaligned load/store */ 175 /* Handle unaligned load/store */
179 if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) { 176 if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
180 unsigned short val_16; 177 unsigned short val_16;
@@ -195,8 +192,19 @@ static tile_bundle_bits rewrite_load_store_unaligned(
195 state->update = 1; 192 state->update = 1;
196 } 193 }
197 } else { 194 } else {
195 unsigned short val_16;
198 val = (val_reg == TREG_ZERO) ? 0 : regs->regs[val_reg]; 196 val = (val_reg == TREG_ZERO) ? 0 : regs->regs[val_reg];
199 err = copy_to_user(addr, &val, size); 197 switch (size) {
198 case 2:
199 val_16 = val;
200 err = copy_to_user(addr, &val_16, sizeof(val_16));
201 break;
202 case 4:
203 err = copy_to_user(addr, &val, sizeof(val));
204 break;
205 default:
206 BUG();
207 }
200 } 208 }
201 209
202 if (err) { 210 if (err) {
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index 91da0f72195..cbc73a8b8fe 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -203,7 +203,7 @@ void __init ipi_init(void)
203 if (hv_get_ipi_pte(tile, KERNEL_PL, &pte) != 0) 203 if (hv_get_ipi_pte(tile, KERNEL_PL, &pte) != 0)
204 panic("Failed to initialize IPI for cpu %d\n", cpu); 204 panic("Failed to initialize IPI for cpu %d\n", cpu);
205 205
206 offset = hv_pte_get_pfn(pte) << PAGE_SHIFT; 206 offset = PFN_PHYS(pte_pfn(pte));
207 ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte); 207 ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte);
208 } 208 }
209#endif 209#endif
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
index cb44ba7ccd2..b08095b402d 100644
--- a/arch/tile/kernel/sys.c
+++ b/arch/tile/kernel/sys.c
@@ -32,11 +32,17 @@
32#include <asm/syscalls.h> 32#include <asm/syscalls.h>
33#include <asm/pgtable.h> 33#include <asm/pgtable.h>
34#include <asm/homecache.h> 34#include <asm/homecache.h>
35#include <asm/cachectl.h>
35#include <arch/chip.h> 36#include <arch/chip.h>
36 37
37SYSCALL_DEFINE0(flush_cache) 38SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len,
39 unsigned long, flags)
38{ 40{
39 homecache_evict(cpumask_of(smp_processor_id())); 41 if (flags & DCACHE)
42 homecache_evict(cpumask_of(smp_processor_id()));
43 if (flags & ICACHE)
44 flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm),
45 0, 0, 0, NULL, NULL, 0);
40 return 0; 46 return 0;
41} 47}
42 48
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index 71ae728e9d0..e25b0a89c18 100644
--- a/arch/tile/kernel/sysfs.c
+++ b/arch/tile/kernel/sysfs.c
@@ -93,6 +93,10 @@ HV_CONF_ATTR(mezz_part, HV_CONFSTR_MEZZ_PART_NUM)
93HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM) 93HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM)
94HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV) 94HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV)
95HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC) 95HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC)
96HV_CONF_ATTR(cpumod_part, HV_CONFSTR_CPUMOD_PART_NUM)
97HV_CONF_ATTR(cpumod_serial, HV_CONFSTR_CPUMOD_SERIAL_NUM)
98HV_CONF_ATTR(cpumod_revision, HV_CONFSTR_CPUMOD_REV)
99HV_CONF_ATTR(cpumod_description,HV_CONFSTR_CPUMOD_DESC)
96HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL) 100HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL)
97 101
98static struct attribute *board_attrs[] = { 102static struct attribute *board_attrs[] = {
@@ -104,6 +108,10 @@ static struct attribute *board_attrs[] = {
104 &dev_attr_mezz_serial.attr, 108 &dev_attr_mezz_serial.attr,
105 &dev_attr_mezz_revision.attr, 109 &dev_attr_mezz_revision.attr,
106 &dev_attr_mezz_description.attr, 110 &dev_attr_mezz_description.attr,
111 &dev_attr_cpumod_part.attr,
112 &dev_attr_cpumod_serial.attr,
113 &dev_attr_cpumod_revision.attr,
114 &dev_attr_cpumod_description.attr,
107 &dev_attr_switch_control.attr, 115 &dev_attr_switch_control.attr,
108 NULL 116 NULL
109}; 117};
diff --git a/arch/tile/kernel/tlb.c b/arch/tile/kernel/tlb.c
index a5f241c24ca..3fd54d5bbd4 100644
--- a/arch/tile/kernel/tlb.c
+++ b/arch/tile/kernel/tlb.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/cpumask.h> 16#include <linux/cpumask.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/hugetlb.h>
18#include <asm/tlbflush.h> 19#include <asm/tlbflush.h>
19#include <asm/homecache.h> 20#include <asm/homecache.h>
20#include <hv/hypervisor.h> 21#include <hv/hypervisor.h>
@@ -49,25 +50,25 @@ void flush_tlb_current_task(void)
49 flush_tlb_mm(current->mm); 50 flush_tlb_mm(current->mm);
50} 51}
51 52
52void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm, 53void flush_tlb_page_mm(struct vm_area_struct *vma, struct mm_struct *mm,
53 unsigned long va) 54 unsigned long va)
54{ 55{
55 unsigned long size = hv_page_size(vma); 56 unsigned long size = vma_kernel_pagesize(vma);
56 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0; 57 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
57 flush_remote(0, cache, mm_cpumask(mm), 58 flush_remote(0, cache, mm_cpumask(mm),
58 va, size, size, mm_cpumask(mm), NULL, 0); 59 va, size, size, mm_cpumask(mm), NULL, 0);
59} 60}
60 61
61void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va) 62void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
62{ 63{
63 flush_tlb_page_mm(vma, vma->vm_mm, va); 64 flush_tlb_page_mm(vma, vma->vm_mm, va);
64} 65}
65EXPORT_SYMBOL(flush_tlb_page); 66EXPORT_SYMBOL(flush_tlb_page);
66 67
67void flush_tlb_range(const struct vm_area_struct *vma, 68void flush_tlb_range(struct vm_area_struct *vma,
68 unsigned long start, unsigned long end) 69 unsigned long start, unsigned long end)
69{ 70{
70 unsigned long size = hv_page_size(vma); 71 unsigned long size = vma_kernel_pagesize(vma);
71 struct mm_struct *mm = vma->vm_mm; 72 struct mm_struct *mm = vma->vm_mm;
72 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0; 73 int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
73 flush_remote(0, cache, mm_cpumask(mm), start, end - start, size, 74 flush_remote(0, cache, mm_cpumask(mm), start, end - start, size,
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 73cff814ac5..5b19a23c890 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -195,6 +195,25 @@ static int special_ill(bundle_bits bundle, int *sigp, int *codep)
195 return 1; 195 return 1;
196} 196}
197 197
198static const char *const int_name[] = {
199 [INT_MEM_ERROR] = "Memory error",
200 [INT_ILL] = "Illegal instruction",
201 [INT_GPV] = "General protection violation",
202 [INT_UDN_ACCESS] = "UDN access",
203 [INT_IDN_ACCESS] = "IDN access",
204#if CHIP_HAS_SN()
205 [INT_SN_ACCESS] = "SN access",
206#endif
207 [INT_SWINT_3] = "Software interrupt 3",
208 [INT_SWINT_2] = "Software interrupt 2",
209 [INT_SWINT_0] = "Software interrupt 0",
210 [INT_UNALIGN_DATA] = "Unaligned data",
211 [INT_DOUBLE_FAULT] = "Double fault",
212#ifdef __tilegx__
213 [INT_ILL_TRANS] = "Illegal virtual address",
214#endif
215};
216
198void __kprobes do_trap(struct pt_regs *regs, int fault_num, 217void __kprobes do_trap(struct pt_regs *regs, int fault_num,
199 unsigned long reason) 218 unsigned long reason)
200{ 219{
@@ -211,10 +230,17 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
211 * current process and hope for the best. 230 * current process and hope for the best.
212 */ 231 */
213 if (!user_mode(regs)) { 232 if (!user_mode(regs)) {
233 const char *name;
214 if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ 234 if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */
215 return; 235 return;
216 pr_alert("Kernel took bad trap %d at PC %#lx\n", 236 if (fault_num >= 0 &&
217 fault_num, regs->pc); 237 fault_num < sizeof(int_name)/sizeof(int_name[0]) &&
238 int_name[fault_num] != NULL)
239 name = int_name[fault_num];
240 else
241 name = "Unknown interrupt";
242 pr_alert("Kernel took bad trap %d (%s) at PC %#lx\n",
243 fault_num, name, regs->pc);
218 if (fault_num == INT_GPV) 244 if (fault_num == INT_GPV)
219 pr_alert("GPV_REASON is %#lx\n", reason); 245 pr_alert("GPV_REASON is %#lx\n", reason);
220 show_regs(regs); 246 show_regs(regs);
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
index 771b251b409..f5cada70c3c 100644
--- a/arch/tile/lib/atomic_32.c
+++ b/arch/tile/lib/atomic_32.c
@@ -18,7 +18,6 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/atomic.h> 20#include <linux/atomic.h>
21#include <asm/futex.h>
22#include <arch/chip.h> 21#include <arch/chip.h>
23 22
24/* See <asm/atomic_32.h> */ 23/* See <asm/atomic_32.h> */
@@ -50,7 +49,7 @@ int atomic_locks[PAGE_SIZE / sizeof(int)] __page_aligned_bss;
50 49
51#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 50#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
52 51
53static inline int *__atomic_hashed_lock(volatile void *v) 52int *__atomic_hashed_lock(volatile void *v)
54{ 53{
55 /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec_32.S */ 54 /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec_32.S */
56#if ATOMIC_LOCKS_FOUND_VIA_TABLE() 55#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
@@ -191,47 +190,6 @@ u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
191EXPORT_SYMBOL(_atomic64_cmpxchg); 190EXPORT_SYMBOL(_atomic64_cmpxchg);
192 191
193 192
194static inline int *__futex_setup(int __user *v)
195{
196 /*
197 * Issue a prefetch to the counter to bring it into cache.
198 * As for __atomic_setup, but we can't do a read into the L1
199 * since it might fault; instead we do a prefetch into the L2.
200 */
201 __insn_prefetch(v);
202 return __atomic_hashed_lock((int __force *)v);
203}
204
205struct __get_user futex_set(u32 __user *v, int i)
206{
207 return __atomic_xchg((int __force *)v, __futex_setup(v), i);
208}
209
210struct __get_user futex_add(u32 __user *v, int n)
211{
212 return __atomic_xchg_add((int __force *)v, __futex_setup(v), n);
213}
214
215struct __get_user futex_or(u32 __user *v, int n)
216{
217 return __atomic_or((int __force *)v, __futex_setup(v), n);
218}
219
220struct __get_user futex_andn(u32 __user *v, int n)
221{
222 return __atomic_andn((int __force *)v, __futex_setup(v), n);
223}
224
225struct __get_user futex_xor(u32 __user *v, int n)
226{
227 return __atomic_xor((int __force *)v, __futex_setup(v), n);
228}
229
230struct __get_user futex_cmpxchg(u32 __user *v, int o, int n)
231{
232 return __atomic_cmpxchg((int __force *)v, __futex_setup(v), o, n);
233}
234
235/* 193/*
236 * If any of the atomic or futex routines hit a bad address (not in 194 * If any of the atomic or futex routines hit a bad address (not in
237 * the page tables at kernel PL) this routine is called. The futex 195 * the page tables at kernel PL) this routine is called. The futex
@@ -323,7 +281,4 @@ void __init __init_atomic_per_cpu(void)
323 BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE); 281 BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
324 282
325#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */ 283#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
326
327 /* The futex code makes this assumption, so we validate it here. */
328 BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
329} 284}
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
index 2a81d32de0d..dd5f0a33fda 100644
--- a/arch/tile/lib/exports.c
+++ b/arch/tile/lib/exports.c
@@ -18,14 +18,6 @@
18 18
19/* arch/tile/lib/usercopy.S */ 19/* arch/tile/lib/usercopy.S */
20#include <linux/uaccess.h> 20#include <linux/uaccess.h>
21EXPORT_SYMBOL(__get_user_1);
22EXPORT_SYMBOL(__get_user_2);
23EXPORT_SYMBOL(__get_user_4);
24EXPORT_SYMBOL(__get_user_8);
25EXPORT_SYMBOL(__put_user_1);
26EXPORT_SYMBOL(__put_user_2);
27EXPORT_SYMBOL(__put_user_4);
28EXPORT_SYMBOL(__put_user_8);
29EXPORT_SYMBOL(strnlen_user_asm); 21EXPORT_SYMBOL(strnlen_user_asm);
30EXPORT_SYMBOL(strncpy_from_user_asm); 22EXPORT_SYMBOL(strncpy_from_user_asm);
31EXPORT_SYMBOL(clear_user_asm); 23EXPORT_SYMBOL(clear_user_asm);
diff --git a/arch/tile/lib/memchr_64.c b/arch/tile/lib/memchr_64.c
index 84fdc8d8e73..6f867dbf7c5 100644
--- a/arch/tile/lib/memchr_64.c
+++ b/arch/tile/lib/memchr_64.c
@@ -15,6 +15,7 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include "string-endian.h"
18 19
19void *memchr(const void *s, int c, size_t n) 20void *memchr(const void *s, int c, size_t n)
20{ 21{
@@ -39,11 +40,8 @@ void *memchr(const void *s, int c, size_t n)
39 40
40 /* Read the first word, but munge it so that bytes before the array 41 /* Read the first word, but munge it so that bytes before the array
41 * will not match goal. 42 * will not match goal.
42 *
43 * Note that this shift count expression works because we know
44 * shift counts are taken mod 64.
45 */ 43 */
46 before_mask = (1ULL << (s_int << 3)) - 1; 44 before_mask = MASK(s_int);
47 v = (*p | before_mask) ^ (goal & before_mask); 45 v = (*p | before_mask) ^ (goal & before_mask);
48 46
49 /* Compute the address of the last byte. */ 47 /* Compute the address of the last byte. */
@@ -65,7 +63,7 @@ void *memchr(const void *s, int c, size_t n)
65 /* We found a match, but it might be in a byte past the end 63 /* We found a match, but it might be in a byte past the end
66 * of the array. 64 * of the array.
67 */ 65 */
68 ret = ((char *)p) + (__insn_ctz(bits) >> 3); 66 ret = ((char *)p) + (CFZ(bits) >> 3);
69 return (ret <= last_byte_ptr) ? ret : NULL; 67 return (ret <= last_byte_ptr) ? ret : NULL;
70} 68}
71EXPORT_SYMBOL(memchr); 69EXPORT_SYMBOL(memchr);
diff --git a/arch/tile/lib/memcpy_64.c b/arch/tile/lib/memcpy_64.c
index 3fab9a6a2bb..c79b8e7c682 100644
--- a/arch/tile/lib/memcpy_64.c
+++ b/arch/tile/lib/memcpy_64.c
@@ -15,7 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#define __memcpy memcpy
19/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */ 18/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
20 19
21/* Must be 8 bytes in size. */ 20/* Must be 8 bytes in size. */
@@ -188,6 +187,7 @@ int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
188 187
189 /* n != 0 if we get here. Write out any trailing bytes. */ 188 /* n != 0 if we get here. Write out any trailing bytes. */
190 dst1 = (char *)dst8; 189 dst1 = (char *)dst8;
190#ifndef __BIG_ENDIAN__
191 if (n & 4) { 191 if (n & 4) {
192 ST4((uint32_t *)dst1, final); 192 ST4((uint32_t *)dst1, final);
193 dst1 += 4; 193 dst1 += 4;
@@ -202,11 +202,30 @@ int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
202 } 202 }
203 if (n) 203 if (n)
204 ST1((uint8_t *)dst1, final); 204 ST1((uint8_t *)dst1, final);
205#else
206 if (n & 4) {
207 ST4((uint32_t *)dst1, final >> 32);
208 dst1 += 4;
209 }
210 else
211 {
212 final >>= 32;
213 }
214 if (n & 2) {
215 ST2((uint16_t *)dst1, final >> 16);
216 dst1 += 2;
217 }
218 else
219 {
220 final >>= 16;
221 }
222 if (n & 1)
223 ST1((uint8_t *)dst1, final >> 8);
224#endif
205 225
206 return RETVAL; 226 return RETVAL;
207} 227}
208 228
209
210#ifdef USERCOPY_FUNC 229#ifdef USERCOPY_FUNC
211#undef ST1 230#undef ST1
212#undef ST2 231#undef ST2
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c
index b2fe15e0107..3bc4b4e40d9 100644
--- a/arch/tile/lib/memcpy_tile64.c
+++ b/arch/tile/lib/memcpy_tile64.c
@@ -160,7 +160,7 @@ retry_source:
160 break; 160 break;
161 if (get_remote_cache_cpu(src_pte) == smp_processor_id()) 161 if (get_remote_cache_cpu(src_pte) == smp_processor_id())
162 break; 162 break;
163 src_page = pfn_to_page(hv_pte_get_pfn(src_pte)); 163 src_page = pfn_to_page(pte_pfn(src_pte));
164 get_page(src_page); 164 get_page(src_page);
165 if (pte_val(src_pte) != pte_val(*src_ptep)) { 165 if (pte_val(src_pte) != pte_val(*src_ptep)) {
166 put_page(src_page); 166 put_page(src_page);
@@ -168,7 +168,7 @@ retry_source:
168 } 168 }
169 if (pte_huge(src_pte)) { 169 if (pte_huge(src_pte)) {
170 /* Adjust the PTE to correspond to a small page */ 170 /* Adjust the PTE to correspond to a small page */
171 int pfn = hv_pte_get_pfn(src_pte); 171 int pfn = pte_pfn(src_pte);
172 pfn += (((unsigned long)source & (HPAGE_SIZE-1)) 172 pfn += (((unsigned long)source & (HPAGE_SIZE-1))
173 >> PAGE_SHIFT); 173 >> PAGE_SHIFT);
174 src_pte = pfn_pte(pfn, src_pte); 174 src_pte = pfn_pte(pfn, src_pte);
@@ -188,7 +188,7 @@ retry_dest:
188 put_page(src_page); 188 put_page(src_page);
189 break; 189 break;
190 } 190 }
191 dst_page = pfn_to_page(hv_pte_get_pfn(dst_pte)); 191 dst_page = pfn_to_page(pte_pfn(dst_pte));
192 if (dst_page == src_page) { 192 if (dst_page == src_page) {
193 /* 193 /*
194 * Source and dest are on the same page; this 194 * Source and dest are on the same page; this
@@ -206,7 +206,7 @@ retry_dest:
206 } 206 }
207 if (pte_huge(dst_pte)) { 207 if (pte_huge(dst_pte)) {
208 /* Adjust the PTE to correspond to a small page */ 208 /* Adjust the PTE to correspond to a small page */
209 int pfn = hv_pte_get_pfn(dst_pte); 209 int pfn = pte_pfn(dst_pte);
210 pfn += (((unsigned long)dest & (HPAGE_SIZE-1)) 210 pfn += (((unsigned long)dest & (HPAGE_SIZE-1))
211 >> PAGE_SHIFT); 211 >> PAGE_SHIFT);
212 dst_pte = pfn_pte(pfn, dst_pte); 212 dst_pte = pfn_pte(pfn, dst_pte);
diff --git a/arch/tile/lib/strchr_64.c b/arch/tile/lib/strchr_64.c
index 617a9273aaa..f39f9dc422b 100644
--- a/arch/tile/lib/strchr_64.c
+++ b/arch/tile/lib/strchr_64.c
@@ -15,8 +15,7 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18 18#include "string-endian.h"
19#undef strchr
20 19
21char *strchr(const char *s, int c) 20char *strchr(const char *s, int c)
22{ 21{
@@ -33,13 +32,9 @@ char *strchr(const char *s, int c)
33 * match neither zero nor goal (we make sure the high bit of each 32 * match neither zero nor goal (we make sure the high bit of each
34 * byte is 1, and the low 7 bits are all the opposite of the goal 33 * byte is 1, and the low 7 bits are all the opposite of the goal
35 * byte). 34 * byte).
36 *
37 * Note that this shift count expression works because we know shift
38 * counts are taken mod 64.
39 */ 35 */
40 const uint64_t before_mask = (1ULL << (s_int << 3)) - 1; 36 const uint64_t before_mask = MASK(s_int);
41 uint64_t v = (*p | before_mask) ^ 37 uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui(before_mask, 1));
42 (goal & __insn_v1shrsi(before_mask, 1));
43 38
44 uint64_t zero_matches, goal_matches; 39 uint64_t zero_matches, goal_matches;
45 while (1) { 40 while (1) {
@@ -55,8 +50,8 @@ char *strchr(const char *s, int c)
55 v = *++p; 50 v = *++p;
56 } 51 }
57 52
58 z = __insn_ctz(zero_matches); 53 z = CFZ(zero_matches);
59 g = __insn_ctz(goal_matches); 54 g = CFZ(goal_matches);
60 55
61 /* If we found c before '\0' we got a match. Note that if c == '\0' 56 /* If we found c before '\0' we got a match. Note that if c == '\0'
62 * then g == z, and we correctly return the address of the '\0' 57 * then g == z, and we correctly return the address of the '\0'
diff --git a/arch/tile/lib/string-endian.h b/arch/tile/lib/string-endian.h
new file mode 100644
index 00000000000..c0eed7ce69c
--- /dev/null
+++ b/arch/tile/lib/string-endian.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
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
6 * as published by the Free Software Foundation, version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11 * NON INFRINGEMENT. See the GNU General Public License for
12 * more details.
13 *
14 * Provide a mask based on the pointer alignment that
15 * sets up non-zero bytes before the beginning of the string.
16 * The MASK expression works because shift counts are taken mod 64.
17 * Also, specify how to count "first" and "last" bits
18 * when the bits have been read as a word.
19 */
20
21#include <asm/byteorder.h>
22
23#ifdef __LITTLE_ENDIAN
24#define MASK(x) (__insn_shl(1ULL, (x << 3)) - 1)
25#define NULMASK(x) ((2ULL << x) - 1)
26#define CFZ(x) __insn_ctz(x)
27#define REVCZ(x) __insn_clz(x)
28#else
29#define MASK(x) (__insn_shl(-2LL, ((-x << 3) - 1)))
30#define NULMASK(x) (-2LL << (63 - x))
31#define CFZ(x) __insn_clz(x)
32#define REVCZ(x) __insn_ctz(x)
33#endif
diff --git a/arch/tile/lib/strlen_64.c b/arch/tile/lib/strlen_64.c
index 1c92d46202a..9583fc3361f 100644
--- a/arch/tile/lib/strlen_64.c
+++ b/arch/tile/lib/strlen_64.c
@@ -15,8 +15,7 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/module.h> 17#include <linux/module.h>
18 18#include "string-endian.h"
19#undef strlen
20 19
21size_t strlen(const char *s) 20size_t strlen(const char *s)
22{ 21{
@@ -24,15 +23,13 @@ size_t strlen(const char *s)
24 const uintptr_t s_int = (uintptr_t) s; 23 const uintptr_t s_int = (uintptr_t) s;
25 const uint64_t *p = (const uint64_t *)(s_int & -8); 24 const uint64_t *p = (const uint64_t *)(s_int & -8);
26 25
27 /* Read the first word, but force bytes before the string to be nonzero. 26 /* Read and MASK the first word. */
28 * This expression works because we know shift counts are taken mod 64. 27 uint64_t v = *p | MASK(s_int);
29 */
30 uint64_t v = *p | ((1ULL << (s_int << 3)) - 1);
31 28
32 uint64_t bits; 29 uint64_t bits;
33 while ((bits = __insn_v1cmpeqi(v, 0)) == 0) 30 while ((bits = __insn_v1cmpeqi(v, 0)) == 0)
34 v = *++p; 31 v = *++p;
35 32
36 return ((const char *)p) + (__insn_ctz(bits) >> 3) - s; 33 return ((const char *)p) + (CFZ(bits) >> 3) - s;
37} 34}
38EXPORT_SYMBOL(strlen); 35EXPORT_SYMBOL(strlen);
diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S
index 979f76d8374..b62d002af00 100644
--- a/arch/tile/lib/usercopy_32.S
+++ b/arch/tile/lib/usercopy_32.S
@@ -19,82 +19,6 @@
19 19
20/* Access user memory, but use MMU to avoid propagating kernel exceptions. */ 20/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
21 21
22 .pushsection .fixup,"ax"
23
24get_user_fault:
25 { move r0, zero; move r1, zero }
26 { movei r2, -EFAULT; jrp lr }
27 ENDPROC(get_user_fault)
28
29put_user_fault:
30 { movei r0, -EFAULT; jrp lr }
31 ENDPROC(put_user_fault)
32
33 .popsection
34
35/*
36 * __get_user_N functions take a pointer in r0, and return 0 in r2
37 * on success, with the value in r0; or else -EFAULT in r2.
38 */
39#define __get_user_N(bytes, LOAD) \
40 STD_ENTRY(__get_user_##bytes); \
411: { LOAD r0, r0; move r1, zero; move r2, zero }; \
42 jrp lr; \
43 STD_ENDPROC(__get_user_##bytes); \
44 .pushsection __ex_table,"a"; \
45 .word 1b, get_user_fault; \
46 .popsection
47
48__get_user_N(1, lb_u)
49__get_user_N(2, lh_u)
50__get_user_N(4, lw)
51
52/*
53 * __get_user_8 takes a pointer in r0, and returns 0 in r2
54 * on success, with the value in r0/r1; or else -EFAULT in r2.
55 */
56 STD_ENTRY(__get_user_8);
571: { lw r0, r0; addi r1, r0, 4 };
582: { lw r1, r1; move r2, zero };
59 jrp lr;
60 STD_ENDPROC(__get_user_8);
61 .pushsection __ex_table,"a";
62 .word 1b, get_user_fault;
63 .word 2b, get_user_fault;
64 .popsection
65
66/*
67 * __put_user_N functions take a value in r0 and a pointer in r1,
68 * and return 0 in r0 on success or -EFAULT on failure.
69 */
70#define __put_user_N(bytes, STORE) \
71 STD_ENTRY(__put_user_##bytes); \
721: { STORE r1, r0; move r0, zero }; \
73 jrp lr; \
74 STD_ENDPROC(__put_user_##bytes); \
75 .pushsection __ex_table,"a"; \
76 .word 1b, put_user_fault; \
77 .popsection
78
79__put_user_N(1, sb)
80__put_user_N(2, sh)
81__put_user_N(4, sw)
82
83/*
84 * __put_user_8 takes a value in r0/r1 and a pointer in r2,
85 * and returns 0 in r0 on success or -EFAULT on failure.
86 */
87STD_ENTRY(__put_user_8)
881: { sw r2, r0; addi r2, r2, 4 }
892: { sw r2, r1; move r0, zero }
90 jrp lr
91 STD_ENDPROC(__put_user_8)
92 .pushsection __ex_table,"a"
93 .word 1b, put_user_fault
94 .word 2b, put_user_fault
95 .popsection
96
97
98/* 22/*
99 * strnlen_user_asm takes the pointer in r0, and the length bound in r1. 23 * strnlen_user_asm takes the pointer in r0, and the length bound in r1.
100 * It returns the length, including the terminating NUL, or zero on exception. 24 * It returns the length, including the terminating NUL, or zero on exception.
diff --git a/arch/tile/lib/usercopy_64.S b/arch/tile/lib/usercopy_64.S
index 2ff44f87b78..adb2dbbc70c 100644
--- a/arch/tile/lib/usercopy_64.S
+++ b/arch/tile/lib/usercopy_64.S
@@ -19,55 +19,6 @@
19 19
20/* Access user memory, but use MMU to avoid propagating kernel exceptions. */ 20/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
21 21
22 .pushsection .fixup,"ax"
23
24get_user_fault:
25 { movei r1, -EFAULT; move r0, zero }
26 jrp lr
27 ENDPROC(get_user_fault)
28
29put_user_fault:
30 { movei r0, -EFAULT; jrp lr }
31 ENDPROC(put_user_fault)
32
33 .popsection
34
35/*
36 * __get_user_N functions take a pointer in r0, and return 0 in r1
37 * on success, with the value in r0; or else -EFAULT in r1.
38 */
39#define __get_user_N(bytes, LOAD) \
40 STD_ENTRY(__get_user_##bytes); \
411: { LOAD r0, r0; move r1, zero }; \
42 jrp lr; \
43 STD_ENDPROC(__get_user_##bytes); \
44 .pushsection __ex_table,"a"; \
45 .quad 1b, get_user_fault; \
46 .popsection
47
48__get_user_N(1, ld1u)
49__get_user_N(2, ld2u)
50__get_user_N(4, ld4u)
51__get_user_N(8, ld)
52
53/*
54 * __put_user_N functions take a value in r0 and a pointer in r1,
55 * and return 0 in r0 on success or -EFAULT on failure.
56 */
57#define __put_user_N(bytes, STORE) \
58 STD_ENTRY(__put_user_##bytes); \
591: { STORE r1, r0; move r0, zero }; \
60 jrp lr; \
61 STD_ENDPROC(__put_user_##bytes); \
62 .pushsection __ex_table,"a"; \
63 .quad 1b, put_user_fault; \
64 .popsection
65
66__put_user_N(1, st1)
67__put_user_N(2, st2)
68__put_user_N(4, st4)
69__put_user_N(8, st)
70
71/* 22/*
72 * strnlen_user_asm takes the pointer in r0, and the length bound in r1. 23 * strnlen_user_asm takes the pointer in r0, and the length bound in r1.
73 * It returns the length, including the terminating NUL, or zero on exception. 24 * It returns the length, including the terminating NUL, or zero on exception.
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 22e58f51ed2..84ce7abbf5a 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -187,7 +187,7 @@ static pgd_t *get_current_pgd(void)
187 HV_Context ctx = hv_inquire_context(); 187 HV_Context ctx = hv_inquire_context();
188 unsigned long pgd_pfn = ctx.page_table >> PAGE_SHIFT; 188 unsigned long pgd_pfn = ctx.page_table >> PAGE_SHIFT;
189 struct page *pgd_page = pfn_to_page(pgd_pfn); 189 struct page *pgd_page = pfn_to_page(pgd_pfn);
190 BUG_ON(PageHighMem(pgd_page)); /* oops, HIGHPTE? */ 190 BUG_ON(PageHighMem(pgd_page));
191 return (pgd_t *) __va(ctx.page_table); 191 return (pgd_t *) __va(ctx.page_table);
192} 192}
193 193
@@ -273,11 +273,15 @@ static int handle_page_fault(struct pt_regs *regs,
273 int si_code; 273 int si_code;
274 int is_kernel_mode; 274 int is_kernel_mode;
275 pgd_t *pgd; 275 pgd_t *pgd;
276 unsigned int flags;
276 277
277 /* on TILE, protection faults are always writes */ 278 /* on TILE, protection faults are always writes */
278 if (!is_page_fault) 279 if (!is_page_fault)
279 write = 1; 280 write = 1;
280 281
282 flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
283 (write ? FAULT_FLAG_WRITE : 0));
284
281 is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL); 285 is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL);
282 286
283 tsk = validate_current(); 287 tsk = validate_current();
@@ -382,6 +386,8 @@ static int handle_page_fault(struct pt_regs *regs,
382 vma = NULL; /* happy compiler */ 386 vma = NULL; /* happy compiler */
383 goto bad_area_nosemaphore; 387 goto bad_area_nosemaphore;
384 } 388 }
389
390retry:
385 down_read(&mm->mmap_sem); 391 down_read(&mm->mmap_sem);
386 } 392 }
387 393
@@ -429,7 +435,11 @@ good_area:
429 * make sure we exit gracefully rather than endlessly redo 435 * make sure we exit gracefully rather than endlessly redo
430 * the fault. 436 * the fault.
431 */ 437 */
432 fault = handle_mm_fault(mm, vma, address, write); 438 fault = handle_mm_fault(mm, vma, address, flags);
439
440 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
441 return 0;
442
433 if (unlikely(fault & VM_FAULT_ERROR)) { 443 if (unlikely(fault & VM_FAULT_ERROR)) {
434 if (fault & VM_FAULT_OOM) 444 if (fault & VM_FAULT_OOM)
435 goto out_of_memory; 445 goto out_of_memory;
@@ -437,10 +447,22 @@ good_area:
437 goto do_sigbus; 447 goto do_sigbus;
438 BUG(); 448 BUG();
439 } 449 }
440 if (fault & VM_FAULT_MAJOR) 450 if (flags & FAULT_FLAG_ALLOW_RETRY) {
441 tsk->maj_flt++; 451 if (fault & VM_FAULT_MAJOR)
442 else 452 tsk->maj_flt++;
443 tsk->min_flt++; 453 else
454 tsk->min_flt++;
455 if (fault & VM_FAULT_RETRY) {
456 flags &= ~FAULT_FLAG_ALLOW_RETRY;
457
458 /*
459 * No need to up_read(&mm->mmap_sem) as we would
460 * have already released it in __lock_page_or_retry
461 * in mm/filemap.c.
462 */
463 goto retry;
464 }
465 }
444 466
445#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() 467#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
446 /* 468 /*
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index 499f73770b0..dbcbdf7b8aa 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -30,6 +30,7 @@
30#include <linux/cache.h> 30#include <linux/cache.h>
31#include <linux/smp.h> 31#include <linux/smp.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/hugetlb.h>
33 34
34#include <asm/page.h> 35#include <asm/page.h>
35#include <asm/sections.h> 36#include <asm/sections.h>
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index 42cfcba4e1e..812e2d03797 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -27,85 +27,161 @@
27#include <linux/mman.h> 27#include <linux/mman.h>
28#include <asm/tlb.h> 28#include <asm/tlb.h>
29#include <asm/tlbflush.h> 29#include <asm/tlbflush.h>
30#include <asm/setup.h>
31
32#ifdef CONFIG_HUGETLB_SUPER_PAGES
33
34/*
35 * Provide an additional huge page size (in addition to the regular default
36 * huge page size) if no "hugepagesz" arguments are specified.
37 * Note that it must be smaller than the default huge page size so
38 * that it's possible to allocate them on demand from the buddy allocator.
39 * You can change this to 64K (on a 16K build), 256K, 1M, or 4M,
40 * or not define it at all.
41 */
42#define ADDITIONAL_HUGE_SIZE (1024 * 1024UL)
43
44/* "Extra" page-size multipliers, one per level of the page table. */
45int huge_shift[HUGE_SHIFT_ENTRIES] = {
46#ifdef ADDITIONAL_HUGE_SIZE
47#define ADDITIONAL_HUGE_SHIFT __builtin_ctzl(ADDITIONAL_HUGE_SIZE / PAGE_SIZE)
48 [HUGE_SHIFT_PAGE] = ADDITIONAL_HUGE_SHIFT
49#endif
50};
51
52/*
53 * This routine is a hybrid of pte_alloc_map() and pte_alloc_kernel().
54 * It assumes that L2 PTEs are never in HIGHMEM (we don't support that).
55 * It locks the user pagetable, and bumps up the mm->nr_ptes field,
56 * but otherwise allocate the page table using the kernel versions.
57 */
58static pte_t *pte_alloc_hugetlb(struct mm_struct *mm, pmd_t *pmd,
59 unsigned long address)
60{
61 pte_t *new;
62
63 if (pmd_none(*pmd)) {
64 new = pte_alloc_one_kernel(mm, address);
65 if (!new)
66 return NULL;
67
68 smp_wmb(); /* See comment in __pte_alloc */
69
70 spin_lock(&mm->page_table_lock);
71 if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
72 mm->nr_ptes++;
73 pmd_populate_kernel(mm, pmd, new);
74 new = NULL;
75 } else
76 VM_BUG_ON(pmd_trans_splitting(*pmd));
77 spin_unlock(&mm->page_table_lock);
78 if (new)
79 pte_free_kernel(mm, new);
80 }
81
82 return pte_offset_kernel(pmd, address);
83}
84#endif
30 85
31pte_t *huge_pte_alloc(struct mm_struct *mm, 86pte_t *huge_pte_alloc(struct mm_struct *mm,
32 unsigned long addr, unsigned long sz) 87 unsigned long addr, unsigned long sz)
33{ 88{
34 pgd_t *pgd; 89 pgd_t *pgd;
35 pud_t *pud; 90 pud_t *pud;
36 pte_t *pte = NULL;
37 91
38 /* We do not yet support multiple huge page sizes. */ 92 addr &= -sz; /* Mask off any low bits in the address. */
39 BUG_ON(sz != PMD_SIZE);
40 93
41 pgd = pgd_offset(mm, addr); 94 pgd = pgd_offset(mm, addr);
42 pud = pud_alloc(mm, pgd, addr); 95 pud = pud_alloc(mm, pgd, addr);
43 if (pud)
44 pte = (pte_t *) pmd_alloc(mm, pud, addr);
45 BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
46 96
47 return pte; 97#ifdef CONFIG_HUGETLB_SUPER_PAGES
98 if (sz >= PGDIR_SIZE) {
99 BUG_ON(sz != PGDIR_SIZE &&
100 sz != PGDIR_SIZE << huge_shift[HUGE_SHIFT_PGDIR]);
101 return (pte_t *)pud;
102 } else {
103 pmd_t *pmd = pmd_alloc(mm, pud, addr);
104 if (sz >= PMD_SIZE) {
105 BUG_ON(sz != PMD_SIZE &&
106 sz != (PMD_SIZE << huge_shift[HUGE_SHIFT_PMD]));
107 return (pte_t *)pmd;
108 }
109 else {
110 if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE])
111 panic("Unexpected page size %#lx\n", sz);
112 return pte_alloc_hugetlb(mm, pmd, addr);
113 }
114 }
115#else
116 BUG_ON(sz != PMD_SIZE);
117 return (pte_t *) pmd_alloc(mm, pud, addr);
118#endif
48} 119}
49 120
50pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 121static pte_t *get_pte(pte_t *base, int index, int level)
51{ 122{
52 pgd_t *pgd; 123 pte_t *ptep = base + index;
53 pud_t *pud; 124#ifdef CONFIG_HUGETLB_SUPER_PAGES
54 pmd_t *pmd = NULL; 125 if (!pte_present(*ptep) && huge_shift[level] != 0) {
55 126 unsigned long mask = -1UL << huge_shift[level];
56 pgd = pgd_offset(mm, addr); 127 pte_t *super_ptep = base + (index & mask);
57 if (pgd_present(*pgd)) { 128 pte_t pte = *super_ptep;
58 pud = pud_offset(pgd, addr); 129 if (pte_present(pte) && pte_super(pte))
59 if (pud_present(*pud)) 130 ptep = super_ptep;
60 pmd = pmd_offset(pud, addr);
61 } 131 }
62 return (pte_t *) pmd; 132#endif
133 return ptep;
63} 134}
64 135
65#ifdef HUGETLB_TEST 136pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
66struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
67 int write)
68{ 137{
69 unsigned long start = address; 138 pgd_t *pgd;
70 int length = 1; 139 pud_t *pud;
71 int nr; 140 pmd_t *pmd;
72 struct page *page; 141#ifdef CONFIG_HUGETLB_SUPER_PAGES
73 struct vm_area_struct *vma; 142 pte_t *pte;
74 143#endif
75 vma = find_vma(mm, addr);
76 if (!vma || !is_vm_hugetlb_page(vma))
77 return ERR_PTR(-EINVAL);
78
79 pte = huge_pte_offset(mm, address);
80 144
81 /* hugetlb should be locked, and hence, prefaulted */ 145 /* Get the top-level page table entry. */
82 WARN_ON(!pte || pte_none(*pte)); 146 pgd = (pgd_t *)get_pte((pte_t *)mm->pgd, pgd_index(addr), 0);
147 if (!pgd_present(*pgd))
148 return NULL;
83 149
84 page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)]; 150 /* We don't have four levels. */
151 pud = pud_offset(pgd, addr);
152#ifndef __PAGETABLE_PUD_FOLDED
153# error support fourth page table level
154#endif
85 155
86 WARN_ON(!PageHead(page)); 156 /* Check for an L0 huge PTE, if we have three levels. */
157#ifndef __PAGETABLE_PMD_FOLDED
158 if (pud_huge(*pud))
159 return (pte_t *)pud;
87 160
88 return page; 161 pmd = (pmd_t *)get_pte((pte_t *)pud_page_vaddr(*pud),
89} 162 pmd_index(addr), 1);
90 163 if (!pmd_present(*pmd))
91int pmd_huge(pmd_t pmd) 164 return NULL;
92{ 165#else
93 return 0; 166 pmd = pmd_offset(pud, addr);
94} 167#endif
95 168
96int pud_huge(pud_t pud) 169 /* Check for an L1 huge PTE. */
97{ 170 if (pmd_huge(*pmd))
98 return 0; 171 return (pte_t *)pmd;
99} 172
173#ifdef CONFIG_HUGETLB_SUPER_PAGES
174 /* Check for an L2 huge PTE. */
175 pte = get_pte((pte_t *)pmd_page_vaddr(*pmd), pte_index(addr), 2);
176 if (!pte_present(*pte))
177 return NULL;
178 if (pte_super(*pte))
179 return pte;
180#endif
100 181
101struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
102 pmd_t *pmd, int write)
103{
104 return NULL; 182 return NULL;
105} 183}
106 184
107#else
108
109struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, 185struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
110 int write) 186 int write)
111{ 187{
@@ -149,8 +225,6 @@ int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
149 return 0; 225 return 0;
150} 226}
151 227
152#endif
153
154#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA 228#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
155static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, 229static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
156 unsigned long addr, unsigned long len, 230 unsigned long addr, unsigned long len,
@@ -322,21 +396,102 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
322 return hugetlb_get_unmapped_area_topdown(file, addr, len, 396 return hugetlb_get_unmapped_area_topdown(file, addr, len,
323 pgoff, flags); 397 pgoff, flags);
324} 398}
399#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
325 400
326static __init int setup_hugepagesz(char *opt) 401#ifdef CONFIG_HUGETLB_SUPER_PAGES
402static __init int __setup_hugepagesz(unsigned long ps)
327{ 403{
328 unsigned long ps = memparse(opt, &opt); 404 int log_ps = __builtin_ctzl(ps);
329 if (ps == PMD_SIZE) { 405 int level, base_shift;
330 hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); 406
331 } else if (ps == PUD_SIZE) { 407 if ((1UL << log_ps) != ps || (log_ps & 1) != 0) {
332 hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); 408 pr_warn("Not enabling %ld byte huge pages;"
409 " must be a power of four.\n", ps);
410 return -EINVAL;
411 }
412
413 if (ps > 64*1024*1024*1024UL) {
414 pr_warn("Not enabling %ld MB huge pages;"
415 " largest legal value is 64 GB .\n", ps >> 20);
416 return -EINVAL;
417 } else if (ps >= PUD_SIZE) {
418 static long hv_jpage_size;
419 if (hv_jpage_size == 0)
420 hv_jpage_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO);
421 if (hv_jpage_size != PUD_SIZE) {
422 pr_warn("Not enabling >= %ld MB huge pages:"
423 " hypervisor reports size %ld\n",
424 PUD_SIZE >> 20, hv_jpage_size);
425 return -EINVAL;
426 }
427 level = 0;
428 base_shift = PUD_SHIFT;
429 } else if (ps >= PMD_SIZE) {
430 level = 1;
431 base_shift = PMD_SHIFT;
432 } else if (ps > PAGE_SIZE) {
433 level = 2;
434 base_shift = PAGE_SHIFT;
333 } else { 435 } else {
334 pr_err("hugepagesz: Unsupported page size %lu M\n", 436 pr_err("hugepagesz: huge page size %ld too small\n", ps);
335 ps >> 20); 437 return -EINVAL;
336 return 0;
337 } 438 }
338 return 1; 439
440 if (log_ps != base_shift) {
441 int shift_val = log_ps - base_shift;
442 if (huge_shift[level] != 0) {
443 int old_shift = base_shift + huge_shift[level];
444 pr_warn("Not enabling %ld MB huge pages;"
445 " already have size %ld MB.\n",
446 ps >> 20, (1UL << old_shift) >> 20);
447 return -EINVAL;
448 }
449 if (hv_set_pte_super_shift(level, shift_val) != 0) {
450 pr_warn("Not enabling %ld MB huge pages;"
451 " no hypervisor support.\n", ps >> 20);
452 return -EINVAL;
453 }
454 printk(KERN_DEBUG "Enabled %ld MB huge pages\n", ps >> 20);
455 huge_shift[level] = shift_val;
456 }
457
458 hugetlb_add_hstate(log_ps - PAGE_SHIFT);
459
460 return 0;
461}
462
463static bool saw_hugepagesz;
464
465static __init int setup_hugepagesz(char *opt)
466{
467 if (!saw_hugepagesz) {
468 saw_hugepagesz = true;
469 memset(huge_shift, 0, sizeof(huge_shift));
470 }
471 return __setup_hugepagesz(memparse(opt, NULL));
339} 472}
340__setup("hugepagesz=", setup_hugepagesz); 473__setup("hugepagesz=", setup_hugepagesz);
341 474
342#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/ 475#ifdef ADDITIONAL_HUGE_SIZE
476/*
477 * Provide an additional huge page size if no "hugepagesz" args are given.
478 * In that case, all the cores have properly set up their hv super_shift
479 * already, but we need to notify the hugetlb code to enable the
480 * new huge page size from the Linux point of view.
481 */
482static __init int add_default_hugepagesz(void)
483{
484 if (!saw_hugepagesz) {
485 BUILD_BUG_ON(ADDITIONAL_HUGE_SIZE >= PMD_SIZE ||
486 ADDITIONAL_HUGE_SIZE <= PAGE_SIZE);
487 BUILD_BUG_ON((PAGE_SIZE << ADDITIONAL_HUGE_SHIFT) !=
488 ADDITIONAL_HUGE_SIZE);
489 BUILD_BUG_ON(ADDITIONAL_HUGE_SHIFT & 1);
490 hugetlb_add_hstate(ADDITIONAL_HUGE_SHIFT);
491 }
492 return 0;
493}
494arch_initcall(add_default_hugepagesz);
495#endif
496
497#endif /* CONFIG_HUGETLB_SUPER_PAGES */
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index 6a9d20ddc34..630dd2ce2af 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -82,7 +82,7 @@ static int num_l2_ptes[MAX_NUMNODES];
82 82
83static void init_prealloc_ptes(int node, int pages) 83static void init_prealloc_ptes(int node, int pages)
84{ 84{
85 BUG_ON(pages & (HV_L2_ENTRIES-1)); 85 BUG_ON(pages & (PTRS_PER_PTE - 1));
86 if (pages) { 86 if (pages) {
87 num_l2_ptes[node] = pages; 87 num_l2_ptes[node] = pages;
88 l2_ptes[node] = __alloc_bootmem(pages * sizeof(pte_t), 88 l2_ptes[node] = __alloc_bootmem(pages * sizeof(pte_t),
@@ -131,14 +131,9 @@ static void __init assign_pte(pmd_t *pmd, pte_t *page_table)
131 131
132#ifdef __tilegx__ 132#ifdef __tilegx__
133 133
134#if HV_L1_SIZE != HV_L2_SIZE
135# error Rework assumption that L1 and L2 page tables are same size.
136#endif
137
138/* Since pmd_t arrays and pte_t arrays are the same size, just use casts. */
139static inline pmd_t *alloc_pmd(void) 134static inline pmd_t *alloc_pmd(void)
140{ 135{
141 return (pmd_t *)alloc_pte(); 136 return __alloc_bootmem(L1_KERNEL_PGTABLE_SIZE, HV_PAGE_TABLE_ALIGN, 0);
142} 137}
143 138
144static inline void assign_pmd(pud_t *pud, pmd_t *pmd) 139static inline void assign_pmd(pud_t *pud, pmd_t *pmd)
@@ -444,6 +439,7 @@ static pgd_t pgtables[PTRS_PER_PGD]
444 */ 439 */
445static void __init kernel_physical_mapping_init(pgd_t *pgd_base) 440static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
446{ 441{
442 unsigned long long irqmask;
447 unsigned long address, pfn; 443 unsigned long address, pfn;
448 pmd_t *pmd; 444 pmd_t *pmd;
449 pte_t *pte; 445 pte_t *pte;
@@ -633,10 +629,13 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
633 * - install pgtables[] as the real page table 629 * - install pgtables[] as the real page table
634 * - flush the TLB so the new page table takes effect 630 * - flush the TLB so the new page table takes effect
635 */ 631 */
632 irqmask = interrupt_mask_save_mask();
633 interrupt_mask_set_mask(-1ULL);
636 rc = flush_and_install_context(__pa(pgtables), 634 rc = flush_and_install_context(__pa(pgtables),
637 init_pgprot((unsigned long)pgtables), 635 init_pgprot((unsigned long)pgtables),
638 __get_cpu_var(current_asid), 636 __get_cpu_var(current_asid),
639 cpumask_bits(my_cpu_mask)); 637 cpumask_bits(my_cpu_mask));
638 interrupt_mask_restore_mask(irqmask);
640 BUG_ON(rc != 0); 639 BUG_ON(rc != 0);
641 640
642 /* Copy the page table back to the normal swapper_pg_dir. */ 641 /* Copy the page table back to the normal swapper_pg_dir. */
@@ -699,6 +698,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
699#endif /* CONFIG_HIGHMEM */ 698#endif /* CONFIG_HIGHMEM */
700 699
701 700
701#ifndef CONFIG_64BIT
702static void __init init_free_pfn_range(unsigned long start, unsigned long end) 702static void __init init_free_pfn_range(unsigned long start, unsigned long end)
703{ 703{
704 unsigned long pfn; 704 unsigned long pfn;
@@ -771,6 +771,7 @@ static void __init set_non_bootmem_pages_init(void)
771 init_free_pfn_range(start, end); 771 init_free_pfn_range(start, end);
772 } 772 }
773} 773}
774#endif
774 775
775/* 776/*
776 * paging_init() sets up the page tables - note that all of lowmem is 777 * paging_init() sets up the page tables - note that all of lowmem is
@@ -807,7 +808,7 @@ void __init paging_init(void)
807 * changing init_mm once we get up and running, and there's no 808 * changing init_mm once we get up and running, and there's no
808 * need for e.g. vmalloc_sync_all(). 809 * need for e.g. vmalloc_sync_all().
809 */ 810 */
810 BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END)); 811 BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END - 1));
811 pud = pud_offset(pgd_base + pgd_index(VMALLOC_START), VMALLOC_START); 812 pud = pud_offset(pgd_base + pgd_index(VMALLOC_START), VMALLOC_START);
812 assign_pmd(pud, alloc_pmd()); 813 assign_pmd(pud, alloc_pmd());
813#endif 814#endif
@@ -859,8 +860,10 @@ void __init mem_init(void)
859 /* this will put all bootmem onto the freelists */ 860 /* this will put all bootmem onto the freelists */
860 totalram_pages += free_all_bootmem(); 861 totalram_pages += free_all_bootmem();
861 862
863#ifndef CONFIG_64BIT
862 /* count all remaining LOWMEM and give all HIGHMEM to page allocator */ 864 /* count all remaining LOWMEM and give all HIGHMEM to page allocator */
863 set_non_bootmem_pages_init(); 865 set_non_bootmem_pages_init();
866#endif
864 867
865 codesize = (unsigned long)&_etext - (unsigned long)&_text; 868 codesize = (unsigned long)&_etext - (unsigned long)&_text;
866 datasize = (unsigned long)&_end - (unsigned long)&_sdata; 869 datasize = (unsigned long)&_end - (unsigned long)&_sdata;
diff --git a/arch/tile/mm/migrate.h b/arch/tile/mm/migrate.h
index cd45a0837fa..91683d97917 100644
--- a/arch/tile/mm/migrate.h
+++ b/arch/tile/mm/migrate.h
@@ -24,6 +24,9 @@
24/* 24/*
25 * This function is used as a helper when setting up the initial 25 * This function is used as a helper when setting up the initial
26 * page table (swapper_pg_dir). 26 * page table (swapper_pg_dir).
27 *
28 * You must mask ALL interrupts prior to invoking this code, since
29 * you can't legally touch the stack during the cache flush.
27 */ 30 */
28extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access, 31extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
29 HV_ASID asid, 32 HV_ASID asid,
@@ -39,6 +42,9 @@ extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
39 * 42 *
40 * Note that any non-NULL pointers must not point to the page that 43 * Note that any non-NULL pointers must not point to the page that
41 * is handled by the stack_pte itself. 44 * is handled by the stack_pte itself.
45 *
46 * You must mask ALL interrupts prior to invoking this code, since
47 * you can't legally touch the stack during the cache flush.
42 */ 48 */
43extern int homecache_migrate_stack_and_flush(pte_t stack_pte, unsigned long va, 49extern int homecache_migrate_stack_and_flush(pte_t stack_pte, unsigned long va,
44 size_t length, pte_t *stack_ptep, 50 size_t length, pte_t *stack_ptep,
diff --git a/arch/tile/mm/migrate_32.S b/arch/tile/mm/migrate_32.S
index ac01a7cdf77..5305814bf18 100644
--- a/arch/tile/mm/migrate_32.S
+++ b/arch/tile/mm/migrate_32.S
@@ -40,8 +40,7 @@
40#define FRAME_R32 16 40#define FRAME_R32 16
41#define FRAME_R33 20 41#define FRAME_R33 20
42#define FRAME_R34 24 42#define FRAME_R34 24
43#define FRAME_R35 28 43#define FRAME_SIZE 28
44#define FRAME_SIZE 32
45 44
46 45
47 46
@@ -66,12 +65,11 @@
66#define r_my_cpumask r5 65#define r_my_cpumask r5
67 66
68/* Locals (callee-save); must not be more than FRAME_xxx above. */ 67/* Locals (callee-save); must not be more than FRAME_xxx above. */
69#define r_save_ics r30 68#define r_context_lo r30
70#define r_context_lo r31 69#define r_context_hi r31
71#define r_context_hi r32 70#define r_access_lo r32
72#define r_access_lo r33 71#define r_access_hi r33
73#define r_access_hi r34 72#define r_asid r34
74#define r_asid r35
75 73
76STD_ENTRY(flush_and_install_context) 74STD_ENTRY(flush_and_install_context)
77 /* 75 /*
@@ -104,11 +102,7 @@ STD_ENTRY(flush_and_install_context)
104 sw r_tmp, r33 102 sw r_tmp, r33
105 addi r_tmp, sp, FRAME_R34 103 addi r_tmp, sp, FRAME_R34
106 } 104 }
107 { 105 sw r_tmp, r34
108 sw r_tmp, r34
109 addi r_tmp, sp, FRAME_R35
110 }
111 sw r_tmp, r35
112 106
113 /* Move some arguments to callee-save registers. */ 107 /* Move some arguments to callee-save registers. */
114 { 108 {
@@ -121,13 +115,6 @@ STD_ENTRY(flush_and_install_context)
121 } 115 }
122 move r_asid, r_asid_in 116 move r_asid, r_asid_in
123 117
124 /* Disable interrupts, since we can't use our stack. */
125 {
126 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
127 movei r_tmp, 1
128 }
129 mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
130
131 /* First, flush our L2 cache. */ 118 /* First, flush our L2 cache. */
132 { 119 {
133 move r0, zero /* cache_pa */ 120 move r0, zero /* cache_pa */
@@ -163,7 +150,7 @@ STD_ENTRY(flush_and_install_context)
163 } 150 }
164 { 151 {
165 move r4, r_asid 152 move r4, r_asid
166 movei r5, HV_CTX_DIRECTIO 153 moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
167 } 154 }
168 jal hv_install_context 155 jal hv_install_context
169 bnz r0, .Ldone 156 bnz r0, .Ldone
@@ -175,9 +162,6 @@ STD_ENTRY(flush_and_install_context)
175 } 162 }
176 163
177.Ldone: 164.Ldone:
178 /* Reset interrupts back how they were before. */
179 mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
180
181 /* Restore the callee-saved registers and return. */ 165 /* Restore the callee-saved registers and return. */
182 addli lr, sp, FRAME_SIZE 166 addli lr, sp, FRAME_SIZE
183 { 167 {
@@ -202,10 +186,6 @@ STD_ENTRY(flush_and_install_context)
202 } 186 }
203 { 187 {
204 lw r34, r_tmp 188 lw r34, r_tmp
205 addli r_tmp, sp, FRAME_R35
206 }
207 {
208 lw r35, r_tmp
209 addi sp, sp, FRAME_SIZE 189 addi sp, sp, FRAME_SIZE
210 } 190 }
211 jrp lr 191 jrp lr
diff --git a/arch/tile/mm/migrate_64.S b/arch/tile/mm/migrate_64.S
index e76fea688be..1d15b10833d 100644
--- a/arch/tile/mm/migrate_64.S
+++ b/arch/tile/mm/migrate_64.S
@@ -38,8 +38,7 @@
38#define FRAME_R30 16 38#define FRAME_R30 16
39#define FRAME_R31 24 39#define FRAME_R31 24
40#define FRAME_R32 32 40#define FRAME_R32 32
41#define FRAME_R33 40 41#define FRAME_SIZE 40
42#define FRAME_SIZE 48
43 42
44 43
45 44
@@ -60,10 +59,9 @@
60#define r_my_cpumask r3 59#define r_my_cpumask r3
61 60
62/* Locals (callee-save); must not be more than FRAME_xxx above. */ 61/* Locals (callee-save); must not be more than FRAME_xxx above. */
63#define r_save_ics r30 62#define r_context r30
64#define r_context r31 63#define r_access r31
65#define r_access r32 64#define r_asid r32
66#define r_asid r33
67 65
68/* 66/*
69 * Caller-save locals and frame constants are the same as 67 * Caller-save locals and frame constants are the same as
@@ -93,11 +91,7 @@ STD_ENTRY(flush_and_install_context)
93 st r_tmp, r31 91 st r_tmp, r31
94 addi r_tmp, sp, FRAME_R32 92 addi r_tmp, sp, FRAME_R32
95 } 93 }
96 { 94 st r_tmp, r32
97 st r_tmp, r32
98 addi r_tmp, sp, FRAME_R33
99 }
100 st r_tmp, r33
101 95
102 /* Move some arguments to callee-save registers. */ 96 /* Move some arguments to callee-save registers. */
103 { 97 {
@@ -106,13 +100,6 @@ STD_ENTRY(flush_and_install_context)
106 } 100 }
107 move r_asid, r_asid_in 101 move r_asid, r_asid_in
108 102
109 /* Disable interrupts, since we can't use our stack. */
110 {
111 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
112 movei r_tmp, 1
113 }
114 mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
115
116 /* First, flush our L2 cache. */ 103 /* First, flush our L2 cache. */
117 { 104 {
118 move r0, zero /* cache_pa */ 105 move r0, zero /* cache_pa */
@@ -147,7 +134,7 @@ STD_ENTRY(flush_and_install_context)
147 } 134 }
148 { 135 {
149 move r2, r_asid 136 move r2, r_asid
150 movei r3, HV_CTX_DIRECTIO 137 moveli r3, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
151 } 138 }
152 jal hv_install_context 139 jal hv_install_context
153 bnez r0, 1f 140 bnez r0, 1f
@@ -158,10 +145,7 @@ STD_ENTRY(flush_and_install_context)
158 jal hv_flush_all 145 jal hv_flush_all
159 } 146 }
160 147
1611: /* Reset interrupts back how they were before. */ 1481: /* Restore the callee-saved registers and return. */
162 mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
163
164 /* Restore the callee-saved registers and return. */
165 addli lr, sp, FRAME_SIZE 149 addli lr, sp, FRAME_SIZE
166 { 150 {
167 ld lr, lr 151 ld lr, lr
@@ -177,10 +161,6 @@ STD_ENTRY(flush_and_install_context)
177 } 161 }
178 { 162 {
179 ld r32, r_tmp 163 ld r32, r_tmp
180 addli r_tmp, sp, FRAME_R33
181 }
182 {
183 ld r33, r_tmp
184 addi sp, sp, FRAME_SIZE 164 addi sp, sp, FRAME_SIZE
185 } 165 }
186 jrp lr 166 jrp lr
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
index 2410aa899b3..345edfed9fc 100644
--- a/arch/tile/mm/pgtable.c
+++ b/arch/tile/mm/pgtable.c
@@ -132,15 +132,6 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
132 set_pte_pfn(address, phys >> PAGE_SHIFT, flags); 132 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
133} 133}
134 134
135#if defined(CONFIG_HIGHPTE)
136pte_t *_pte_offset_map(pmd_t *dir, unsigned long address)
137{
138 pte_t *pte = kmap_atomic(pmd_page(*dir)) +
139 (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
140 return &pte[pte_index(address)];
141}
142#endif
143
144/** 135/**
145 * shatter_huge_page() - ensure a given address is mapped by a small page. 136 * shatter_huge_page() - ensure a given address is mapped by a small page.
146 * 137 *
@@ -289,33 +280,26 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
289 280
290#define L2_USER_PGTABLE_PAGES (1 << L2_USER_PGTABLE_ORDER) 281#define L2_USER_PGTABLE_PAGES (1 << L2_USER_PGTABLE_ORDER)
291 282
292struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) 283struct page *pgtable_alloc_one(struct mm_struct *mm, unsigned long address,
284 int order)
293{ 285{
294 gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO; 286 gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO;
295 struct page *p; 287 struct page *p;
296#if L2_USER_PGTABLE_ORDER > 0
297 int i; 288 int i;
298#endif
299
300#ifdef CONFIG_HIGHPTE
301 flags |= __GFP_HIGHMEM;
302#endif
303 289
304 p = alloc_pages(flags, L2_USER_PGTABLE_ORDER); 290 p = alloc_pages(flags, L2_USER_PGTABLE_ORDER);
305 if (p == NULL) 291 if (p == NULL)
306 return NULL; 292 return NULL;
307 293
308#if L2_USER_PGTABLE_ORDER > 0
309 /* 294 /*
310 * Make every page have a page_count() of one, not just the first. 295 * Make every page have a page_count() of one, not just the first.
311 * We don't use __GFP_COMP since it doesn't look like it works 296 * We don't use __GFP_COMP since it doesn't look like it works
312 * correctly with tlb_remove_page(). 297 * correctly with tlb_remove_page().
313 */ 298 */
314 for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) { 299 for (i = 1; i < order; ++i) {
315 init_page_count(p+i); 300 init_page_count(p+i);
316 inc_zone_page_state(p+i, NR_PAGETABLE); 301 inc_zone_page_state(p+i, NR_PAGETABLE);
317 } 302 }
318#endif
319 303
320 pgtable_page_ctor(p); 304 pgtable_page_ctor(p);
321 return p; 305 return p;
@@ -326,28 +310,28 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
326 * process). We have to correct whatever pte_alloc_one() did before 310 * process). We have to correct whatever pte_alloc_one() did before
327 * returning the pages to the allocator. 311 * returning the pages to the allocator.
328 */ 312 */
329void pte_free(struct mm_struct *mm, struct page *p) 313void pgtable_free(struct mm_struct *mm, struct page *p, int order)
330{ 314{
331 int i; 315 int i;
332 316
333 pgtable_page_dtor(p); 317 pgtable_page_dtor(p);
334 __free_page(p); 318 __free_page(p);
335 319
336 for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) { 320 for (i = 1; i < order; ++i) {
337 __free_page(p+i); 321 __free_page(p+i);
338 dec_zone_page_state(p+i, NR_PAGETABLE); 322 dec_zone_page_state(p+i, NR_PAGETABLE);
339 } 323 }
340} 324}
341 325
342void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte, 326void __pgtable_free_tlb(struct mmu_gather *tlb, struct page *pte,
343 unsigned long address) 327 unsigned long address, int order)
344{ 328{
345 int i; 329 int i;
346 330
347 pgtable_page_dtor(pte); 331 pgtable_page_dtor(pte);
348 tlb_remove_page(tlb, pte); 332 tlb_remove_page(tlb, pte);
349 333
350 for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) { 334 for (i = 1; i < order; ++i) {
351 tlb_remove_page(tlb, pte + i); 335 tlb_remove_page(tlb, pte + i);
352 dec_zone_page_state(pte + i, NR_PAGETABLE); 336 dec_zone_page_state(pte + i, NR_PAGETABLE);
353 } 337 }
@@ -490,7 +474,7 @@ void set_pte(pte_t *ptep, pte_t pte)
490/* Can this mm load a PTE with cached_priority set? */ 474/* Can this mm load a PTE with cached_priority set? */
491static inline int mm_is_priority_cached(struct mm_struct *mm) 475static inline int mm_is_priority_cached(struct mm_struct *mm)
492{ 476{
493 return mm->context.priority_cached; 477 return mm->context.priority_cached != 0;
494} 478}
495 479
496/* 480/*
@@ -500,8 +484,8 @@ static inline int mm_is_priority_cached(struct mm_struct *mm)
500void start_mm_caching(struct mm_struct *mm) 484void start_mm_caching(struct mm_struct *mm)
501{ 485{
502 if (!mm_is_priority_cached(mm)) { 486 if (!mm_is_priority_cached(mm)) {
503 mm->context.priority_cached = -1U; 487 mm->context.priority_cached = -1UL;
504 hv_set_caching(-1U); 488 hv_set_caching(-1UL);
505 } 489 }
506} 490}
507 491
@@ -516,7 +500,7 @@ void start_mm_caching(struct mm_struct *mm)
516 * Presumably we'll come back later and have more luck and clear 500 * Presumably we'll come back later and have more luck and clear
517 * the value then; for now we'll just keep the cache marked for priority. 501 * the value then; for now we'll just keep the cache marked for priority.
518 */ 502 */
519static unsigned int update_priority_cached(struct mm_struct *mm) 503static unsigned long update_priority_cached(struct mm_struct *mm)
520{ 504{
521 if (mm->context.priority_cached && down_write_trylock(&mm->mmap_sem)) { 505 if (mm->context.priority_cached && down_write_trylock(&mm->mmap_sem)) {
522 struct vm_area_struct *vm; 506 struct vm_area_struct *vm;
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 55c0661e2b5..097091059aa 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -121,15 +121,8 @@ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
121 121
122LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt)) 122LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
123 123
124CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) 124# Used by link-vmlinux.sh which has special support for um link
125define cmd_vmlinux__ 125export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
126 $(CC) $(CFLAGS_vmlinux) -o $@ \
127 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
128 -Wl,--start-group $(vmlinux-main) -Wl,--end-group \
129 -lutil \
130 $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \
131 FORCE ,$^) ; rm -f linux
132endef
133 126
134# When cleaning we don't include .config, so we don't include 127# When cleaning we don't include .config, so we don't include
135# TT or skas makefiles and don't clean skas_ptregs.h. 128# TT or skas makefiles and don't clean skas_ptregs.h.
diff --git a/arch/um/include/asm/kvm_para.h b/arch/um/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/um/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/unicore32/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>
diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild
index 0e9dec6cadd..e5287d8517a 100644
--- a/arch/x86/Kbuild
+++ b/arch/x86/Kbuild
@@ -1,4 +1,3 @@
1
2obj-$(CONFIG_KVM) += kvm/ 1obj-$(CONFIG_KVM) += kvm/
3 2
4# Xen paravirtualization support 3# Xen paravirtualization support
@@ -7,6 +6,7 @@ obj-$(CONFIG_XEN) += xen/
7# lguest paravirtualization support 6# lguest paravirtualization support
8obj-$(CONFIG_LGUEST_GUEST) += lguest/ 7obj-$(CONFIG_LGUEST_GUEST) += lguest/
9 8
9obj-y += realmode/
10obj-y += kernel/ 10obj-y += kernel/
11obj-y += mm/ 11obj-y += mm/
12 12
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 66cc380bebf..d700811785e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -32,6 +32,7 @@ config X86
32 select ARCH_WANT_OPTIONAL_GPIOLIB 32 select ARCH_WANT_OPTIONAL_GPIOLIB
33 select ARCH_WANT_FRAME_POINTERS 33 select ARCH_WANT_FRAME_POINTERS
34 select HAVE_DMA_ATTRS 34 select HAVE_DMA_ATTRS
35 select HAVE_DMA_CONTIGUOUS if !SWIOTLB
35 select HAVE_KRETPROBES 36 select HAVE_KRETPROBES
36 select HAVE_OPTPROBES 37 select HAVE_OPTPROBES
37 select HAVE_FTRACE_MCOUNT_RECORD 38 select HAVE_FTRACE_MCOUNT_RECORD
@@ -92,6 +93,8 @@ config X86
92 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC) 93 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
93 select GENERIC_TIME_VSYSCALL if X86_64 94 select GENERIC_TIME_VSYSCALL if X86_64
94 select KTIME_SCALAR if X86_32 95 select KTIME_SCALAR if X86_32
96 select GENERIC_STRNCPY_FROM_USER
97 select GENERIC_STRNLEN_USER
95 98
96config INSTRUCTION_DECODER 99config INSTRUCTION_DECODER
97 def_bool (KPROBES || PERF_EVENTS || UPROBES) 100 def_bool (KPROBES || PERF_EVENTS || UPROBES)
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 610001d385d..0c44630d178 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -29,7 +29,7 @@
29#include <asm/processor.h> 29#include <asm/processor.h>
30#include <asm/mmu.h> 30#include <asm/mmu.h>
31#include <asm/mpspec.h> 31#include <asm/mpspec.h>
32#include <asm/trampoline.h> 32#include <asm/realmode.h>
33 33
34#define COMPILER_DEPENDENT_INT64 long long 34#define COMPILER_DEPENDENT_INT64 long long
35#define COMPILER_DEPENDENT_UINT64 unsigned long long 35#define COMPILER_DEPENDENT_UINT64 unsigned long long
@@ -117,11 +117,8 @@ static inline void acpi_disable_pci(void)
117/* Low-level suspend routine. */ 117/* Low-level suspend routine. */
118extern int acpi_suspend_lowlevel(void); 118extern int acpi_suspend_lowlevel(void);
119 119
120extern const unsigned char acpi_wakeup_code[]; 120/* Physical address to resume after wakeup */
121#define acpi_wakeup_address (__pa(TRAMPOLINE_SYM(acpi_wakeup_code))) 121#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start))
122
123/* early initialization routine */
124extern void acpi_reserve_wakeup_memory(void);
125 122
126/* 123/*
127 * Check if the CPU can handle C2 and deeper 124 * Check if the CPU can handle C2 and deeper
diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h
new file mode 100644
index 00000000000..c0924165997
--- /dev/null
+++ b/arch/x86/include/asm/dma-contiguous.h
@@ -0,0 +1,13 @@
1#ifndef ASMX86_DMA_CONTIGUOUS_H
2#define ASMX86_DMA_CONTIGUOUS_H
3
4#ifdef __KERNEL__
5
6#include <linux/types.h>
7#include <asm-generic/dma-contiguous.h>
8
9static inline void
10dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
11
12#endif
13#endif
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 61c0bd25845..f7b4c7903e7 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -13,6 +13,7 @@
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/swiotlb.h> 14#include <asm/swiotlb.h>
15#include <asm-generic/dma-coherent.h> 15#include <asm-generic/dma-coherent.h>
16#include <linux/dma-contiguous.h>
16 17
17#ifdef CONFIG_ISA 18#ifdef CONFIG_ISA
18# define ISA_DMA_BIT_MASK DMA_BIT_MASK(24) 19# define ISA_DMA_BIT_MASK DMA_BIT_MASK(24)
@@ -62,6 +63,10 @@ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
62 dma_addr_t *dma_addr, gfp_t flag, 63 dma_addr_t *dma_addr, gfp_t flag,
63 struct dma_attrs *attrs); 64 struct dma_attrs *attrs);
64 65
66extern void dma_generic_free_coherent(struct device *dev, size_t size,
67 void *vaddr, dma_addr_t dma_addr,
68 struct dma_attrs *attrs);
69
65#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */ 70#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
66extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size); 71extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
67extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr); 72extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index c222e1a1b12..1ac46c22dd5 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -200,7 +200,7 @@ typedef u32 __attribute__((vector_size(16))) sse128_t;
200 200
201/* Type, address-of, and value of an instruction's operand. */ 201/* Type, address-of, and value of an instruction's operand. */
202struct operand { 202struct operand {
203 enum { OP_REG, OP_MEM, OP_IMM, OP_XMM, OP_NONE } type; 203 enum { OP_REG, OP_MEM, OP_IMM, OP_XMM, OP_MM, OP_NONE } type;
204 unsigned int bytes; 204 unsigned int bytes;
205 union { 205 union {
206 unsigned long orig_val; 206 unsigned long orig_val;
@@ -213,12 +213,14 @@ struct operand {
213 unsigned seg; 213 unsigned seg;
214 } mem; 214 } mem;
215 unsigned xmm; 215 unsigned xmm;
216 unsigned mm;
216 } addr; 217 } addr;
217 union { 218 union {
218 unsigned long val; 219 unsigned long val;
219 u64 val64; 220 u64 val64;
220 char valptr[sizeof(unsigned long) + 2]; 221 char valptr[sizeof(unsigned long) + 2];
221 sse128_t vec_val; 222 sse128_t vec_val;
223 u64 mm_val;
222 }; 224 };
223}; 225};
224 226
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index e5b97be12d2..db7c1f2709a 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -173,6 +173,9 @@ enum {
173#define DR7_FIXED_1 0x00000400 173#define DR7_FIXED_1 0x00000400
174#define DR7_VOLATILE 0xffff23ff 174#define DR7_VOLATILE 0xffff23ff
175 175
176/* apic attention bits */
177#define KVM_APIC_CHECK_VAPIC 0
178
176/* 179/*
177 * We don't want allocation failures within the mmu code, so we preallocate 180 * We don't want allocation failures within the mmu code, so we preallocate
178 * enough memory for a single page fault in a cache. 181 * enough memory for a single page fault in a cache.
@@ -238,8 +241,6 @@ struct kvm_mmu_page {
238#endif 241#endif
239 242
240 int write_flooding_count; 243 int write_flooding_count;
241
242 struct rcu_head rcu;
243}; 244};
244 245
245struct kvm_pio_request { 246struct kvm_pio_request {
@@ -338,6 +339,7 @@ struct kvm_vcpu_arch {
338 u64 efer; 339 u64 efer;
339 u64 apic_base; 340 u64 apic_base;
340 struct kvm_lapic *apic; /* kernel irqchip context */ 341 struct kvm_lapic *apic; /* kernel irqchip context */
342 unsigned long apic_attention;
341 int32_t apic_arb_prio; 343 int32_t apic_arb_prio;
342 int mp_state; 344 int mp_state;
343 int sipi_vector; 345 int sipi_vector;
@@ -537,8 +539,6 @@ struct kvm_arch {
537 u64 hv_guest_os_id; 539 u64 hv_guest_os_id;
538 u64 hv_hypercall; 540 u64 hv_hypercall;
539 541
540 atomic_t reader_counter;
541
542 #ifdef CONFIG_KVM_MMU_AUDIT 542 #ifdef CONFIG_KVM_MMU_AUDIT
543 int audit_point; 543 int audit_point;
544 #endif 544 #endif
@@ -713,8 +713,9 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
713 713
714int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); 714int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
715void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); 715void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
716int kvm_mmu_rmap_write_protect(struct kvm *kvm, u64 gfn, 716void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
717 struct kvm_memory_slot *slot); 717 struct kvm_memory_slot *slot,
718 gfn_t gfn_offset, unsigned long mask);
718void kvm_mmu_zap_all(struct kvm *kvm); 719void kvm_mmu_zap_all(struct kvm *kvm);
719unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); 720unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
720void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); 721void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 183922e13de..63ab1661d00 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -95,6 +95,14 @@ struct kvm_vcpu_pv_apf_data {
95extern void kvmclock_init(void); 95extern void kvmclock_init(void);
96extern int kvm_register_clock(char *txt); 96extern int kvm_register_clock(char *txt);
97 97
98#ifdef CONFIG_KVM_CLOCK
99bool kvm_check_and_clear_guest_paused(void);
100#else
101static inline bool kvm_check_and_clear_guest_paused(void)
102{
103 return false;
104}
105#endif /* CONFIG_KVMCLOCK */
98 106
99/* This instruction is vmcall. On non-VT architectures, it will generate a 107/* This instruction is vmcall. On non-VT architectures, it will generate a
100 * trap that we will then rewrite to the appropriate instruction. 108 * trap that we will then rewrite to the appropriate instruction.
@@ -173,14 +181,16 @@ static inline int kvm_para_available(void)
173 if (boot_cpu_data.cpuid_level < 0) 181 if (boot_cpu_data.cpuid_level < 0)
174 return 0; /* So we don't blow up on old processors */ 182 return 0; /* So we don't blow up on old processors */
175 183
176 cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); 184 if (cpu_has_hypervisor) {
177 memcpy(signature + 0, &ebx, 4); 185 cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx);
178 memcpy(signature + 4, &ecx, 4); 186 memcpy(signature + 0, &ebx, 4);
179 memcpy(signature + 8, &edx, 4); 187 memcpy(signature + 4, &ecx, 4);
180 signature[12] = 0; 188 memcpy(signature + 8, &edx, 4);
189 signature[12] = 0;
181 190
182 if (strcmp(signature, "KVMKVMKVM") == 0) 191 if (strcmp(signature, "KVMKVMKVM") == 0)
183 return 1; 192 return 1;
193 }
184 194
185 return 0; 195 return 0;
186} 196}
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h
index effff47a3c8..43876f16caf 100644
--- a/arch/x86/include/asm/pgtable-3level.h
+++ b/arch/x86/include/asm/pgtable-3level.h
@@ -31,6 +31,56 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte)
31 ptep->pte_low = pte.pte_low; 31 ptep->pte_low = pte.pte_low;
32} 32}
33 33
34#define pmd_read_atomic pmd_read_atomic
35/*
36 * pte_offset_map_lock on 32bit PAE kernels was reading the pmd_t with
37 * a "*pmdp" dereference done by gcc. Problem is, in certain places
38 * where pte_offset_map_lock is called, concurrent page faults are
39 * allowed, if the mmap_sem is hold for reading. An example is mincore
40 * vs page faults vs MADV_DONTNEED. On the page fault side
41 * pmd_populate rightfully does a set_64bit, but if we're reading the
42 * pmd_t with a "*pmdp" on the mincore side, a SMP race can happen
43 * because gcc will not read the 64bit of the pmd atomically. To fix
44 * this all places running pmd_offset_map_lock() while holding the
45 * mmap_sem in read mode, shall read the pmdp pointer using this
46 * function to know if the pmd is null nor not, and in turn to know if
47 * they can run pmd_offset_map_lock or pmd_trans_huge or other pmd
48 * operations.
49 *
50 * Without THP if the mmap_sem is hold for reading, the
51 * pmd can only transition from null to not null while pmd_read_atomic runs.
52 * So there's no need of literally reading it atomically.
53 *
54 * With THP if the mmap_sem is hold for reading, the pmd can become
55 * THP or null or point to a pte (and in turn become "stable") at any
56 * time under pmd_read_atomic, so it's mandatory to read it atomically
57 * with cmpxchg8b.
58 */
59#ifndef CONFIG_TRANSPARENT_HUGEPAGE
60static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
61{
62 pmdval_t ret;
63 u32 *tmp = (u32 *)pmdp;
64
65 ret = (pmdval_t) (*tmp);
66 if (ret) {
67 /*
68 * If the low part is null, we must not read the high part
69 * or we can end up with a partial pmd.
70 */
71 smp_rmb();
72 ret |= ((pmdval_t)*(tmp + 1)) << 32;
73 }
74
75 return (pmd_t) { ret };
76}
77#else /* CONFIG_TRANSPARENT_HUGEPAGE */
78static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
79{
80 return (pmd_t) { atomic64_read((atomic64_t *)pmdp) };
81}
82#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
83
34static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) 84static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
35{ 85{
36 set_64bit((unsigned long long *)(ptep), native_pte_val(pte)); 86 set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 7745b257f03..39bc5777211 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -544,13 +544,16 @@ static inline void load_sp0(struct tss_struct *tss,
544 * enable), so that any CPU's that boot up 544 * enable), so that any CPU's that boot up
545 * after us can get the correct flags. 545 * after us can get the correct flags.
546 */ 546 */
547extern unsigned long mmu_cr4_features; 547extern unsigned long mmu_cr4_features;
548extern u32 *trampoline_cr4_features;
548 549
549static inline void set_in_cr4(unsigned long mask) 550static inline void set_in_cr4(unsigned long mask)
550{ 551{
551 unsigned long cr4; 552 unsigned long cr4;
552 553
553 mmu_cr4_features |= mask; 554 mmu_cr4_features |= mask;
555 if (trampoline_cr4_features)
556 *trampoline_cr4_features = mmu_cr4_features;
554 cr4 = read_cr4(); 557 cr4 = read_cr4();
555 cr4 |= mask; 558 cr4 |= mask;
556 write_cr4(cr4); 559 write_cr4(cr4);
@@ -561,6 +564,8 @@ static inline void clear_in_cr4(unsigned long mask)
561 unsigned long cr4; 564 unsigned long cr4;
562 565
563 mmu_cr4_features &= ~mask; 566 mmu_cr4_features &= ~mask;
567 if (trampoline_cr4_features)
568 *trampoline_cr4_features = mmu_cr4_features;
564 cr4 = read_cr4(); 569 cr4 = read_cr4();
565 cr4 &= ~mask; 570 cr4 &= ~mask;
566 write_cr4(cr4); 571 write_cr4(cr4);
diff --git a/arch/x86/include/asm/pvclock-abi.h b/arch/x86/include/asm/pvclock-abi.h
index 35f2d1948ad..6167fd79818 100644
--- a/arch/x86/include/asm/pvclock-abi.h
+++ b/arch/x86/include/asm/pvclock-abi.h
@@ -40,5 +40,6 @@ struct pvclock_wall_clock {
40} __attribute__((__packed__)); 40} __attribute__((__packed__));
41 41
42#define PVCLOCK_TSC_STABLE_BIT (1 << 0) 42#define PVCLOCK_TSC_STABLE_BIT (1 << 0)
43#define PVCLOCK_GUEST_STOPPED (1 << 1)
43#endif /* __ASSEMBLY__ */ 44#endif /* __ASSEMBLY__ */
44#endif /* _ASM_X86_PVCLOCK_ABI_H */ 45#endif /* _ASM_X86_PVCLOCK_ABI_H */
diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
new file mode 100644
index 00000000000..fce3f4ae5bd
--- /dev/null
+++ b/arch/x86/include/asm/realmode.h
@@ -0,0 +1,62 @@
1#ifndef _ARCH_X86_REALMODE_H
2#define _ARCH_X86_REALMODE_H
3
4#include <linux/types.h>
5#include <asm/io.h>
6
7/* This must match data at realmode.S */
8struct real_mode_header {
9 u32 text_start;
10 u32 ro_end;
11 /* SMP trampoline */
12 u32 trampoline_start;
13 u32 trampoline_status;
14 u32 trampoline_header;
15#ifdef CONFIG_X86_64
16 u32 trampoline_pgd;
17#endif
18 /* ACPI S3 wakeup */
19#ifdef CONFIG_ACPI_SLEEP
20 u32 wakeup_start;
21 u32 wakeup_header;
22#endif
23 /* APM/BIOS reboot */
24#ifdef CONFIG_X86_32
25 u32 machine_real_restart_asm;
26#endif
27};
28
29/* This must match data at trampoline_32/64.S */
30struct trampoline_header {
31#ifdef CONFIG_X86_32
32 u32 start;
33 u16 gdt_pad;
34 u16 gdt_limit;
35 u32 gdt_base;
36#else
37 u64 start;
38 u64 efer;
39 u32 cr4;
40#endif
41};
42
43extern struct real_mode_header *real_mode_header;
44extern unsigned char real_mode_blob_end[];
45
46extern unsigned long init_rsp;
47extern unsigned long initial_code;
48extern unsigned long initial_gs;
49
50extern unsigned char real_mode_blob[];
51extern unsigned char real_mode_relocs[];
52
53#ifdef CONFIG_X86_32
54extern unsigned char startup_32_smp[];
55extern unsigned char boot_gdt[];
56#else
57extern unsigned char secondary_startup_64[];
58#endif
59
60extern void __init setup_real_mode(void);
61
62#endif /* _ARCH_X86_REALMODE_H */
diff --git a/arch/x86/include/asm/sta2x11.h b/arch/x86/include/asm/sta2x11.h
new file mode 100644
index 00000000000..e9d32df89cc
--- /dev/null
+++ b/arch/x86/include/asm/sta2x11.h
@@ -0,0 +1,12 @@
1/*
2 * Header file for STMicroelectronics ConneXt (STA2X11) IOHub
3 */
4#ifndef __ASM_STA2X11_H
5#define __ASM_STA2X11_H
6
7#include <linux/pci.h>
8
9/* This needs to be called from the MFD to configure its sub-devices */
10struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev);
11
12#endif /* __ASM_STA2X11_H */
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h
deleted file mode 100644
index feca3118a73..00000000000
--- a/arch/x86/include/asm/trampoline.h
+++ /dev/null
@@ -1,39 +0,0 @@
1#ifndef _ASM_X86_TRAMPOLINE_H
2#define _ASM_X86_TRAMPOLINE_H
3
4#ifndef __ASSEMBLY__
5
6#include <linux/types.h>
7#include <asm/io.h>
8
9/*
10 * Trampoline 80x86 program as an array. These are in the init rodata
11 * segment, but that's okay, because we only care about the relative
12 * addresses of the symbols.
13 */
14extern const unsigned char x86_trampoline_start [];
15extern const unsigned char x86_trampoline_end [];
16extern unsigned char *x86_trampoline_base;
17
18extern unsigned long init_rsp;
19extern unsigned long initial_code;
20extern unsigned long initial_gs;
21
22extern void __init setup_trampolines(void);
23
24extern const unsigned char trampoline_data[];
25extern const unsigned char trampoline_status[];
26
27#define TRAMPOLINE_SYM(x) \
28 ((void *)(x86_trampoline_base + \
29 ((const unsigned char *)(x) - x86_trampoline_start)))
30
31/* Address of the SMP trampoline */
32static inline unsigned long trampoline_address(void)
33{
34 return virt_to_phys(TRAMPOLINE_SYM(trampoline_data));
35}
36
37#endif /* __ASSEMBLY__ */
38
39#endif /* _ASM_X86_TRAMPOLINE_H */
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 851fe0dc13b..04cd6882308 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -32,6 +32,7 @@
32 32
33#define segment_eq(a, b) ((a).seg == (b).seg) 33#define segment_eq(a, b) ((a).seg == (b).seg)
34 34
35#define user_addr_max() (current_thread_info()->addr_limit.seg)
35#define __addr_ok(addr) \ 36#define __addr_ok(addr) \
36 ((unsigned long __force)(addr) < \ 37 ((unsigned long __force)(addr) < \
37 (current_thread_info()->addr_limit.seg)) 38 (current_thread_info()->addr_limit.seg))
@@ -565,6 +566,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
565extern __must_check long 566extern __must_check long
566strncpy_from_user(char *dst, const char __user *src, long count); 567strncpy_from_user(char *dst, const char __user *src, long count);
567 568
569extern __must_check long strlen_user(const char __user *str);
570extern __must_check long strnlen_user(const char __user *str, long n);
571
568/* 572/*
569 * movsl can be slow when source and dest are not both 8-byte aligned 573 * movsl can be slow when source and dest are not both 8-byte aligned
570 */ 574 */
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 8084bc73b18..576e39bca6a 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -213,23 +213,6 @@ static inline unsigned long __must_check copy_from_user(void *to,
213 return n; 213 return n;
214} 214}
215 215
216/**
217 * strlen_user: - Get the size of a string in user space.
218 * @str: The string to measure.
219 *
220 * Context: User context only. This function may sleep.
221 *
222 * Get the size of a NUL-terminated string in user space.
223 *
224 * Returns the size of the string INCLUDING the terminating NUL.
225 * On exception, returns 0.
226 *
227 * If there is a limit on the length of a valid string, you may wish to
228 * consider using strnlen_user() instead.
229 */
230#define strlen_user(str) strnlen_user(str, LONG_MAX)
231
232long strnlen_user(const char __user *str, long n);
233unsigned long __must_check clear_user(void __user *mem, unsigned long len); 216unsigned long __must_check clear_user(void __user *mem, unsigned long len);
234unsigned long __must_check __clear_user(void __user *mem, unsigned long len); 217unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
235 218
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index fcd4b6f3ef0..8e796fbbf9c 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -208,9 +208,6 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
208 } 208 }
209} 209}
210 210
211__must_check long strnlen_user(const char __user *str, long n);
212__must_check long __strnlen_user(const char __user *str, long n);
213__must_check long strlen_user(const char __user *str);
214__must_check unsigned long clear_user(void __user *mem, unsigned long len); 211__must_check unsigned long clear_user(void __user *mem, unsigned long len);
215__must_check unsigned long __clear_user(void __user *mem, unsigned long len); 212__must_check unsigned long __clear_user(void __user *mem, unsigned long len);
216 213
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index ae03facfadd..5b238981542 100644
--- a/arch/x86/include/asm/word-at-a-time.h
+++ b/arch/x86/include/asm/word-at-a-time.h
@@ -10,6 +10,11 @@
10 * bit count instruction, that might be better than the multiply 10 * bit count instruction, that might be better than the multiply
11 * and shift, for example. 11 * and shift, for example.
12 */ 12 */
13struct word_at_a_time {
14 const unsigned long one_bits, high_bits;
15};
16
17#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
13 18
14#ifdef CONFIG_64BIT 19#ifdef CONFIG_64BIT
15 20
@@ -37,10 +42,31 @@ static inline long count_masked_bytes(long mask)
37 42
38#endif 43#endif
39 44
40/* Return the high bit set in the first byte that is a zero */ 45/* Return nonzero if it has a zero */
41static inline unsigned long has_zero(unsigned long a) 46static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
47{
48 unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
49 *bits = mask;
50 return mask;
51}
52
53static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
54{
55 return bits;
56}
57
58static inline unsigned long create_zero_mask(unsigned long bits)
59{
60 bits = (bits - 1) & ~bits;
61 return bits >> 7;
62}
63
64/* The mask we created is directly usable as a bytemask */
65#define zero_bytemask(mask) (mask)
66
67static inline unsigned long find_zero(unsigned long mask)
42{ 68{
43 return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); 69 return count_masked_bytes(mask);
44} 70}
45 71
46/* 72/*
diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h
index 1df35417c41..cc146d51449 100644
--- a/arch/x86/include/asm/xen/events.h
+++ b/arch/x86/include/asm/xen/events.h
@@ -6,6 +6,7 @@ enum ipi_vector {
6 XEN_CALL_FUNCTION_VECTOR, 6 XEN_CALL_FUNCTION_VECTOR,
7 XEN_CALL_FUNCTION_SINGLE_VECTOR, 7 XEN_CALL_FUNCTION_SINGLE_VECTOR,
8 XEN_SPIN_UNLOCK_VECTOR, 8 XEN_SPIN_UNLOCK_VECTOR,
9 XEN_IRQ_WORK_VECTOR,
9 10
10 XEN_NR_IPIS, 11 XEN_NR_IPIS,
11}; 12};
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index c34f96c2f7a..93971e841dd 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -44,6 +44,7 @@ extern unsigned long machine_to_phys_nr;
44 44
45extern unsigned long get_phys_to_machine(unsigned long pfn); 45extern unsigned long get_phys_to_machine(unsigned long pfn);
46extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); 46extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
47extern bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn);
47extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 48extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
48extern unsigned long set_phys_range_identity(unsigned long pfn_s, 49extern unsigned long set_phys_range_identity(unsigned long pfn_s,
49 unsigned long pfn_e); 50 unsigned long pfn_e);
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 9bba5b79902..8215e5652d9 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -35,7 +35,6 @@ obj-y += tsc.o io_delay.o rtc.o
35obj-y += pci-iommu_table.o 35obj-y += pci-iommu_table.o
36obj-y += resource.o 36obj-y += resource.o
37 37
38obj-y += trampoline.o trampoline_$(BITS).o
39obj-y += process.o 38obj-y += process.o
40obj-y += i387.o xsave.o 39obj-y += i387.o xsave.o
41obj-y += ptrace.o 40obj-y += ptrace.o
@@ -48,7 +47,6 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o
48obj-y += cpu/ 47obj-y += cpu/
49obj-y += acpi/ 48obj-y += acpi/
50obj-y += reboot.o 49obj-y += reboot.o
51obj-$(CONFIG_X86_32) += reboot_32.o
52obj-$(CONFIG_X86_MSR) += msr.o 50obj-$(CONFIG_X86_MSR) += msr.o
53obj-$(CONFIG_X86_CPUID) += cpuid.o 51obj-$(CONFIG_X86_CPUID) += cpuid.o
54obj-$(CONFIG_PCI) += early-quirks.o 52obj-$(CONFIG_PCI) += early-quirks.o
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
index 6f35260bb3e..163b2258147 100644
--- a/arch/x86/kernel/acpi/Makefile
+++ b/arch/x86/kernel/acpi/Makefile
@@ -1,14 +1,7 @@
1subdir- := realmode
2
3obj-$(CONFIG_ACPI) += boot.o 1obj-$(CONFIG_ACPI) += boot.o
4obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_rm.o wakeup_$(BITS).o 2obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
5 3
6ifneq ($(CONFIG_ACPI_PROCESSOR),) 4ifneq ($(CONFIG_ACPI_PROCESSOR),)
7obj-y += cstate.o 5obj-y += cstate.o
8endif 6endif
9 7
10$(obj)/wakeup_rm.o: $(obj)/realmode/wakeup.bin
11
12$(obj)/realmode/wakeup.bin: FORCE
13 $(Q)$(MAKE) $(build)=$(obj)/realmode
14
diff --git a/arch/x86/kernel/acpi/realmode/.gitignore b/arch/x86/kernel/acpi/realmode/.gitignore
deleted file mode 100644
index 58f1f48a58f..00000000000
--- a/arch/x86/kernel/acpi/realmode/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
1wakeup.bin
2wakeup.elf
3wakeup.lds
diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile
deleted file mode 100644
index 6a564ac67ef..00000000000
--- a/arch/x86/kernel/acpi/realmode/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
1#
2# arch/x86/kernel/acpi/realmode/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8
9always := wakeup.bin
10targets := wakeup.elf wakeup.lds
11
12wakeup-y += wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o
13
14# The link order of the video-*.o modules can matter. In particular,
15# video-vga.o *must* be listed first, followed by video-vesa.o.
16# Hardware-specific drivers should follow in the order they should be
17# probed, and video-bios.o should typically be last.
18wakeup-y += video-vga.o
19wakeup-y += video-vesa.o
20wakeup-y += video-bios.o
21
22targets += $(wakeup-y)
23
24bootsrc := $(src)/../../../boot
25
26# ---------------------------------------------------------------------------
27
28# How to compile the 16-bit code. Note we always compile for -march=i386,
29# that way we can complain to the user if the CPU is insufficient.
30# Compile with _SETUP since this is similar to the boot-time setup code.
31KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \
32 -I$(srctree)/$(bootsrc) \
33 $(cflags-y) \
34 -Wall -Wstrict-prototypes \
35 -march=i386 -mregparm=3 \
36 -include $(srctree)/$(bootsrc)/code16gcc.h \
37 -fno-strict-aliasing -fomit-frame-pointer \
38 $(call cc-option, -ffreestanding) \
39 $(call cc-option, -fno-toplevel-reorder,\
40 $(call cc-option, -fno-unit-at-a-time)) \
41 $(call cc-option, -fno-stack-protector) \
42 $(call cc-option, -mpreferred-stack-boundary=2)
43KBUILD_CFLAGS += $(call cc-option, -m32)
44KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
45GCOV_PROFILE := n
46
47WAKEUP_OBJS = $(addprefix $(obj)/,$(wakeup-y))
48
49LDFLAGS_wakeup.elf := -T
50
51CPPFLAGS_wakeup.lds += -P -C
52
53$(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE
54 $(call if_changed,ld)
55
56OBJCOPYFLAGS_wakeup.bin := -O binary
57
58$(obj)/wakeup.bin: $(obj)/wakeup.elf FORCE
59 $(call if_changed,objcopy)
diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S
deleted file mode 100644
index f51eb0bb56c..00000000000
--- a/arch/x86/kernel/acpi/realmode/bioscall.S
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/bioscall.S"
diff --git a/arch/x86/kernel/acpi/realmode/copy.S b/arch/x86/kernel/acpi/realmode/copy.S
deleted file mode 100644
index dc59ebee69d..00000000000
--- a/arch/x86/kernel/acpi/realmode/copy.S
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/copy.S"
diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c
deleted file mode 100644
index 6206033ba20..00000000000
--- a/arch/x86/kernel/acpi/realmode/regs.c
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/regs.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-bios.c b/arch/x86/kernel/acpi/realmode/video-bios.c
deleted file mode 100644
index 7deabc144a2..00000000000
--- a/arch/x86/kernel/acpi/realmode/video-bios.c
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/video-bios.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-mode.c b/arch/x86/kernel/acpi/realmode/video-mode.c
deleted file mode 100644
index 328ad209f11..00000000000
--- a/arch/x86/kernel/acpi/realmode/video-mode.c
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/video-mode.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-vesa.c b/arch/x86/kernel/acpi/realmode/video-vesa.c
deleted file mode 100644
index 9dbb9672226..00000000000
--- a/arch/x86/kernel/acpi/realmode/video-vesa.c
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/video-vesa.c"
diff --git a/arch/x86/kernel/acpi/realmode/video-vga.c b/arch/x86/kernel/acpi/realmode/video-vga.c
deleted file mode 100644
index bcc81255f37..00000000000
--- a/arch/x86/kernel/acpi/realmode/video-vga.c
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../boot/video-vga.c"
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S
deleted file mode 100644
index d4f8010a5b1..00000000000
--- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * wakeup.ld
3 *
4 * Linker script for the real-mode wakeup code
5 */
6#undef i386
7#include "wakeup.h"
8
9OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10OUTPUT_ARCH(i386)
11ENTRY(_start)
12
13SECTIONS
14{
15 . = 0;
16 .jump : {
17 *(.jump)
18 } = 0x90909090
19
20 . = WAKEUP_HEADER_OFFSET;
21 .header : {
22 *(.header)
23 }
24
25 . = ALIGN(16);
26 .text : {
27 *(.text*)
28 } = 0x90909090
29
30 . = ALIGN(16);
31 .rodata : {
32 *(.rodata*)
33 }
34
35 .videocards : {
36 video_cards = .;
37 *(.videocards)
38 video_cards_end = .;
39 }
40
41 . = ALIGN(16);
42 .data : {
43 *(.data*)
44 }
45
46 . = ALIGN(16);
47 .bss : {
48 __bss_start = .;
49 *(.bss)
50 __bss_end = .;
51 }
52
53 .signature : {
54 *(.signature)
55 }
56
57 _end = .;
58
59 /DISCARD/ : {
60 *(.note*)
61 }
62}
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 146a49c763a..95bf99de905 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -14,8 +14,9 @@
14#include <asm/desc.h> 14#include <asm/desc.h>
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/cacheflush.h> 16#include <asm/cacheflush.h>
17#include <asm/realmode.h>
17 18
18#include "realmode/wakeup.h" 19#include "../../realmode/rm/wakeup.h"
19#include "sleep.h" 20#include "sleep.h"
20 21
21unsigned long acpi_realmode_flags; 22unsigned long acpi_realmode_flags;
@@ -36,13 +37,9 @@ asmlinkage void acpi_enter_s3(void)
36 */ 37 */
37int acpi_suspend_lowlevel(void) 38int acpi_suspend_lowlevel(void)
38{ 39{
39 struct wakeup_header *header; 40 struct wakeup_header *header =
40 /* address in low memory of the wakeup routine. */ 41 (struct wakeup_header *) __va(real_mode_header->wakeup_header);
41 char *acpi_realmode;
42 42
43 acpi_realmode = TRAMPOLINE_SYM(acpi_wakeup_code);
44
45 header = (struct wakeup_header *)(acpi_realmode + WAKEUP_HEADER_OFFSET);
46 if (header->signature != WAKEUP_HEADER_SIGNATURE) { 43 if (header->signature != WAKEUP_HEADER_SIGNATURE) {
47 printk(KERN_ERR "wakeup header does not match\n"); 44 printk(KERN_ERR "wakeup header does not match\n");
48 return -EINVAL; 45 return -EINVAL;
@@ -50,27 +47,6 @@ int acpi_suspend_lowlevel(void)
50 47
51 header->video_mode = saved_video_mode; 48 header->video_mode = saved_video_mode;
52 49
53 header->wakeup_jmp_seg = acpi_wakeup_address >> 4;
54
55 /*
56 * Set up the wakeup GDT. We set these up as Big Real Mode,
57 * that is, with limits set to 4 GB. At least the Lenovo
58 * Thinkpad X61 is known to need this for the video BIOS
59 * initialization quirk to work; this is likely to also
60 * be the case for other laptops or integrated video devices.
61 */
62
63 /* GDT[0]: GDT self-pointer */
64 header->wakeup_gdt[0] =
65 (u64)(sizeof(header->wakeup_gdt) - 1) +
66 ((u64)__pa(&header->wakeup_gdt) << 16);
67 /* GDT[1]: big real mode-like code segment */
68 header->wakeup_gdt[1] =
69 GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff);
70 /* GDT[2]: big real mode-like data segment */
71 header->wakeup_gdt[2] =
72 GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff);
73
74#ifndef CONFIG_64BIT 50#ifndef CONFIG_64BIT
75 store_gdt((struct desc_ptr *)&header->pmode_gdt); 51 store_gdt((struct desc_ptr *)&header->pmode_gdt);
76 52
@@ -95,7 +71,6 @@ int acpi_suspend_lowlevel(void)
95 header->pmode_cr3 = (u32)__pa(&initial_page_table); 71 header->pmode_cr3 = (u32)__pa(&initial_page_table);
96 saved_magic = 0x12345678; 72 saved_magic = 0x12345678;
97#else /* CONFIG_64BIT */ 73#else /* CONFIG_64BIT */
98 header->trampoline_segment = trampoline_address() >> 4;
99#ifdef CONFIG_SMP 74#ifdef CONFIG_SMP
100 stack_start = (unsigned long)temp_stack + sizeof(temp_stack); 75 stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
101 early_gdt_descr.address = 76 early_gdt_descr.address =
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h
index d68677a2a01..5653a5791ec 100644
--- a/arch/x86/kernel/acpi/sleep.h
+++ b/arch/x86/kernel/acpi/sleep.h
@@ -2,8 +2,8 @@
2 * Variables and functions used by the code in sleep.c 2 * Variables and functions used by the code in sleep.c
3 */ 3 */
4 4
5#include <asm/trampoline.h>
6#include <linux/linkage.h> 5#include <linux/linkage.h>
6#include <asm/realmode.h>
7 7
8extern unsigned long saved_video_mode; 8extern unsigned long saved_video_mode;
9extern long saved_magic; 9extern long saved_magic;
diff --git a/arch/x86/kernel/acpi/wakeup_rm.S b/arch/x86/kernel/acpi/wakeup_rm.S
deleted file mode 100644
index 63b8ab524f2..00000000000
--- a/arch/x86/kernel/acpi/wakeup_rm.S
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * Wrapper script for the realmode binary as a transport object
3 * before copying to low memory.
4 */
5#include <asm/page_types.h>
6
7 .section ".x86_trampoline","a"
8 .balign PAGE_SIZE
9 .globl acpi_wakeup_code
10acpi_wakeup_code:
11 .incbin "arch/x86/kernel/acpi/realmode/wakeup.bin"
12 .size acpi_wakeup_code, .-acpi_wakeup_code
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c
index 507ea58688e..cd8b166a173 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-apei.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c
@@ -42,7 +42,8 @@ void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err)
42 struct mce m; 42 struct mce m;
43 43
44 /* Only corrected MC is reported */ 44 /* Only corrected MC is reported */
45 if (!corrected) 45 if (!corrected || !(mem_err->validation_bits &
46 CPER_MEM_VALID_PHYSICAL_ADDRESS))
46 return; 47 return;
47 48
48 mce_setup(&m); 49 mce_setup(&m);
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 0c82091b165..413c2ced887 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -126,6 +126,16 @@ static struct severity {
126 SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA), 126 SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
127 USER 127 USER
128 ), 128 ),
129 MCESEV(
130 KEEP, "HT thread notices Action required: instruction fetch error",
131 SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
132 MCGMASK(MCG_STATUS_EIPV, 0)
133 ),
134 MCESEV(
135 AR, "Action required: instruction fetch error",
136 SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
137 USER
138 ),
129#endif 139#endif
130 MCESEV( 140 MCESEV(
131 PANIC, "Action required: unknown MCACOD", 141 PANIC, "Action required: unknown MCACOD",
@@ -165,15 +175,19 @@ static struct severity {
165}; 175};
166 176
167/* 177/*
168 * If the EIPV bit is set, it means the saved IP is the 178 * If mcgstatus indicated that ip/cs on the stack were
169 * instruction which caused the MCE. 179 * no good, then "m->cs" will be zero and we will have
180 * to assume the worst case (IN_KERNEL) as we actually
181 * have no idea what we were executing when the machine
182 * check hit.
183 * If we do have a good "m->cs" (or a faked one in the
184 * case we were executing in VM86 mode) we can use it to
185 * distinguish an exception taken in user from from one
186 * taken in the kernel.
170 */ 187 */
171static int error_context(struct mce *m) 188static int error_context(struct mce *m)
172{ 189{
173 if (m->mcgstatus & MCG_STATUS_EIPV) 190 return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
174 return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
175 /* Unknown, assume kernel */
176 return IN_KERNEL;
177} 191}
178 192
179int mce_severity(struct mce *m, int tolerant, char **msg) 193int mce_severity(struct mce *m, int tolerant, char **msg)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index aaa056f3169..b4180f425fb 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -437,6 +437,14 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs)
437 if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) { 437 if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) {
438 m->ip = regs->ip; 438 m->ip = regs->ip;
439 m->cs = regs->cs; 439 m->cs = regs->cs;
440
441 /*
442 * When in VM86 mode make the cs look like ring 3
443 * always. This is a lie, but it's better than passing
444 * the additional vm86 bit around everywhere.
445 */
446 if (v8086_mode(regs))
447 m->cs |= 3;
440 } 448 }
441 /* Use accurate RIP reporting if available. */ 449 /* Use accurate RIP reporting if available. */
442 if (rip_msr) 450 if (rip_msr)
@@ -641,16 +649,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
641 * Do a quick check if any of the events requires a panic. 649 * Do a quick check if any of the events requires a panic.
642 * This decides if we keep the events around or clear them. 650 * This decides if we keep the events around or clear them.
643 */ 651 */
644static int mce_no_way_out(struct mce *m, char **msg) 652static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp)
645{ 653{
646 int i; 654 int i, ret = 0;
647 655
648 for (i = 0; i < banks; i++) { 656 for (i = 0; i < banks; i++) {
649 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); 657 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
658 if (m->status & MCI_STATUS_VAL)
659 __set_bit(i, validp);
650 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) 660 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
651 return 1; 661 ret = 1;
652 } 662 }
653 return 0; 663 return ret;
654} 664}
655 665
656/* 666/*
@@ -1013,6 +1023,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1013 */ 1023 */
1014 int kill_it = 0; 1024 int kill_it = 0;
1015 DECLARE_BITMAP(toclear, MAX_NR_BANKS); 1025 DECLARE_BITMAP(toclear, MAX_NR_BANKS);
1026 DECLARE_BITMAP(valid_banks, MAX_NR_BANKS);
1016 char *msg = "Unknown"; 1027 char *msg = "Unknown";
1017 1028
1018 atomic_inc(&mce_entry); 1029 atomic_inc(&mce_entry);
@@ -1027,7 +1038,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1027 final = &__get_cpu_var(mces_seen); 1038 final = &__get_cpu_var(mces_seen);
1028 *final = m; 1039 *final = m;
1029 1040
1030 no_way_out = mce_no_way_out(&m, &msg); 1041 memset(valid_banks, 0, sizeof(valid_banks));
1042 no_way_out = mce_no_way_out(&m, &msg, valid_banks);
1031 1043
1032 barrier(); 1044 barrier();
1033 1045
@@ -1047,6 +1059,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1047 order = mce_start(&no_way_out); 1059 order = mce_start(&no_way_out);
1048 for (i = 0; i < banks; i++) { 1060 for (i = 0; i < banks; i++) {
1049 __clear_bit(i, toclear); 1061 __clear_bit(i, toclear);
1062 if (!test_bit(i, valid_banks))
1063 continue;
1050 if (!mce_banks[i].ctl) 1064 if (!mce_banks[i].ctl)
1051 continue; 1065 continue;
1052 1066
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 62d61e9976e..41857970517 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -113,7 +113,9 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
113 int x = e820x->nr_map; 113 int x = e820x->nr_map;
114 114
115 if (x >= ARRAY_SIZE(e820x->map)) { 115 if (x >= ARRAY_SIZE(e820x->map)) {
116 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); 116 printk(KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n",
117 (unsigned long long) start,
118 (unsigned long long) (start + size - 1));
117 return; 119 return;
118 } 120 }
119 121
@@ -133,19 +135,19 @@ static void __init e820_print_type(u32 type)
133 switch (type) { 135 switch (type) {
134 case E820_RAM: 136 case E820_RAM:
135 case E820_RESERVED_KERN: 137 case E820_RESERVED_KERN:
136 printk(KERN_CONT "(usable)"); 138 printk(KERN_CONT "usable");
137 break; 139 break;
138 case E820_RESERVED: 140 case E820_RESERVED:
139 printk(KERN_CONT "(reserved)"); 141 printk(KERN_CONT "reserved");
140 break; 142 break;
141 case E820_ACPI: 143 case E820_ACPI:
142 printk(KERN_CONT "(ACPI data)"); 144 printk(KERN_CONT "ACPI data");
143 break; 145 break;
144 case E820_NVS: 146 case E820_NVS:
145 printk(KERN_CONT "(ACPI NVS)"); 147 printk(KERN_CONT "ACPI NVS");
146 break; 148 break;
147 case E820_UNUSABLE: 149 case E820_UNUSABLE:
148 printk(KERN_CONT "(unusable)"); 150 printk(KERN_CONT "unusable");
149 break; 151 break;
150 default: 152 default:
151 printk(KERN_CONT "type %u", type); 153 printk(KERN_CONT "type %u", type);
@@ -158,10 +160,10 @@ void __init e820_print_map(char *who)
158 int i; 160 int i;
159 161
160 for (i = 0; i < e820.nr_map; i++) { 162 for (i = 0; i < e820.nr_map; i++) {
161 printk(KERN_INFO " %s: %016Lx - %016Lx ", who, 163 printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
162 (unsigned long long) e820.map[i].addr, 164 (unsigned long long) e820.map[i].addr,
163 (unsigned long long) 165 (unsigned long long)
164 (e820.map[i].addr + e820.map[i].size)); 166 (e820.map[i].addr + e820.map[i].size - 1));
165 e820_print_type(e820.map[i].type); 167 e820_print_type(e820.map[i].type);
166 printk(KERN_CONT "\n"); 168 printk(KERN_CONT "\n");
167 } 169 }
@@ -428,9 +430,8 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
428 size = ULLONG_MAX - start; 430 size = ULLONG_MAX - start;
429 431
430 end = start + size; 432 end = start + size;
431 printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ", 433 printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ",
432 (unsigned long long) start, 434 (unsigned long long) start, (unsigned long long) (end - 1));
433 (unsigned long long) end);
434 e820_print_type(old_type); 435 e820_print_type(old_type);
435 printk(KERN_CONT " ==> "); 436 printk(KERN_CONT " ==> ");
436 e820_print_type(new_type); 437 e820_print_type(new_type);
@@ -509,9 +510,8 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
509 size = ULLONG_MAX - start; 510 size = ULLONG_MAX - start;
510 511
511 end = start + size; 512 end = start + size;
512 printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ", 513 printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ",
513 (unsigned long long) start, 514 (unsigned long long) start, (unsigned long long) (end - 1));
514 (unsigned long long) end);
515 if (checktype) 515 if (checktype)
516 e820_print_type(old_type); 516 e820_print_type(old_type);
517 printk(KERN_CONT "\n"); 517 printk(KERN_CONT "\n");
@@ -567,7 +567,7 @@ void __init update_e820(void)
567 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map)) 567 if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
568 return; 568 return;
569 e820.nr_map = nr_map; 569 e820.nr_map = nr_map;
570 printk(KERN_INFO "modified physical RAM map:\n"); 570 printk(KERN_INFO "e820: modified physical RAM map:\n");
571 e820_print_map("modified"); 571 e820_print_map("modified");
572} 572}
573static void __init update_e820_saved(void) 573static void __init update_e820_saved(void)
@@ -637,8 +637,8 @@ __init void e820_setup_gap(void)
637 if (!found) { 637 if (!found) {
638 gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024; 638 gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
639 printk(KERN_ERR 639 printk(KERN_ERR
640 "PCI: Warning: Cannot find a gap in the 32bit address range\n" 640 "e820: cannot find a gap in the 32bit address range\n"
641 "PCI: Unassigned devices with 32bit resource registers may break!\n"); 641 "e820: PCI devices with unassigned 32bit BARs may break!\n");
642 } 642 }
643#endif 643#endif
644 644
@@ -648,8 +648,8 @@ __init void e820_setup_gap(void)
648 pci_mem_start = gapstart; 648 pci_mem_start = gapstart;
649 649
650 printk(KERN_INFO 650 printk(KERN_INFO
651 "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", 651 "e820: [mem %#010lx-%#010lx] available for PCI devices\n",
652 pci_mem_start, gapstart, gapsize); 652 gapstart, gapstart + gapsize - 1);
653} 653}
654 654
655/** 655/**
@@ -667,7 +667,7 @@ void __init parse_e820_ext(struct setup_data *sdata)
667 extmap = (struct e820entry *)(sdata->data); 667 extmap = (struct e820entry *)(sdata->data);
668 __append_e820_map(extmap, entries); 668 __append_e820_map(extmap, entries);
669 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); 669 sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
670 printk(KERN_INFO "extended physical RAM map:\n"); 670 printk(KERN_INFO "e820: extended physical RAM map:\n");
671 e820_print_map("extended"); 671 e820_print_map("extended");
672} 672}
673 673
@@ -734,7 +734,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
734 addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE); 734 addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
735 if (addr) { 735 if (addr) {
736 e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED); 736 e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED);
737 printk(KERN_INFO "update e820_saved for early_reserve_e820\n"); 737 printk(KERN_INFO "e820: update e820_saved for early_reserve_e820\n");
738 update_e820_saved(); 738 update_e820_saved();
739 } 739 }
740 740
@@ -784,7 +784,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
784 if (last_pfn > max_arch_pfn) 784 if (last_pfn > max_arch_pfn)
785 last_pfn = max_arch_pfn; 785 last_pfn = max_arch_pfn;
786 786
787 printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n", 787 printk(KERN_INFO "e820: last_pfn = %#lx max_arch_pfn = %#lx\n",
788 last_pfn, max_arch_pfn); 788 last_pfn, max_arch_pfn);
789 return last_pfn; 789 return last_pfn;
790} 790}
@@ -888,7 +888,7 @@ void __init finish_e820_parsing(void)
888 early_panic("Invalid user supplied memory map"); 888 early_panic("Invalid user supplied memory map");
889 e820.nr_map = nr; 889 e820.nr_map = nr;
890 890
891 printk(KERN_INFO "user-defined physical RAM map:\n"); 891 printk(KERN_INFO "e820: user-defined physical RAM map:\n");
892 e820_print_map("user"); 892 e820_print_map("user");
893 } 893 }
894} 894}
@@ -996,8 +996,9 @@ void __init e820_reserve_resources_late(void)
996 end = MAX_RESOURCE_SIZE; 996 end = MAX_RESOURCE_SIZE;
997 if (start >= end) 997 if (start >= end)
998 continue; 998 continue;
999 printk(KERN_DEBUG "reserve RAM buffer: %016llx - %016llx ", 999 printk(KERN_DEBUG
1000 start, end); 1000 "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n",
1001 start, end);
1001 reserve_region_with_split(&iomem_resource, start, end, 1002 reserve_region_with_split(&iomem_resource, start, end,
1002 "RAM buffer"); 1003 "RAM buffer");
1003 } 1004 }
@@ -1047,7 +1048,7 @@ void __init setup_memory_map(void)
1047 1048
1048 who = x86_init.resources.memory_setup(); 1049 who = x86_init.resources.memory_setup();
1049 memcpy(&e820_saved, &e820, sizeof(struct e820map)); 1050 memcpy(&e820_saved, &e820, sizeof(struct e820map));
1050 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 1051 printk(KERN_INFO "e820: BIOS-provided physical RAM map:\n");
1051 e820_print_map(who); 1052 e820_print_map(who);
1052} 1053}
1053 1054
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 51ff18616d5..c18f59d1010 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -14,7 +14,6 @@
14#include <asm/sections.h> 14#include <asm/sections.h>
15#include <asm/e820.h> 15#include <asm/e820.h>
16#include <asm/page.h> 16#include <asm/page.h>
17#include <asm/trampoline.h>
18#include <asm/apic.h> 17#include <asm/apic.h>
19#include <asm/io_apic.h> 18#include <asm/io_apic.h>
20#include <asm/bios_ebda.h> 19#include <asm/bios_ebda.h>
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 3a3b779f41d..037df57a99a 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -24,7 +24,6 @@
24#include <asm/sections.h> 24#include <asm/sections.h>
25#include <asm/kdebug.h> 25#include <asm/kdebug.h>
26#include <asm/e820.h> 26#include <asm/e820.h>
27#include <asm/trampoline.h>
28#include <asm/bios_ebda.h> 27#include <asm/bios_ebda.h>
29 28
30static void __init zap_identity_mappings(void) 29static void __init zap_identity_mappings(void)
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 463c9797ca6..d42ab17b739 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -274,10 +274,7 @@ num_subarch_entries = (. - subarch_entries) / 4
274 * If cpu hotplug is not supported then this code can go in init section 274 * If cpu hotplug is not supported then this code can go in init section
275 * which will be freed later 275 * which will be freed later
276 */ 276 */
277
278__CPUINIT 277__CPUINIT
279
280#ifdef CONFIG_SMP
281ENTRY(startup_32_smp) 278ENTRY(startup_32_smp)
282 cld 279 cld
283 movl $(__BOOT_DS),%eax 280 movl $(__BOOT_DS),%eax
@@ -288,7 +285,7 @@ ENTRY(startup_32_smp)
288 movl pa(stack_start),%ecx 285 movl pa(stack_start),%ecx
289 movl %eax,%ss 286 movl %eax,%ss
290 leal -__PAGE_OFFSET(%ecx),%esp 287 leal -__PAGE_OFFSET(%ecx),%esp
291#endif /* CONFIG_SMP */ 288
292default_entry: 289default_entry:
293 290
294/* 291/*
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 7a40f244732..94bf9cc2c7e 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -139,10 +139,6 @@ ident_complete:
139 /* Fixup phys_base */ 139 /* Fixup phys_base */
140 addq %rbp, phys_base(%rip) 140 addq %rbp, phys_base(%rip)
141 141
142 /* Fixup trampoline */
143 addq %rbp, trampoline_level4_pgt + 0(%rip)
144 addq %rbp, trampoline_level4_pgt + (511*8)(%rip)
145
146 /* Due to ENTRY(), sometimes the empty space gets filled with 142 /* Due to ENTRY(), sometimes the empty space gets filled with
147 * zeros. Better take a jmp than relying on empty space being 143 * zeros. Better take a jmp than relying on empty space being
148 * filled with 0x90 (nop) 144 * filled with 0x90 (nop)
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index f8492da65bf..086eb58c6e8 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -22,6 +22,7 @@
22#include <asm/msr.h> 22#include <asm/msr.h>
23#include <asm/apic.h> 23#include <asm/apic.h>
24#include <linux/percpu.h> 24#include <linux/percpu.h>
25#include <linux/hardirq.h>
25 26
26#include <asm/x86_init.h> 27#include <asm/x86_init.h>
27#include <asm/reboot.h> 28#include <asm/reboot.h>
@@ -114,6 +115,25 @@ static void kvm_get_preset_lpj(void)
114 preset_lpj = lpj; 115 preset_lpj = lpj;
115} 116}
116 117
118bool kvm_check_and_clear_guest_paused(void)
119{
120 bool ret = false;
121 struct pvclock_vcpu_time_info *src;
122
123 /*
124 * per_cpu() is safe here because this function is only called from
125 * timer functions where preemption is already disabled.
126 */
127 WARN_ON(!in_atomic());
128 src = &__get_cpu_var(hv_clock);
129 if ((src->flags & PVCLOCK_GUEST_STOPPED) != 0) {
130 __this_cpu_and(hv_clock.flags, ~PVCLOCK_GUEST_STOPPED);
131 ret = true;
132 }
133
134 return ret;
135}
136
117static struct clocksource kvm_clock = { 137static struct clocksource kvm_clock = {
118 .name = "kvm-clock", 138 .name = "kvm-clock",
119 .read = kvm_clock_get_cycles, 139 .read = kvm_clock_get_cycles,
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index b02d4dd6b8a..d2b56489d70 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -27,7 +27,6 @@
27#include <asm/proto.h> 27#include <asm/proto.h>
28#include <asm/bios_ebda.h> 28#include <asm/bios_ebda.h>
29#include <asm/e820.h> 29#include <asm/e820.h>
30#include <asm/trampoline.h>
31#include <asm/setup.h> 30#include <asm/setup.h>
32#include <asm/smp.h> 31#include <asm/smp.h>
33 32
@@ -568,8 +567,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
568 struct mpf_intel *mpf; 567 struct mpf_intel *mpf;
569 unsigned long mem; 568 unsigned long mem;
570 569
571 apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n", 570 apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n",
572 bp, length); 571 base, base + length - 1);
573 BUILD_BUG_ON(sizeof(*mpf) != 16); 572 BUILD_BUG_ON(sizeof(*mpf) != 16);
574 573
575 while (length > 0) { 574 while (length > 0) {
@@ -584,8 +583,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
584#endif 583#endif
585 mpf_found = mpf; 584 mpf_found = mpf;
586 585
587 printk(KERN_INFO "found SMP MP-table at [%p] %llx\n", 586 printk(KERN_INFO "found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n",
588 mpf, (u64)virt_to_phys(mpf)); 587 (unsigned long long) virt_to_phys(mpf),
588 (unsigned long long) virt_to_phys(mpf) +
589 sizeof(*mpf) - 1, mpf);
589 590
590 mem = virt_to_phys(mpf); 591 mem = virt_to_phys(mpf);
591 memblock_reserve(mem, sizeof(*mpf)); 592 memblock_reserve(mem, sizeof(*mpf));
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 3003250ac51..62c9457ccd2 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -100,14 +100,18 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
100 struct dma_attrs *attrs) 100 struct dma_attrs *attrs)
101{ 101{
102 unsigned long dma_mask; 102 unsigned long dma_mask;
103 struct page *page; 103 struct page *page = NULL;
104 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
104 dma_addr_t addr; 105 dma_addr_t addr;
105 106
106 dma_mask = dma_alloc_coherent_mask(dev, flag); 107 dma_mask = dma_alloc_coherent_mask(dev, flag);
107 108
108 flag |= __GFP_ZERO; 109 flag |= __GFP_ZERO;
109again: 110again:
110 page = alloc_pages_node(dev_to_node(dev), flag, get_order(size)); 111 if (!(flag & GFP_ATOMIC))
112 page = dma_alloc_from_contiguous(dev, count, get_order(size));
113 if (!page)
114 page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
111 if (!page) 115 if (!page)
112 return NULL; 116 return NULL;
113 117
@@ -127,6 +131,16 @@ again:
127 return page_address(page); 131 return page_address(page);
128} 132}
129 133
134void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr,
135 dma_addr_t dma_addr, struct dma_attrs *attrs)
136{
137 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
138 struct page *page = virt_to_page(vaddr);
139
140 if (!dma_release_from_contiguous(dev, page, count))
141 free_pages((unsigned long)vaddr, get_order(size));
142}
143
130/* 144/*
131 * See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel 145 * See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel
132 * parameter documentation. 146 * parameter documentation.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index f96050685b4..871be4a84c7 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -74,12 +74,6 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
74 return nents; 74 return nents;
75} 75}
76 76
77static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
78 dma_addr_t dma_addr, struct dma_attrs *attrs)
79{
80 free_pages((unsigned long)vaddr, get_order(size));
81}
82
83static void nommu_sync_single_for_device(struct device *dev, 77static void nommu_sync_single_for_device(struct device *dev,
84 dma_addr_t addr, size_t size, 78 dma_addr_t addr, size_t size,
85 enum dma_data_direction dir) 79 enum dma_data_direction dir)
@@ -97,7 +91,7 @@ static void nommu_sync_sg_for_device(struct device *dev,
97 91
98struct dma_map_ops nommu_dma_ops = { 92struct dma_map_ops nommu_dma_ops = {
99 .alloc = dma_generic_alloc_coherent, 93 .alloc = dma_generic_alloc_coherent,
100 .free = nommu_free_coherent, 94 .free = dma_generic_free_coherent,
101 .map_sg = nommu_map_sg, 95 .map_sg = nommu_map_sg,
102 .map_page = nommu_map_page, 96 .map_page = nommu_map_page,
103 .sync_single_for_device = nommu_sync_single_for_device, 97 .sync_single_for_device = nommu_sync_single_for_device,
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 77215c23fba..79c45af8160 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -24,6 +24,7 @@
24#ifdef CONFIG_X86_32 24#ifdef CONFIG_X86_32
25# include <linux/ctype.h> 25# include <linux/ctype.h>
26# include <linux/mc146818rtc.h> 26# include <linux/mc146818rtc.h>
27# include <asm/realmode.h>
27#else 28#else
28# include <asm/x86_init.h> 29# include <asm/x86_init.h>
29#endif 30#endif
@@ -156,15 +157,10 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
156 return 0; 157 return 0;
157} 158}
158 159
159extern const unsigned char machine_real_restart_asm[];
160extern const u64 machine_real_restart_gdt[3];
161
162void machine_real_restart(unsigned int type) 160void machine_real_restart(unsigned int type)
163{ 161{
164 void *restart_va; 162 void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int))
165 unsigned long restart_pa; 163 real_mode_header->machine_real_restart_asm;
166 void (*restart_lowmem)(unsigned int);
167 u64 *lowmem_gdt;
168 164
169 local_irq_disable(); 165 local_irq_disable();
170 166
@@ -195,21 +191,6 @@ void machine_real_restart(unsigned int type)
195 * too. */ 191 * too. */
196 *((unsigned short *)0x472) = reboot_mode; 192 *((unsigned short *)0x472) = reboot_mode;
197 193
198 /* Patch the GDT in the low memory trampoline */
199 lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
200
201 restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
202 restart_pa = virt_to_phys(restart_va);
203 restart_lowmem = (void (*)(unsigned int))restart_pa;
204
205 /* GDT[0]: GDT self-pointer */
206 lowmem_gdt[0] =
207 (u64)(sizeof(machine_real_restart_gdt) - 1) +
208 ((u64)virt_to_phys(lowmem_gdt) << 16);
209 /* GDT[1]: 64K real mode code segment */
210 lowmem_gdt[1] =
211 GDT_ENTRY(0x009b, restart_pa, 0xffff);
212
213 /* Jump to the identity-mapped low memory code */ 194 /* Jump to the identity-mapped low memory code */
214 restart_lowmem(type); 195 restart_lowmem(type);
215} 196}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 366c688d619..16be6dc14db 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -49,6 +49,7 @@
49#include <asm/pci-direct.h> 49#include <asm/pci-direct.h>
50#include <linux/init_ohci1394_dma.h> 50#include <linux/init_ohci1394_dma.h>
51#include <linux/kvm_para.h> 51#include <linux/kvm_para.h>
52#include <linux/dma-contiguous.h>
52 53
53#include <linux/errno.h> 54#include <linux/errno.h>
54#include <linux/kernel.h> 55#include <linux/kernel.h>
@@ -72,7 +73,7 @@
72 73
73#include <asm/mtrr.h> 74#include <asm/mtrr.h>
74#include <asm/apic.h> 75#include <asm/apic.h>
75#include <asm/trampoline.h> 76#include <asm/realmode.h>
76#include <asm/e820.h> 77#include <asm/e820.h>
77#include <asm/mpspec.h> 78#include <asm/mpspec.h>
78#include <asm/setup.h> 79#include <asm/setup.h>
@@ -333,8 +334,8 @@ static void __init relocate_initrd(void)
333 memblock_reserve(ramdisk_here, area_size); 334 memblock_reserve(ramdisk_here, area_size);
334 initrd_start = ramdisk_here + PAGE_OFFSET; 335 initrd_start = ramdisk_here + PAGE_OFFSET;
335 initrd_end = initrd_start + ramdisk_size; 336 initrd_end = initrd_start + ramdisk_size;
336 printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", 337 printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
337 ramdisk_here, ramdisk_here + ramdisk_size); 338 ramdisk_here, ramdisk_here + ramdisk_size - 1);
338 339
339 q = (char *)initrd_start; 340 q = (char *)initrd_start;
340 341
@@ -365,8 +366,8 @@ static void __init relocate_initrd(void)
365 /* high pages is not converted by early_res_to_bootmem */ 366 /* high pages is not converted by early_res_to_bootmem */
366 ramdisk_image = boot_params.hdr.ramdisk_image; 367 ramdisk_image = boot_params.hdr.ramdisk_image;
367 ramdisk_size = boot_params.hdr.ramdisk_size; 368 ramdisk_size = boot_params.hdr.ramdisk_size;
368 printk(KERN_INFO "Move RAMDISK from %016llx - %016llx to" 369 printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
369 " %08llx - %08llx\n", 370 " [mem %#010llx-%#010llx]\n",
370 ramdisk_image, ramdisk_image + ramdisk_size - 1, 371 ramdisk_image, ramdisk_image + ramdisk_size - 1,
371 ramdisk_here, ramdisk_here + ramdisk_size - 1); 372 ramdisk_here, ramdisk_here + ramdisk_size - 1);
372} 373}
@@ -391,8 +392,8 @@ static void __init reserve_initrd(void)
391 ramdisk_size, end_of_lowmem>>1); 392 ramdisk_size, end_of_lowmem>>1);
392 } 393 }
393 394
394 printk(KERN_INFO "RAMDISK: %08llx - %08llx\n", ramdisk_image, 395 printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
395 ramdisk_end); 396 ramdisk_end - 1);
396 397
397 398
398 if (ramdisk_end <= end_of_lowmem) { 399 if (ramdisk_end <= end_of_lowmem) {
@@ -905,10 +906,10 @@ void __init setup_arch(char **cmdline_p)
905 setup_bios_corruption_check(); 906 setup_bios_corruption_check();
906#endif 907#endif
907 908
908 printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n", 909 printk(KERN_DEBUG "initial memory mapped: [mem 0x00000000-%#010lx]\n",
909 max_pfn_mapped<<PAGE_SHIFT); 910 (max_pfn_mapped<<PAGE_SHIFT) - 1);
910 911
911 setup_trampolines(); 912 setup_real_mode();
912 913
913 init_gbpages(); 914 init_gbpages();
914 915
@@ -925,6 +926,7 @@ void __init setup_arch(char **cmdline_p)
925 } 926 }
926#endif 927#endif
927 memblock.current_limit = get_max_mapped(); 928 memblock.current_limit = get_max_mapped();
929 dma_contiguous_reserve(0);
928 930
929 /* 931 /*
930 * NOTE: On x86-32, only from this point on, fixmaps are ready for use. 932 * NOTE: On x86-32, only from this point on, fixmaps are ready for use.
@@ -966,6 +968,8 @@ void __init setup_arch(char **cmdline_p)
966 if (boot_cpu_data.cpuid_level >= 0) { 968 if (boot_cpu_data.cpuid_level >= 0) {
967 /* A CPU has %cr4 if and only if it has CPUID */ 969 /* A CPU has %cr4 if and only if it has CPUID */
968 mmu_cr4_features = read_cr4(); 970 mmu_cr4_features = read_cr4();
971 if (trampoline_cr4_features)
972 *trampoline_cr4_features = mmu_cr4_features;
969 } 973 }
970 974
971#ifdef CONFIG_X86_32 975#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 433529e29be..f56f96da77f 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -57,7 +57,7 @@
57#include <asm/nmi.h> 57#include <asm/nmi.h>
58#include <asm/irq.h> 58#include <asm/irq.h>
59#include <asm/idle.h> 59#include <asm/idle.h>
60#include <asm/trampoline.h> 60#include <asm/realmode.h>
61#include <asm/cpu.h> 61#include <asm/cpu.h>
62#include <asm/numa.h> 62#include <asm/numa.h>
63#include <asm/pgtable.h> 63#include <asm/pgtable.h>
@@ -73,6 +73,8 @@
73#include <asm/smpboot_hooks.h> 73#include <asm/smpboot_hooks.h>
74#include <asm/i8259.h> 74#include <asm/i8259.h>
75 75
76#include <asm/realmode.h>
77
76/* State of each CPU */ 78/* State of each CPU */
77DEFINE_PER_CPU(int, cpu_state) = { 0 }; 79DEFINE_PER_CPU(int, cpu_state) = { 0 };
78 80
@@ -660,8 +662,12 @@ static void __cpuinit announce_cpu(int cpu, int apicid)
660 */ 662 */
661static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) 663static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
662{ 664{
665 volatile u32 *trampoline_status =
666 (volatile u32 *) __va(real_mode_header->trampoline_status);
667 /* start_ip had better be page-aligned! */
668 unsigned long start_ip = real_mode_header->trampoline_start;
669
663 unsigned long boot_error = 0; 670 unsigned long boot_error = 0;
664 unsigned long start_ip;
665 int timeout; 671 int timeout;
666 672
667 alternatives_smp_switch(1); 673 alternatives_smp_switch(1);
@@ -684,9 +690,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
684 initial_code = (unsigned long)start_secondary; 690 initial_code = (unsigned long)start_secondary;
685 stack_start = idle->thread.sp; 691 stack_start = idle->thread.sp;
686 692
687 /* start_ip had better be page-aligned! */
688 start_ip = trampoline_address();
689
690 /* So we see what's up */ 693 /* So we see what's up */
691 announce_cpu(cpu, apicid); 694 announce_cpu(cpu, apicid);
692 695
@@ -749,8 +752,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
749 pr_debug("CPU%d: has booted.\n", cpu); 752 pr_debug("CPU%d: has booted.\n", cpu);
750 } else { 753 } else {
751 boot_error = 1; 754 boot_error = 1;
752 if (*(volatile u32 *)TRAMPOLINE_SYM(trampoline_status) 755 if (*trampoline_status == 0xA5A5A5A5)
753 == 0xA5A5A5A5)
754 /* trampoline started but...? */ 756 /* trampoline started but...? */
755 pr_err("CPU%d: Stuck ??\n", cpu); 757 pr_err("CPU%d: Stuck ??\n", cpu);
756 else 758 else
@@ -776,7 +778,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
776 } 778 }
777 779
778 /* mark "stuck" area as not stuck */ 780 /* mark "stuck" area as not stuck */
779 *(volatile u32 *)TRAMPOLINE_SYM(trampoline_status) = 0; 781 *trampoline_status = 0;
780 782
781 if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { 783 if (get_uv_system_type() != UV_NON_UNIQUE_APIC) {
782 /* 784 /*
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
index 6410744ac5c..f84fe00fad4 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -32,7 +32,7 @@
32#include <linux/mm.h> 32#include <linux/mm.h>
33#include <linux/tboot.h> 33#include <linux/tboot.h>
34 34
35#include <asm/trampoline.h> 35#include <asm/realmode.h>
36#include <asm/processor.h> 36#include <asm/processor.h>
37#include <asm/bootparam.h> 37#include <asm/bootparam.h>
38#include <asm/pgtable.h> 38#include <asm/pgtable.h>
@@ -44,7 +44,7 @@
44#include <asm/e820.h> 44#include <asm/e820.h>
45#include <asm/io.h> 45#include <asm/io.h>
46 46
47#include "acpi/realmode/wakeup.h" 47#include "../realmode/rm/wakeup.h"
48 48
49/* Global pointer to shared data; NULL means no measured launch. */ 49/* Global pointer to shared data; NULL means no measured launch. */
50struct tboot *tboot __read_mostly; 50struct tboot *tboot __read_mostly;
@@ -201,7 +201,8 @@ static int tboot_setup_sleep(void)
201 add_mac_region(e820.map[i].addr, e820.map[i].size); 201 add_mac_region(e820.map[i].addr, e820.map[i].size);
202 } 202 }
203 203
204 tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address; 204 tboot->acpi_sinfo.kernel_s3_resume_vector =
205 real_mode_header->wakeup_start;
205 206
206 return 0; 207 return 0;
207} 208}
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c
deleted file mode 100644
index a73b61055ad..00000000000
--- a/arch/x86/kernel/trampoline.c
+++ /dev/null
@@ -1,42 +0,0 @@
1#include <linux/io.h>
2#include <linux/memblock.h>
3
4#include <asm/trampoline.h>
5#include <asm/cacheflush.h>
6#include <asm/pgtable.h>
7
8unsigned char *x86_trampoline_base;
9
10void __init setup_trampolines(void)
11{
12 phys_addr_t mem;
13 size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start);
14
15 /* Has to be in very low memory so we can execute real-mode AP code. */
16 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
17 if (!mem)
18 panic("Cannot allocate trampoline\n");
19
20 x86_trampoline_base = __va(mem);
21 memblock_reserve(mem, size);
22
23 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
24 x86_trampoline_base, (unsigned long long)mem, size);
25
26 memcpy(x86_trampoline_base, x86_trampoline_start, size);
27}
28
29/*
30 * setup_trampolines() gets called very early, to guarantee the
31 * availability of low memory. This is before the proper kernel page
32 * tables are set up, so we cannot set page permissions in that
33 * function. Thus, we use an arch_initcall instead.
34 */
35static int __init configure_trampolines(void)
36{
37 size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start);
38
39 set_memory_x((unsigned long)x86_trampoline_base, size >> PAGE_SHIFT);
40 return 0;
41}
42arch_initcall(configure_trampolines);
diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S
deleted file mode 100644
index 451c0a7ef7f..00000000000
--- a/arch/x86/kernel/trampoline_32.S
+++ /dev/null
@@ -1,83 +0,0 @@
1/*
2 *
3 * Trampoline.S Derived from Setup.S by Linus Torvalds
4 *
5 * 4 Jan 1997 Michael Chastain: changed to gnu as.
6 *
7 * This is only used for booting secondary CPUs in SMP machine
8 *
9 * Entry: CS:IP point to the start of our code, we are
10 * in real mode with no stack, but the rest of the
11 * trampoline page to make our stack and everything else
12 * is a mystery.
13 *
14 * We jump into arch/x86/kernel/head_32.S.
15 *
16 * On entry to trampoline_data, the processor is in real mode
17 * with 16-bit addressing and 16-bit data. CS has some value
18 * and IP is zero. Thus, data addresses need to be absolute
19 * (no relocation) and are taken with regard to r_base.
20 *
21 * If you work on this file, check the object module with
22 * objdump --reloc to make sure there are no relocation
23 * entries except for:
24 *
25 * TYPE VALUE
26 * R_386_32 startup_32_smp
27 * R_386_32 boot_gdt
28 */
29
30#include <linux/linkage.h>
31#include <linux/init.h>
32#include <asm/segment.h>
33#include <asm/page_types.h>
34
35#ifdef CONFIG_SMP
36
37 .section ".x86_trampoline","a"
38 .balign PAGE_SIZE
39 .code16
40
41ENTRY(trampoline_data)
42r_base = .
43 wbinvd # Needed for NUMA-Q should be harmless for others
44 mov %cs, %ax # Code and data in the same place
45 mov %ax, %ds
46
47 cli # We should be safe anyway
48
49 movl $0xA5A5A5A5, trampoline_status - r_base
50 # write marker for master knows we're running
51
52 /* GDT tables in non default location kernel can be beyond 16MB and
53 * lgdt will not be able to load the address as in real mode default
54 * operand size is 16bit. Use lgdtl instead to force operand size
55 * to 32 bit.
56 */
57
58 lidtl boot_idt_descr - r_base # load idt with 0, 0
59 lgdtl boot_gdt_descr - r_base # load gdt with whatever is appropriate
60
61 xor %ax, %ax
62 inc %ax # protected mode (PE) bit
63 lmsw %ax # into protected mode
64 # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
65 ljmpl $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
66
67 # These need to be in the same 64K segment as the above;
68 # hence we don't use the boot_gdt_descr defined in head.S
69boot_gdt_descr:
70 .word __BOOT_DS + 7 # gdt limit
71 .long boot_gdt - __PAGE_OFFSET # gdt base
72
73boot_idt_descr:
74 .word 0 # idt limit = 0
75 .long 0 # idt base = 0L
76
77ENTRY(trampoline_status)
78 .long 0
79
80.globl trampoline_end
81trampoline_end:
82
83#endif /* CONFIG_SMP */
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 0f703f10901..22a1530146a 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -197,18 +197,6 @@ SECTIONS
197 197
198 INIT_DATA_SECTION(16) 198 INIT_DATA_SECTION(16)
199 199
200 /*
201 * Code and data for a variety of lowlevel trampolines, to be
202 * copied into base memory (< 1 MiB) during initialization.
203 * Since it is copied early, the main copy can be discarded
204 * afterwards.
205 */
206 .x86_trampoline : AT(ADDR(.x86_trampoline) - LOAD_OFFSET) {
207 x86_trampoline_start = .;
208 *(.x86_trampoline)
209 x86_trampoline_end = .;
210 }
211
212 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { 200 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
213 __x86_cpu_dev_start = .; 201 __x86_cpu_dev_start = .;
214 *(.x86_cpu_dev.init) 202 *(.x86_cpu_dev.init)
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 1a7fe868f37..a28f338843e 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -36,6 +36,7 @@ config KVM
36 select TASKSTATS 36 select TASKSTATS
37 select TASK_DELAY_ACCT 37 select TASK_DELAY_ACCT
38 select PERF_EVENTS 38 select PERF_EVENTS
39 select HAVE_KVM_MSI
39 ---help--- 40 ---help---
40 Support hosting fully virtualized guest machines using hardware 41 Support hosting fully virtualized guest machines using hardware
41 virtualization extensions. You will need a fairly recent 42 virtualization extensions. You will need a fairly recent
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 9fed5bedaad..7df1c6d839f 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -247,7 +247,8 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
247 247
248 /* cpuid 7.0.ebx */ 248 /* cpuid 7.0.ebx */
249 const u32 kvm_supported_word9_x86_features = 249 const u32 kvm_supported_word9_x86_features =
250 F(FSGSBASE) | F(BMI1) | F(AVX2) | F(SMEP) | F(BMI2) | F(ERMS); 250 F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
251 F(BMI2) | F(ERMS) | F(RTM);
251 252
252 /* all calls to cpuid_count() should be made on the same cpu */ 253 /* all calls to cpuid_count() should be made on the same cpu */
253 get_cpu(); 254 get_cpu();
@@ -397,7 +398,7 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
397 case KVM_CPUID_SIGNATURE: { 398 case KVM_CPUID_SIGNATURE: {
398 char signature[12] = "KVMKVMKVM\0\0"; 399 char signature[12] = "KVMKVMKVM\0\0";
399 u32 *sigptr = (u32 *)signature; 400 u32 *sigptr = (u32 *)signature;
400 entry->eax = 0; 401 entry->eax = KVM_CPUID_FEATURES;
401 entry->ebx = sigptr[0]; 402 entry->ebx = sigptr[0];
402 entry->ecx = sigptr[1]; 403 entry->ecx = sigptr[1];
403 entry->edx = sigptr[2]; 404 entry->edx = sigptr[2];
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 83756223f8a..f95d242ee9f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -142,6 +142,10 @@
142#define Src2FS (OpFS << Src2Shift) 142#define Src2FS (OpFS << Src2Shift)
143#define Src2GS (OpGS << Src2Shift) 143#define Src2GS (OpGS << Src2Shift)
144#define Src2Mask (OpMask << Src2Shift) 144#define Src2Mask (OpMask << Src2Shift)
145#define Mmx ((u64)1 << 40) /* MMX Vector instruction */
146#define Aligned ((u64)1 << 41) /* Explicitly aligned (e.g. MOVDQA) */
147#define Unaligned ((u64)1 << 42) /* Explicitly unaligned (e.g. MOVDQU) */
148#define Avx ((u64)1 << 43) /* Advanced Vector Extensions */
145 149
146#define X2(x...) x, x 150#define X2(x...) x, x
147#define X3(x...) X2(x), x 151#define X3(x...) X2(x), x
@@ -557,6 +561,29 @@ static void set_segment_selector(struct x86_emulate_ctxt *ctxt, u16 selector,
557 ctxt->ops->set_segment(ctxt, selector, &desc, base3, seg); 561 ctxt->ops->set_segment(ctxt, selector, &desc, base3, seg);
558} 562}
559 563
564/*
565 * x86 defines three classes of vector instructions: explicitly
566 * aligned, explicitly unaligned, and the rest, which change behaviour
567 * depending on whether they're AVX encoded or not.
568 *
569 * Also included is CMPXCHG16B which is not a vector instruction, yet it is
570 * subject to the same check.
571 */
572static bool insn_aligned(struct x86_emulate_ctxt *ctxt, unsigned size)
573{
574 if (likely(size < 16))
575 return false;
576
577 if (ctxt->d & Aligned)
578 return true;
579 else if (ctxt->d & Unaligned)
580 return false;
581 else if (ctxt->d & Avx)
582 return false;
583 else
584 return true;
585}
586
560static int __linearize(struct x86_emulate_ctxt *ctxt, 587static int __linearize(struct x86_emulate_ctxt *ctxt,
561 struct segmented_address addr, 588 struct segmented_address addr,
562 unsigned size, bool write, bool fetch, 589 unsigned size, bool write, bool fetch,
@@ -621,6 +648,8 @@ static int __linearize(struct x86_emulate_ctxt *ctxt,
621 } 648 }
622 if (fetch ? ctxt->mode != X86EMUL_MODE_PROT64 : ctxt->ad_bytes != 8) 649 if (fetch ? ctxt->mode != X86EMUL_MODE_PROT64 : ctxt->ad_bytes != 8)
623 la &= (u32)-1; 650 la &= (u32)-1;
651 if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0))
652 return emulate_gp(ctxt, 0);
624 *linear = la; 653 *linear = la;
625 return X86EMUL_CONTINUE; 654 return X86EMUL_CONTINUE;
626bad: 655bad:
@@ -859,6 +888,40 @@ static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data,
859 ctxt->ops->put_fpu(ctxt); 888 ctxt->ops->put_fpu(ctxt);
860} 889}
861 890
891static void read_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg)
892{
893 ctxt->ops->get_fpu(ctxt);
894 switch (reg) {
895 case 0: asm("movq %%mm0, %0" : "=m"(*data)); break;
896 case 1: asm("movq %%mm1, %0" : "=m"(*data)); break;
897 case 2: asm("movq %%mm2, %0" : "=m"(*data)); break;
898 case 3: asm("movq %%mm3, %0" : "=m"(*data)); break;
899 case 4: asm("movq %%mm4, %0" : "=m"(*data)); break;
900 case 5: asm("movq %%mm5, %0" : "=m"(*data)); break;
901 case 6: asm("movq %%mm6, %0" : "=m"(*data)); break;
902 case 7: asm("movq %%mm7, %0" : "=m"(*data)); break;
903 default: BUG();
904 }
905 ctxt->ops->put_fpu(ctxt);
906}
907
908static void write_mmx_reg(struct x86_emulate_ctxt *ctxt, u64 *data, int reg)
909{
910 ctxt->ops->get_fpu(ctxt);
911 switch (reg) {
912 case 0: asm("movq %0, %%mm0" : : "m"(*data)); break;
913 case 1: asm("movq %0, %%mm1" : : "m"(*data)); break;
914 case 2: asm("movq %0, %%mm2" : : "m"(*data)); break;
915 case 3: asm("movq %0, %%mm3" : : "m"(*data)); break;
916 case 4: asm("movq %0, %%mm4" : : "m"(*data)); break;
917 case 5: asm("movq %0, %%mm5" : : "m"(*data)); break;
918 case 6: asm("movq %0, %%mm6" : : "m"(*data)); break;
919 case 7: asm("movq %0, %%mm7" : : "m"(*data)); break;
920 default: BUG();
921 }
922 ctxt->ops->put_fpu(ctxt);
923}
924
862static void decode_register_operand(struct x86_emulate_ctxt *ctxt, 925static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
863 struct operand *op) 926 struct operand *op)
864{ 927{
@@ -875,6 +938,13 @@ static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
875 read_sse_reg(ctxt, &op->vec_val, reg); 938 read_sse_reg(ctxt, &op->vec_val, reg);
876 return; 939 return;
877 } 940 }
941 if (ctxt->d & Mmx) {
942 reg &= 7;
943 op->type = OP_MM;
944 op->bytes = 8;
945 op->addr.mm = reg;
946 return;
947 }
878 948
879 op->type = OP_REG; 949 op->type = OP_REG;
880 if (ctxt->d & ByteOp) { 950 if (ctxt->d & ByteOp) {
@@ -902,7 +972,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
902 ctxt->modrm_rm = base_reg = (ctxt->rex_prefix & 1) << 3; /* REG.B */ 972 ctxt->modrm_rm = base_reg = (ctxt->rex_prefix & 1) << 3; /* REG.B */
903 } 973 }
904 974
905 ctxt->modrm = insn_fetch(u8, ctxt);
906 ctxt->modrm_mod |= (ctxt->modrm & 0xc0) >> 6; 975 ctxt->modrm_mod |= (ctxt->modrm & 0xc0) >> 6;
907 ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3; 976 ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3;
908 ctxt->modrm_rm |= (ctxt->modrm & 0x07); 977 ctxt->modrm_rm |= (ctxt->modrm & 0x07);
@@ -920,6 +989,12 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
920 read_sse_reg(ctxt, &op->vec_val, ctxt->modrm_rm); 989 read_sse_reg(ctxt, &op->vec_val, ctxt->modrm_rm);
921 return rc; 990 return rc;
922 } 991 }
992 if (ctxt->d & Mmx) {
993 op->type = OP_MM;
994 op->bytes = 8;
995 op->addr.xmm = ctxt->modrm_rm & 7;
996 return rc;
997 }
923 fetch_register_operand(op); 998 fetch_register_operand(op);
924 return rc; 999 return rc;
925 } 1000 }
@@ -1387,6 +1462,9 @@ static int writeback(struct x86_emulate_ctxt *ctxt)
1387 case OP_XMM: 1462 case OP_XMM:
1388 write_sse_reg(ctxt, &ctxt->dst.vec_val, ctxt->dst.addr.xmm); 1463 write_sse_reg(ctxt, &ctxt->dst.vec_val, ctxt->dst.addr.xmm);
1389 break; 1464 break;
1465 case OP_MM:
1466 write_mmx_reg(ctxt, &ctxt->dst.mm_val, ctxt->dst.addr.mm);
1467 break;
1390 case OP_NONE: 1468 case OP_NONE:
1391 /* no writeback */ 1469 /* no writeback */
1392 break; 1470 break;
@@ -2790,7 +2868,7 @@ static int em_rdpmc(struct x86_emulate_ctxt *ctxt)
2790 2868
2791static int em_mov(struct x86_emulate_ctxt *ctxt) 2869static int em_mov(struct x86_emulate_ctxt *ctxt)
2792{ 2870{
2793 ctxt->dst.val = ctxt->src.val; 2871 memcpy(ctxt->dst.valptr, ctxt->src.valptr, ctxt->op_bytes);
2794 return X86EMUL_CONTINUE; 2872 return X86EMUL_CONTINUE;
2795} 2873}
2796 2874
@@ -2870,12 +2948,6 @@ static int em_mov_sreg_rm(struct x86_emulate_ctxt *ctxt)
2870 return load_segment_descriptor(ctxt, sel, ctxt->modrm_reg); 2948 return load_segment_descriptor(ctxt, sel, ctxt->modrm_reg);
2871} 2949}
2872 2950
2873static int em_movdqu(struct x86_emulate_ctxt *ctxt)
2874{
2875 memcpy(&ctxt->dst.vec_val, &ctxt->src.vec_val, ctxt->op_bytes);
2876 return X86EMUL_CONTINUE;
2877}
2878
2879static int em_invlpg(struct x86_emulate_ctxt *ctxt) 2951static int em_invlpg(struct x86_emulate_ctxt *ctxt)
2880{ 2952{
2881 int rc; 2953 int rc;
@@ -3061,35 +3133,13 @@ static int em_btc(struct x86_emulate_ctxt *ctxt)
3061 3133
3062static int em_bsf(struct x86_emulate_ctxt *ctxt) 3134static int em_bsf(struct x86_emulate_ctxt *ctxt)
3063{ 3135{
3064 u8 zf; 3136 emulate_2op_SrcV_nobyte(ctxt, "bsf");
3065
3066 __asm__ ("bsf %2, %0; setz %1"
3067 : "=r"(ctxt->dst.val), "=q"(zf)
3068 : "r"(ctxt->src.val));
3069
3070 ctxt->eflags &= ~X86_EFLAGS_ZF;
3071 if (zf) {
3072 ctxt->eflags |= X86_EFLAGS_ZF;
3073 /* Disable writeback. */
3074 ctxt->dst.type = OP_NONE;
3075 }
3076 return X86EMUL_CONTINUE; 3137 return X86EMUL_CONTINUE;
3077} 3138}
3078 3139
3079static int em_bsr(struct x86_emulate_ctxt *ctxt) 3140static int em_bsr(struct x86_emulate_ctxt *ctxt)
3080{ 3141{
3081 u8 zf; 3142 emulate_2op_SrcV_nobyte(ctxt, "bsr");
3082
3083 __asm__ ("bsr %2, %0; setz %1"
3084 : "=r"(ctxt->dst.val), "=q"(zf)
3085 : "r"(ctxt->src.val));
3086
3087 ctxt->eflags &= ~X86_EFLAGS_ZF;
3088 if (zf) {
3089 ctxt->eflags |= X86_EFLAGS_ZF;
3090 /* Disable writeback. */
3091 ctxt->dst.type = OP_NONE;
3092 }
3093 return X86EMUL_CONTINUE; 3143 return X86EMUL_CONTINUE;
3094} 3144}
3095 3145
@@ -3286,8 +3336,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
3286 .check_perm = (_p) } 3336 .check_perm = (_p) }
3287#define N D(0) 3337#define N D(0)
3288#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) } 3338#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) }
3289#define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) } 3339#define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) }
3290#define GD(_f, _g) { .flags = ((_f) | GroupDual), .u.gdual = (_g) } 3340#define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) }
3291#define I(_f, _e) { .flags = (_f), .u.execute = (_e) } 3341#define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
3292#define II(_f, _e, _i) \ 3342#define II(_f, _e, _i) \
3293 { .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i } 3343 { .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i }
@@ -3307,25 +3357,25 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
3307 I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e) 3357 I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)
3308 3358
3309static struct opcode group7_rm1[] = { 3359static struct opcode group7_rm1[] = {
3310 DI(SrcNone | ModRM | Priv, monitor), 3360 DI(SrcNone | Priv, monitor),
3311 DI(SrcNone | ModRM | Priv, mwait), 3361 DI(SrcNone | Priv, mwait),
3312 N, N, N, N, N, N, 3362 N, N, N, N, N, N,
3313}; 3363};
3314 3364
3315static struct opcode group7_rm3[] = { 3365static struct opcode group7_rm3[] = {
3316 DIP(SrcNone | ModRM | Prot | Priv, vmrun, check_svme_pa), 3366 DIP(SrcNone | Prot | Priv, vmrun, check_svme_pa),
3317 II(SrcNone | ModRM | Prot | VendorSpecific, em_vmmcall, vmmcall), 3367 II(SrcNone | Prot | VendorSpecific, em_vmmcall, vmmcall),
3318 DIP(SrcNone | ModRM | Prot | Priv, vmload, check_svme_pa), 3368 DIP(SrcNone | Prot | Priv, vmload, check_svme_pa),
3319 DIP(SrcNone | ModRM | Prot | Priv, vmsave, check_svme_pa), 3369 DIP(SrcNone | Prot | Priv, vmsave, check_svme_pa),
3320 DIP(SrcNone | ModRM | Prot | Priv, stgi, check_svme), 3370 DIP(SrcNone | Prot | Priv, stgi, check_svme),
3321 DIP(SrcNone | ModRM | Prot | Priv, clgi, check_svme), 3371 DIP(SrcNone | Prot | Priv, clgi, check_svme),
3322 DIP(SrcNone | ModRM | Prot | Priv, skinit, check_svme), 3372 DIP(SrcNone | Prot | Priv, skinit, check_svme),
3323 DIP(SrcNone | ModRM | Prot | Priv, invlpga, check_svme), 3373 DIP(SrcNone | Prot | Priv, invlpga, check_svme),
3324}; 3374};
3325 3375
3326static struct opcode group7_rm7[] = { 3376static struct opcode group7_rm7[] = {
3327 N, 3377 N,
3328 DIP(SrcNone | ModRM, rdtscp, check_rdtsc), 3378 DIP(SrcNone, rdtscp, check_rdtsc),
3329 N, N, N, N, N, N, 3379 N, N, N, N, N, N,
3330}; 3380};
3331 3381
@@ -3341,81 +3391,86 @@ static struct opcode group1[] = {
3341}; 3391};
3342 3392
3343static struct opcode group1A[] = { 3393static struct opcode group1A[] = {
3344 I(DstMem | SrcNone | ModRM | Mov | Stack, em_pop), N, N, N, N, N, N, N, 3394 I(DstMem | SrcNone | Mov | Stack, em_pop), N, N, N, N, N, N, N,
3345}; 3395};
3346 3396
3347static struct opcode group3[] = { 3397static struct opcode group3[] = {
3348 I(DstMem | SrcImm | ModRM, em_test), 3398 I(DstMem | SrcImm, em_test),
3349 I(DstMem | SrcImm | ModRM, em_test), 3399 I(DstMem | SrcImm, em_test),
3350 I(DstMem | SrcNone | ModRM | Lock, em_not), 3400 I(DstMem | SrcNone | Lock, em_not),
3351 I(DstMem | SrcNone | ModRM | Lock, em_neg), 3401 I(DstMem | SrcNone | Lock, em_neg),
3352 I(SrcMem | ModRM, em_mul_ex), 3402 I(SrcMem, em_mul_ex),
3353 I(SrcMem | ModRM, em_imul_ex), 3403 I(SrcMem, em_imul_ex),
3354 I(SrcMem | ModRM, em_div_ex), 3404 I(SrcMem, em_div_ex),
3355 I(SrcMem | ModRM, em_idiv_ex), 3405 I(SrcMem, em_idiv_ex),
3356}; 3406};
3357 3407
3358static struct opcode group4[] = { 3408static struct opcode group4[] = {
3359 I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45), 3409 I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
3360 I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45), 3410 I(ByteOp | DstMem | SrcNone | Lock, em_grp45),
3361 N, N, N, N, N, N, 3411 N, N, N, N, N, N,
3362}; 3412};
3363 3413
3364static struct opcode group5[] = { 3414static struct opcode group5[] = {
3365 I(DstMem | SrcNone | ModRM | Lock, em_grp45), 3415 I(DstMem | SrcNone | Lock, em_grp45),
3366 I(DstMem | SrcNone | ModRM | Lock, em_grp45), 3416 I(DstMem | SrcNone | Lock, em_grp45),
3367 I(SrcMem | ModRM | Stack, em_grp45), 3417 I(SrcMem | Stack, em_grp45),
3368 I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far), 3418 I(SrcMemFAddr | ImplicitOps | Stack, em_call_far),
3369 I(SrcMem | ModRM | Stack, em_grp45), 3419 I(SrcMem | Stack, em_grp45),
3370 I(SrcMemFAddr | ModRM | ImplicitOps, em_grp45), 3420 I(SrcMemFAddr | ImplicitOps, em_grp45),
3371 I(SrcMem | ModRM | Stack, em_grp45), N, 3421 I(SrcMem | Stack, em_grp45), N,
3372}; 3422};
3373 3423
3374static struct opcode group6[] = { 3424static struct opcode group6[] = {
3375 DI(ModRM | Prot, sldt), 3425 DI(Prot, sldt),
3376 DI(ModRM | Prot, str), 3426 DI(Prot, str),
3377 DI(ModRM | Prot | Priv, lldt), 3427 DI(Prot | Priv, lldt),
3378 DI(ModRM | Prot | Priv, ltr), 3428 DI(Prot | Priv, ltr),
3379 N, N, N, N, 3429 N, N, N, N,
3380}; 3430};
3381 3431
3382static struct group_dual group7 = { { 3432static struct group_dual group7 = { {
3383 DI(ModRM | Mov | DstMem | Priv, sgdt), 3433 DI(Mov | DstMem | Priv, sgdt),
3384 DI(ModRM | Mov | DstMem | Priv, sidt), 3434 DI(Mov | DstMem | Priv, sidt),
3385 II(ModRM | SrcMem | Priv, em_lgdt, lgdt), 3435 II(SrcMem | Priv, em_lgdt, lgdt),
3386 II(ModRM | SrcMem | Priv, em_lidt, lidt), 3436 II(SrcMem | Priv, em_lidt, lidt),
3387 II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N, 3437 II(SrcNone | DstMem | Mov, em_smsw, smsw), N,
3388 II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), 3438 II(SrcMem16 | Mov | Priv, em_lmsw, lmsw),
3389 II(SrcMem | ModRM | ByteOp | Priv | NoAccess, em_invlpg, invlpg), 3439 II(SrcMem | ByteOp | Priv | NoAccess, em_invlpg, invlpg),
3390}, { 3440}, {
3391 I(SrcNone | ModRM | Priv | VendorSpecific, em_vmcall), 3441 I(SrcNone | Priv | VendorSpecific, em_vmcall),
3392 EXT(0, group7_rm1), 3442 EXT(0, group7_rm1),
3393 N, EXT(0, group7_rm3), 3443 N, EXT(0, group7_rm3),
3394 II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N, 3444 II(SrcNone | DstMem | Mov, em_smsw, smsw), N,
3395 II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), EXT(0, group7_rm7), 3445 II(SrcMem16 | Mov | Priv, em_lmsw, lmsw),
3446 EXT(0, group7_rm7),
3396} }; 3447} };
3397 3448
3398static struct opcode group8[] = { 3449static struct opcode group8[] = {
3399 N, N, N, N, 3450 N, N, N, N,
3400 I(DstMem | SrcImmByte | ModRM, em_bt), 3451 I(DstMem | SrcImmByte, em_bt),
3401 I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_bts), 3452 I(DstMem | SrcImmByte | Lock | PageTable, em_bts),
3402 I(DstMem | SrcImmByte | ModRM | Lock, em_btr), 3453 I(DstMem | SrcImmByte | Lock, em_btr),
3403 I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_btc), 3454 I(DstMem | SrcImmByte | Lock | PageTable, em_btc),
3404}; 3455};
3405 3456
3406static struct group_dual group9 = { { 3457static struct group_dual group9 = { {
3407 N, I(DstMem64 | ModRM | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N, 3458 N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
3408}, { 3459}, {
3409 N, N, N, N, N, N, N, N, 3460 N, N, N, N, N, N, N, N,
3410} }; 3461} };
3411 3462
3412static struct opcode group11[] = { 3463static struct opcode group11[] = {
3413 I(DstMem | SrcImm | ModRM | Mov | PageTable, em_mov), 3464 I(DstMem | SrcImm | Mov | PageTable, em_mov),
3414 X7(D(Undefined)), 3465 X7(D(Undefined)),
3415}; 3466};
3416 3467
3417static struct gprefix pfx_0f_6f_0f_7f = { 3468static struct gprefix pfx_0f_6f_0f_7f = {
3418 N, N, N, I(Sse, em_movdqu), 3469 I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov),
3470};
3471
3472static struct gprefix pfx_vmovntpx = {
3473 I(0, em_mov), N, N, N,
3419}; 3474};
3420 3475
3421static struct opcode opcode_table[256] = { 3476static struct opcode opcode_table[256] = {
@@ -3464,10 +3519,10 @@ static struct opcode opcode_table[256] = {
3464 /* 0x70 - 0x7F */ 3519 /* 0x70 - 0x7F */
3465 X16(D(SrcImmByte)), 3520 X16(D(SrcImmByte)),
3466 /* 0x80 - 0x87 */ 3521 /* 0x80 - 0x87 */
3467 G(ByteOp | DstMem | SrcImm | ModRM | Group, group1), 3522 G(ByteOp | DstMem | SrcImm, group1),
3468 G(DstMem | SrcImm | ModRM | Group, group1), 3523 G(DstMem | SrcImm, group1),
3469 G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1), 3524 G(ByteOp | DstMem | SrcImm | No64, group1),
3470 G(DstMem | SrcImmByte | ModRM | Group, group1), 3525 G(DstMem | SrcImmByte, group1),
3471 I2bv(DstMem | SrcReg | ModRM, em_test), 3526 I2bv(DstMem | SrcReg | ModRM, em_test),
3472 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_xchg), 3527 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_xchg),
3473 /* 0x88 - 0x8F */ 3528 /* 0x88 - 0x8F */
@@ -3549,7 +3604,8 @@ static struct opcode twobyte_table[256] = {
3549 IIP(ModRM | SrcMem | Priv | Op3264, em_cr_write, cr_write, check_cr_write), 3604 IIP(ModRM | SrcMem | Priv | Op3264, em_cr_write, cr_write, check_cr_write),
3550 IIP(ModRM | SrcMem | Priv | Op3264, em_dr_write, dr_write, check_dr_write), 3605 IIP(ModRM | SrcMem | Priv | Op3264, em_dr_write, dr_write, check_dr_write),
3551 N, N, N, N, 3606 N, N, N, N,
3552 N, N, N, N, N, N, N, N, 3607 N, N, N, GP(ModRM | DstMem | SrcReg | Sse | Mov | Aligned, &pfx_vmovntpx),
3608 N, N, N, N,
3553 /* 0x30 - 0x3F */ 3609 /* 0x30 - 0x3F */
3554 II(ImplicitOps | Priv, em_wrmsr, wrmsr), 3610 II(ImplicitOps | Priv, em_wrmsr, wrmsr),
3555 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), 3611 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
@@ -3897,17 +3953,16 @@ done_prefixes:
3897 } 3953 }
3898 ctxt->d = opcode.flags; 3954 ctxt->d = opcode.flags;
3899 3955
3956 if (ctxt->d & ModRM)
3957 ctxt->modrm = insn_fetch(u8, ctxt);
3958
3900 while (ctxt->d & GroupMask) { 3959 while (ctxt->d & GroupMask) {
3901 switch (ctxt->d & GroupMask) { 3960 switch (ctxt->d & GroupMask) {
3902 case Group: 3961 case Group:
3903 ctxt->modrm = insn_fetch(u8, ctxt);
3904 --ctxt->_eip;
3905 goffset = (ctxt->modrm >> 3) & 7; 3962 goffset = (ctxt->modrm >> 3) & 7;
3906 opcode = opcode.u.group[goffset]; 3963 opcode = opcode.u.group[goffset];
3907 break; 3964 break;
3908 case GroupDual: 3965 case GroupDual:
3909 ctxt->modrm = insn_fetch(u8, ctxt);
3910 --ctxt->_eip;
3911 goffset = (ctxt->modrm >> 3) & 7; 3966 goffset = (ctxt->modrm >> 3) & 7;
3912 if ((ctxt->modrm >> 6) == 3) 3967 if ((ctxt->modrm >> 6) == 3)
3913 opcode = opcode.u.gdual->mod3[goffset]; 3968 opcode = opcode.u.gdual->mod3[goffset];
@@ -3960,6 +4015,8 @@ done_prefixes:
3960 4015
3961 if (ctxt->d & Sse) 4016 if (ctxt->d & Sse)
3962 ctxt->op_bytes = 16; 4017 ctxt->op_bytes = 16;
4018 else if (ctxt->d & Mmx)
4019 ctxt->op_bytes = 8;
3963 4020
3964 /* ModRM and SIB bytes. */ 4021 /* ModRM and SIB bytes. */
3965 if (ctxt->d & ModRM) { 4022 if (ctxt->d & ModRM) {
@@ -4030,6 +4087,35 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
4030 return false; 4087 return false;
4031} 4088}
4032 4089
4090static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt)
4091{
4092 bool fault = false;
4093
4094 ctxt->ops->get_fpu(ctxt);
4095 asm volatile("1: fwait \n\t"
4096 "2: \n\t"
4097 ".pushsection .fixup,\"ax\" \n\t"
4098 "3: \n\t"
4099 "movb $1, %[fault] \n\t"
4100 "jmp 2b \n\t"
4101 ".popsection \n\t"
4102 _ASM_EXTABLE(1b, 3b)
4103 : [fault]"+qm"(fault));
4104 ctxt->ops->put_fpu(ctxt);
4105
4106 if (unlikely(fault))
4107 return emulate_exception(ctxt, MF_VECTOR, 0, false);
4108
4109 return X86EMUL_CONTINUE;
4110}
4111
4112static void fetch_possible_mmx_operand(struct x86_emulate_ctxt *ctxt,
4113 struct operand *op)
4114{
4115 if (op->type == OP_MM)
4116 read_mmx_reg(ctxt, &op->mm_val, op->addr.mm);
4117}
4118
4033int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) 4119int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
4034{ 4120{
4035 struct x86_emulate_ops *ops = ctxt->ops; 4121 struct x86_emulate_ops *ops = ctxt->ops;
@@ -4054,18 +4140,31 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
4054 goto done; 4140 goto done;
4055 } 4141 }
4056 4142
4057 if ((ctxt->d & Sse) 4143 if (((ctxt->d & (Sse|Mmx)) && ((ops->get_cr(ctxt, 0) & X86_CR0_EM)))
4058 && ((ops->get_cr(ctxt, 0) & X86_CR0_EM) 4144 || ((ctxt->d & Sse) && !(ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR))) {
4059 || !(ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR))) {
4060 rc = emulate_ud(ctxt); 4145 rc = emulate_ud(ctxt);
4061 goto done; 4146 goto done;
4062 } 4147 }
4063 4148
4064 if ((ctxt->d & Sse) && (ops->get_cr(ctxt, 0) & X86_CR0_TS)) { 4149 if ((ctxt->d & (Sse|Mmx)) && (ops->get_cr(ctxt, 0) & X86_CR0_TS)) {
4065 rc = emulate_nm(ctxt); 4150 rc = emulate_nm(ctxt);
4066 goto done; 4151 goto done;
4067 } 4152 }
4068 4153
4154 if (ctxt->d & Mmx) {
4155 rc = flush_pending_x87_faults(ctxt);
4156 if (rc != X86EMUL_CONTINUE)
4157 goto done;
4158 /*
4159 * Now that we know the fpu is exception safe, we can fetch
4160 * operands from it.
4161 */
4162 fetch_possible_mmx_operand(ctxt, &ctxt->src);
4163 fetch_possible_mmx_operand(ctxt, &ctxt->src2);
4164 if (!(ctxt->d & Mov))
4165 fetch_possible_mmx_operand(ctxt, &ctxt->dst);
4166 }
4167
4069 if (unlikely(ctxt->guest_mode) && ctxt->intercept) { 4168 if (unlikely(ctxt->guest_mode) && ctxt->intercept) {
4070 rc = emulator_check_intercept(ctxt, ctxt->intercept, 4169 rc = emulator_check_intercept(ctxt, ctxt->intercept,
4071 X86_ICPT_PRE_EXCEPT); 4170 X86_ICPT_PRE_EXCEPT);
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index d68f99df690..adba28f88d1 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -34,7 +34,6 @@
34 34
35#include <linux/kvm_host.h> 35#include <linux/kvm_host.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/workqueue.h>
38 37
39#include "irq.h" 38#include "irq.h"
40#include "i8254.h" 39#include "i8254.h"
@@ -249,7 +248,7 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
249 /* in this case, we had multiple outstanding pit interrupts 248 /* in this case, we had multiple outstanding pit interrupts
250 * that we needed to inject. Reinject 249 * that we needed to inject. Reinject
251 */ 250 */
252 queue_work(ps->pit->wq, &ps->pit->expired); 251 queue_kthread_work(&ps->pit->worker, &ps->pit->expired);
253 ps->irq_ack = 1; 252 ps->irq_ack = 1;
254 spin_unlock(&ps->inject_lock); 253 spin_unlock(&ps->inject_lock);
255} 254}
@@ -270,7 +269,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
270static void destroy_pit_timer(struct kvm_pit *pit) 269static void destroy_pit_timer(struct kvm_pit *pit)
271{ 270{
272 hrtimer_cancel(&pit->pit_state.pit_timer.timer); 271 hrtimer_cancel(&pit->pit_state.pit_timer.timer);
273 cancel_work_sync(&pit->expired); 272 flush_kthread_work(&pit->expired);
274} 273}
275 274
276static bool kpit_is_periodic(struct kvm_timer *ktimer) 275static bool kpit_is_periodic(struct kvm_timer *ktimer)
@@ -284,7 +283,7 @@ static struct kvm_timer_ops kpit_ops = {
284 .is_periodic = kpit_is_periodic, 283 .is_periodic = kpit_is_periodic,
285}; 284};
286 285
287static void pit_do_work(struct work_struct *work) 286static void pit_do_work(struct kthread_work *work)
288{ 287{
289 struct kvm_pit *pit = container_of(work, struct kvm_pit, expired); 288 struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
290 struct kvm *kvm = pit->kvm; 289 struct kvm *kvm = pit->kvm;
@@ -328,7 +327,7 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
328 327
329 if (ktimer->reinject || !atomic_read(&ktimer->pending)) { 328 if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
330 atomic_inc(&ktimer->pending); 329 atomic_inc(&ktimer->pending);
331 queue_work(pt->wq, &pt->expired); 330 queue_kthread_work(&pt->worker, &pt->expired);
332 } 331 }
333 332
334 if (ktimer->t_ops->is_periodic(ktimer)) { 333 if (ktimer->t_ops->is_periodic(ktimer)) {
@@ -353,7 +352,7 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
353 352
354 /* TODO The new value only affected after the retriggered */ 353 /* TODO The new value only affected after the retriggered */
355 hrtimer_cancel(&pt->timer); 354 hrtimer_cancel(&pt->timer);
356 cancel_work_sync(&ps->pit->expired); 355 flush_kthread_work(&ps->pit->expired);
357 pt->period = interval; 356 pt->period = interval;
358 ps->is_periodic = is_period; 357 ps->is_periodic = is_period;
359 358
@@ -669,6 +668,8 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
669{ 668{
670 struct kvm_pit *pit; 669 struct kvm_pit *pit;
671 struct kvm_kpit_state *pit_state; 670 struct kvm_kpit_state *pit_state;
671 struct pid *pid;
672 pid_t pid_nr;
672 int ret; 673 int ret;
673 674
674 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); 675 pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
@@ -685,14 +686,20 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
685 mutex_lock(&pit->pit_state.lock); 686 mutex_lock(&pit->pit_state.lock);
686 spin_lock_init(&pit->pit_state.inject_lock); 687 spin_lock_init(&pit->pit_state.inject_lock);
687 688
688 pit->wq = create_singlethread_workqueue("kvm-pit-wq"); 689 pid = get_pid(task_tgid(current));
689 if (!pit->wq) { 690 pid_nr = pid_vnr(pid);
691 put_pid(pid);
692
693 init_kthread_worker(&pit->worker);
694 pit->worker_task = kthread_run(kthread_worker_fn, &pit->worker,
695 "kvm-pit/%d", pid_nr);
696 if (IS_ERR(pit->worker_task)) {
690 mutex_unlock(&pit->pit_state.lock); 697 mutex_unlock(&pit->pit_state.lock);
691 kvm_free_irq_source_id(kvm, pit->irq_source_id); 698 kvm_free_irq_source_id(kvm, pit->irq_source_id);
692 kfree(pit); 699 kfree(pit);
693 return NULL; 700 return NULL;
694 } 701 }
695 INIT_WORK(&pit->expired, pit_do_work); 702 init_kthread_work(&pit->expired, pit_do_work);
696 703
697 kvm->arch.vpit = pit; 704 kvm->arch.vpit = pit;
698 pit->kvm = kvm; 705 pit->kvm = kvm;
@@ -736,7 +743,7 @@ fail:
736 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier); 743 kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
737 kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier); 744 kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
738 kvm_free_irq_source_id(kvm, pit->irq_source_id); 745 kvm_free_irq_source_id(kvm, pit->irq_source_id);
739 destroy_workqueue(pit->wq); 746 kthread_stop(pit->worker_task);
740 kfree(pit); 747 kfree(pit);
741 return NULL; 748 return NULL;
742} 749}
@@ -756,10 +763,10 @@ void kvm_free_pit(struct kvm *kvm)
756 mutex_lock(&kvm->arch.vpit->pit_state.lock); 763 mutex_lock(&kvm->arch.vpit->pit_state.lock);
757 timer = &kvm->arch.vpit->pit_state.pit_timer.timer; 764 timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
758 hrtimer_cancel(timer); 765 hrtimer_cancel(timer);
759 cancel_work_sync(&kvm->arch.vpit->expired); 766 flush_kthread_work(&kvm->arch.vpit->expired);
767 kthread_stop(kvm->arch.vpit->worker_task);
760 kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id); 768 kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id);
761 mutex_unlock(&kvm->arch.vpit->pit_state.lock); 769 mutex_unlock(&kvm->arch.vpit->pit_state.lock);
762 destroy_workqueue(kvm->arch.vpit->wq);
763 kfree(kvm->arch.vpit); 770 kfree(kvm->arch.vpit);
764 } 771 }
765} 772}
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index 51a97426e79..fdf40425ea1 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -1,6 +1,8 @@
1#ifndef __I8254_H 1#ifndef __I8254_H
2#define __I8254_H 2#define __I8254_H
3 3
4#include <linux/kthread.h>
5
4#include "iodev.h" 6#include "iodev.h"
5 7
6struct kvm_kpit_channel_state { 8struct kvm_kpit_channel_state {
@@ -39,8 +41,9 @@ struct kvm_pit {
39 struct kvm_kpit_state pit_state; 41 struct kvm_kpit_state pit_state;
40 int irq_source_id; 42 int irq_source_id;
41 struct kvm_irq_mask_notifier mask_notifier; 43 struct kvm_irq_mask_notifier mask_notifier;
42 struct workqueue_struct *wq; 44 struct kthread_worker worker;
43 struct work_struct expired; 45 struct task_struct *worker_task;
46 struct kthread_work expired;
44}; 47};
45 48
46#define KVM_PIT_BASE_ADDRESS 0x40 49#define KVM_PIT_BASE_ADDRESS 0x40
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 858432287ab..93c15743f1e 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -92,6 +92,11 @@ static inline int apic_test_and_clear_vector(int vec, void *bitmap)
92 return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); 92 return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
93} 93}
94 94
95static inline int apic_test_vector(int vec, void *bitmap)
96{
97 return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
98}
99
95static inline void apic_set_vector(int vec, void *bitmap) 100static inline void apic_set_vector(int vec, void *bitmap)
96{ 101{
97 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); 102 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
@@ -480,7 +485,6 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
480static void apic_set_eoi(struct kvm_lapic *apic) 485static void apic_set_eoi(struct kvm_lapic *apic)
481{ 486{
482 int vector = apic_find_highest_isr(apic); 487 int vector = apic_find_highest_isr(apic);
483 int trigger_mode;
484 /* 488 /*
485 * Not every write EOI will has corresponding ISR, 489 * Not every write EOI will has corresponding ISR,
486 * one example is when Kernel check timer on setup_IO_APIC 490 * one example is when Kernel check timer on setup_IO_APIC
@@ -491,12 +495,15 @@ static void apic_set_eoi(struct kvm_lapic *apic)
491 apic_clear_vector(vector, apic->regs + APIC_ISR); 495 apic_clear_vector(vector, apic->regs + APIC_ISR);
492 apic_update_ppr(apic); 496 apic_update_ppr(apic);
493 497
494 if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR)) 498 if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) &&
495 trigger_mode = IOAPIC_LEVEL_TRIG; 499 kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) {
496 else 500 int trigger_mode;
497 trigger_mode = IOAPIC_EDGE_TRIG; 501 if (apic_test_vector(vector, apic->regs + APIC_TMR))
498 if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) 502 trigger_mode = IOAPIC_LEVEL_TRIG;
503 else
504 trigger_mode = IOAPIC_EDGE_TRIG;
499 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); 505 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
506 }
500 kvm_make_request(KVM_REQ_EVENT, apic->vcpu); 507 kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
501} 508}
502 509
@@ -1081,6 +1088,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
1081 apic_update_ppr(apic); 1088 apic_update_ppr(apic);
1082 1089
1083 vcpu->arch.apic_arb_prio = 0; 1090 vcpu->arch.apic_arb_prio = 0;
1091 vcpu->arch.apic_attention = 0;
1084 1092
1085 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr=" 1093 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr="
1086 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__, 1094 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__,
@@ -1280,7 +1288,7 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
1280 u32 data; 1288 u32 data;
1281 void *vapic; 1289 void *vapic;
1282 1290
1283 if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) 1291 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
1284 return; 1292 return;
1285 1293
1286 vapic = kmap_atomic(vcpu->arch.apic->vapic_page); 1294 vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
@@ -1297,7 +1305,7 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
1297 struct kvm_lapic *apic; 1305 struct kvm_lapic *apic;
1298 void *vapic; 1306 void *vapic;
1299 1307
1300 if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr) 1308 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
1301 return; 1309 return;
1302 1310
1303 apic = vcpu->arch.apic; 1311 apic = vcpu->arch.apic;
@@ -1317,10 +1325,11 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
1317 1325
1318void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) 1326void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
1319{ 1327{
1320 if (!irqchip_in_kernel(vcpu->kvm))
1321 return;
1322
1323 vcpu->arch.apic->vapic_addr = vapic_addr; 1328 vcpu->arch.apic->vapic_addr = vapic_addr;
1329 if (vapic_addr)
1330 __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
1331 else
1332 __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
1324} 1333}
1325 1334
1326int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1335int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 4cb16426884..72102e0ab7c 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -135,8 +135,6 @@ module_param(dbg, bool, 0644);
135#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \ 135#define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
136 | PT64_NX_MASK) 136 | PT64_NX_MASK)
137 137
138#define PTE_LIST_EXT 4
139
140#define ACC_EXEC_MASK 1 138#define ACC_EXEC_MASK 1
141#define ACC_WRITE_MASK PT_WRITABLE_MASK 139#define ACC_WRITE_MASK PT_WRITABLE_MASK
142#define ACC_USER_MASK PT_USER_MASK 140#define ACC_USER_MASK PT_USER_MASK
@@ -151,6 +149,9 @@ module_param(dbg, bool, 0644);
151 149
152#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) 150#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
153 151
152/* make pte_list_desc fit well in cache line */
153#define PTE_LIST_EXT 3
154
154struct pte_list_desc { 155struct pte_list_desc {
155 u64 *sptes[PTE_LIST_EXT]; 156 u64 *sptes[PTE_LIST_EXT];
156 struct pte_list_desc *more; 157 struct pte_list_desc *more;
@@ -550,19 +551,29 @@ static u64 mmu_spte_get_lockless(u64 *sptep)
550 551
551static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu) 552static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu)
552{ 553{
553 rcu_read_lock(); 554 /*
554 atomic_inc(&vcpu->kvm->arch.reader_counter); 555 * Prevent page table teardown by making any free-er wait during
555 556 * kvm_flush_remote_tlbs() IPI to all active vcpus.
556 /* Increase the counter before walking shadow page table */ 557 */
557 smp_mb__after_atomic_inc(); 558 local_irq_disable();
559 vcpu->mode = READING_SHADOW_PAGE_TABLES;
560 /*
561 * Make sure a following spte read is not reordered ahead of the write
562 * to vcpu->mode.
563 */
564 smp_mb();
558} 565}
559 566
560static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu) 567static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu)
561{ 568{
562 /* Decrease the counter after walking shadow page table finished */ 569 /*
563 smp_mb__before_atomic_dec(); 570 * Make sure the write to vcpu->mode is not reordered in front of
564 atomic_dec(&vcpu->kvm->arch.reader_counter); 571 * reads to sptes. If it does, kvm_commit_zap_page() can see us
565 rcu_read_unlock(); 572 * OUTSIDE_GUEST_MODE and proceed to free the shadow page table.
573 */
574 smp_mb();
575 vcpu->mode = OUTSIDE_GUEST_MODE;
576 local_irq_enable();
566} 577}
567 578
568static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, 579static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
@@ -841,32 +852,6 @@ static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte,
841 return count; 852 return count;
842} 853}
843 854
844static u64 *pte_list_next(unsigned long *pte_list, u64 *spte)
845{
846 struct pte_list_desc *desc;
847 u64 *prev_spte;
848 int i;
849
850 if (!*pte_list)
851 return NULL;
852 else if (!(*pte_list & 1)) {
853 if (!spte)
854 return (u64 *)*pte_list;
855 return NULL;
856 }
857 desc = (struct pte_list_desc *)(*pte_list & ~1ul);
858 prev_spte = NULL;
859 while (desc) {
860 for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i) {
861 if (prev_spte == spte)
862 return desc->sptes[i];
863 prev_spte = desc->sptes[i];
864 }
865 desc = desc->more;
866 }
867 return NULL;
868}
869
870static void 855static void
871pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc, 856pte_list_desc_remove_entry(unsigned long *pte_list, struct pte_list_desc *desc,
872 int i, struct pte_list_desc *prev_desc) 857 int i, struct pte_list_desc *prev_desc)
@@ -987,11 +972,6 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
987 return pte_list_add(vcpu, spte, rmapp); 972 return pte_list_add(vcpu, spte, rmapp);
988} 973}
989 974
990static u64 *rmap_next(unsigned long *rmapp, u64 *spte)
991{
992 return pte_list_next(rmapp, spte);
993}
994
995static void rmap_remove(struct kvm *kvm, u64 *spte) 975static void rmap_remove(struct kvm *kvm, u64 *spte)
996{ 976{
997 struct kvm_mmu_page *sp; 977 struct kvm_mmu_page *sp;
@@ -1004,106 +984,201 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
1004 pte_list_remove(spte, rmapp); 984 pte_list_remove(spte, rmapp);
1005} 985}
1006 986
987/*
988 * Used by the following functions to iterate through the sptes linked by a
989 * rmap. All fields are private and not assumed to be used outside.
990 */
991struct rmap_iterator {
992 /* private fields */
993 struct pte_list_desc *desc; /* holds the sptep if not NULL */
994 int pos; /* index of the sptep */
995};
996
997/*
998 * Iteration must be started by this function. This should also be used after
999 * removing/dropping sptes from the rmap link because in such cases the
1000 * information in the itererator may not be valid.
1001 *
1002 * Returns sptep if found, NULL otherwise.
1003 */
1004static u64 *rmap_get_first(unsigned long rmap, struct rmap_iterator *iter)
1005{
1006 if (!rmap)
1007 return NULL;
1008
1009 if (!(rmap & 1)) {
1010 iter->desc = NULL;
1011 return (u64 *)rmap;
1012 }
1013
1014 iter->desc = (struct pte_list_desc *)(rmap & ~1ul);
1015 iter->pos = 0;
1016 return iter->desc->sptes[iter->pos];
1017}
1018
1019/*
1020 * Must be used with a valid iterator: e.g. after rmap_get_first().
1021 *
1022 * Returns sptep if found, NULL otherwise.
1023 */
1024static u64 *rmap_get_next(struct rmap_iterator *iter)
1025{
1026 if (iter->desc) {
1027 if (iter->pos < PTE_LIST_EXT - 1) {
1028 u64 *sptep;
1029
1030 ++iter->pos;
1031 sptep = iter->desc->sptes[iter->pos];
1032 if (sptep)
1033 return sptep;
1034 }
1035
1036 iter->desc = iter->desc->more;
1037
1038 if (iter->desc) {
1039 iter->pos = 0;
1040 /* desc->sptes[0] cannot be NULL */
1041 return iter->desc->sptes[iter->pos];
1042 }
1043 }
1044
1045 return NULL;
1046}
1047
1007static void drop_spte(struct kvm *kvm, u64 *sptep) 1048static void drop_spte(struct kvm *kvm, u64 *sptep)
1008{ 1049{
1009 if (mmu_spte_clear_track_bits(sptep)) 1050 if (mmu_spte_clear_track_bits(sptep))
1010 rmap_remove(kvm, sptep); 1051 rmap_remove(kvm, sptep);
1011} 1052}
1012 1053
1013int kvm_mmu_rmap_write_protect(struct kvm *kvm, u64 gfn, 1054static int __rmap_write_protect(struct kvm *kvm, unsigned long *rmapp, int level)
1014 struct kvm_memory_slot *slot)
1015{ 1055{
1016 unsigned long *rmapp; 1056 u64 *sptep;
1017 u64 *spte; 1057 struct rmap_iterator iter;
1018 int i, write_protected = 0; 1058 int write_protected = 0;
1019 1059
1020 rmapp = __gfn_to_rmap(gfn, PT_PAGE_TABLE_LEVEL, slot); 1060 for (sptep = rmap_get_first(*rmapp, &iter); sptep;) {
1021 spte = rmap_next(rmapp, NULL); 1061 BUG_ON(!(*sptep & PT_PRESENT_MASK));
1022 while (spte) { 1062 rmap_printk("rmap_write_protect: spte %p %llx\n", sptep, *sptep);
1023 BUG_ON(!(*spte & PT_PRESENT_MASK)); 1063
1024 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); 1064 if (!is_writable_pte(*sptep)) {
1025 if (is_writable_pte(*spte)) { 1065 sptep = rmap_get_next(&iter);
1026 mmu_spte_update(spte, *spte & ~PT_WRITABLE_MASK); 1066 continue;
1027 write_protected = 1;
1028 } 1067 }
1029 spte = rmap_next(rmapp, spte);
1030 }
1031 1068
1032 /* check for huge page mappings */ 1069 if (level == PT_PAGE_TABLE_LEVEL) {
1033 for (i = PT_DIRECTORY_LEVEL; 1070 mmu_spte_update(sptep, *sptep & ~PT_WRITABLE_MASK);
1034 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { 1071 sptep = rmap_get_next(&iter);
1035 rmapp = __gfn_to_rmap(gfn, i, slot); 1072 } else {
1036 spte = rmap_next(rmapp, NULL); 1073 BUG_ON(!is_large_pte(*sptep));
1037 while (spte) { 1074 drop_spte(kvm, sptep);
1038 BUG_ON(!(*spte & PT_PRESENT_MASK)); 1075 --kvm->stat.lpages;
1039 BUG_ON(!is_large_pte(*spte)); 1076 sptep = rmap_get_first(*rmapp, &iter);
1040 pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
1041 if (is_writable_pte(*spte)) {
1042 drop_spte(kvm, spte);
1043 --kvm->stat.lpages;
1044 spte = NULL;
1045 write_protected = 1;
1046 }
1047 spte = rmap_next(rmapp, spte);
1048 } 1077 }
1078
1079 write_protected = 1;
1049 } 1080 }
1050 1081
1051 return write_protected; 1082 return write_protected;
1052} 1083}
1053 1084
1085/**
1086 * kvm_mmu_write_protect_pt_masked - write protect selected PT level pages
1087 * @kvm: kvm instance
1088 * @slot: slot to protect
1089 * @gfn_offset: start of the BITS_PER_LONG pages we care about
1090 * @mask: indicates which pages we should protect
1091 *
1092 * Used when we do not need to care about huge page mappings: e.g. during dirty
1093 * logging we do not have any such mappings.
1094 */
1095void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
1096 struct kvm_memory_slot *slot,
1097 gfn_t gfn_offset, unsigned long mask)
1098{
1099 unsigned long *rmapp;
1100
1101 while (mask) {
1102 rmapp = &slot->rmap[gfn_offset + __ffs(mask)];
1103 __rmap_write_protect(kvm, rmapp, PT_PAGE_TABLE_LEVEL);
1104
1105 /* clear the first set bit */
1106 mask &= mask - 1;
1107 }
1108}
1109
1054static int rmap_write_protect(struct kvm *kvm, u64 gfn) 1110static int rmap_write_protect(struct kvm *kvm, u64 gfn)
1055{ 1111{
1056 struct kvm_memory_slot *slot; 1112 struct kvm_memory_slot *slot;
1113 unsigned long *rmapp;
1114 int i;
1115 int write_protected = 0;
1057 1116
1058 slot = gfn_to_memslot(kvm, gfn); 1117 slot = gfn_to_memslot(kvm, gfn);
1059 return kvm_mmu_rmap_write_protect(kvm, gfn, slot); 1118
1119 for (i = PT_PAGE_TABLE_LEVEL;
1120 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
1121 rmapp = __gfn_to_rmap(gfn, i, slot);
1122 write_protected |= __rmap_write_protect(kvm, rmapp, i);
1123 }
1124
1125 return write_protected;
1060} 1126}
1061 1127
1062static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, 1128static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
1063 unsigned long data) 1129 unsigned long data)
1064{ 1130{
1065 u64 *spte; 1131 u64 *sptep;
1132 struct rmap_iterator iter;
1066 int need_tlb_flush = 0; 1133 int need_tlb_flush = 0;
1067 1134
1068 while ((spte = rmap_next(rmapp, NULL))) { 1135 while ((sptep = rmap_get_first(*rmapp, &iter))) {
1069 BUG_ON(!(*spte & PT_PRESENT_MASK)); 1136 BUG_ON(!(*sptep & PT_PRESENT_MASK));
1070 rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte); 1137 rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", sptep, *sptep);
1071 drop_spte(kvm, spte); 1138
1139 drop_spte(kvm, sptep);
1072 need_tlb_flush = 1; 1140 need_tlb_flush = 1;
1073 } 1141 }
1142
1074 return need_tlb_flush; 1143 return need_tlb_flush;
1075} 1144}
1076 1145
1077static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, 1146static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp,
1078 unsigned long data) 1147 unsigned long data)
1079{ 1148{
1149 u64 *sptep;
1150 struct rmap_iterator iter;
1080 int need_flush = 0; 1151 int need_flush = 0;
1081 u64 *spte, new_spte; 1152 u64 new_spte;
1082 pte_t *ptep = (pte_t *)data; 1153 pte_t *ptep = (pte_t *)data;
1083 pfn_t new_pfn; 1154 pfn_t new_pfn;
1084 1155
1085 WARN_ON(pte_huge(*ptep)); 1156 WARN_ON(pte_huge(*ptep));
1086 new_pfn = pte_pfn(*ptep); 1157 new_pfn = pte_pfn(*ptep);
1087 spte = rmap_next(rmapp, NULL); 1158
1088 while (spte) { 1159 for (sptep = rmap_get_first(*rmapp, &iter); sptep;) {
1089 BUG_ON(!is_shadow_present_pte(*spte)); 1160 BUG_ON(!is_shadow_present_pte(*sptep));
1090 rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", spte, *spte); 1161 rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", sptep, *sptep);
1162
1091 need_flush = 1; 1163 need_flush = 1;
1164
1092 if (pte_write(*ptep)) { 1165 if (pte_write(*ptep)) {
1093 drop_spte(kvm, spte); 1166 drop_spte(kvm, sptep);
1094 spte = rmap_next(rmapp, NULL); 1167 sptep = rmap_get_first(*rmapp, &iter);
1095 } else { 1168 } else {
1096 new_spte = *spte &~ (PT64_BASE_ADDR_MASK); 1169 new_spte = *sptep & ~PT64_BASE_ADDR_MASK;
1097 new_spte |= (u64)new_pfn << PAGE_SHIFT; 1170 new_spte |= (u64)new_pfn << PAGE_SHIFT;
1098 1171
1099 new_spte &= ~PT_WRITABLE_MASK; 1172 new_spte &= ~PT_WRITABLE_MASK;
1100 new_spte &= ~SPTE_HOST_WRITEABLE; 1173 new_spte &= ~SPTE_HOST_WRITEABLE;
1101 new_spte &= ~shadow_accessed_mask; 1174 new_spte &= ~shadow_accessed_mask;
1102 mmu_spte_clear_track_bits(spte); 1175
1103 mmu_spte_set(spte, new_spte); 1176 mmu_spte_clear_track_bits(sptep);
1104 spte = rmap_next(rmapp, spte); 1177 mmu_spte_set(sptep, new_spte);
1178 sptep = rmap_get_next(&iter);
1105 } 1179 }
1106 } 1180 }
1181
1107 if (need_flush) 1182 if (need_flush)
1108 kvm_flush_remote_tlbs(kvm); 1183 kvm_flush_remote_tlbs(kvm);
1109 1184
@@ -1162,7 +1237,8 @@ void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
1162static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, 1237static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1163 unsigned long data) 1238 unsigned long data)
1164{ 1239{
1165 u64 *spte; 1240 u64 *sptep;
1241 struct rmap_iterator iter;
1166 int young = 0; 1242 int young = 0;
1167 1243
1168 /* 1244 /*
@@ -1175,25 +1251,24 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1175 if (!shadow_accessed_mask) 1251 if (!shadow_accessed_mask)
1176 return kvm_unmap_rmapp(kvm, rmapp, data); 1252 return kvm_unmap_rmapp(kvm, rmapp, data);
1177 1253
1178 spte = rmap_next(rmapp, NULL); 1254 for (sptep = rmap_get_first(*rmapp, &iter); sptep;
1179 while (spte) { 1255 sptep = rmap_get_next(&iter)) {
1180 int _young; 1256 BUG_ON(!(*sptep & PT_PRESENT_MASK));
1181 u64 _spte = *spte; 1257
1182 BUG_ON(!(_spte & PT_PRESENT_MASK)); 1258 if (*sptep & PT_ACCESSED_MASK) {
1183 _young = _spte & PT_ACCESSED_MASK;
1184 if (_young) {
1185 young = 1; 1259 young = 1;
1186 clear_bit(PT_ACCESSED_SHIFT, (unsigned long *)spte); 1260 clear_bit(PT_ACCESSED_SHIFT, (unsigned long *)sptep);
1187 } 1261 }
1188 spte = rmap_next(rmapp, spte);
1189 } 1262 }
1263
1190 return young; 1264 return young;
1191} 1265}
1192 1266
1193static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp, 1267static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1194 unsigned long data) 1268 unsigned long data)
1195{ 1269{
1196 u64 *spte; 1270 u64 *sptep;
1271 struct rmap_iterator iter;
1197 int young = 0; 1272 int young = 0;
1198 1273
1199 /* 1274 /*
@@ -1204,16 +1279,14 @@ static int kvm_test_age_rmapp(struct kvm *kvm, unsigned long *rmapp,
1204 if (!shadow_accessed_mask) 1279 if (!shadow_accessed_mask)
1205 goto out; 1280 goto out;
1206 1281
1207 spte = rmap_next(rmapp, NULL); 1282 for (sptep = rmap_get_first(*rmapp, &iter); sptep;
1208 while (spte) { 1283 sptep = rmap_get_next(&iter)) {
1209 u64 _spte = *spte; 1284 BUG_ON(!(*sptep & PT_PRESENT_MASK));
1210 BUG_ON(!(_spte & PT_PRESENT_MASK)); 1285
1211 young = _spte & PT_ACCESSED_MASK; 1286 if (*sptep & PT_ACCESSED_MASK) {
1212 if (young) {
1213 young = 1; 1287 young = 1;
1214 break; 1288 break;
1215 } 1289 }
1216 spte = rmap_next(rmapp, spte);
1217 } 1290 }
1218out: 1291out:
1219 return young; 1292 return young;
@@ -1865,10 +1938,11 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
1865 1938
1866static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) 1939static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
1867{ 1940{
1868 u64 *parent_pte; 1941 u64 *sptep;
1942 struct rmap_iterator iter;
1869 1943
1870 while ((parent_pte = pte_list_next(&sp->parent_ptes, NULL))) 1944 while ((sptep = rmap_get_first(sp->parent_ptes, &iter)))
1871 drop_parent_pte(sp, parent_pte); 1945 drop_parent_pte(sp, sptep);
1872} 1946}
1873 1947
1874static int mmu_zap_unsync_children(struct kvm *kvm, 1948static int mmu_zap_unsync_children(struct kvm *kvm,
@@ -1925,30 +1999,6 @@ static int kvm_mmu_prepare_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp,
1925 return ret; 1999 return ret;
1926} 2000}
1927 2001
1928static void kvm_mmu_isolate_pages(struct list_head *invalid_list)
1929{
1930 struct kvm_mmu_page *sp;
1931
1932 list_for_each_entry(sp, invalid_list, link)
1933 kvm_mmu_isolate_page(sp);
1934}
1935
1936static void free_pages_rcu(struct rcu_head *head)
1937{
1938 struct kvm_mmu_page *next, *sp;
1939
1940 sp = container_of(head, struct kvm_mmu_page, rcu);
1941 while (sp) {
1942 if (!list_empty(&sp->link))
1943 next = list_first_entry(&sp->link,
1944 struct kvm_mmu_page, link);
1945 else
1946 next = NULL;
1947 kvm_mmu_free_page(sp);
1948 sp = next;
1949 }
1950}
1951
1952static void kvm_mmu_commit_zap_page(struct kvm *kvm, 2002static void kvm_mmu_commit_zap_page(struct kvm *kvm,
1953 struct list_head *invalid_list) 2003 struct list_head *invalid_list)
1954{ 2004{
@@ -1957,17 +2007,17 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm,
1957 if (list_empty(invalid_list)) 2007 if (list_empty(invalid_list))
1958 return; 2008 return;
1959 2009
1960 kvm_flush_remote_tlbs(kvm); 2010 /*
1961 2011 * wmb: make sure everyone sees our modifications to the page tables
1962 if (atomic_read(&kvm->arch.reader_counter)) { 2012 * rmb: make sure we see changes to vcpu->mode
1963 kvm_mmu_isolate_pages(invalid_list); 2013 */
1964 sp = list_first_entry(invalid_list, struct kvm_mmu_page, link); 2014 smp_mb();
1965 list_del_init(invalid_list);
1966 2015
1967 trace_kvm_mmu_delay_free_pages(sp); 2016 /*
1968 call_rcu(&sp->rcu, free_pages_rcu); 2017 * Wait for all vcpus to exit guest mode and/or lockless shadow
1969 return; 2018 * page table walks.
1970 } 2019 */
2020 kvm_flush_remote_tlbs(kvm);
1971 2021
1972 do { 2022 do {
1973 sp = list_first_entry(invalid_list, struct kvm_mmu_page, link); 2023 sp = list_first_entry(invalid_list, struct kvm_mmu_page, link);
@@ -1975,7 +2025,6 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm,
1975 kvm_mmu_isolate_page(sp); 2025 kvm_mmu_isolate_page(sp);
1976 kvm_mmu_free_page(sp); 2026 kvm_mmu_free_page(sp);
1977 } while (!list_empty(invalid_list)); 2027 } while (!list_empty(invalid_list));
1978
1979} 2028}
1980 2029
1981/* 2030/*
@@ -3554,7 +3603,7 @@ static bool detect_write_flooding(struct kvm_mmu_page *sp)
3554 * Skip write-flooding detected for the sp whose level is 1, because 3603 * Skip write-flooding detected for the sp whose level is 1, because
3555 * it can become unsync, then the guest page is not write-protected. 3604 * it can become unsync, then the guest page is not write-protected.
3556 */ 3605 */
3557 if (sp->role.level == 1) 3606 if (sp->role.level == PT_PAGE_TABLE_LEVEL)
3558 return false; 3607 return false;
3559 3608
3560 return ++sp->write_flooding_count >= 3; 3609 return ++sp->write_flooding_count >= 3;
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index 715da5a19a5..7d7d0b9e23e 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -192,7 +192,8 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
192{ 192{
193 struct kvm_memory_slot *slot; 193 struct kvm_memory_slot *slot;
194 unsigned long *rmapp; 194 unsigned long *rmapp;
195 u64 *spte; 195 u64 *sptep;
196 struct rmap_iterator iter;
196 197
197 if (sp->role.direct || sp->unsync || sp->role.invalid) 198 if (sp->role.direct || sp->unsync || sp->role.invalid)
198 return; 199 return;
@@ -200,13 +201,12 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp)
200 slot = gfn_to_memslot(kvm, sp->gfn); 201 slot = gfn_to_memslot(kvm, sp->gfn);
201 rmapp = &slot->rmap[sp->gfn - slot->base_gfn]; 202 rmapp = &slot->rmap[sp->gfn - slot->base_gfn];
202 203
203 spte = rmap_next(rmapp, NULL); 204 for (sptep = rmap_get_first(*rmapp, &iter); sptep;
204 while (spte) { 205 sptep = rmap_get_next(&iter)) {
205 if (is_writable_pte(*spte)) 206 if (is_writable_pte(*sptep))
206 audit_printk(kvm, "shadow page has writable " 207 audit_printk(kvm, "shadow page has writable "
207 "mappings: gfn %llx role %x\n", 208 "mappings: gfn %llx role %x\n",
208 sp->gfn, sp->role.word); 209 sp->gfn, sp->role.word);
209 spte = rmap_next(rmapp, spte);
210 } 210 }
211} 211}
212 212
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index df5a70311be..34f970937ef 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -658,7 +658,7 @@ static gpa_t FNAME(get_level1_sp_gpa)(struct kvm_mmu_page *sp)
658{ 658{
659 int offset = 0; 659 int offset = 0;
660 660
661 WARN_ON(sp->role.level != 1); 661 WARN_ON(sp->role.level != PT_PAGE_TABLE_LEVEL);
662 662
663 if (PTTYPE == 32) 663 if (PTTYPE == 32)
664 offset = sp->role.quadrant << PT64_LEVEL_BITS; 664 offset = sp->role.quadrant << PT64_LEVEL_BITS;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index e334389e1c7..f75af406b26 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -22,6 +22,7 @@
22#include "x86.h" 22#include "x86.h"
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/mod_devicetable.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
27#include <linux/highmem.h> 28#include <linux/highmem.h>
@@ -42,6 +43,12 @@
42MODULE_AUTHOR("Qumranet"); 43MODULE_AUTHOR("Qumranet");
43MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
44 45
46static const struct x86_cpu_id svm_cpu_id[] = {
47 X86_FEATURE_MATCH(X86_FEATURE_SVM),
48 {}
49};
50MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id);
51
45#define IOPM_ALLOC_ORDER 2 52#define IOPM_ALLOC_ORDER 2
46#define MSRPM_ALLOC_ORDER 1 53#define MSRPM_ALLOC_ORDER 1
47 54
@@ -3240,6 +3247,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
3240 svm_clear_vintr(svm); 3247 svm_clear_vintr(svm);
3241 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; 3248 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
3242 mark_dirty(svm->vmcb, VMCB_INTR); 3249 mark_dirty(svm->vmcb, VMCB_INTR);
3250 ++svm->vcpu.stat.irq_window_exits;
3243 /* 3251 /*
3244 * If the user space waits to inject interrupts, exit as soon as 3252 * If the user space waits to inject interrupts, exit as soon as
3245 * possible 3253 * possible
@@ -3247,7 +3255,6 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
3247 if (!irqchip_in_kernel(svm->vcpu.kvm) && 3255 if (!irqchip_in_kernel(svm->vcpu.kvm) &&
3248 kvm_run->request_interrupt_window && 3256 kvm_run->request_interrupt_window &&
3249 !kvm_cpu_has_interrupt(&svm->vcpu)) { 3257 !kvm_cpu_has_interrupt(&svm->vcpu)) {
3250 ++svm->vcpu.stat.irq_window_exits;
3251 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; 3258 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
3252 return 0; 3259 return 0;
3253 } 3260 }
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 4ff0ab9bc3c..32eb5886629 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -27,6 +27,7 @@
27#include <linux/highmem.h> 27#include <linux/highmem.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/mod_devicetable.h>
30#include <linux/ftrace_event.h> 31#include <linux/ftrace_event.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32#include <linux/tboot.h> 33#include <linux/tboot.h>
@@ -51,6 +52,12 @@
51MODULE_AUTHOR("Qumranet"); 52MODULE_AUTHOR("Qumranet");
52MODULE_LICENSE("GPL"); 53MODULE_LICENSE("GPL");
53 54
55static const struct x86_cpu_id vmx_cpu_id[] = {
56 X86_FEATURE_MATCH(X86_FEATURE_VMX),
57 {}
58};
59MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id);
60
54static bool __read_mostly enable_vpid = 1; 61static bool __read_mostly enable_vpid = 1;
55module_param_named(vpid, enable_vpid, bool, 0444); 62module_param_named(vpid, enable_vpid, bool, 0444);
56 63
@@ -386,6 +393,9 @@ struct vcpu_vmx {
386 struct { 393 struct {
387 int loaded; 394 int loaded;
388 u16 fs_sel, gs_sel, ldt_sel; 395 u16 fs_sel, gs_sel, ldt_sel;
396#ifdef CONFIG_X86_64
397 u16 ds_sel, es_sel;
398#endif
389 int gs_ldt_reload_needed; 399 int gs_ldt_reload_needed;
390 int fs_reload_needed; 400 int fs_reload_needed;
391 } host_state; 401 } host_state;
@@ -1411,6 +1421,11 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
1411 } 1421 }
1412 1422
1413#ifdef CONFIG_X86_64 1423#ifdef CONFIG_X86_64
1424 savesegment(ds, vmx->host_state.ds_sel);
1425 savesegment(es, vmx->host_state.es_sel);
1426#endif
1427
1428#ifdef CONFIG_X86_64
1414 vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE)); 1429 vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
1415 vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE)); 1430 vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
1416#else 1431#else
@@ -1450,6 +1465,19 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
1450 } 1465 }
1451 if (vmx->host_state.fs_reload_needed) 1466 if (vmx->host_state.fs_reload_needed)
1452 loadsegment(fs, vmx->host_state.fs_sel); 1467 loadsegment(fs, vmx->host_state.fs_sel);
1468#ifdef CONFIG_X86_64
1469 if (unlikely(vmx->host_state.ds_sel | vmx->host_state.es_sel)) {
1470 loadsegment(ds, vmx->host_state.ds_sel);
1471 loadsegment(es, vmx->host_state.es_sel);
1472 }
1473#else
1474 /*
1475 * The sysexit path does not restore ds/es, so we must set them to
1476 * a reasonable value ourselves.
1477 */
1478 loadsegment(ds, __USER_DS);
1479 loadsegment(es, __USER_DS);
1480#endif
1453 reload_tss(); 1481 reload_tss();
1454#ifdef CONFIG_X86_64 1482#ifdef CONFIG_X86_64
1455 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base); 1483 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
@@ -3633,8 +3661,18 @@ static void vmx_set_constant_host_state(void)
3633 vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */ 3661 vmcs_writel(HOST_CR3, read_cr3()); /* 22.2.3 FIXME: shadow tables */
3634 3662
3635 vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ 3663 vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */
3664#ifdef CONFIG_X86_64
3665 /*
3666 * Load null selectors, so we can avoid reloading them in
3667 * __vmx_load_host_state(), in case userspace uses the null selectors
3668 * too (the expected case).
3669 */
3670 vmcs_write16(HOST_DS_SELECTOR, 0);
3671 vmcs_write16(HOST_ES_SELECTOR, 0);
3672#else
3636 vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ 3673 vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
3637 vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ 3674 vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */
3675#endif
3638 vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ 3676 vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */
3639 vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ 3677 vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */
3640 3678
@@ -6256,7 +6294,6 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
6256 } 6294 }
6257 } 6295 }
6258 6296
6259 asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
6260 vmx->loaded_vmcs->launched = 1; 6297 vmx->loaded_vmcs->launched = 1;
6261 6298
6262 vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); 6299 vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
@@ -6343,7 +6380,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
6343 return &vmx->vcpu; 6380 return &vmx->vcpu;
6344 6381
6345free_vmcs: 6382free_vmcs:
6346 free_vmcs(vmx->loaded_vmcs->vmcs); 6383 free_loaded_vmcs(vmx->loaded_vmcs);
6347free_msrs: 6384free_msrs:
6348 kfree(vmx->guest_msrs); 6385 kfree(vmx->guest_msrs);
6349uninit_vcpu: 6386uninit_vcpu:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 185a2b823a2..be6d54929fa 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2147,6 +2147,7 @@ int kvm_dev_ioctl_check_extension(long ext)
2147 case KVM_CAP_ASYNC_PF: 2147 case KVM_CAP_ASYNC_PF:
2148 case KVM_CAP_GET_TSC_KHZ: 2148 case KVM_CAP_GET_TSC_KHZ:
2149 case KVM_CAP_PCI_2_3: 2149 case KVM_CAP_PCI_2_3:
2150 case KVM_CAP_KVMCLOCK_CTRL:
2150 r = 1; 2151 r = 1;
2151 break; 2152 break;
2152 case KVM_CAP_COALESCED_MMIO: 2153 case KVM_CAP_COALESCED_MMIO:
@@ -2597,6 +2598,23 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
2597 return r; 2598 return r;
2598} 2599}
2599 2600
2601/*
2602 * kvm_set_guest_paused() indicates to the guest kernel that it has been
2603 * stopped by the hypervisor. This function will be called from the host only.
2604 * EINVAL is returned when the host attempts to set the flag for a guest that
2605 * does not support pv clocks.
2606 */
2607static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
2608{
2609 struct pvclock_vcpu_time_info *src = &vcpu->arch.hv_clock;
2610 if (!vcpu->arch.time_page)
2611 return -EINVAL;
2612 src->flags |= PVCLOCK_GUEST_STOPPED;
2613 mark_page_dirty(vcpu->kvm, vcpu->arch.time >> PAGE_SHIFT);
2614 kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
2615 return 0;
2616}
2617
2600long kvm_arch_vcpu_ioctl(struct file *filp, 2618long kvm_arch_vcpu_ioctl(struct file *filp,
2601 unsigned int ioctl, unsigned long arg) 2619 unsigned int ioctl, unsigned long arg)
2602{ 2620{
@@ -2873,6 +2891,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
2873 r = vcpu->arch.virtual_tsc_khz; 2891 r = vcpu->arch.virtual_tsc_khz;
2874 goto out; 2892 goto out;
2875 } 2893 }
2894 case KVM_KVMCLOCK_CTRL: {
2895 r = kvm_set_guest_paused(vcpu);
2896 goto out;
2897 }
2876 default: 2898 default:
2877 r = -EINVAL; 2899 r = -EINVAL;
2878 } 2900 }
@@ -3045,57 +3067,32 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
3045} 3067}
3046 3068
3047/** 3069/**
3048 * write_protect_slot - write protect a slot for dirty logging 3070 * kvm_vm_ioctl_get_dirty_log - get and clear the log of dirty pages in a slot
3049 * @kvm: the kvm instance 3071 * @kvm: kvm instance
3050 * @memslot: the slot we protect 3072 * @log: slot id and address to which we copy the log
3051 * @dirty_bitmap: the bitmap indicating which pages are dirty
3052 * @nr_dirty_pages: the number of dirty pages
3053 * 3073 *
3054 * We have two ways to find all sptes to protect: 3074 * We need to keep it in mind that VCPU threads can write to the bitmap
3055 * 1. Use kvm_mmu_slot_remove_write_access() which walks all shadow pages and 3075 * concurrently. So, to avoid losing data, we keep the following order for
3056 * checks ones that have a spte mapping a page in the slot. 3076 * each bit:
3057 * 2. Use kvm_mmu_rmap_write_protect() for each gfn found in the bitmap.
3058 * 3077 *
3059 * Generally speaking, if there are not so many dirty pages compared to the 3078 * 1. Take a snapshot of the bit and clear it if needed.
3060 * number of shadow pages, we should use the latter. 3079 * 2. Write protect the corresponding page.
3080 * 3. Flush TLB's if needed.
3081 * 4. Copy the snapshot to the userspace.
3061 * 3082 *
3062 * Note that letting others write into a page marked dirty in the old bitmap 3083 * Between 2 and 3, the guest may write to the page using the remaining TLB
3063 * by using the remaining tlb entry is not a problem. That page will become 3084 * entry. This is not a problem because the page will be reported dirty at
3064 * write protected again when we flush the tlb and then be reported dirty to 3085 * step 4 using the snapshot taken before and step 3 ensures that successive
3065 * the user space by copying the old bitmap. 3086 * writes will be logged for the next call.
3066 */
3067static void write_protect_slot(struct kvm *kvm,
3068 struct kvm_memory_slot *memslot,
3069 unsigned long *dirty_bitmap,
3070 unsigned long nr_dirty_pages)
3071{
3072 spin_lock(&kvm->mmu_lock);
3073
3074 /* Not many dirty pages compared to # of shadow pages. */
3075 if (nr_dirty_pages < kvm->arch.n_used_mmu_pages) {
3076 unsigned long gfn_offset;
3077
3078 for_each_set_bit(gfn_offset, dirty_bitmap, memslot->npages) {
3079 unsigned long gfn = memslot->base_gfn + gfn_offset;
3080
3081 kvm_mmu_rmap_write_protect(kvm, gfn, memslot);
3082 }
3083 kvm_flush_remote_tlbs(kvm);
3084 } else
3085 kvm_mmu_slot_remove_write_access(kvm, memslot->id);
3086
3087 spin_unlock(&kvm->mmu_lock);
3088}
3089
3090/*
3091 * Get (and clear) the dirty memory log for a memory slot.
3092 */ 3087 */
3093int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, 3088int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
3094 struct kvm_dirty_log *log)
3095{ 3089{
3096 int r; 3090 int r;
3097 struct kvm_memory_slot *memslot; 3091 struct kvm_memory_slot *memslot;
3098 unsigned long n, nr_dirty_pages; 3092 unsigned long n, i;
3093 unsigned long *dirty_bitmap;
3094 unsigned long *dirty_bitmap_buffer;
3095 bool is_dirty = false;
3099 3096
3100 mutex_lock(&kvm->slots_lock); 3097 mutex_lock(&kvm->slots_lock);
3101 3098
@@ -3104,49 +3101,42 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
3104 goto out; 3101 goto out;
3105 3102
3106 memslot = id_to_memslot(kvm->memslots, log->slot); 3103 memslot = id_to_memslot(kvm->memslots, log->slot);
3104
3105 dirty_bitmap = memslot->dirty_bitmap;
3107 r = -ENOENT; 3106 r = -ENOENT;
3108 if (!memslot->dirty_bitmap) 3107 if (!dirty_bitmap)
3109 goto out; 3108 goto out;
3110 3109
3111 n = kvm_dirty_bitmap_bytes(memslot); 3110 n = kvm_dirty_bitmap_bytes(memslot);
3112 nr_dirty_pages = memslot->nr_dirty_pages;
3113 3111
3114 /* If nothing is dirty, don't bother messing with page tables. */ 3112 dirty_bitmap_buffer = dirty_bitmap + n / sizeof(long);
3115 if (nr_dirty_pages) { 3113 memset(dirty_bitmap_buffer, 0, n);
3116 struct kvm_memslots *slots, *old_slots;
3117 unsigned long *dirty_bitmap, *dirty_bitmap_head;
3118 3114
3119 dirty_bitmap = memslot->dirty_bitmap; 3115 spin_lock(&kvm->mmu_lock);
3120 dirty_bitmap_head = memslot->dirty_bitmap_head;
3121 if (dirty_bitmap == dirty_bitmap_head)
3122 dirty_bitmap_head += n / sizeof(long);
3123 memset(dirty_bitmap_head, 0, n);
3124 3116
3125 r = -ENOMEM; 3117 for (i = 0; i < n / sizeof(long); i++) {
3126 slots = kmemdup(kvm->memslots, sizeof(*kvm->memslots), GFP_KERNEL); 3118 unsigned long mask;
3127 if (!slots) 3119 gfn_t offset;
3128 goto out;
3129 3120
3130 memslot = id_to_memslot(slots, log->slot); 3121 if (!dirty_bitmap[i])
3131 memslot->nr_dirty_pages = 0; 3122 continue;
3132 memslot->dirty_bitmap = dirty_bitmap_head;
3133 update_memslots(slots, NULL);
3134 3123
3135 old_slots = kvm->memslots; 3124 is_dirty = true;
3136 rcu_assign_pointer(kvm->memslots, slots);
3137 synchronize_srcu_expedited(&kvm->srcu);
3138 kfree(old_slots);
3139 3125
3140 write_protect_slot(kvm, memslot, dirty_bitmap, nr_dirty_pages); 3126 mask = xchg(&dirty_bitmap[i], 0);
3127 dirty_bitmap_buffer[i] = mask;
3141 3128
3142 r = -EFAULT; 3129 offset = i * BITS_PER_LONG;
3143 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) 3130 kvm_mmu_write_protect_pt_masked(kvm, memslot, offset, mask);
3144 goto out;
3145 } else {
3146 r = -EFAULT;
3147 if (clear_user(log->dirty_bitmap, n))
3148 goto out;
3149 } 3131 }
3132 if (is_dirty)
3133 kvm_flush_remote_tlbs(kvm);
3134
3135 spin_unlock(&kvm->mmu_lock);
3136
3137 r = -EFAULT;
3138 if (copy_to_user(log->dirty_bitmap, dirty_bitmap_buffer, n))
3139 goto out;
3150 3140
3151 r = 0; 3141 r = 0;
3152out: 3142out:
@@ -3728,9 +3718,8 @@ struct read_write_emulator_ops {
3728static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes) 3718static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
3729{ 3719{
3730 if (vcpu->mmio_read_completed) { 3720 if (vcpu->mmio_read_completed) {
3731 memcpy(val, vcpu->mmio_data, bytes);
3732 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, 3721 trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
3733 vcpu->mmio_phys_addr, *(u64 *)val); 3722 vcpu->mmio_fragments[0].gpa, *(u64 *)val);
3734 vcpu->mmio_read_completed = 0; 3723 vcpu->mmio_read_completed = 0;
3735 return 1; 3724 return 1;
3736 } 3725 }
@@ -3766,8 +3755,9 @@ static int read_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
3766static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, 3755static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa,
3767 void *val, int bytes) 3756 void *val, int bytes)
3768{ 3757{
3769 memcpy(vcpu->mmio_data, val, bytes); 3758 struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0];
3770 memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8); 3759
3760 memcpy(vcpu->run->mmio.data, frag->data, frag->len);
3771 return X86EMUL_CONTINUE; 3761 return X86EMUL_CONTINUE;
3772} 3762}
3773 3763
@@ -3794,10 +3784,7 @@ static int emulator_read_write_onepage(unsigned long addr, void *val,
3794 gpa_t gpa; 3784 gpa_t gpa;
3795 int handled, ret; 3785 int handled, ret;
3796 bool write = ops->write; 3786 bool write = ops->write;
3797 3787 struct kvm_mmio_fragment *frag;
3798 if (ops->read_write_prepare &&
3799 ops->read_write_prepare(vcpu, val, bytes))
3800 return X86EMUL_CONTINUE;
3801 3788
3802 ret = vcpu_mmio_gva_to_gpa(vcpu, addr, &gpa, exception, write); 3789 ret = vcpu_mmio_gva_to_gpa(vcpu, addr, &gpa, exception, write);
3803 3790
@@ -3823,15 +3810,19 @@ mmio:
3823 bytes -= handled; 3810 bytes -= handled;
3824 val += handled; 3811 val += handled;
3825 3812
3826 vcpu->mmio_needed = 1; 3813 while (bytes) {
3827 vcpu->run->exit_reason = KVM_EXIT_MMIO; 3814 unsigned now = min(bytes, 8U);
3828 vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
3829 vcpu->mmio_size = bytes;
3830 vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
3831 vcpu->run->mmio.is_write = vcpu->mmio_is_write = write;
3832 vcpu->mmio_index = 0;
3833 3815
3834 return ops->read_write_exit_mmio(vcpu, gpa, val, bytes); 3816 frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++];
3817 frag->gpa = gpa;
3818 frag->data = val;
3819 frag->len = now;
3820
3821 gpa += now;
3822 val += now;
3823 bytes -= now;
3824 }
3825 return X86EMUL_CONTINUE;
3835} 3826}
3836 3827
3837int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, 3828int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
@@ -3840,10 +3831,18 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
3840 struct read_write_emulator_ops *ops) 3831 struct read_write_emulator_ops *ops)
3841{ 3832{
3842 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); 3833 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
3834 gpa_t gpa;
3835 int rc;
3836
3837 if (ops->read_write_prepare &&
3838 ops->read_write_prepare(vcpu, val, bytes))
3839 return X86EMUL_CONTINUE;
3840
3841 vcpu->mmio_nr_fragments = 0;
3843 3842
3844 /* Crossing a page boundary? */ 3843 /* Crossing a page boundary? */
3845 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { 3844 if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
3846 int rc, now; 3845 int now;
3847 3846
3848 now = -addr & ~PAGE_MASK; 3847 now = -addr & ~PAGE_MASK;
3849 rc = emulator_read_write_onepage(addr, val, now, exception, 3848 rc = emulator_read_write_onepage(addr, val, now, exception,
@@ -3856,8 +3855,25 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
3856 bytes -= now; 3855 bytes -= now;
3857 } 3856 }
3858 3857
3859 return emulator_read_write_onepage(addr, val, bytes, exception, 3858 rc = emulator_read_write_onepage(addr, val, bytes, exception,
3860 vcpu, ops); 3859 vcpu, ops);
3860 if (rc != X86EMUL_CONTINUE)
3861 return rc;
3862
3863 if (!vcpu->mmio_nr_fragments)
3864 return rc;
3865
3866 gpa = vcpu->mmio_fragments[0].gpa;
3867
3868 vcpu->mmio_needed = 1;
3869 vcpu->mmio_cur_fragment = 0;
3870
3871 vcpu->run->mmio.len = vcpu->mmio_fragments[0].len;
3872 vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write;
3873 vcpu->run->exit_reason = KVM_EXIT_MMIO;
3874 vcpu->run->mmio.phys_addr = gpa;
3875
3876 return ops->read_write_exit_mmio(vcpu, gpa, val, bytes);
3861} 3877}
3862 3878
3863static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt, 3879static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
@@ -5263,10 +5279,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5263 kvm_deliver_pmi(vcpu); 5279 kvm_deliver_pmi(vcpu);
5264 } 5280 }
5265 5281
5266 r = kvm_mmu_reload(vcpu);
5267 if (unlikely(r))
5268 goto out;
5269
5270 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { 5282 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
5271 inject_pending_event(vcpu); 5283 inject_pending_event(vcpu);
5272 5284
@@ -5282,6 +5294,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5282 } 5294 }
5283 } 5295 }
5284 5296
5297 r = kvm_mmu_reload(vcpu);
5298 if (unlikely(r)) {
5299 kvm_x86_ops->cancel_injection(vcpu);
5300 goto out;
5301 }
5302
5285 preempt_disable(); 5303 preempt_disable();
5286 5304
5287 kvm_x86_ops->prepare_guest_switch(vcpu); 5305 kvm_x86_ops->prepare_guest_switch(vcpu);
@@ -5456,33 +5474,55 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
5456 return r; 5474 return r;
5457} 5475}
5458 5476
5477/*
5478 * Implements the following, as a state machine:
5479 *
5480 * read:
5481 * for each fragment
5482 * write gpa, len
5483 * exit
5484 * copy data
5485 * execute insn
5486 *
5487 * write:
5488 * for each fragment
5489 * write gpa, len
5490 * copy data
5491 * exit
5492 */
5459static int complete_mmio(struct kvm_vcpu *vcpu) 5493static int complete_mmio(struct kvm_vcpu *vcpu)
5460{ 5494{
5461 struct kvm_run *run = vcpu->run; 5495 struct kvm_run *run = vcpu->run;
5496 struct kvm_mmio_fragment *frag;
5462 int r; 5497 int r;
5463 5498
5464 if (!(vcpu->arch.pio.count || vcpu->mmio_needed)) 5499 if (!(vcpu->arch.pio.count || vcpu->mmio_needed))
5465 return 1; 5500 return 1;
5466 5501
5467 if (vcpu->mmio_needed) { 5502 if (vcpu->mmio_needed) {
5468 vcpu->mmio_needed = 0; 5503 /* Complete previous fragment */
5504 frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
5469 if (!vcpu->mmio_is_write) 5505 if (!vcpu->mmio_is_write)
5470 memcpy(vcpu->mmio_data + vcpu->mmio_index, 5506 memcpy(frag->data, run->mmio.data, frag->len);
5471 run->mmio.data, 8); 5507 if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) {
5472 vcpu->mmio_index += 8; 5508 vcpu->mmio_needed = 0;
5473 if (vcpu->mmio_index < vcpu->mmio_size) { 5509 if (vcpu->mmio_is_write)
5474 run->exit_reason = KVM_EXIT_MMIO; 5510 return 1;
5475 run->mmio.phys_addr = vcpu->mmio_phys_addr + vcpu->mmio_index; 5511 vcpu->mmio_read_completed = 1;
5476 memcpy(run->mmio.data, vcpu->mmio_data + vcpu->mmio_index, 8); 5512 goto done;
5477 run->mmio.len = min(vcpu->mmio_size - vcpu->mmio_index, 8);
5478 run->mmio.is_write = vcpu->mmio_is_write;
5479 vcpu->mmio_needed = 1;
5480 return 0;
5481 } 5513 }
5514 /* Initiate next fragment */
5515 ++frag;
5516 run->exit_reason = KVM_EXIT_MMIO;
5517 run->mmio.phys_addr = frag->gpa;
5482 if (vcpu->mmio_is_write) 5518 if (vcpu->mmio_is_write)
5483 return 1; 5519 memcpy(run->mmio.data, frag->data, frag->len);
5484 vcpu->mmio_read_completed = 1; 5520 run->mmio.len = frag->len;
5521 run->mmio.is_write = vcpu->mmio_is_write;
5522 return 0;
5523
5485 } 5524 }
5525done:
5486 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); 5526 vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
5487 r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); 5527 r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
5488 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 5528 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
@@ -6399,21 +6439,9 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
6399 kvm_cpu_has_interrupt(vcpu)); 6439 kvm_cpu_has_interrupt(vcpu));
6400} 6440}
6401 6441
6402void kvm_vcpu_kick(struct kvm_vcpu *vcpu) 6442int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
6403{ 6443{
6404 int me; 6444 return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE;
6405 int cpu = vcpu->cpu;
6406
6407 if (waitqueue_active(&vcpu->wq)) {
6408 wake_up_interruptible(&vcpu->wq);
6409 ++vcpu->stat.halt_wakeup;
6410 }
6411
6412 me = get_cpu();
6413 if (cpu != me && (unsigned)cpu < nr_cpu_ids && cpu_online(cpu))
6414 if (kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE)
6415 smp_send_reschedule(cpu);
6416 put_cpu();
6417} 6445}
6418 6446
6419int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu) 6447int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index cb80c293cdd..3d1134ddb88 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -64,7 +64,7 @@ static inline int is_pse(struct kvm_vcpu *vcpu)
64 64
65static inline int is_paging(struct kvm_vcpu *vcpu) 65static inline int is_paging(struct kvm_vcpu *vcpu)
66{ 66{
67 return kvm_read_cr0_bits(vcpu, X86_CR0_PG); 67 return likely(kvm_read_cr0_bits(vcpu, X86_CR0_PG));
68} 68}
69 69
70static inline u32 bit(int bitno) 70static inline u32 bit(int bitno)
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c
index 2e4e4b02c37..f61ee67ec00 100644
--- a/arch/x86/lib/usercopy.c
+++ b/arch/x86/lib/usercopy.c
@@ -43,100 +43,3 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
43 return len; 43 return len;
44} 44}
45EXPORT_SYMBOL_GPL(copy_from_user_nmi); 45EXPORT_SYMBOL_GPL(copy_from_user_nmi);
46
47/*
48 * Do a strncpy, return length of string without final '\0'.
49 * 'count' is the user-supplied count (return 'count' if we
50 * hit it), 'max' is the address space maximum (and we return
51 * -EFAULT if we hit it).
52 */
53static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
54{
55 long res = 0;
56
57 /*
58 * Truncate 'max' to the user-specified limit, so that
59 * we only have one limit we need to check in the loop
60 */
61 if (max > count)
62 max = count;
63
64 while (max >= sizeof(unsigned long)) {
65 unsigned long c, mask;
66
67 /* Fall back to byte-at-a-time if we get a page fault */
68 if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
69 break;
70 mask = has_zero(c);
71 if (mask) {
72 mask = (mask - 1) & ~mask;
73 mask >>= 7;
74 *(unsigned long *)(dst+res) = c & mask;
75 return res + count_masked_bytes(mask);
76 }
77 *(unsigned long *)(dst+res) = c;
78 res += sizeof(unsigned long);
79 max -= sizeof(unsigned long);
80 }
81
82 while (max) {
83 char c;
84
85 if (unlikely(__get_user(c,src+res)))
86 return -EFAULT;
87 dst[res] = c;
88 if (!c)
89 return res;
90 res++;
91 max--;
92 }
93
94 /*
95 * Uhhuh. We hit 'max'. But was that the user-specified maximum
96 * too? If so, that's ok - we got as much as the user asked for.
97 */
98 if (res >= count)
99 return res;
100
101 /*
102 * Nope: we hit the address space limit, and we still had more
103 * characters the caller would have wanted. That's an EFAULT.
104 */
105 return -EFAULT;
106}
107
108/**
109 * strncpy_from_user: - Copy a NUL terminated string from userspace.
110 * @dst: Destination address, in kernel space. This buffer must be at
111 * least @count bytes long.
112 * @src: Source address, in user space.
113 * @count: Maximum number of bytes to copy, including the trailing NUL.
114 *
115 * Copies a NUL-terminated string from userspace to kernel space.
116 *
117 * On success, returns the length of the string (not including the trailing
118 * NUL).
119 *
120 * If access to userspace fails, returns -EFAULT (some data may have been
121 * copied).
122 *
123 * If @count is smaller than the length of the string, copies @count bytes
124 * and returns @count.
125 */
126long
127strncpy_from_user(char *dst, const char __user *src, long count)
128{
129 unsigned long max_addr, src_addr;
130
131 if (unlikely(count <= 0))
132 return 0;
133
134 max_addr = current_thread_info()->addr_limit.seg;
135 src_addr = (unsigned long)src;
136 if (likely(src_addr < max_addr)) {
137 unsigned long max = max_addr - src_addr;
138 return do_strncpy_from_user(dst, src, count, max);
139 }
140 return -EFAULT;
141}
142EXPORT_SYMBOL(strncpy_from_user);
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 883b216c60b..1781b2f950e 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -95,47 +95,6 @@ __clear_user(void __user *to, unsigned long n)
95} 95}
96EXPORT_SYMBOL(__clear_user); 96EXPORT_SYMBOL(__clear_user);
97 97
98/**
99 * strnlen_user: - Get the size of a string in user space.
100 * @s: The string to measure.
101 * @n: The maximum valid length
102 *
103 * Get the size of a NUL-terminated string in user space.
104 *
105 * Returns the size of the string INCLUDING the terminating NUL.
106 * On exception, returns 0.
107 * If the string is too long, returns a value greater than @n.
108 */
109long strnlen_user(const char __user *s, long n)
110{
111 unsigned long mask = -__addr_ok(s);
112 unsigned long res, tmp;
113
114 might_fault();
115
116 __asm__ __volatile__(
117 " testl %0, %0\n"
118 " jz 3f\n"
119 " andl %0,%%ecx\n"
120 "0: repne; scasb\n"
121 " setne %%al\n"
122 " subl %%ecx,%0\n"
123 " addl %0,%%eax\n"
124 "1:\n"
125 ".section .fixup,\"ax\"\n"
126 "2: xorl %%eax,%%eax\n"
127 " jmp 1b\n"
128 "3: movb $1,%%al\n"
129 " jmp 1b\n"
130 ".previous\n"
131 _ASM_EXTABLE(0b,2b)
132 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
133 :"0" (n), "1" (s), "2" (0), "3" (mask)
134 :"cc");
135 return res & mask;
136}
137EXPORT_SYMBOL(strnlen_user);
138
139#ifdef CONFIG_X86_INTEL_USERCOPY 98#ifdef CONFIG_X86_INTEL_USERCOPY
140static unsigned long 99static unsigned long
141__copy_user_intel(void __user *to, const void *from, unsigned long size) 100__copy_user_intel(void __user *to, const void *from, unsigned long size)
diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c
index 0d0326f388c..e5b130bc2d0 100644
--- a/arch/x86/lib/usercopy_64.c
+++ b/arch/x86/lib/usercopy_64.c
@@ -52,54 +52,6 @@ unsigned long clear_user(void __user *to, unsigned long n)
52} 52}
53EXPORT_SYMBOL(clear_user); 53EXPORT_SYMBOL(clear_user);
54 54
55/*
56 * Return the size of a string (including the ending 0)
57 *
58 * Return 0 on exception, a value greater than N if too long
59 */
60
61long __strnlen_user(const char __user *s, long n)
62{
63 long res = 0;
64 char c;
65
66 while (1) {
67 if (res>n)
68 return n+1;
69 if (__get_user(c, s))
70 return 0;
71 if (!c)
72 return res+1;
73 res++;
74 s++;
75 }
76}
77EXPORT_SYMBOL(__strnlen_user);
78
79long strnlen_user(const char __user *s, long n)
80{
81 if (!access_ok(VERIFY_READ, s, 1))
82 return 0;
83 return __strnlen_user(s, n);
84}
85EXPORT_SYMBOL(strnlen_user);
86
87long strlen_user(const char __user *s)
88{
89 long res = 0;
90 char c;
91
92 for (;;) {
93 if (get_user(c, s))
94 return 0;
95 if (!c)
96 return res+1;
97 res++;
98 s++;
99 }
100}
101EXPORT_SYMBOL(strlen_user);
102
103unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len) 55unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
104{ 56{
105 if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 57 if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 319b6f2fb8b..97141c26a13 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -84,8 +84,9 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en
84 pgt_buf_end = pgt_buf_start; 84 pgt_buf_end = pgt_buf_start;
85 pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); 85 pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
86 86
87 printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", 87 printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n",
88 end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); 88 end - 1, pgt_buf_start << PAGE_SHIFT,
89 (pgt_buf_top << PAGE_SHIFT) - 1);
89} 90}
90 91
91void __init native_pagetable_reserve(u64 start, u64 end) 92void __init native_pagetable_reserve(u64 start, u64 end)
@@ -132,7 +133,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
132 int nr_range, i; 133 int nr_range, i;
133 int use_pse, use_gbpages; 134 int use_pse, use_gbpages;
134 135
135 printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); 136 printk(KERN_INFO "init_memory_mapping: [mem %#010lx-%#010lx]\n",
137 start, end - 1);
136 138
137#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) 139#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK)
138 /* 140 /*
@@ -251,8 +253,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
251 } 253 }
252 254
253 for (i = 0; i < nr_range; i++) 255 for (i = 0; i < nr_range; i++)
254 printk(KERN_DEBUG " %010lx - %010lx page %s\n", 256 printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
255 mr[i].start, mr[i].end, 257 mr[i].start, mr[i].end - 1,
256 (mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":( 258 (mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
257 (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k")); 259 (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
258 260
@@ -350,8 +352,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
350 * create a kernel page fault: 352 * create a kernel page fault:
351 */ 353 */
352#ifdef CONFIG_DEBUG_PAGEALLOC 354#ifdef CONFIG_DEBUG_PAGEALLOC
353 printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", 355 printk(KERN_INFO "debug: unmapping init [mem %#010lx-%#010lx]\n",
354 begin, end); 356 begin, end - 1);
355 set_memory_np(begin, (end - begin) >> PAGE_SHIFT); 357 set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
356#else 358#else
357 /* 359 /*
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 19d3fa08b11..2d125be1bae 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -141,8 +141,8 @@ static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
141 141
142 /* whine about and ignore invalid blks */ 142 /* whine about and ignore invalid blks */
143 if (start > end || nid < 0 || nid >= MAX_NUMNODES) { 143 if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
144 pr_warning("NUMA: Warning: invalid memblk node %d (%Lx-%Lx)\n", 144 pr_warning("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
145 nid, start, end); 145 nid, start, end - 1);
146 return 0; 146 return 0;
147 } 147 }
148 148
@@ -210,8 +210,8 @@ static void __init setup_node_data(int nid, u64 start, u64 end)
210 210
211 start = roundup(start, ZONE_ALIGN); 211 start = roundup(start, ZONE_ALIGN);
212 212
213 printk(KERN_INFO "Initmem setup node %d %016Lx-%016Lx\n", 213 printk(KERN_INFO "Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
214 nid, start, end); 214 nid, start, end - 1);
215 215
216 /* 216 /*
217 * Allocate node data. Try remap allocator first, node-local 217 * Allocate node data. Try remap allocator first, node-local
@@ -232,7 +232,7 @@ static void __init setup_node_data(int nid, u64 start, u64 end)
232 } 232 }
233 233
234 /* report and initialize */ 234 /* report and initialize */
235 printk(KERN_INFO " NODE_DATA [%016Lx - %016Lx]%s\n", 235 printk(KERN_INFO " NODE_DATA [mem %#010Lx-%#010Lx]%s\n",
236 nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : ""); 236 nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : "");
237 tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); 237 tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
238 if (!remapped && tnid != nid) 238 if (!remapped && tnid != nid)
@@ -291,14 +291,14 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
291 */ 291 */
292 if (bi->end > bj->start && bi->start < bj->end) { 292 if (bi->end > bj->start && bi->start < bj->end) {
293 if (bi->nid != bj->nid) { 293 if (bi->nid != bj->nid) {
294 pr_err("NUMA: node %d (%Lx-%Lx) overlaps with node %d (%Lx-%Lx)\n", 294 pr_err("NUMA: node %d [mem %#010Lx-%#010Lx] overlaps with node %d [mem %#010Lx-%#010Lx]\n",
295 bi->nid, bi->start, bi->end, 295 bi->nid, bi->start, bi->end - 1,
296 bj->nid, bj->start, bj->end); 296 bj->nid, bj->start, bj->end - 1);
297 return -EINVAL; 297 return -EINVAL;
298 } 298 }
299 pr_warning("NUMA: Warning: node %d (%Lx-%Lx) overlaps with itself (%Lx-%Lx)\n", 299 pr_warning("NUMA: Warning: node %d [mem %#010Lx-%#010Lx] overlaps with itself [mem %#010Lx-%#010Lx]\n",
300 bi->nid, bi->start, bi->end, 300 bi->nid, bi->start, bi->end - 1,
301 bj->start, bj->end); 301 bj->start, bj->end - 1);
302 } 302 }
303 303
304 /* 304 /*
@@ -320,9 +320,9 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
320 } 320 }
321 if (k < mi->nr_blks) 321 if (k < mi->nr_blks)
322 continue; 322 continue;
323 printk(KERN_INFO "NUMA: Node %d [%Lx,%Lx) + [%Lx,%Lx) -> [%Lx,%Lx)\n", 323 printk(KERN_INFO "NUMA: Node %d [mem %#010Lx-%#010Lx] + [mem %#010Lx-%#010Lx] -> [mem %#010Lx-%#010Lx]\n",
324 bi->nid, bi->start, bi->end, bj->start, bj->end, 324 bi->nid, bi->start, bi->end - 1, bj->start,
325 start, end); 325 bj->end - 1, start, end - 1);
326 bi->start = start; 326 bi->start = start;
327 bi->end = end; 327 bi->end = end;
328 numa_remove_memblk_from(j--, mi); 328 numa_remove_memblk_from(j--, mi);
@@ -616,8 +616,8 @@ static int __init dummy_numa_init(void)
616{ 616{
617 printk(KERN_INFO "%s\n", 617 printk(KERN_INFO "%s\n",
618 numa_off ? "NUMA turned off" : "No NUMA configuration found"); 618 numa_off ? "NUMA turned off" : "No NUMA configuration found");
619 printk(KERN_INFO "Faking a node at %016Lx-%016Lx\n", 619 printk(KERN_INFO "Faking a node at [mem %#018Lx-%#018Lx]\n",
620 0LLU, PFN_PHYS(max_pfn)); 620 0LLU, PFN_PHYS(max_pfn) - 1);
621 621
622 node_set(0, numa_nodes_parsed); 622 node_set(0, numa_nodes_parsed);
623 numa_add_memblk(0, 0, PFN_PHYS(max_pfn)); 623 numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
index 871dd886817..dbbbb47260c 100644
--- a/arch/x86/mm/numa_emulation.c
+++ b/arch/x86/mm/numa_emulation.c
@@ -68,8 +68,8 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei,
68 numa_remove_memblk_from(phys_blk, pi); 68 numa_remove_memblk_from(phys_blk, pi);
69 } 69 }
70 70
71 printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", nid, 71 printk(KERN_INFO "Faking node %d at [mem %#018Lx-%#018Lx] (%LuMB)\n",
72 eb->start, eb->end, (eb->end - eb->start) >> 20); 72 nid, eb->start, eb->end - 1, (eb->end - eb->start) >> 20);
73 return 0; 73 return 0;
74} 74}
75 75
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index bea6e573e02..3d68ef6d226 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -225,9 +225,8 @@ static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type,
225 page = pfn_to_page(pfn); 225 page = pfn_to_page(pfn);
226 type = get_page_memtype(page); 226 type = get_page_memtype(page);
227 if (type != -1) { 227 if (type != -1) {
228 printk(KERN_INFO "reserve_ram_pages_type failed " 228 printk(KERN_INFO "reserve_ram_pages_type failed [mem %#010Lx-%#010Lx], track 0x%lx, req 0x%lx\n",
229 "0x%Lx-0x%Lx, track 0x%lx, req 0x%lx\n", 229 start, end - 1, type, req_type);
230 start, end, type, req_type);
231 if (new_type) 230 if (new_type)
232 *new_type = type; 231 *new_type = type;
233 232
@@ -330,9 +329,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
330 329
331 err = rbt_memtype_check_insert(new, new_type); 330 err = rbt_memtype_check_insert(new, new_type);
332 if (err) { 331 if (err) {
333 printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " 332 printk(KERN_INFO "reserve_memtype failed [mem %#010Lx-%#010Lx], track %s, req %s\n",
334 "track %s, req %s\n", 333 start, end - 1,
335 start, end, cattr_name(new->type), cattr_name(req_type)); 334 cattr_name(new->type), cattr_name(req_type));
336 kfree(new); 335 kfree(new);
337 spin_unlock(&memtype_lock); 336 spin_unlock(&memtype_lock);
338 337
@@ -341,8 +340,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
341 340
342 spin_unlock(&memtype_lock); 341 spin_unlock(&memtype_lock);
343 342
344 dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n", 343 dprintk("reserve_memtype added [mem %#010Lx-%#010Lx], track %s, req %s, ret %s\n",
345 start, end, cattr_name(new->type), cattr_name(req_type), 344 start, end - 1, cattr_name(new->type), cattr_name(req_type),
346 new_type ? cattr_name(*new_type) : "-"); 345 new_type ? cattr_name(*new_type) : "-");
347 346
348 return err; 347 return err;
@@ -376,14 +375,14 @@ int free_memtype(u64 start, u64 end)
376 spin_unlock(&memtype_lock); 375 spin_unlock(&memtype_lock);
377 376
378 if (!entry) { 377 if (!entry) {
379 printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", 378 printk(KERN_INFO "%s:%d freeing invalid memtype [mem %#010Lx-%#010Lx]\n",
380 current->comm, current->pid, start, end); 379 current->comm, current->pid, start, end - 1);
381 return -EINVAL; 380 return -EINVAL;
382 } 381 }
383 382
384 kfree(entry); 383 kfree(entry);
385 384
386 dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); 385 dprintk("free_memtype request [mem %#010Lx-%#010Lx]\n", start, end - 1);
387 386
388 return 0; 387 return 0;
389} 388}
@@ -507,9 +506,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
507 506
508 while (cursor < to) { 507 while (cursor < to) {
509 if (!devmem_is_allowed(pfn)) { 508 if (!devmem_is_allowed(pfn)) {
510 printk(KERN_INFO 509 printk(KERN_INFO "Program %s tried to access /dev/mem between [mem %#010Lx-%#010Lx]\n",
511 "Program %s tried to access /dev/mem between %Lx->%Lx.\n", 510 current->comm, from, to - 1);
512 current->comm, from, to);
513 return 0; 511 return 0;
514 } 512 }
515 cursor += PAGE_SIZE; 513 cursor += PAGE_SIZE;
@@ -570,12 +568,11 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
570 size; 568 size;
571 569
572 if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) { 570 if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
573 printk(KERN_INFO 571 printk(KERN_INFO "%s:%d ioremap_change_attr failed %s "
574 "%s:%d ioremap_change_attr failed %s " 572 "for [mem %#010Lx-%#010Lx]\n",
575 "for %Lx-%Lx\n",
576 current->comm, current->pid, 573 current->comm, current->pid,
577 cattr_name(flags), 574 cattr_name(flags),
578 base, (unsigned long long)(base + size)); 575 base, (unsigned long long)(base + size-1));
579 return -EINVAL; 576 return -EINVAL;
580 } 577 }
581 return 0; 578 return 0;
@@ -607,12 +604,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
607 604
608 flags = lookup_memtype(paddr); 605 flags = lookup_memtype(paddr);
609 if (want_flags != flags) { 606 if (want_flags != flags) {
610 printk(KERN_WARNING 607 printk(KERN_WARNING "%s:%d map pfn RAM range req %s for [mem %#010Lx-%#010Lx], got %s\n",
611 "%s:%d map pfn RAM range req %s for %Lx-%Lx, got %s\n",
612 current->comm, current->pid, 608 current->comm, current->pid,
613 cattr_name(want_flags), 609 cattr_name(want_flags),
614 (unsigned long long)paddr, 610 (unsigned long long)paddr,
615 (unsigned long long)(paddr + size), 611 (unsigned long long)(paddr + size - 1),
616 cattr_name(flags)); 612 cattr_name(flags));
617 *vma_prot = __pgprot((pgprot_val(*vma_prot) & 613 *vma_prot = __pgprot((pgprot_val(*vma_prot) &
618 (~_PAGE_CACHE_MASK)) | 614 (~_PAGE_CACHE_MASK)) |
@@ -630,11 +626,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
630 !is_new_memtype_allowed(paddr, size, want_flags, flags)) { 626 !is_new_memtype_allowed(paddr, size, want_flags, flags)) {
631 free_memtype(paddr, paddr + size); 627 free_memtype(paddr, paddr + size);
632 printk(KERN_ERR "%s:%d map pfn expected mapping type %s" 628 printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
633 " for %Lx-%Lx, got %s\n", 629 " for [mem %#010Lx-%#010Lx], got %s\n",
634 current->comm, current->pid, 630 current->comm, current->pid,
635 cattr_name(want_flags), 631 cattr_name(want_flags),
636 (unsigned long long)paddr, 632 (unsigned long long)paddr,
637 (unsigned long long)(paddr + size), 633 (unsigned long long)(paddr + size - 1),
638 cattr_name(flags)); 634 cattr_name(flags));
639 return -EINVAL; 635 return -EINVAL;
640 } 636 }
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
index efb5b4b9371..732af3a9618 100644
--- a/arch/x86/mm/srat.c
+++ b/arch/x86/mm/srat.c
@@ -176,8 +176,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
176 return; 176 return;
177 } 177 }
178 178
179 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, 179 printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
180 start, end); 180 node, pxm,
181 (unsigned long long) start, (unsigned long long) end - 1);
181} 182}
182 183
183void __init acpi_numa_arch_fixup(void) {} 184void __init acpi_numa_arch_fixup(void) {}
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 7415aa92791..56ab74989cf 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -64,6 +64,10 @@ static int xen_register_pirq(u32 gsi, int gsi_override, int triggering,
64 int shareable = 0; 64 int shareable = 0;
65 char *name; 65 char *name;
66 66
67 irq = xen_irq_from_gsi(gsi);
68 if (irq > 0)
69 return irq;
70
67 if (set_pirq) 71 if (set_pirq)
68 pirq = gsi; 72 pirq = gsi;
69 73
diff --git a/arch/x86/realmode/Makefile b/arch/x86/realmode/Makefile
new file mode 100644
index 00000000000..94f7fbe97b0
--- /dev/null
+++ b/arch/x86/realmode/Makefile
@@ -0,0 +1,18 @@
1#
2# arch/x86/realmode/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8#
9
10subdir- := rm
11
12obj-y += init.o
13obj-y += rmpiggy.o
14
15$(obj)/rmpiggy.o: $(obj)/rm/realmode.bin
16
17$(obj)/rm/realmode.bin: FORCE
18 $(Q)$(MAKE) $(build)=$(obj)/rm $@
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
new file mode 100644
index 00000000000..cbca565af5b
--- /dev/null
+++ b/arch/x86/realmode/init.c
@@ -0,0 +1,115 @@
1#include <linux/io.h>
2#include <linux/memblock.h>
3
4#include <asm/cacheflush.h>
5#include <asm/pgtable.h>
6#include <asm/realmode.h>
7
8struct real_mode_header *real_mode_header;
9u32 *trampoline_cr4_features;
10
11void __init setup_real_mode(void)
12{
13 phys_addr_t mem;
14 u16 real_mode_seg;
15 u32 *rel;
16 u32 count;
17 u32 *ptr;
18 u16 *seg;
19 int i;
20 unsigned char *base;
21 struct trampoline_header *trampoline_header;
22 size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob);
23#ifdef CONFIG_X86_64
24 u64 *trampoline_pgd;
25 u64 efer;
26#endif
27
28 /* Has to be in very low memory so we can execute real-mode AP code. */
29 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
30 if (!mem)
31 panic("Cannot allocate trampoline\n");
32
33 base = __va(mem);
34 memblock_reserve(mem, size);
35 real_mode_header = (struct real_mode_header *) base;
36 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
37 base, (unsigned long long)mem, size);
38
39 memcpy(base, real_mode_blob, size);
40
41 real_mode_seg = __pa(base) >> 4;
42 rel = (u32 *) real_mode_relocs;
43
44 /* 16-bit segment relocations. */
45 count = rel[0];
46 rel = &rel[1];
47 for (i = 0; i < count; i++) {
48 seg = (u16 *) (base + rel[i]);
49 *seg = real_mode_seg;
50 }
51
52 /* 32-bit linear relocations. */
53 count = rel[i];
54 rel = &rel[i + 1];
55 for (i = 0; i < count; i++) {
56 ptr = (u32 *) (base + rel[i]);
57 *ptr += __pa(base);
58 }
59
60 /* Must be perfomed *after* relocation. */
61 trampoline_header = (struct trampoline_header *)
62 __va(real_mode_header->trampoline_header);
63
64#ifdef CONFIG_X86_32
65 trampoline_header->start = __pa(startup_32_smp);
66 trampoline_header->gdt_limit = __BOOT_DS + 7;
67 trampoline_header->gdt_base = __pa(boot_gdt);
68#else
69 /*
70 * Some AMD processors will #GP(0) if EFER.LMA is set in WRMSR
71 * so we need to mask it out.
72 */
73 rdmsrl(MSR_EFER, efer);
74 trampoline_header->efer = efer & ~EFER_LMA;
75
76 trampoline_header->start = (u64) secondary_startup_64;
77 trampoline_cr4_features = &trampoline_header->cr4;
78 *trampoline_cr4_features = read_cr4();
79
80 trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
81 trampoline_pgd[0] = __pa(level3_ident_pgt) + _KERNPG_TABLE;
82 trampoline_pgd[511] = __pa(level3_kernel_pgt) + _KERNPG_TABLE;
83#endif
84}
85
86/*
87 * set_real_mode_permissions() gets called very early, to guarantee the
88 * availability of low memory. This is before the proper kernel page
89 * tables are set up, so we cannot set page permissions in that
90 * function. Thus, we use an arch_initcall instead.
91 */
92static int __init set_real_mode_permissions(void)
93{
94 unsigned char *base = (unsigned char *) real_mode_header;
95 size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob);
96
97 size_t ro_size =
98 PAGE_ALIGN(real_mode_header->ro_end) -
99 __pa(base);
100
101 size_t text_size =
102 PAGE_ALIGN(real_mode_header->ro_end) -
103 real_mode_header->text_start;
104
105 unsigned long text_start =
106 (unsigned long) __va(real_mode_header->text_start);
107
108 set_memory_nx((unsigned long) base, size >> PAGE_SHIFT);
109 set_memory_ro((unsigned long) base, ro_size >> PAGE_SHIFT);
110 set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT);
111
112 return 0;
113}
114
115arch_initcall(set_real_mode_permissions);
diff --git a/arch/x86/realmode/rm/.gitignore b/arch/x86/realmode/rm/.gitignore
new file mode 100644
index 00000000000..b6ed3a2555c
--- /dev/null
+++ b/arch/x86/realmode/rm/.gitignore
@@ -0,0 +1,3 @@
1pasyms.h
2realmode.lds
3realmode.relocs
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile
new file mode 100644
index 00000000000..5b84a2d3088
--- /dev/null
+++ b/arch/x86/realmode/rm/Makefile
@@ -0,0 +1,82 @@
1#
2# arch/x86/realmode/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8#
9
10always := realmode.bin realmode.relocs
11
12wakeup-objs := wakeup_asm.o wakemain.o video-mode.o
13wakeup-objs += copy.o bioscall.o regs.o
14# The link order of the video-*.o modules can matter. In particular,
15# video-vga.o *must* be listed first, followed by video-vesa.o.
16# Hardware-specific drivers should follow in the order they should be
17# probed, and video-bios.o should typically be last.
18wakeup-objs += video-vga.o
19wakeup-objs += video-vesa.o
20wakeup-objs += video-bios.o
21
22realmode-y += header.o
23realmode-y += trampoline_$(BITS).o
24realmode-y += stack.o
25realmode-$(CONFIG_X86_32) += reboot_32.o
26realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs)
27
28targets += $(realmode-y)
29
30REALMODE_OBJS = $(addprefix $(obj)/,$(realmode-y))
31
32sed-pasyms := -n -r -e 's/^([0-9a-fA-F]+) [ABCDGRSTVW] (.+)$$/pa_\2 = \2;/p'
33
34quiet_cmd_pasyms = PASYMS $@
35 cmd_pasyms = $(NM) $(filter-out FORCE,$^) | \
36 sed $(sed-pasyms) | sort | uniq > $@
37
38targets += pasyms.h
39$(obj)/pasyms.h: $(REALMODE_OBJS) FORCE
40 $(call if_changed,pasyms)
41
42targets += realmode.lds
43$(obj)/realmode.lds: $(obj)/pasyms.h
44
45LDFLAGS_realmode.elf := --emit-relocs -T
46CPPFLAGS_realmode.lds += -P -C -I$(obj)
47
48targets += realmode.elf
49$(obj)/realmode.elf: $(obj)/realmode.lds $(REALMODE_OBJS) FORCE
50 $(call if_changed,ld)
51
52OBJCOPYFLAGS_realmode.bin := -O binary
53
54targets += realmode.bin
55$(obj)/realmode.bin: $(obj)/realmode.elf $(obj)/realmode.relocs
56 $(call if_changed,objcopy)
57
58quiet_cmd_relocs = RELOCS $@
59 cmd_relocs = arch/x86/tools/relocs --realmode $< > $@
60
61targets += realmode.relocs
62$(obj)/realmode.relocs: $(obj)/realmode.elf FORCE
63 $(call if_changed,relocs)
64
65# ---------------------------------------------------------------------------
66
67# How to compile the 16-bit code. Note we always compile for -march=i386,
68# that way we can complain to the user if the CPU is insufficient.
69KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \
70 -I$(srctree)/arch/x86/boot \
71 -DDISABLE_BRANCH_PROFILING \
72 -Wall -Wstrict-prototypes \
73 -march=i386 -mregparm=3 \
74 -include $(srctree)/$(src)/../../boot/code16gcc.h \
75 -fno-strict-aliasing -fomit-frame-pointer \
76 $(call cc-option, -ffreestanding) \
77 $(call cc-option, -fno-toplevel-reorder,\
78 $(call cc-option, -fno-unit-at-a-time)) \
79 $(call cc-option, -fno-stack-protector) \
80 $(call cc-option, -mpreferred-stack-boundary=2)
81KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
82GCOV_PROFILE := n
diff --git a/arch/x86/realmode/rm/bioscall.S b/arch/x86/realmode/rm/bioscall.S
new file mode 100644
index 00000000000..16162d19791
--- /dev/null
+++ b/arch/x86/realmode/rm/bioscall.S
@@ -0,0 +1 @@
#include "../../boot/bioscall.S"
diff --git a/arch/x86/realmode/rm/copy.S b/arch/x86/realmode/rm/copy.S
new file mode 100644
index 00000000000..b785e6f38fd
--- /dev/null
+++ b/arch/x86/realmode/rm/copy.S
@@ -0,0 +1 @@
#include "../../boot/copy.S"
diff --git a/arch/x86/realmode/rm/header.S b/arch/x86/realmode/rm/header.S
new file mode 100644
index 00000000000..fadf48378ad
--- /dev/null
+++ b/arch/x86/realmode/rm/header.S
@@ -0,0 +1,41 @@
1/*
2 * Real-mode blob header; this should match realmode.h and be
3 * readonly; for mutable data instead add pointers into the .data
4 * or .bss sections as appropriate.
5 */
6
7#include <linux/linkage.h>
8#include <asm/page_types.h>
9
10#include "realmode.h"
11
12 .section ".header", "a"
13
14 .balign 16
15GLOBAL(real_mode_header)
16 .long pa_text_start
17 .long pa_ro_end
18 /* SMP trampoline */
19 .long pa_trampoline_start
20 .long pa_trampoline_status
21 .long pa_trampoline_header
22#ifdef CONFIG_X86_64
23 .long pa_trampoline_pgd;
24#endif
25 /* ACPI S3 wakeup */
26#ifdef CONFIG_ACPI_SLEEP
27 .long pa_wakeup_start
28 .long pa_wakeup_header
29#endif
30 /* APM/BIOS reboot */
31#ifdef CONFIG_X86_32
32 .long pa_machine_real_restart_asm
33#endif
34END(real_mode_header)
35
36 /* End signature, used to verify integrity */
37 .section ".signature","a"
38 .balign 4
39GLOBAL(end_signature)
40 .long REALMODE_END_SIGNATURE
41END(end_signature)
diff --git a/arch/x86/realmode/rm/realmode.h b/arch/x86/realmode/rm/realmode.h
new file mode 100644
index 00000000000..d74cff6350e
--- /dev/null
+++ b/arch/x86/realmode/rm/realmode.h
@@ -0,0 +1,21 @@
1#ifndef ARCH_X86_REALMODE_RM_REALMODE_H
2#define ARCH_X86_REALMODE_RM_REALMODE_H
3
4#ifdef __ASSEMBLY__
5
6/*
7 * 16-bit ljmpw to the real_mode_seg
8 *
9 * This must be open-coded since gas will choke on using a
10 * relocatable symbol for the segment portion.
11 */
12#define LJMPW_RM(to) .byte 0xea ; .word (to), real_mode_seg
13
14#endif /* __ASSEMBLY__ */
15
16/*
17 * Signature at the end of the realmode region
18 */
19#define REALMODE_END_SIGNATURE 0x65a22c82
20
21#endif /* ARCH_X86_REALMODE_RM_REALMODE_H */
diff --git a/arch/x86/realmode/rm/realmode.lds.S b/arch/x86/realmode/rm/realmode.lds.S
new file mode 100644
index 00000000000..86b2e8d6b1f
--- /dev/null
+++ b/arch/x86/realmode/rm/realmode.lds.S
@@ -0,0 +1,76 @@
1/*
2 * realmode.lds.S
3 *
4 * Linker script for the real-mode code
5 */
6
7#include <asm/page_types.h>
8
9#undef i386
10
11OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
12OUTPUT_ARCH(i386)
13
14SECTIONS
15{
16 real_mode_seg = 0;
17
18 . = 0;
19 .header : {
20 pa_real_mode_base = .;
21 *(.header)
22 }
23
24 . = ALIGN(4);
25 .rodata : {
26 *(.rodata)
27 *(.rodata.*)
28 . = ALIGN(16);
29 video_cards = .;
30 *(.videocards)
31 video_cards_end = .;
32 }
33
34 . = ALIGN(PAGE_SIZE);
35 pa_text_start = .;
36 .text : {
37 *(.text)
38 *(.text.*)
39 }
40
41 .text32 : {
42 *(.text32)
43 *(.text32.*)
44 }
45
46 .text64 : {
47 *(.text64)
48 *(.text64.*)
49 }
50 pa_ro_end = .;
51
52 . = ALIGN(PAGE_SIZE);
53 .data : {
54 *(.data)
55 *(.data.*)
56 }
57
58 . = ALIGN(128);
59 .bss : {
60 *(.bss*)
61 }
62
63 /* End signature for integrity checking */
64 . = ALIGN(4);
65 .signature : {
66 *(.signature)
67 }
68
69 /DISCARD/ : {
70 *(.note*)
71 *(.debug*)
72 *(.eh_frame*)
73 }
74
75#include "pasyms.h"
76}
diff --git a/arch/x86/kernel/reboot_32.S b/arch/x86/realmode/rm/reboot_32.S
index 1d5c46df0d7..114044876b3 100644
--- a/arch/x86/kernel/reboot_32.S
+++ b/arch/x86/realmode/rm/reboot_32.S
@@ -2,6 +2,7 @@
2#include <linux/init.h> 2#include <linux/init.h>
3#include <asm/segment.h> 3#include <asm/segment.h>
4#include <asm/page_types.h> 4#include <asm/page_types.h>
5#include "realmode.h"
5 6
6/* 7/*
7 * The following code and data reboots the machine by switching to real 8 * The following code and data reboots the machine by switching to real
@@ -13,34 +14,20 @@
13 * 14 *
14 * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. 15 * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax.
15 */ 16 */
16 .section ".x86_trampoline","a" 17 .section ".text32", "ax"
17 .balign 16
18 .code32 18 .code32
19ENTRY(machine_real_restart_asm)
20r_base = .
21 /* Get our own relocated address */
22 call 1f
231: popl %ebx
24 subl $(1b - r_base), %ebx
25
26 /* Compute the equivalent real-mode segment */
27 movl %ebx, %ecx
28 shrl $4, %ecx
29
30 /* Patch post-real-mode segment jump */
31 movw (dispatch_table - r_base)(%ebx,%eax,2),%ax
32 movw %ax, (101f - r_base)(%ebx)
33 movw %cx, (102f - r_base)(%ebx)
34 19
20 .balign 16
21ENTRY(machine_real_restart_asm)
35 /* Set up the IDT for real mode. */ 22 /* Set up the IDT for real mode. */
36 lidtl (machine_real_restart_idt - r_base)(%ebx) 23 lidtl pa_machine_real_restart_idt
37 24
38 /* 25 /*
39 * Set up a GDT from which we can load segment descriptors for real 26 * Set up a GDT from which we can load segment descriptors for real
40 * mode. The GDT is not used in real mode; it is just needed here to 27 * mode. The GDT is not used in real mode; it is just needed here to
41 * prepare the descriptors. 28 * prepare the descriptors.
42 */ 29 */
43 lgdtl (machine_real_restart_gdt - r_base)(%ebx) 30 lgdtl pa_machine_real_restart_gdt
44 31
45 /* 32 /*
46 * Load the data segment registers with 16-bit compatible values 33 * Load the data segment registers with 16-bit compatible values
@@ -51,7 +38,7 @@ r_base = .
51 movl %ecx, %fs 38 movl %ecx, %fs
52 movl %ecx, %gs 39 movl %ecx, %gs
53 movl %ecx, %ss 40 movl %ecx, %ss
54 ljmpl $8, $1f - r_base 41 ljmpw $8, $1f
55 42
56/* 43/*
57 * This is 16-bit protected mode code to disable paging and the cache, 44 * This is 16-bit protected mode code to disable paging and the cache,
@@ -76,27 +63,29 @@ r_base = .
76 * 63 *
77 * Most of this work is probably excessive, but it is what is tested. 64 * Most of this work is probably excessive, but it is what is tested.
78 */ 65 */
66 .text
79 .code16 67 .code16
68
69 .balign 16
70machine_real_restart_asm16:
801: 711:
81 xorl %ecx, %ecx 72 xorl %ecx, %ecx
82 movl %cr0, %eax 73 movl %cr0, %edx
83 andl $0x00000011, %eax 74 andl $0x00000011, %edx
84 orl $0x60000000, %eax 75 orl $0x60000000, %edx
85 movl %eax, %cr0 76 movl %edx, %cr0
86 movl %ecx, %cr3 77 movl %ecx, %cr3
87 movl %cr0, %edx 78 movl %cr0, %edx
88 andl $0x60000000, %edx /* If no cache bits -> no wbinvd */ 79 testl $0x60000000, %edx /* If no cache bits -> no wbinvd */
89 jz 2f 80 jz 2f
90 wbinvd 81 wbinvd
912: 822:
92 andb $0x10, %al 83 andb $0x10, %dl
93 movl %eax, %cr0 84 movl %edx, %cr0
94 .byte 0xea /* ljmpw */ 85 LJMPW_RM(3f)
95101: .word 0 /* Offset */ 863:
96102: .word 0 /* Segment */ 87 andw %ax, %ax
97 88 jz bios
98bios:
99 ljmpw $0xf000, $0xfff0
100 89
101apm: 90apm:
102 movw $0x1000, %ax 91 movw $0x1000, %ax
@@ -106,26 +95,34 @@ apm:
106 movw $0x0001, %bx 95 movw $0x0001, %bx
107 movw $0x0003, %cx 96 movw $0x0003, %cx
108 int $0x15 97 int $0x15
98 /* This should never return... */
109 99
110END(machine_real_restart_asm) 100bios:
101 ljmpw $0xf000, $0xfff0
111 102
112 .balign 16 103 .section ".rodata", "a"
113 /* These must match <asm/reboot.h */
114dispatch_table:
115 .word bios - r_base
116 .word apm - r_base
117END(dispatch_table)
118 104
119 .balign 16 105 .balign 16
120machine_real_restart_idt: 106GLOBAL(machine_real_restart_idt)
121 .word 0xffff /* Length - real mode default value */ 107 .word 0xffff /* Length - real mode default value */
122 .long 0 /* Base - real mode default value */ 108 .long 0 /* Base - real mode default value */
123END(machine_real_restart_idt) 109END(machine_real_restart_idt)
124 110
125 .balign 16 111 .balign 16
126ENTRY(machine_real_restart_gdt) 112GLOBAL(machine_real_restart_gdt)
127 .quad 0 /* Self-pointer, filled in by PM code */ 113 /* Self-pointer */
128 .quad 0 /* 16-bit code segment, filled in by PM code */ 114 .word 0xffff /* Length - real mode default value */
115 .long pa_machine_real_restart_gdt
116 .word 0
117
118 /*
119 * 16-bit code segment pointing to real_mode_seg
120 * Selector value 8
121 */
122 .word 0xffff /* Limit */
123 .long 0x9b000000 + pa_real_mode_base
124 .word 0
125
129 /* 126 /*
130 * 16-bit data segment with the selector value 16 = 0x10 and 127 * 16-bit data segment with the selector value 16 = 0x10 and
131 * base value 0x100; since this is consistent with real mode 128 * base value 0x100; since this is consistent with real mode
diff --git a/arch/x86/realmode/rm/regs.c b/arch/x86/realmode/rm/regs.c
new file mode 100644
index 00000000000..fbb15b9f9ca
--- /dev/null
+++ b/arch/x86/realmode/rm/regs.c
@@ -0,0 +1 @@
#include "../../boot/regs.c"
diff --git a/arch/x86/realmode/rm/stack.S b/arch/x86/realmode/rm/stack.S
new file mode 100644
index 00000000000..867ae87adfa
--- /dev/null
+++ b/arch/x86/realmode/rm/stack.S
@@ -0,0 +1,19 @@
1/*
2 * Common heap and stack allocations
3 */
4
5#include <linux/linkage.h>
6
7 .data
8GLOBAL(HEAP)
9 .long rm_heap
10GLOBAL(heap_end)
11 .long rm_stack
12
13 .bss
14 .balign 16
15GLOBAL(rm_heap)
16 .space 2048
17GLOBAL(rm_stack)
18 .space 2048
19GLOBAL(rm_stack_end)
diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S
new file mode 100644
index 00000000000..c1b2791183e
--- /dev/null
+++ b/arch/x86/realmode/rm/trampoline_32.S
@@ -0,0 +1,74 @@
1/*
2 *
3 * Trampoline.S Derived from Setup.S by Linus Torvalds
4 *
5 * 4 Jan 1997 Michael Chastain: changed to gnu as.
6 *
7 * This is only used for booting secondary CPUs in SMP machine
8 *
9 * Entry: CS:IP point to the start of our code, we are
10 * in real mode with no stack, but the rest of the
11 * trampoline page to make our stack and everything else
12 * is a mystery.
13 *
14 * We jump into arch/x86/kernel/head_32.S.
15 *
16 * On entry to trampoline_start, the processor is in real mode
17 * with 16-bit addressing and 16-bit data. CS has some value
18 * and IP is zero. Thus, we load CS to the physical segment
19 * of the real mode code before doing anything further.
20 */
21
22#include <linux/linkage.h>
23#include <linux/init.h>
24#include <asm/segment.h>
25#include <asm/page_types.h>
26#include "realmode.h"
27
28 .text
29 .code16
30
31 .balign PAGE_SIZE
32ENTRY(trampoline_start)
33 wbinvd # Needed for NUMA-Q should be harmless for others
34
35 LJMPW_RM(1f)
361:
37 mov %cs, %ax # Code and data in the same place
38 mov %ax, %ds
39
40 cli # We should be safe anyway
41
42 movl tr_start, %eax # where we need to go
43
44 movl $0xA5A5A5A5, trampoline_status
45 # write marker for master knows we're running
46
47 /*
48 * GDT tables in non default location kernel can be beyond 16MB and
49 * lgdt will not be able to load the address as in real mode default
50 * operand size is 16bit. Use lgdtl instead to force operand size
51 * to 32 bit.
52 */
53 lidtl tr_idt # load idt with 0, 0
54 lgdtl tr_gdt # load gdt with whatever is appropriate
55
56 movw $1, %dx # protected mode (PE) bit
57 lmsw %dx # into protected mode
58
59 ljmpl $__BOOT_CS, $pa_startup_32
60
61 .section ".text32","ax"
62 .code32
63ENTRY(startup_32) # note: also used from wakeup_asm.S
64 jmp *%eax
65
66 .bss
67 .balign 8
68GLOBAL(trampoline_header)
69 tr_start: .space 4
70 tr_gdt_pad: .space 2
71 tr_gdt: .space 6
72END(trampoline_header)
73
74#include "trampoline_common.S"
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index 09ff51799e9..bb360dc39d2 100644
--- a/arch/x86/kernel/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -5,12 +5,12 @@
5 * 4 Jan 1997 Michael Chastain: changed to gnu as. 5 * 4 Jan 1997 Michael Chastain: changed to gnu as.
6 * 15 Sept 2005 Eric Biederman: 64bit PIC support 6 * 15 Sept 2005 Eric Biederman: 64bit PIC support
7 * 7 *
8 * Entry: CS:IP point to the start of our code, we are 8 * Entry: CS:IP point to the start of our code, we are
9 * in real mode with no stack, but the rest of the 9 * in real mode with no stack, but the rest of the
10 * trampoline page to make our stack and everything else 10 * trampoline page to make our stack and everything else
11 * is a mystery. 11 * is a mystery.
12 * 12 *
13 * On entry to trampoline_data, the processor is in real mode 13 * On entry to trampoline_start, the processor is in real mode
14 * with 16-bit addressing and 16-bit data. CS has some value 14 * with 16-bit addressing and 16-bit data. CS has some value
15 * and IP is zero. Thus, data addresses need to be absolute 15 * and IP is zero. Thus, data addresses need to be absolute
16 * (no relocation) and are taken with regard to r_base. 16 * (no relocation) and are taken with regard to r_base.
@@ -31,43 +31,33 @@
31#include <asm/msr.h> 31#include <asm/msr.h>
32#include <asm/segment.h> 32#include <asm/segment.h>
33#include <asm/processor-flags.h> 33#include <asm/processor-flags.h>
34#include "realmode.h"
34 35
35 .section ".x86_trampoline","a" 36 .text
36 .balign PAGE_SIZE
37 .code16 37 .code16
38 38
39ENTRY(trampoline_data) 39 .balign PAGE_SIZE
40r_base = . 40ENTRY(trampoline_start)
41 cli # We should be safe anyway 41 cli # We should be safe anyway
42 wbinvd 42 wbinvd
43
44 LJMPW_RM(1f)
451:
43 mov %cs, %ax # Code and data in the same place 46 mov %cs, %ax # Code and data in the same place
44 mov %ax, %ds 47 mov %ax, %ds
45 mov %ax, %es 48 mov %ax, %es
46 mov %ax, %ss 49 mov %ax, %ss
47 50
51 movl $0xA5A5A5A5, trampoline_status
52 # write marker for master knows we're running
48 53
49 movl $0xA5A5A5A5, trampoline_status - r_base 54 # Setup stack
50 # write marker for master knows we're running 55 movl $rm_stack_end, %esp
51
52 # Setup stack
53 movw $(trampoline_stack_end - r_base), %sp
54 56
55 call verify_cpu # Verify the cpu supports long mode 57 call verify_cpu # Verify the cpu supports long mode
56 testl %eax, %eax # Check for return code 58 testl %eax, %eax # Check for return code
57 jnz no_longmode 59 jnz no_longmode
58 60
59 mov %cs, %ax
60 movzx %ax, %esi # Find the 32bit trampoline location
61 shll $4, %esi
62
63 # Fixup the absolute vectors
64 leal (startup_32 - r_base)(%esi), %eax
65 movl %eax, startup_32_vector - r_base
66 leal (startup_64 - r_base)(%esi), %eax
67 movl %eax, startup_64_vector - r_base
68 leal (tgdt - r_base)(%esi), %eax
69 movl %eax, (tgdt + 2 - r_base)
70
71 /* 61 /*
72 * GDT tables in non default location kernel can be beyond 16MB and 62 * GDT tables in non default location kernel can be beyond 16MB and
73 * lgdt will not be able to load the address as in real mode default 63 * lgdt will not be able to load the address as in real mode default
@@ -75,36 +65,49 @@ r_base = .
75 * to 32 bit. 65 * to 32 bit.
76 */ 66 */
77 67
78 lidtl tidt - r_base # load idt with 0, 0 68 lidtl tr_idt # load idt with 0, 0
79 lgdtl tgdt - r_base # load gdt with whatever is appropriate 69 lgdtl tr_gdt # load gdt with whatever is appropriate
70
71 movw $__KERNEL_DS, %dx # Data segment descriptor
80 72
81 mov $X86_CR0_PE, %ax # protected mode (PE) bit 73 # Enable protected mode
82 lmsw %ax # into protected mode 74 movl $X86_CR0_PE, %eax # protected mode (PE) bit
75 movl %eax, %cr0 # into protected mode
83 76
84 # flush prefetch and jump to startup_32 77 # flush prefetch and jump to startup_32
85 ljmpl *(startup_32_vector - r_base) 78 ljmpl $__KERNEL32_CS, $pa_startup_32
86 79
80no_longmode:
81 hlt
82 jmp no_longmode
83#include "../kernel/verify_cpu.S"
84
85 .section ".text32","ax"
87 .code32 86 .code32
88 .balign 4 87 .balign 4
89startup_32: 88ENTRY(startup_32)
90 movl $__KERNEL_DS, %eax # Initialize the %ds segment register 89 movl %edx, %ss
91 movl %eax, %ds 90 addl $pa_real_mode_base, %esp
92 91 movl %edx, %ds
93 movl $X86_CR4_PAE, %eax 92 movl %edx, %es
93 movl %edx, %fs
94 movl %edx, %gs
95
96 movl pa_tr_cr4, %eax
94 movl %eax, %cr4 # Enable PAE mode 97 movl %eax, %cr4 # Enable PAE mode
95 98
96 # Setup trampoline 4 level pagetables 99 # Setup trampoline 4 level pagetables
97 leal (trampoline_level4_pgt - r_base)(%esi), %eax 100 movl $pa_trampoline_pgd, %eax
98 movl %eax, %cr3 101 movl %eax, %cr3
99 102
103 # Set up EFER
104 movl pa_tr_efer, %eax
105 movl pa_tr_efer + 4, %edx
100 movl $MSR_EFER, %ecx 106 movl $MSR_EFER, %ecx
101 movl $(1 << _EFER_LME), %eax # Enable Long Mode
102 xorl %edx, %edx
103 wrmsr 107 wrmsr
104 108
105 # Enable paging and in turn activate Long Mode 109 # Enable paging and in turn activate Long Mode
106 # Enable protected mode 110 movl $(X86_CR0_PG | X86_CR0_WP | X86_CR0_PE), %eax
107 movl $(X86_CR0_PG | X86_CR0_PE), %eax
108 movl %eax, %cr0 111 movl %eax, %cr0
109 112
110 /* 113 /*
@@ -113,59 +116,38 @@ startup_32:
113 * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use 116 * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use
114 * the new gdt/idt that has __KERNEL_CS with CS.L = 1. 117 * the new gdt/idt that has __KERNEL_CS with CS.L = 1.
115 */ 118 */
116 ljmp *(startup_64_vector - r_base)(%esi) 119 ljmpl $__KERNEL_CS, $pa_startup_64
117 120
121 .section ".text64","ax"
118 .code64 122 .code64
119 .balign 4 123 .balign 4
120startup_64: 124ENTRY(startup_64)
121 # Now jump into the kernel using virtual addresses 125 # Now jump into the kernel using virtual addresses
122 movq $secondary_startup_64, %rax 126 jmpq *tr_start(%rip)
123 jmp *%rax
124
125 .code16
126no_longmode:
127 hlt
128 jmp no_longmode
129#include "verify_cpu.S"
130
131 .balign 4
132 # Careful these need to be in the same 64K segment as the above;
133tidt:
134 .word 0 # idt limit = 0
135 .word 0, 0 # idt base = 0L
136 127
128 .section ".rodata","a"
137 # Duplicate the global descriptor table 129 # Duplicate the global descriptor table
138 # so the kernel can live anywhere 130 # so the kernel can live anywhere
139 .balign 4 131 .balign 16
140tgdt: 132 .globl tr_gdt
141 .short tgdt_end - tgdt # gdt limit 133tr_gdt:
142 .long tgdt - r_base 134 .short tr_gdt_end - tr_gdt - 1 # gdt limit
143 .short 0 135 .long pa_tr_gdt
136 .short 0
144 .quad 0x00cf9b000000ffff # __KERNEL32_CS 137 .quad 0x00cf9b000000ffff # __KERNEL32_CS
145 .quad 0x00af9b000000ffff # __KERNEL_CS 138 .quad 0x00af9b000000ffff # __KERNEL_CS
146 .quad 0x00cf93000000ffff # __KERNEL_DS 139 .quad 0x00cf93000000ffff # __KERNEL_DS
147tgdt_end: 140tr_gdt_end:
148 141
149 .balign 4 142 .bss
150startup_32_vector: 143 .balign PAGE_SIZE
151 .long startup_32 - r_base 144GLOBAL(trampoline_pgd) .space PAGE_SIZE
152 .word __KERNEL32_CS, 0
153 145
154 .balign 4 146 .balign 8
155startup_64_vector: 147GLOBAL(trampoline_header)
156 .long startup_64 - r_base 148 tr_start: .space 8
157 .word __KERNEL_CS, 0 149 GLOBAL(tr_efer) .space 8
150 GLOBAL(tr_cr4) .space 4
151END(trampoline_header)
158 152
159 .balign 4 153#include "trampoline_common.S"
160ENTRY(trampoline_status)
161 .long 0
162
163trampoline_stack:
164 .org 0x1000
165trampoline_stack_end:
166ENTRY(trampoline_level4_pgt)
167 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
168 .fill 510,8,0
169 .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
170
171ENTRY(trampoline_end)
diff --git a/arch/x86/realmode/rm/trampoline_common.S b/arch/x86/realmode/rm/trampoline_common.S
new file mode 100644
index 00000000000..b1ecdb9692a
--- /dev/null
+++ b/arch/x86/realmode/rm/trampoline_common.S
@@ -0,0 +1,7 @@
1 .section ".rodata","a"
2 .balign 16
3tr_idt: .fill 1, 6, 0
4
5 .bss
6 .balign 4
7GLOBAL(trampoline_status) .space 4
diff --git a/arch/x86/realmode/rm/video-bios.c b/arch/x86/realmode/rm/video-bios.c
new file mode 100644
index 00000000000..848b25aaf11
--- /dev/null
+++ b/arch/x86/realmode/rm/video-bios.c
@@ -0,0 +1 @@
#include "../../boot/video-bios.c"
diff --git a/arch/x86/realmode/rm/video-mode.c b/arch/x86/realmode/rm/video-mode.c
new file mode 100644
index 00000000000..2a98b7e2368
--- /dev/null
+++ b/arch/x86/realmode/rm/video-mode.c
@@ -0,0 +1 @@
#include "../../boot/video-mode.c"
diff --git a/arch/x86/realmode/rm/video-vesa.c b/arch/x86/realmode/rm/video-vesa.c
new file mode 100644
index 00000000000..413edddb51e
--- /dev/null
+++ b/arch/x86/realmode/rm/video-vesa.c
@@ -0,0 +1 @@
#include "../../boot/video-vesa.c"
diff --git a/arch/x86/realmode/rm/video-vga.c b/arch/x86/realmode/rm/video-vga.c
new file mode 100644
index 00000000000..3085f5c9d28
--- /dev/null
+++ b/arch/x86/realmode/rm/video-vga.c
@@ -0,0 +1 @@
#include "../../boot/video-vga.c"
diff --git a/arch/x86/kernel/acpi/realmode/wakemain.c b/arch/x86/realmode/rm/wakemain.c
index 883962d9eef..91405d515ec 100644
--- a/arch/x86/kernel/acpi/realmode/wakemain.c
+++ b/arch/x86/realmode/rm/wakemain.c
@@ -65,7 +65,8 @@ void main(void)
65{ 65{
66 /* Kill machine if structures are wrong */ 66 /* Kill machine if structures are wrong */
67 if (wakeup_header.real_magic != 0x12345678) 67 if (wakeup_header.real_magic != 0x12345678)
68 while (1); 68 while (1)
69 ;
69 70
70 if (wakeup_header.realmode_flags & 4) 71 if (wakeup_header.realmode_flags & 4)
71 send_morse("...-"); 72 send_morse("...-");
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/realmode/rm/wakeup.h
index 97a29e1430e..9317e0042f2 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.h
+++ b/arch/x86/realmode/rm/wakeup.h
@@ -12,9 +12,8 @@
12/* This must match data at wakeup.S */ 12/* This must match data at wakeup.S */
13struct wakeup_header { 13struct wakeup_header {
14 u16 video_mode; /* Video mode number */ 14 u16 video_mode; /* Video mode number */
15 u16 _jmp1; /* ljmpl opcode, 32-bit only */
16 u32 pmode_entry; /* Protected mode resume point, 32-bit only */ 15 u32 pmode_entry; /* Protected mode resume point, 32-bit only */
17 u16 _jmp2; /* CS value, 32-bit only */ 16 u16 pmode_cs;
18 u32 pmode_cr0; /* Protected mode cr0 */ 17 u32 pmode_cr0; /* Protected mode cr0 */
19 u32 pmode_cr3; /* Protected mode cr3 */ 18 u32 pmode_cr3; /* Protected mode cr3 */
20 u32 pmode_cr4; /* Protected mode cr4 */ 19 u32 pmode_cr4; /* Protected mode cr4 */
@@ -26,12 +25,6 @@ struct wakeup_header {
26 u32 pmode_behavior; /* Wakeup routine behavior flags */ 25 u32 pmode_behavior; /* Wakeup routine behavior flags */
27 u32 realmode_flags; 26 u32 realmode_flags;
28 u32 real_magic; 27 u32 real_magic;
29 u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
30 u8 _pad1;
31 u8 wakeup_jmp;
32 u16 wakeup_jmp_off;
33 u16 wakeup_jmp_seg;
34 u64 wakeup_gdt[3];
35 u32 signature; /* To check we have correct structure */ 28 u32 signature; /* To check we have correct structure */
36} __attribute__((__packed__)); 29} __attribute__((__packed__));
37 30
@@ -40,7 +33,6 @@ extern struct wakeup_header wakeup_header;
40 33
41#define WAKEUP_HEADER_OFFSET 8 34#define WAKEUP_HEADER_OFFSET 8
42#define WAKEUP_HEADER_SIGNATURE 0x51ee1111 35#define WAKEUP_HEADER_SIGNATURE 0x51ee1111
43#define WAKEUP_END_SIGNATURE 0x65a22c82
44 36
45/* Wakeup behavior bits */ 37/* Wakeup behavior bits */
46#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 38#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/realmode/rm/wakeup_asm.S
index b4fd836e405..8905166b0bb 100644
--- a/arch/x86/kernel/acpi/realmode/wakeup.S
+++ b/arch/x86/realmode/rm/wakeup_asm.S
@@ -1,50 +1,47 @@
1/* 1/*
2 * ACPI wakeup real mode startup stub 2 * ACPI wakeup real mode startup stub
3 */ 3 */
4#include <linux/linkage.h>
4#include <asm/segment.h> 5#include <asm/segment.h>
5#include <asm/msr-index.h> 6#include <asm/msr-index.h>
6#include <asm/page_types.h> 7#include <asm/page_types.h>
7#include <asm/pgtable_types.h> 8#include <asm/pgtable_types.h>
8#include <asm/processor-flags.h> 9#include <asm/processor-flags.h>
10#include "realmode.h"
9#include "wakeup.h" 11#include "wakeup.h"
10 12
11 .code16 13 .code16
12 .section ".jump", "ax"
13 .globl _start
14_start:
15 cli
16 jmp wakeup_code
17 14
18/* This should match the structure in wakeup.h */ 15/* This should match the structure in wakeup.h */
19 .section ".header", "a" 16 .section ".data", "aw"
20 .globl wakeup_header 17
21wakeup_header: 18 .balign 16
22video_mode: .short 0 /* Video mode number */ 19GLOBAL(wakeup_header)
23pmode_return: .byte 0x66, 0xea /* ljmpl */ 20 video_mode: .short 0 /* Video mode number */
24 .long 0 /* offset goes here */ 21 pmode_entry: .long 0
25 .short __KERNEL_CS 22 pmode_cs: .short __KERNEL_CS
26pmode_cr0: .long 0 /* Saved %cr0 */ 23 pmode_cr0: .long 0 /* Saved %cr0 */
27pmode_cr3: .long 0 /* Saved %cr3 */ 24 pmode_cr3: .long 0 /* Saved %cr3 */
28pmode_cr4: .long 0 /* Saved %cr4 */ 25 pmode_cr4: .long 0 /* Saved %cr4 */
29pmode_efer: .quad 0 /* Saved EFER */ 26 pmode_efer: .quad 0 /* Saved EFER */
30pmode_gdt: .quad 0 27 pmode_gdt: .quad 0
31pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ 28 pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */
32pmode_behavior: .long 0 /* Wakeup behavior flags */ 29 pmode_behavior: .long 0 /* Wakeup behavior flags */
33realmode_flags: .long 0 30 realmode_flags: .long 0
34real_magic: .long 0 31 real_magic: .long 0
35trampoline_segment: .word 0 32 signature: .long WAKEUP_HEADER_SIGNATURE
36_pad1: .byte 0 33END(wakeup_header)
37wakeup_jmp: .byte 0xea /* ljmpw */
38wakeup_jmp_off: .word 3f
39wakeup_jmp_seg: .word 0
40wakeup_gdt: .quad 0, 0, 0
41signature: .long WAKEUP_HEADER_SIGNATURE
42 34
43 .text 35 .text
44 .code16 36 .code16
45wakeup_code: 37
38 .balign 16
39ENTRY(wakeup_start)
40 cli
46 cld 41 cld
47 42
43 LJMPW_RM(3f)
443:
48 /* Apparently some dimwit BIOS programmers don't know how to 45 /* Apparently some dimwit BIOS programmers don't know how to
49 program a PM to RM transition, and we might end up here with 46 program a PM to RM transition, and we might end up here with
50 junk in the data segment descriptor registers. The only way 47 junk in the data segment descriptor registers. The only way
@@ -54,8 +51,7 @@ wakeup_code:
54 movl %cr0, %eax 51 movl %cr0, %eax
55 orb $X86_CR0_PE, %al 52 orb $X86_CR0_PE, %al
56 movl %eax, %cr0 53 movl %eax, %cr0
57 jmp 1f 54 ljmpw $8, $2f
581: ljmpw $8, $2f
592: 552:
60 movw %cx, %ds 56 movw %cx, %ds
61 movw %cx, %es 57 movw %cx, %es
@@ -65,16 +61,18 @@ wakeup_code:
65 61
66 andb $~X86_CR0_PE, %al 62 andb $~X86_CR0_PE, %al
67 movl %eax, %cr0 63 movl %eax, %cr0
68 jmp wakeup_jmp 64 LJMPW_RM(3f)
693: 653:
70 /* Set up segments */ 66 /* Set up segments */
71 movw %cs, %ax 67 movw %cs, %ax
68 movw %ax, %ss
69 movl $rm_stack_end, %esp
72 movw %ax, %ds 70 movw %ax, %ds
73 movw %ax, %es 71 movw %ax, %es
74 movw %ax, %ss 72 movw %ax, %fs
75 lidtl wakeup_idt 73 movw %ax, %gs
76 74
77 movl $wakeup_stack_end, %esp 75 lidtl wakeup_idt
78 76
79 /* Clear the EFLAGS */ 77 /* Clear the EFLAGS */
80 pushl $0 78 pushl $0
@@ -87,7 +85,7 @@ wakeup_code:
87 85
88 /* Check we really have everything... */ 86 /* Check we really have everything... */
89 movl end_signature, %eax 87 movl end_signature, %eax
90 cmpl $WAKEUP_END_SIGNATURE, %eax 88 cmpl $REALMODE_END_SIGNATURE, %eax
91 jne bogus_real_magic 89 jne bogus_real_magic
92 90
93 /* Call the C code */ 91 /* Call the C code */
@@ -128,14 +126,13 @@ wakeup_code:
128 lgdtl pmode_gdt 126 lgdtl pmode_gdt
129 127
130 /* This really couldn't... */ 128 /* This really couldn't... */
131 movl pmode_cr0, %eax 129 movl pmode_entry, %eax
132 movl %eax, %cr0 130 movl pmode_cr0, %ecx
133 jmp pmode_return 131 movl %ecx, %cr0
132 ljmpl $__KERNEL_CS, $pa_startup_32
133 /* -> jmp *%eax in trampoline_32.S */
134#else 134#else
135 pushw $0 135 jmp trampoline_start
136 pushw trampoline_segment
137 pushw $0
138 lret
139#endif 136#endif
140 137
141bogus_real_magic: 138bogus_real_magic:
@@ -143,28 +140,38 @@ bogus_real_magic:
143 hlt 140 hlt
144 jmp 1b 141 jmp 1b
145 142
146 .data 143 .section ".rodata","a"
144
145 /*
146 * Set up the wakeup GDT. We set these up as Big Real Mode,
147 * that is, with limits set to 4 GB. At least the Lenovo
148 * Thinkpad X61 is known to need this for the video BIOS
149 * initialization quirk to work; this is likely to also
150 * be the case for other laptops or integrated video devices.
151 */
152
153 .balign 16
154GLOBAL(wakeup_gdt)
155 .word 3*8-1 /* Self-descriptor */
156 .long pa_wakeup_gdt
157 .word 0
158
159 .word 0xffff /* 16-bit code segment @ real_mode_base */
160 .long 0x9b000000 + pa_real_mode_base
161 .word 0x008f /* big real mode */
162
163 .word 0xffff /* 16-bit data segment @ real_mode_base */
164 .long 0x93000000 + pa_real_mode_base
165 .word 0x008f /* big real mode */
166END(wakeup_gdt)
167
168 .section ".rodata","a"
147 .balign 8 169 .balign 8
148 170
149 /* This is the standard real-mode IDT */ 171 /* This is the standard real-mode IDT */
150wakeup_idt: 172 .balign 16
173GLOBAL(wakeup_idt)
151 .word 0xffff /* limit */ 174 .word 0xffff /* limit */
152 .long 0 /* address */ 175 .long 0 /* address */
153 .word 0 176 .word 0
154 177END(wakeup_idt)
155 .globl HEAP, heap_end
156HEAP:
157 .long wakeup_heap
158heap_end:
159 .long wakeup_stack
160
161 .bss
162wakeup_heap:
163 .space 2048
164wakeup_stack:
165 .space 2048
166wakeup_stack_end:
167
168 .section ".signature","a"
169end_signature:
170 .long WAKEUP_END_SIGNATURE
diff --git a/arch/x86/realmode/rmpiggy.S b/arch/x86/realmode/rmpiggy.S
new file mode 100644
index 00000000000..204c6ece0e9
--- /dev/null
+++ b/arch/x86/realmode/rmpiggy.S
@@ -0,0 +1,20 @@
1/*
2 * Wrapper script for the realmode binary as a transport object
3 * before copying to low memory.
4 */
5#include <linux/linkage.h>
6#include <asm/page_types.h>
7
8 .section ".init.data","aw"
9
10 .balign PAGE_SIZE
11
12GLOBAL(real_mode_blob)
13 .incbin "arch/x86/realmode/rm/realmode.bin"
14END(real_mode_blob)
15
16GLOBAL(real_mode_blob_end);
17
18GLOBAL(real_mode_relocs)
19 .incbin "arch/x86/realmode/rm/realmode.relocs"
20END(real_mode_relocs)
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index b685296d446..5a1847d6193 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -78,6 +78,13 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
78 78
79static const char * const sym_regex_realmode[S_NSYMTYPES] = { 79static const char * const sym_regex_realmode[S_NSYMTYPES] = {
80/* 80/*
81 * These symbols are known to be relative, even if the linker marks them
82 * as absolute (typically defined outside any section in the linker script.)
83 */
84 [S_REL] =
85 "^pa_",
86
87/*
81 * These are 16-bit segment symbols when compiling 16-bit code. 88 * These are 16-bit segment symbols when compiling 16-bit code.
82 */ 89 */
83 [S_SEG] = 90 [S_SEG] =
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index ef1db1900d8..c8377fb26cd 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -19,107 +19,3 @@ struct dentry * __init xen_init_debugfs(void)
19 return d_xen_debug; 19 return d_xen_debug;
20} 20}
21 21
22struct array_data
23{
24 void *array;
25 unsigned elements;
26};
27
28static int u32_array_open(struct inode *inode, struct file *file)
29{
30 file->private_data = NULL;
31 return nonseekable_open(inode, file);
32}
33
34static size_t format_array(char *buf, size_t bufsize, const char *fmt,
35 u32 *array, unsigned array_size)
36{
37 size_t ret = 0;
38 unsigned i;
39
40 for(i = 0; i < array_size; i++) {
41 size_t len;
42
43 len = snprintf(buf, bufsize, fmt, array[i]);
44 len++; /* ' ' or '\n' */
45 ret += len;
46
47 if (buf) {
48 buf += len;
49 bufsize -= len;
50 buf[-1] = (i == array_size-1) ? '\n' : ' ';
51 }
52 }
53
54 ret++; /* \0 */
55 if (buf)
56 *buf = '\0';
57
58 return ret;
59}
60
61static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size)
62{
63 size_t len = format_array(NULL, 0, fmt, array, array_size);
64 char *ret;
65
66 ret = kmalloc(len, GFP_KERNEL);
67 if (ret == NULL)
68 return NULL;
69
70 format_array(ret, len, fmt, array, array_size);
71 return ret;
72}
73
74static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
75 loff_t *ppos)
76{
77 struct inode *inode = file->f_path.dentry->d_inode;
78 struct array_data *data = inode->i_private;
79 size_t size;
80
81 if (*ppos == 0) {
82 if (file->private_data) {
83 kfree(file->private_data);
84 file->private_data = NULL;
85 }
86
87 file->private_data = format_array_alloc("%u", data->array, data->elements);
88 }
89
90 size = 0;
91 if (file->private_data)
92 size = strlen(file->private_data);
93
94 return simple_read_from_buffer(buf, len, ppos, file->private_data, size);
95}
96
97static int xen_array_release(struct inode *inode, struct file *file)
98{
99 kfree(file->private_data);
100
101 return 0;
102}
103
104static const struct file_operations u32_array_fops = {
105 .owner = THIS_MODULE,
106 .open = u32_array_open,
107 .release= xen_array_release,
108 .read = u32_array_read,
109 .llseek = no_llseek,
110};
111
112struct dentry *xen_debugfs_create_u32_array(const char *name, umode_t mode,
113 struct dentry *parent,
114 u32 *array, unsigned elements)
115{
116 struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
117
118 if (data == NULL)
119 return NULL;
120
121 data->array = array;
122 data->elements = elements;
123
124 return debugfs_create_file(name, mode, parent, data, &u32_array_fops);
125}
diff --git a/arch/x86/xen/debugfs.h b/arch/x86/xen/debugfs.h
index 78d25499be5..12ebf3325c7 100644
--- a/arch/x86/xen/debugfs.h
+++ b/arch/x86/xen/debugfs.h
@@ -3,8 +3,4 @@
3 3
4struct dentry * __init xen_init_debugfs(void); 4struct dentry * __init xen_init_debugfs(void);
5 5
6struct dentry *xen_debugfs_create_u32_array(const char *name, umode_t mode,
7 struct dentry *parent,
8 u32 *array, unsigned elements);
9
10#endif /* _XEN_DEBUGFS_H */ 6#endif /* _XEN_DEBUGFS_H */
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index c0f5facdb10..75f33b2a593 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -42,6 +42,7 @@
42#include <xen/page.h> 42#include <xen/page.h>
43#include <xen/hvm.h> 43#include <xen/hvm.h>
44#include <xen/hvc-console.h> 44#include <xen/hvc-console.h>
45#include <xen/acpi.h>
45 46
46#include <asm/paravirt.h> 47#include <asm/paravirt.h>
47#include <asm/apic.h> 48#include <asm/apic.h>
@@ -75,6 +76,7 @@
75 76
76#include "xen-ops.h" 77#include "xen-ops.h"
77#include "mmu.h" 78#include "mmu.h"
79#include "smp.h"
78#include "multicalls.h" 80#include "multicalls.h"
79 81
80EXPORT_SYMBOL_GPL(hypercall_page); 82EXPORT_SYMBOL_GPL(hypercall_page);
@@ -883,6 +885,14 @@ static void set_xen_basic_apic_ops(void)
883 apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle; 885 apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
884 apic->set_apic_id = xen_set_apic_id; 886 apic->set_apic_id = xen_set_apic_id;
885 apic->get_apic_id = xen_get_apic_id; 887 apic->get_apic_id = xen_get_apic_id;
888
889#ifdef CONFIG_SMP
890 apic->send_IPI_allbutself = xen_send_IPI_allbutself;
891 apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
892 apic->send_IPI_mask = xen_send_IPI_mask;
893 apic->send_IPI_all = xen_send_IPI_all;
894 apic->send_IPI_self = xen_send_IPI_self;
895#endif
886} 896}
887 897
888#endif 898#endif
@@ -1340,7 +1350,6 @@ asmlinkage void __init xen_start_kernel(void)
1340 1350
1341 xen_raw_console_write("mapping kernel into physical memory\n"); 1351 xen_raw_console_write("mapping kernel into physical memory\n");
1342 pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); 1352 pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
1343 xen_ident_map_ISA();
1344 1353
1345 /* Allocate and initialize top and mid mfn levels for p2m structure */ 1354 /* Allocate and initialize top and mid mfn levels for p2m structure */
1346 xen_build_mfn_list_list(); 1355 xen_build_mfn_list_list();
@@ -1400,6 +1409,8 @@ asmlinkage void __init xen_start_kernel(void)
1400 1409
1401 /* Make sure ACS will be enabled */ 1410 /* Make sure ACS will be enabled */
1402 pci_request_acs(); 1411 pci_request_acs();
1412
1413 xen_acpi_sleep_register();
1403 } 1414 }
1404#ifdef CONFIG_PCI 1415#ifdef CONFIG_PCI
1405 /* PCI BIOS service won't work from a PV guest. */ 1416 /* PCI BIOS service won't work from a PV guest. */
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 3506cd4f9a4..3a73785631c 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1933,29 +1933,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
1933#endif 1933#endif
1934} 1934}
1935 1935
1936void __init xen_ident_map_ISA(void)
1937{
1938 unsigned long pa;
1939
1940 /*
1941 * If we're dom0, then linear map the ISA machine addresses into
1942 * the kernel's address space.
1943 */
1944 if (!xen_initial_domain())
1945 return;
1946
1947 xen_raw_printk("Xen: setup ISA identity maps\n");
1948
1949 for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) {
1950 pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO);
1951
1952 if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0))
1953 BUG();
1954 }
1955
1956 xen_flush_tlb();
1957}
1958
1959static void __init xen_post_allocator_init(void) 1936static void __init xen_post_allocator_init(void)
1960{ 1937{
1961 pv_mmu_ops.set_pte = xen_set_pte; 1938 pv_mmu_ops.set_pte = xen_set_pte;
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 1b267e75158..ffd08c414e9 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -499,16 +499,18 @@ static bool alloc_p2m(unsigned long pfn)
499 return true; 499 return true;
500} 500}
501 501
502static bool __init __early_alloc_p2m(unsigned long pfn) 502static bool __init early_alloc_p2m_middle(unsigned long pfn, bool check_boundary)
503{ 503{
504 unsigned topidx, mididx, idx; 504 unsigned topidx, mididx, idx;
505 unsigned long *p2m;
506 unsigned long *mid_mfn_p;
505 507
506 topidx = p2m_top_index(pfn); 508 topidx = p2m_top_index(pfn);
507 mididx = p2m_mid_index(pfn); 509 mididx = p2m_mid_index(pfn);
508 idx = p2m_index(pfn); 510 idx = p2m_index(pfn);
509 511
510 /* Pfff.. No boundary cross-over, lets get out. */ 512 /* Pfff.. No boundary cross-over, lets get out. */
511 if (!idx) 513 if (!idx && check_boundary)
512 return false; 514 return false;
513 515
514 WARN(p2m_top[topidx][mididx] == p2m_identity, 516 WARN(p2m_top[topidx][mididx] == p2m_identity,
@@ -522,24 +524,66 @@ static bool __init __early_alloc_p2m(unsigned long pfn)
522 return false; 524 return false;
523 525
524 /* Boundary cross-over for the edges: */ 526 /* Boundary cross-over for the edges: */
525 if (idx) { 527 p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
526 unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
527 unsigned long *mid_mfn_p;
528 528
529 p2m_init(p2m); 529 p2m_init(p2m);
530 530
531 p2m_top[topidx][mididx] = p2m; 531 p2m_top[topidx][mididx] = p2m;
532 532
533 /* For save/restore we need to MFN of the P2M saved */ 533 /* For save/restore we need to MFN of the P2M saved */
534 534
535 mid_mfn_p = p2m_top_mfn_p[topidx]; 535 mid_mfn_p = p2m_top_mfn_p[topidx];
536 WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing), 536 WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing),
537 "P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n", 537 "P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n",
538 topidx, mididx); 538 topidx, mididx);
539 mid_mfn_p[mididx] = virt_to_mfn(p2m); 539 mid_mfn_p[mididx] = virt_to_mfn(p2m);
540
541 return true;
542}
543
544static bool __init early_alloc_p2m(unsigned long pfn)
545{
546 unsigned topidx = p2m_top_index(pfn);
547 unsigned long *mid_mfn_p;
548 unsigned long **mid;
549
550 mid = p2m_top[topidx];
551 mid_mfn_p = p2m_top_mfn_p[topidx];
552 if (mid == p2m_mid_missing) {
553 mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
554
555 p2m_mid_init(mid);
556
557 p2m_top[topidx] = mid;
540 558
559 BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
541 } 560 }
542 return idx != 0; 561 /* And the save/restore P2M tables.. */
562 if (mid_mfn_p == p2m_mid_missing_mfn) {
563 mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
564 p2m_mid_mfn_init(mid_mfn_p);
565
566 p2m_top_mfn_p[topidx] = mid_mfn_p;
567 p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
568 /* Note: we don't set mid_mfn_p[midix] here,
569 * look in early_alloc_p2m_middle */
570 }
571 return true;
572}
573bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn)
574{
575 if (unlikely(!__set_phys_to_machine(pfn, mfn))) {
576 if (!early_alloc_p2m(pfn))
577 return false;
578
579 if (!early_alloc_p2m_middle(pfn, false /* boundary crossover OK!*/))
580 return false;
581
582 if (!__set_phys_to_machine(pfn, mfn))
583 return false;
584 }
585
586 return true;
543} 587}
544unsigned long __init set_phys_range_identity(unsigned long pfn_s, 588unsigned long __init set_phys_range_identity(unsigned long pfn_s,
545 unsigned long pfn_e) 589 unsigned long pfn_e)
@@ -559,35 +603,11 @@ unsigned long __init set_phys_range_identity(unsigned long pfn_s,
559 pfn < ALIGN(pfn_e, (P2M_MID_PER_PAGE * P2M_PER_PAGE)); 603 pfn < ALIGN(pfn_e, (P2M_MID_PER_PAGE * P2M_PER_PAGE));
560 pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE) 604 pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE)
561 { 605 {
562 unsigned topidx = p2m_top_index(pfn); 606 WARN_ON(!early_alloc_p2m(pfn));
563 unsigned long *mid_mfn_p;
564 unsigned long **mid;
565
566 mid = p2m_top[topidx];
567 mid_mfn_p = p2m_top_mfn_p[topidx];
568 if (mid == p2m_mid_missing) {
569 mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
570
571 p2m_mid_init(mid);
572
573 p2m_top[topidx] = mid;
574
575 BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
576 }
577 /* And the save/restore P2M tables.. */
578 if (mid_mfn_p == p2m_mid_missing_mfn) {
579 mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
580 p2m_mid_mfn_init(mid_mfn_p);
581
582 p2m_top_mfn_p[topidx] = mid_mfn_p;
583 p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
584 /* Note: we don't set mid_mfn_p[midix] here,
585 * look in __early_alloc_p2m */
586 }
587 } 607 }
588 608
589 __early_alloc_p2m(pfn_s); 609 early_alloc_p2m_middle(pfn_s, true);
590 __early_alloc_p2m(pfn_e); 610 early_alloc_p2m_middle(pfn_e, true);
591 611
592 for (pfn = pfn_s; pfn < pfn_e; pfn++) 612 for (pfn = pfn_s; pfn < pfn_e; pfn++)
593 if (!__set_phys_to_machine(pfn, IDENTITY_FRAME(pfn))) 613 if (!__set_phys_to_machine(pfn, IDENTITY_FRAME(pfn)))
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 1ba8dff2675..3ebba0753d3 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -26,7 +26,6 @@
26#include <xen/interface/memory.h> 26#include <xen/interface/memory.h>
27#include <xen/interface/physdev.h> 27#include <xen/interface/physdev.h>
28#include <xen/features.h> 28#include <xen/features.h>
29
30#include "xen-ops.h" 29#include "xen-ops.h"
31#include "vdso.h" 30#include "vdso.h"
32 31
@@ -84,8 +83,8 @@ static void __init xen_add_extra_mem(u64 start, u64 size)
84 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 83 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
85} 84}
86 85
87static unsigned long __init xen_release_chunk(unsigned long start, 86static unsigned long __init xen_do_chunk(unsigned long start,
88 unsigned long end) 87 unsigned long end, bool release)
89{ 88{
90 struct xen_memory_reservation reservation = { 89 struct xen_memory_reservation reservation = {
91 .address_bits = 0, 90 .address_bits = 0,
@@ -96,30 +95,138 @@ static unsigned long __init xen_release_chunk(unsigned long start,
96 unsigned long pfn; 95 unsigned long pfn;
97 int ret; 96 int ret;
98 97
99 for(pfn = start; pfn < end; pfn++) { 98 for (pfn = start; pfn < end; pfn++) {
99 unsigned long frame;
100 unsigned long mfn = pfn_to_mfn(pfn); 100 unsigned long mfn = pfn_to_mfn(pfn);
101 101
102 /* Make sure pfn exists to start with */ 102 if (release) {
103 if (mfn == INVALID_P2M_ENTRY || mfn_to_pfn(mfn) != pfn) 103 /* Make sure pfn exists to start with */
104 continue; 104 if (mfn == INVALID_P2M_ENTRY || mfn_to_pfn(mfn) != pfn)
105 105 continue;
106 set_xen_guest_handle(reservation.extent_start, &mfn); 106 frame = mfn;
107 } else {
108 if (mfn != INVALID_P2M_ENTRY)
109 continue;
110 frame = pfn;
111 }
112 set_xen_guest_handle(reservation.extent_start, &frame);
107 reservation.nr_extents = 1; 113 reservation.nr_extents = 1;
108 114
109 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, 115 ret = HYPERVISOR_memory_op(release ? XENMEM_decrease_reservation : XENMEM_populate_physmap,
110 &reservation); 116 &reservation);
111 WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); 117 WARN(ret != 1, "Failed to %s pfn %lx err=%d\n",
118 release ? "release" : "populate", pfn, ret);
119
112 if (ret == 1) { 120 if (ret == 1) {
113 __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); 121 if (!early_set_phys_to_machine(pfn, release ? INVALID_P2M_ENTRY : frame)) {
122 if (release)
123 break;
124 set_xen_guest_handle(reservation.extent_start, &frame);
125 reservation.nr_extents = 1;
126 ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation,
127 &reservation);
128 break;
129 }
114 len++; 130 len++;
115 } 131 } else
132 break;
116 } 133 }
117 printk(KERN_INFO "Freeing %lx-%lx pfn range: %lu pages freed\n", 134 if (len)
118 start, end, len); 135 printk(KERN_INFO "%s %lx-%lx pfn range: %lu pages %s\n",
136 release ? "Freeing" : "Populating",
137 start, end, len,
138 release ? "freed" : "added");
119 139
120 return len; 140 return len;
121} 141}
122 142
143static unsigned long __init xen_release_chunk(unsigned long start,
144 unsigned long end)
145{
146 return xen_do_chunk(start, end, true);
147}
148
149static unsigned long __init xen_populate_chunk(
150 const struct e820entry *list, size_t map_size,
151 unsigned long max_pfn, unsigned long *last_pfn,
152 unsigned long credits_left)
153{
154 const struct e820entry *entry;
155 unsigned int i;
156 unsigned long done = 0;
157 unsigned long dest_pfn;
158
159 for (i = 0, entry = list; i < map_size; i++, entry++) {
160 unsigned long credits = credits_left;
161 unsigned long s_pfn;
162 unsigned long e_pfn;
163 unsigned long pfns;
164 long capacity;
165
166 if (credits <= 0)
167 break;
168
169 if (entry->type != E820_RAM)
170 continue;
171
172 e_pfn = PFN_UP(entry->addr + entry->size);
173
174 /* We only care about E820 after the xen_start_info->nr_pages */
175 if (e_pfn <= max_pfn)
176 continue;
177
178 s_pfn = PFN_DOWN(entry->addr);
179 /* If the E820 falls within the nr_pages, we want to start
180 * at the nr_pages PFN.
181 * If that would mean going past the E820 entry, skip it
182 */
183 if (s_pfn <= max_pfn) {
184 capacity = e_pfn - max_pfn;
185 dest_pfn = max_pfn;
186 } else {
187 /* last_pfn MUST be within E820_RAM regions */
188 if (*last_pfn && e_pfn >= *last_pfn)
189 s_pfn = *last_pfn;
190 capacity = e_pfn - s_pfn;
191 dest_pfn = s_pfn;
192 }
193 /* If we had filled this E820_RAM entry, go to the next one. */
194 if (capacity <= 0)
195 continue;
196
197 if (credits > capacity)
198 credits = capacity;
199
200 pfns = xen_do_chunk(dest_pfn, dest_pfn + credits, false);
201 done += pfns;
202 credits_left -= pfns;
203 *last_pfn = (dest_pfn + pfns);
204 }
205 return done;
206}
207
208static void __init xen_set_identity_and_release_chunk(
209 unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
210 unsigned long *released, unsigned long *identity)
211{
212 unsigned long pfn;
213
214 /*
215 * If the PFNs are currently mapped, the VA mapping also needs
216 * to be updated to be 1:1.
217 */
218 for (pfn = start_pfn; pfn <= max_pfn_mapped && pfn < end_pfn; pfn++)
219 (void)HYPERVISOR_update_va_mapping(
220 (unsigned long)__va(pfn << PAGE_SHIFT),
221 mfn_pte(pfn, PAGE_KERNEL_IO), 0);
222
223 if (start_pfn < nr_pages)
224 *released += xen_release_chunk(
225 start_pfn, min(end_pfn, nr_pages));
226
227 *identity += set_phys_range_identity(start_pfn, end_pfn);
228}
229
123static unsigned long __init xen_set_identity_and_release( 230static unsigned long __init xen_set_identity_and_release(
124 const struct e820entry *list, size_t map_size, unsigned long nr_pages) 231 const struct e820entry *list, size_t map_size, unsigned long nr_pages)
125{ 232{
@@ -142,7 +249,6 @@ static unsigned long __init xen_set_identity_and_release(
142 */ 249 */
143 for (i = 0, entry = list; i < map_size; i++, entry++) { 250 for (i = 0, entry = list; i < map_size; i++, entry++) {
144 phys_addr_t end = entry->addr + entry->size; 251 phys_addr_t end = entry->addr + entry->size;
145
146 if (entry->type == E820_RAM || i == map_size - 1) { 252 if (entry->type == E820_RAM || i == map_size - 1) {
147 unsigned long start_pfn = PFN_DOWN(start); 253 unsigned long start_pfn = PFN_DOWN(start);
148 unsigned long end_pfn = PFN_UP(end); 254 unsigned long end_pfn = PFN_UP(end);
@@ -150,20 +256,19 @@ static unsigned long __init xen_set_identity_and_release(
150 if (entry->type == E820_RAM) 256 if (entry->type == E820_RAM)
151 end_pfn = PFN_UP(entry->addr); 257 end_pfn = PFN_UP(entry->addr);
152 258
153 if (start_pfn < end_pfn) { 259 if (start_pfn < end_pfn)
154 if (start_pfn < nr_pages) 260 xen_set_identity_and_release_chunk(
155 released += xen_release_chunk( 261 start_pfn, end_pfn, nr_pages,
156 start_pfn, min(end_pfn, nr_pages)); 262 &released, &identity);
157 263
158 identity += set_phys_range_identity(
159 start_pfn, end_pfn);
160 }
161 start = end; 264 start = end;
162 } 265 }
163 } 266 }
164 267
165 printk(KERN_INFO "Released %lu pages of unused memory\n", released); 268 if (released)
166 printk(KERN_INFO "Set %ld page(s) to 1-1 mapping\n", identity); 269 printk(KERN_INFO "Released %lu pages of unused memory\n", released);
270 if (identity)
271 printk(KERN_INFO "Set %ld page(s) to 1-1 mapping\n", identity);
167 272
168 return released; 273 return released;
169} 274}
@@ -217,7 +322,9 @@ char * __init xen_memory_setup(void)
217 int rc; 322 int rc;
218 struct xen_memory_map memmap; 323 struct xen_memory_map memmap;
219 unsigned long max_pages; 324 unsigned long max_pages;
325 unsigned long last_pfn = 0;
220 unsigned long extra_pages = 0; 326 unsigned long extra_pages = 0;
327 unsigned long populated;
221 int i; 328 int i;
222 int op; 329 int op;
223 330
@@ -257,9 +364,20 @@ char * __init xen_memory_setup(void)
257 */ 364 */
258 xen_released_pages = xen_set_identity_and_release( 365 xen_released_pages = xen_set_identity_and_release(
259 map, memmap.nr_entries, max_pfn); 366 map, memmap.nr_entries, max_pfn);
260 extra_pages += xen_released_pages;
261 367
262 /* 368 /*
369 * Populate back the non-RAM pages and E820 gaps that had been
370 * released. */
371 populated = xen_populate_chunk(map, memmap.nr_entries,
372 max_pfn, &last_pfn, xen_released_pages);
373
374 extra_pages += (xen_released_pages - populated);
375
376 if (last_pfn > max_pfn) {
377 max_pfn = min(MAX_DOMAIN_PAGES, last_pfn);
378 mem_end = PFN_PHYS(max_pfn);
379 }
380 /*
263 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO 381 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
264 * factor the base size. On non-highmem systems, the base 382 * factor the base size. On non-highmem systems, the base
265 * size is the full initial memory allocation; on highmem it 383 * size is the full initial memory allocation; on highmem it
@@ -272,7 +390,6 @@ char * __init xen_memory_setup(void)
272 */ 390 */
273 extra_pages = min(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)), 391 extra_pages = min(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
274 extra_pages); 392 extra_pages);
275
276 i = 0; 393 i = 0;
277 while (i < memmap.nr_entries) { 394 while (i < memmap.nr_entries) {
278 u64 addr = map[i].addr; 395 u64 addr = map[i].addr;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 3700945ed0d..afb250d22a6 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -16,6 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/irq_work.h>
19 20
20#include <asm/paravirt.h> 21#include <asm/paravirt.h>
21#include <asm/desc.h> 22#include <asm/desc.h>
@@ -41,10 +42,12 @@ cpumask_var_t xen_cpu_initialized_map;
41static DEFINE_PER_CPU(int, xen_resched_irq); 42static DEFINE_PER_CPU(int, xen_resched_irq);
42static DEFINE_PER_CPU(int, xen_callfunc_irq); 43static DEFINE_PER_CPU(int, xen_callfunc_irq);
43static DEFINE_PER_CPU(int, xen_callfuncsingle_irq); 44static DEFINE_PER_CPU(int, xen_callfuncsingle_irq);
45static DEFINE_PER_CPU(int, xen_irq_work);
44static DEFINE_PER_CPU(int, xen_debug_irq) = -1; 46static DEFINE_PER_CPU(int, xen_debug_irq) = -1;
45 47
46static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); 48static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id);
47static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); 49static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
50static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id);
48 51
49/* 52/*
50 * Reschedule call back. 53 * Reschedule call back.
@@ -143,6 +146,17 @@ static int xen_smp_intr_init(unsigned int cpu)
143 goto fail; 146 goto fail;
144 per_cpu(xen_callfuncsingle_irq, cpu) = rc; 147 per_cpu(xen_callfuncsingle_irq, cpu) = rc;
145 148
149 callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
150 rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
151 cpu,
152 xen_irq_work_interrupt,
153 IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING,
154 callfunc_name,
155 NULL);
156 if (rc < 0)
157 goto fail;
158 per_cpu(xen_irq_work, cpu) = rc;
159
146 return 0; 160 return 0;
147 161
148 fail: 162 fail:
@@ -155,6 +169,8 @@ static int xen_smp_intr_init(unsigned int cpu)
155 if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) 169 if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0)
156 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), 170 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu),
157 NULL); 171 NULL);
172 if (per_cpu(xen_irq_work, cpu) >= 0)
173 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
158 174
159 return rc; 175 return rc;
160} 176}
@@ -407,6 +423,7 @@ static void xen_cpu_die(unsigned int cpu)
407 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); 423 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
408 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); 424 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
409 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); 425 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
426 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
410 xen_uninit_lock_cpu(cpu); 427 xen_uninit_lock_cpu(cpu);
411 xen_teardown_timer(cpu); 428 xen_teardown_timer(cpu);
412 429
@@ -469,8 +486,8 @@ static void xen_smp_send_reschedule(int cpu)
469 xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR); 486 xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
470} 487}
471 488
472static void xen_send_IPI_mask(const struct cpumask *mask, 489static void __xen_send_IPI_mask(const struct cpumask *mask,
473 enum ipi_vector vector) 490 int vector)
474{ 491{
475 unsigned cpu; 492 unsigned cpu;
476 493
@@ -482,7 +499,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
482{ 499{
483 int cpu; 500 int cpu;
484 501
485 xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR); 502 __xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
486 503
487 /* Make sure other vcpus get a chance to run if they need to. */ 504 /* Make sure other vcpus get a chance to run if they need to. */
488 for_each_cpu(cpu, mask) { 505 for_each_cpu(cpu, mask) {
@@ -495,10 +512,86 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
495 512
496static void xen_smp_send_call_function_single_ipi(int cpu) 513static void xen_smp_send_call_function_single_ipi(int cpu)
497{ 514{
498 xen_send_IPI_mask(cpumask_of(cpu), 515 __xen_send_IPI_mask(cpumask_of(cpu),
499 XEN_CALL_FUNCTION_SINGLE_VECTOR); 516 XEN_CALL_FUNCTION_SINGLE_VECTOR);
500} 517}
501 518
519static inline int xen_map_vector(int vector)
520{
521 int xen_vector;
522
523 switch (vector) {
524 case RESCHEDULE_VECTOR:
525 xen_vector = XEN_RESCHEDULE_VECTOR;
526 break;
527 case CALL_FUNCTION_VECTOR:
528 xen_vector = XEN_CALL_FUNCTION_VECTOR;
529 break;
530 case CALL_FUNCTION_SINGLE_VECTOR:
531 xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR;
532 break;
533 case IRQ_WORK_VECTOR:
534 xen_vector = XEN_IRQ_WORK_VECTOR;
535 break;
536 default:
537 xen_vector = -1;
538 printk(KERN_ERR "xen: vector 0x%x is not implemented\n",
539 vector);
540 }
541
542 return xen_vector;
543}
544
545void xen_send_IPI_mask(const struct cpumask *mask,
546 int vector)
547{
548 int xen_vector = xen_map_vector(vector);
549
550 if (xen_vector >= 0)
551 __xen_send_IPI_mask(mask, xen_vector);
552}
553
554void xen_send_IPI_all(int vector)
555{
556 int xen_vector = xen_map_vector(vector);
557
558 if (xen_vector >= 0)
559 __xen_send_IPI_mask(cpu_online_mask, xen_vector);
560}
561
562void xen_send_IPI_self(int vector)
563{
564 int xen_vector = xen_map_vector(vector);
565
566 if (xen_vector >= 0)
567 xen_send_IPI_one(smp_processor_id(), xen_vector);
568}
569
570void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
571 int vector)
572{
573 unsigned cpu;
574 unsigned int this_cpu = smp_processor_id();
575
576 if (!(num_online_cpus() > 1))
577 return;
578
579 for_each_cpu_and(cpu, mask, cpu_online_mask) {
580 if (this_cpu == cpu)
581 continue;
582
583 xen_smp_send_call_function_single_ipi(cpu);
584 }
585}
586
587void xen_send_IPI_allbutself(int vector)
588{
589 int xen_vector = xen_map_vector(vector);
590
591 if (xen_vector >= 0)
592 xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
593}
594
502static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id) 595static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
503{ 596{
504 irq_enter(); 597 irq_enter();
@@ -519,6 +612,16 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id)
519 return IRQ_HANDLED; 612 return IRQ_HANDLED;
520} 613}
521 614
615static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id)
616{
617 irq_enter();
618 irq_work_run();
619 inc_irq_stat(apic_irq_work_irqs);
620 irq_exit();
621
622 return IRQ_HANDLED;
623}
624
522static const struct smp_ops xen_smp_ops __initconst = { 625static const struct smp_ops xen_smp_ops __initconst = {
523 .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, 626 .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
524 .smp_prepare_cpus = xen_smp_prepare_cpus, 627 .smp_prepare_cpus = xen_smp_prepare_cpus,
@@ -565,6 +668,7 @@ static void xen_hvm_cpu_die(unsigned int cpu)
565 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); 668 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
566 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); 669 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
567 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); 670 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
671 unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
568 native_cpu_die(cpu); 672 native_cpu_die(cpu);
569} 673}
570 674
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
new file mode 100644
index 00000000000..8981a76d081
--- /dev/null
+++ b/arch/x86/xen/smp.h
@@ -0,0 +1,12 @@
1#ifndef _XEN_SMP_H
2
3extern void xen_send_IPI_mask(const struct cpumask *mask,
4 int vector);
5extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
6 int vector);
7extern void xen_send_IPI_allbutself(int vector);
8extern void physflat_send_IPI_allbutself(int vector);
9extern void xen_send_IPI_all(int vector);
10extern void xen_send_IPI_self(int vector);
11
12#endif
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index d69cc6c3f80..83e866d714c 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -440,12 +440,12 @@ static int __init xen_spinlock_debugfs(void)
440 debugfs_create_u64("time_total", 0444, d_spin_debug, 440 debugfs_create_u64("time_total", 0444, d_spin_debug,
441 &spinlock_stats.time_total); 441 &spinlock_stats.time_total);
442 442
443 xen_debugfs_create_u32_array("histo_total", 0444, d_spin_debug, 443 debugfs_create_u32_array("histo_total", 0444, d_spin_debug,
444 spinlock_stats.histo_spin_total, HISTO_BUCKETS + 1); 444 spinlock_stats.histo_spin_total, HISTO_BUCKETS + 1);
445 xen_debugfs_create_u32_array("histo_spinning", 0444, d_spin_debug, 445 debugfs_create_u32_array("histo_spinning", 0444, d_spin_debug,
446 spinlock_stats.histo_spin_spinning, HISTO_BUCKETS + 1); 446 spinlock_stats.histo_spin_spinning, HISTO_BUCKETS + 1);
447 xen_debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug, 447 debugfs_create_u32_array("histo_blocked", 0444, d_spin_debug,
448 spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1); 448 spinlock_stats.histo_spin_blocked, HISTO_BUCKETS + 1);
449 449
450 return 0; 450 return 0;
451} 451}
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 45c0c0667bd..202d4c15015 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -28,7 +28,6 @@ void xen_setup_shared_info(void);
28void xen_build_mfn_list_list(void); 28void xen_build_mfn_list_list(void);
29void xen_setup_machphys_mapping(void); 29void xen_setup_machphys_mapping(void);
30pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn); 30pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
31void xen_ident_map_ISA(void);
32void xen_reserve_top(void); 31void xen_reserve_top(void);
33extern unsigned long xen_max_p2m_pfn; 32extern unsigned long xen_max_p2m_pfn;
34 33
diff --git a/arch/xtensa/include/asm/kvm_para.h b/arch/xtensa/include/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/xtensa/include/asm/kvm_para.h
@@ -0,0 +1 @@
#include <asm-generic/kvm_para.h>