summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-27 21:14:48 -0700
committerDavid S. Miller <davem@davemloft.net>2012-05-27 21:14:48 -0700
commitc2e1ff39c106ab026e3feb29c038855b7ed00393 (patch)
treee0255b5b9aed8645edc4426f2d4972280910e065 /arch
parent456d3d42460c1fc20ba0d27442443fcd63aaac35 (diff)
parentb48b2c3e50433ff6f7e46186daa7f986bd960215 (diff)
downloadlinux-stable-c2e1ff39c106ab026e3feb29c038855b7ed00393.tar.gz
linux-stable-c2e1ff39c106ab026e3feb29c038855b7ed00393.tar.bz2
linux-stable-c2e1ff39c106ab026e3feb29c038855b7ed00393.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
Pull in Linus's tree to get the commits that blew away ARCH_USES_GETTIMEOFFSET but didn't update Sparc correctly, so that I can apply Stephen Rothwell's fix for that mis-merge. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig3
-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_defconfig1
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig6
-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/mach/arch.h1
-rw-r--r--arch/arm/include/asm/mach/map.h1
-rw-r--r--arch/arm/kernel/setup.c17
-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/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.c4
-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/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/openrisc/Kconfig2
-rw-r--r--arch/openrisc/include/asm/Kbuild1
-rw-r--r--arch/openrisc/include/asm/uaccess.h40
-rw-r--r--arch/openrisc/lib/string.S99
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/boot/dts/mpc8569mds.dts1
-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/ppc_ksyms.c2
-rw-r--r--arch/powerpc/lib/string.S45
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/Kbuild1
-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/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/x86/Kconfig3
-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/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/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/pci-dma.c18
-rw-r--r--arch/x86/kernel/pci-nommu.c8
-rw-r--r--arch/x86/kernel/setup.c2
-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
586 files changed, 16079 insertions, 19988 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index e9a910876cda..8c3d957fa8e2 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -159,6 +159,9 @@ config HAVE_ARCH_TRACEHOOK
config HAVE_DMA_ATTRS
bool
+config HAVE_DMA_CONTIGUOUS
+ bool
+
config USE_GENERIC_SMP_HELPERS
bool
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5458aa9db067..5e7601301b41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -5,6 +5,9 @@ config ARM
select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE if PCI || ISA || PCMCIA
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
+ select CMA if (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
@@ -54,6 +57,14 @@ config ARM
config ARM_HAS_SG_CHAIN
bool
+config NEED_SG_DMA_LENGTH
+ bool
+
+config ARM_DMA_USE_IOMMU
+ select NEED_SG_DMA_LENGTH
+ select ARM_HAS_SG_CHAIN
+ bool
+
config HAVE_PWM
bool
@@ -445,8 +456,10 @@ config ARCH_MXS
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select CLKSRC_MMIO
+ select COMMON_CLK
select HAVE_CLK_PREPARE
select PINCTRL
+ select USE_OF
help
Support for Freescale MXS-based family of processors
@@ -936,6 +949,7 @@ config PLAT_SPEAR
select ARM_AMBA
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
+ select COMMON_CLK
select CLKSRC_MMIO
select GENERIC_CLOCKEVENTS
select HAVE_CLK
@@ -1040,7 +1054,6 @@ source "arch/arm/mach-sa1100/Kconfig"
source "arch/arm/plat-samsung/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig"
-source "arch/arm/plat-s5p/Kconfig"
source "arch/arm/plat-spear/Kconfig"
@@ -1091,6 +1104,7 @@ config PLAT_ORION
bool
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
+ select COMMON_CLK
config PLAT_PXA
bool
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 85348a09d655..01a134141216 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -103,6 +103,35 @@ choice
Say Y here if you want the debug print routines to direct
their output to the second serial port on these devices.
+ config DEBUG_DAVINCI_DA8XX_UART1
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART1"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DA8XX_UART2
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART2"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART2 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DMx_UART0
+ bool "Kernel low-level debugging on DaVinci DMx using UART0"
+ depends on ARCH_DAVINCI_DMx
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART0 serial port on DaVinci DMx devices.
+
+ config DEBUG_DAVINCI_TNETV107X_UART1
+ bool "Kernel low-level debugging on DaVinci TNETV107x using UART1"
+ depends on ARCH_DAVINCI_TNETV107X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on DaVinci TNETV107X
+ devices.
+
config DEBUG_DC21285_PORT
bool "Kernel low-level debugging messages via footbridge serial port"
depends on FOOTBRIDGE
@@ -180,6 +209,14 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX50 or i.MX53.
+ config DEBUG_IMX6Q_UART2
+ bool "i.MX6Q Debug UART2"
+ depends on SOC_IMX6Q
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6Q UART2. This is correct for e.g. the SabreLite
+ board.
+
config DEBUG_IMX6Q_UART4
bool "i.MX6Q Debug UART4"
depends on SOC_IMX6Q
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 157900da8782..0298b00fe241 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -160,9 +160,7 @@ machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_OMAP1) := omap1
-machine-$(CONFIG_ARCH_OMAP2) := omap2
-machine-$(CONFIG_ARCH_OMAP3) := omap2
-machine-$(CONFIG_ARCH_OMAP4) := omap2
+machine-$(CONFIG_ARCH_OMAP2PLUS) := omap2
machine-$(CONFIG_ARCH_ORION5X) := orion5x
machine-$(CONFIG_ARCH_PICOXCELL) := picoxcell
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
@@ -188,6 +186,8 @@ machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
machine-$(CONFIG_ARCH_VT8500) := vt8500
machine-$(CONFIG_ARCH_W90X900) := w90x900
machine-$(CONFIG_FOOTBRIDGE) := footbridge
+machine-$(CONFIG_MACH_SPEAR1310) := spear13xx
+machine-$(CONFIG_MACH_SPEAR1340) := spear13xx
machine-$(CONFIG_MACH_SPEAR300) := spear3xx
machine-$(CONFIG_MACH_SPEAR310) := spear3xx
machine-$(CONFIG_MACH_SPEAR320) := spear3xx
@@ -205,7 +205,7 @@ plat-$(CONFIG_PLAT_NOMADIK) := nomadik
plat-$(CONFIG_PLAT_ORION) := orion
plat-$(CONFIG_PLAT_PXA) := pxa
plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung
-plat-$(CONFIG_PLAT_S5P) := s5p samsung
+plat-$(CONFIG_PLAT_S5P) := samsung
plat-$(CONFIG_PLAT_SPEAR) := spear
plat-$(CONFIG_PLAT_VERSATILE) := versatile
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 399d17b231d2..49945cc1bc7d 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -23,4 +23,52 @@
chosen {
bootargs = "root=/dev/ram0 rw ramdisk=8192 console=ttySAC1,115200";
};
+
+ i2c@12C60000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+ gpios = <&gpb3 0 2 3 0>,
+ <&gpb3 1 2 3 0>;
+
+ eeprom@50 {
+ compatible = "samsung,s524ad0xd1";
+ reg = <0x50>;
+ };
+ };
+
+ i2c@12C70000 {
+ samsung,i2c-sda-delay = <100>;
+ samsung,i2c-max-bus-freq = <20000>;
+ gpios = <&gpb3 2 2 3 0>,
+ <&gpb3 3 2 3 0>;
+
+ eeprom@51 {
+ compatible = "samsung,s524ad0xd1";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@12C80000 {
+ status = "disabled";
+ };
+
+ i2c@12C90000 {
+ status = "disabled";
+ };
+
+ i2c@12CA0000 {
+ status = "disabled";
+ };
+
+ i2c@12CB0000 {
+ status = "disabled";
+ };
+
+ i2c@12CC0000 {
+ status = "disabled";
+ };
+
+ i2c@12CD0000 {
+ status = "disabled";
+ };
};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index dfc433599436..5ca0cdb76413 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -23,11 +23,11 @@
compatible = "samsung,exynos5250";
interrupt-parent = <&gic>;
- gic:interrupt-controller@10490000 {
+ gic:interrupt-controller@10481000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
interrupt-controller;
- reg = <0x10490000 0x1000>, <0x10480000 0x100>;
+ reg = <0x10481000 0x1000>, <0x10482000 0x2000>;
};
watchdog {
@@ -42,30 +42,6 @@
interrupts = <0 43 0>, <0 44 0>;
};
- sdhci@12200000 {
- compatible = "samsung,exynos4210-sdhci";
- reg = <0x12200000 0x100>;
- interrupts = <0 75 0>;
- };
-
- sdhci@12210000 {
- compatible = "samsung,exynos4210-sdhci";
- reg = <0x12210000 0x100>;
- interrupts = <0 76 0>;
- };
-
- sdhci@12220000 {
- compatible = "samsung,exynos4210-sdhci";
- reg = <0x12220000 0x100>;
- interrupts = <0 77 0>;
- };
-
- sdhci@12230000 {
- compatible = "samsung,exynos4210-sdhci";
- reg = <0x12230000 0x100>;
- interrupts = <0 78 0>;
- };
-
serial@12C00000 {
compatible = "samsung,exynos4210-uart";
reg = <0x12C00000 0x100>;
@@ -94,48 +70,64 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12C60000 0x100>;
interrupts = <0 56 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12C70000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C70000 0x100>;
interrupts = <0 57 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12C80000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C80000 0x100>;
interrupts = <0 58 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12C90000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12C90000 0x100>;
interrupts = <0 59 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12CA0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CA0000 0x100>;
interrupts = <0 60 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12CB0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CB0000 0x100>;
interrupts = <0 61 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12CC0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CC0000 0x100>;
interrupts = <0 62 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
i2c@12CD0000 {
compatible = "samsung,s3c2440-i2c";
reg = <0x12CD0000 0x100>;
interrupts = <0 63 0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
amba {
@@ -157,13 +149,13 @@
interrupts = <0 35 0>;
};
- mdma0: pdma@10800000 {
+ mdma0: mdma@10800000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x10800000 0x1000>;
interrupts = <0 33 0>;
};
- mdma1: pdma@11C10000 {
+ mdma1: mdma@11C10000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11C10000 0x1000>;
interrupts = <0 124 0>;
@@ -242,6 +234,12 @@
#gpio-cells = <4>;
};
+ gpc4: gpio-controller@114002E0 {
+ compatible = "samsung,exynos4-gpio";
+ reg = <0x114002E0 0x20>;
+ #gpio-cells = <4>;
+ };
+
gpd0: gpio-controller@11400160 {
compatible = "samsung,exynos4-gpio";
reg = <0x11400160 0x20>;
@@ -388,19 +386,19 @@
gpv2: gpio-controller@10D10040 {
compatible = "samsung,exynos4-gpio";
- reg = <0x10D10040 0x20>;
+ reg = <0x10D10060 0x20>;
#gpio-cells = <4>;
};
gpv3: gpio-controller@10D10060 {
compatible = "samsung,exynos4-gpio";
- reg = <0x10D10060 0x20>;
+ reg = <0x10D10080 0x20>;
#gpio-cells = <4>;
};
gpv4: gpio-controller@10D10080 {
compatible = "samsung,exynos4-gpio";
- reg = <0x10D10080 0x20>;
+ reg = <0x10D100C0 0x20>;
#gpio-cells = <4>;
};
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
new file mode 100644
index 000000000000..70bffa929b65
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx23.dtsi"
+
+/ {
+ model = "Freescale i.MX23 Evaluation Kit";
+ compatible = "fsl,imx23-evk", "fsl,imx23";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx23-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_8bit_pins_a &mmc0_pins_fixup>;
+ bus-width = <8>;
+ wp-gpios = <&gpio1 30 0>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ duart: serial@80070000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
new file mode 100644
index 000000000000..8c5f9994f3fc
--- /dev/null
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ apb@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x80000>;
+ ranges;
+
+ apbh@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x40000>;
+ ranges;
+
+ icoll: interrupt-controller@80000000 {
+ compatible = "fsl,imx23-icoll", "fsl,mxs-icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80000000 0x2000>;
+ };
+
+ dma-apbh@80004000 {
+ compatible = "fsl,imx23-dma-apbh";
+ reg = <0x80004000 2000>;
+ };
+
+ ecc@80008000 {
+ reg = <0x80008000 2000>;
+ status = "disabled";
+ };
+
+ bch@8000a000 {
+ reg = <0x8000a000 2000>;
+ status = "disabled";
+ };
+
+ gpmi@8000c000 {
+ reg = <0x8000c000 2000>;
+ status = "disabled";
+ };
+
+ ssp0: ssp@80010000 {
+ reg = <0x80010000 2000>;
+ interrupts = <15 14>;
+ fsl,ssp-dma-channel = <1>;
+ status = "disabled";
+ };
+
+ etm@80014000 {
+ reg = <0x80014000 2000>;
+ status = "disabled";
+ };
+
+ pinctrl@80018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx23-pinctrl", "simple-bus";
+ reg = <0x80018000 2000>;
+
+ gpio0: gpio@0 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <16>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@1 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <17>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2 {
+ compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
+ interrupts = <18>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ duart_pins_a: duart@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x11a2 0x11b2>;
+ fsl,drive-strength = <0>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <0>;
+ };
+
+ mmc0_8bit_pins_a: mmc0-8bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x2020 0x2030 0x2040
+ 0x2050 0x0082 0x0092 0x00a2
+ 0x00b2 0x2000 0x2010 0x2060>;
+ fsl,drive-strength = <1>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ mmc0_pins_fixup: mmc0-pins-fixup {
+ fsl,pinmux-ids = <0x2010 0x2060>;
+ fsl,pull-up = <0>;
+ };
+ };
+
+ digctl@8001c000 {
+ reg = <0x8001c000 2000>;
+ status = "disabled";
+ };
+
+ emi@80020000 {
+ reg = <0x80020000 2000>;
+ status = "disabled";
+ };
+
+ dma-apbx@80024000 {
+ compatible = "fsl,imx23-dma-apbx";
+ reg = <0x80024000 2000>;
+ };
+
+ dcp@80028000 {
+ reg = <0x80028000 2000>;
+ status = "disabled";
+ };
+
+ pxp@8002a000 {
+ reg = <0x8002a000 2000>;
+ status = "disabled";
+ };
+
+ ocotp@8002c000 {
+ reg = <0x8002c000 2000>;
+ status = "disabled";
+ };
+
+ axi-ahb@8002e000 {
+ reg = <0x8002e000 2000>;
+ status = "disabled";
+ };
+
+ lcdif@80030000 {
+ reg = <0x80030000 2000>;
+ status = "disabled";
+ };
+
+ ssp1: ssp@80034000 {
+ reg = <0x80034000 2000>;
+ interrupts = <2 20>;
+ fsl,ssp-dma-channel = <2>;
+ status = "disabled";
+ };
+
+ tvenc@80038000 {
+ reg = <0x80038000 2000>;
+ status = "disabled";
+ };
+ };
+
+ apbx@80040000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80040000 0x40000>;
+ ranges;
+
+ clkctl@80040000 {
+ reg = <0x80040000 2000>;
+ status = "disabled";
+ };
+
+ saif0: saif@80042000 {
+ reg = <0x80042000 2000>;
+ status = "disabled";
+ };
+
+ power@80044000 {
+ reg = <0x80044000 2000>;
+ status = "disabled";
+ };
+
+ saif1: saif@80046000 {
+ reg = <0x80046000 2000>;
+ status = "disabled";
+ };
+
+ audio-out@80048000 {
+ reg = <0x80048000 2000>;
+ status = "disabled";
+ };
+
+ audio-in@8004c000 {
+ reg = <0x8004c000 2000>;
+ status = "disabled";
+ };
+
+ lradc@80050000 {
+ reg = <0x80050000 2000>;
+ status = "disabled";
+ };
+
+ spdif@80054000 {
+ reg = <0x80054000 2000>;
+ status = "disabled";
+ };
+
+ i2c@80058000 {
+ reg = <0x80058000 2000>;
+ status = "disabled";
+ };
+
+ rtc@8005c000 {
+ reg = <0x8005c000 2000>;
+ status = "disabled";
+ };
+
+ pwm@80064000 {
+ reg = <0x80064000 2000>;
+ status = "disabled";
+ };
+
+ timrot@80068000 {
+ reg = <0x80068000 2000>;
+ status = "disabled";
+ };
+
+ auart0: serial@8006c000 {
+ reg = <0x8006c000 0x2000>;
+ status = "disabled";
+ };
+
+ auart1: serial@8006e000 {
+ reg = <0x8006e000 0x2000>;
+ status = "disabled";
+ };
+
+ duart: serial@80070000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80070000 0x2000>;
+ interrupts = <0>;
+ status = "disabled";
+ };
+
+ usbphy@8007c000 {
+ reg = <0x8007c000 0x2000>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80080000 0x80000>;
+ ranges;
+
+ usbctrl@80080000 {
+ reg = <0x80080000 0x10000>;
+ status = "disabled";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx27-phytec-phycore.dts b/arch/arm/boot/dts/imx27-phytec-phycore.dts
index a51a08fc2af9..2b0ff60247a4 100644
--- a/arch/arm/boot/dts/imx27-phytec-phycore.dts
+++ b/arch/arm/boot/dts/imx27-phytec-phycore.dts
@@ -27,22 +27,22 @@
status = "okay";
};
- uart@1000a000 {
+ serial@1000a000 {
fsl,uart-has-rtscts;
status = "okay";
};
- uart@1000b000 {
+ serial@1000b000 {
fsl,uart-has-rtscts;
status = "okay";
};
- uart@1000c000 {
+ serial@1000c000 {
fsl,uart-has-rtscts;
status = "okay";
};
- fec@1002b000 {
+ ethernet@1002b000 {
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi
index bc5e7d5ddd54..2b1a166d41f9 100644
--- a/arch/arm/boot/dts/imx27.dtsi
+++ b/arch/arm/boot/dts/imx27.dtsi
@@ -59,28 +59,28 @@
status = "disabled";
};
- uart1: uart@1000a000 {
+ uart1: serial@1000a000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000a000 0x1000>;
interrupts = <20>;
status = "disabled";
};
- uart2: uart@1000b000 {
+ uart2: serial@1000b000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000b000 0x1000>;
interrupts = <19>;
status = "disabled";
};
- uart3: uart@1000c000 {
+ uart3: serial@1000c000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000c000 0x1000>;
interrupts = <18>;
status = "disabled";
};
- uart4: uart@1000d000 {
+ uart4: serial@1000d000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1000d000 0x1000>;
interrupts = <17>;
@@ -183,14 +183,14 @@
status = "disabled";
};
- uart5: uart@1001b000 {
+ uart5: serial@1001b000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1001b000 0x1000>;
interrupts = <49>;
status = "disabled";
};
- uart6: uart@1001c000 {
+ uart6: serial@1001c000 {
compatible = "fsl,imx27-uart", "fsl,imx21-uart";
reg = <0x1001c000 0x1000>;
interrupts = <48>;
@@ -206,7 +206,7 @@
status = "disabled";
};
- fec: fec@1002b000 {
+ fec: ethernet@1002b000 {
compatible = "fsl,imx27-fec";
reg = <0x1002b000 0x4000>;
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 000000000000..ee520a529cb4
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx28.dtsi"
+
+/ {
+ model = "Freescale i.MX28 Evaluation Kit";
+ compatible = "fsl,imx28-evk", "fsl,imx28";
+
+ memory {
+ reg = <0x40000000 0x08000000>;
+ };
+
+ apb@80000000 {
+ apbh@80000000 {
+ ssp0: ssp@80010000 {
+ compatible = "fsl,imx28-mmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_8bit_pins_a
+ &mmc0_cd_cfg &mmc0_sck_cfg>;
+ bus-width = <8>;
+ wp-gpios = <&gpio2 12 0>;
+ status = "okay";
+ };
+
+ ssp1: ssp@80012000 {
+ compatible = "fsl,imx28-mmc";
+ bus-width = <8>;
+ wp-gpios = <&gpio0 28 0>;
+ status = "okay";
+ };
+ };
+
+ apbx@80040000 {
+ saif0: saif@80042000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif0_pins_a>;
+ status = "okay";
+ };
+
+ saif1: saif@80046000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&saif1_pins_a>;
+ fsl,saif-master = <&saif0>;
+ status = "okay";
+ };
+
+ i2c0: i2c@80058000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins_a>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ VDDA-supply = <&reg_3p3v>;
+ VDDIO-supply = <&reg_3p3v>;
+
+ };
+ };
+
+ duart: serial@80074000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&duart_pins_a>;
+ status = "okay";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ mac0: ethernet@800f0000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac0_pins_a>;
+ status = "okay";
+ };
+
+ mac1: ethernet@800f4000 {
+ phy-mode = "rmii";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mac1_pins_a>;
+ status = "okay";
+ };
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p3v: 3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx28-evk-sgtl5000",
+ "fsl,mxs-audio-sgtl5000";
+ model = "imx28-evk-sgtl5000";
+ saif-controllers = <&saif0 &saif1>;
+ audio-codec = <&sgtl5000>;
+ };
+};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
new file mode 100644
index 000000000000..4634cb861a59
--- /dev/null
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -0,0 +1,497 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&icoll>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ saif0 = &saif0;
+ saif1 = &saif1;
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ apb@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x80000>;
+ ranges;
+
+ apbh@80000000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x3c900>;
+ ranges;
+
+ icoll: interrupt-controller@80000000 {
+ compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x80000000 0x2000>;
+ };
+
+ hsadc@80002000 {
+ reg = <0x80002000 2000>;
+ interrupts = <13 87>;
+ status = "disabled";
+ };
+
+ dma-apbh@80004000 {
+ compatible = "fsl,imx28-dma-apbh";
+ reg = <0x80004000 2000>;
+ };
+
+ perfmon@80006000 {
+ reg = <0x80006000 800>;
+ interrupts = <27>;
+ status = "disabled";
+ };
+
+ bch@8000a000 {
+ reg = <0x8000a000 2000>;
+ interrupts = <41>;
+ status = "disabled";
+ };
+
+ gpmi@8000c000 {
+ reg = <0x8000c000 2000>;
+ interrupts = <42 88>;
+ status = "disabled";
+ };
+
+ ssp0: ssp@80010000 {
+ reg = <0x80010000 2000>;
+ interrupts = <96 82>;
+ fsl,ssp-dma-channel = <0>;
+ status = "disabled";
+ };
+
+ ssp1: ssp@80012000 {
+ reg = <0x80012000 2000>;
+ interrupts = <97 83>;
+ fsl,ssp-dma-channel = <1>;
+ status = "disabled";
+ };
+
+ ssp2: ssp@80014000 {
+ reg = <0x80014000 2000>;
+ interrupts = <98 84>;
+ fsl,ssp-dma-channel = <2>;
+ status = "disabled";
+ };
+
+ ssp3: ssp@80016000 {
+ reg = <0x80016000 2000>;
+ interrupts = <99 85>;
+ fsl,ssp-dma-channel = <3>;
+ status = "disabled";
+ };
+
+ pinctrl@80018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-pinctrl", "simple-bus";
+ reg = <0x80018000 2000>;
+
+ gpio0: gpio@0 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <127>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@1 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <126>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <125>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@3 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <124>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@4 {
+ compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+ interrupts = <123>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ duart_pins_a: duart@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x3102 0x3112>;
+ fsl,drive-strength = <0>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <0>;
+ };
+
+ mac0_pins_a: mac0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x4000 0x4010 0x4020
+ 0x4030 0x4040 0x4060 0x4070
+ 0x4080 0x4100>;
+ fsl,drive-strength = <1>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ mac1_pins_a: mac1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x40f1 0x4091 0x40a1
+ 0x40e1 0x40b1 0x40c1>;
+ fsl,drive-strength = <1>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ mmc0_8bit_pins_a: mmc0-8bit@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x2000 0x2010 0x2020
+ 0x2030 0x2040 0x2050 0x2060
+ 0x2070 0x2080 0x2090 0x20a0>;
+ fsl,drive-strength = <1>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ mmc0_cd_cfg: mmc0-cd-cfg {
+ fsl,pinmux-ids = <0x2090>;
+ fsl,pull-up = <0>;
+ };
+
+ mmc0_sck_cfg: mmc0-sck-cfg {
+ fsl,pinmux-ids = <0x20a0>;
+ fsl,drive-strength = <2>;
+ fsl,pull-up = <0>;
+ };
+
+ i2c0_pins_a: i2c0@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x3180 0x3190>;
+ fsl,drive-strength = <1>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ saif0_pins_a: saif0@0 {
+ reg = <0>;
+ fsl,pinmux-ids =
+ <0x3140 0x3150 0x3160 0x3170>;
+ fsl,drive-strength = <2>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+
+ saif1_pins_a: saif1@0 {
+ reg = <0>;
+ fsl,pinmux-ids = <0x31a0>;
+ fsl,drive-strength = <2>;
+ fsl,voltage = <1>;
+ fsl,pull-up = <1>;
+ };
+ };
+
+ digctl@8001c000 {
+ reg = <0x8001c000 2000>;
+ interrupts = <89>;
+ status = "disabled";
+ };
+
+ etm@80022000 {
+ reg = <0x80022000 2000>;
+ status = "disabled";
+ };
+
+ dma-apbx@80024000 {
+ compatible = "fsl,imx28-dma-apbx";
+ reg = <0x80024000 2000>;
+ };
+
+ dcp@80028000 {
+ reg = <0x80028000 2000>;
+ interrupts = <52 53 54>;
+ status = "disabled";
+ };
+
+ pxp@8002a000 {
+ reg = <0x8002a000 2000>;
+ interrupts = <39>;
+ status = "disabled";
+ };
+
+ ocotp@8002c000 {
+ reg = <0x8002c000 2000>;
+ status = "disabled";
+ };
+
+ axi-ahb@8002e000 {
+ reg = <0x8002e000 2000>;
+ status = "disabled";
+ };
+
+ lcdif@80030000 {
+ reg = <0x80030000 2000>;
+ interrupts = <38 86>;
+ status = "disabled";
+ };
+
+ can0: can@80032000 {
+ reg = <0x80032000 2000>;
+ interrupts = <8>;
+ status = "disabled";
+ };
+
+ can1: can@80034000 {
+ reg = <0x80034000 2000>;
+ interrupts = <9>;
+ status = "disabled";
+ };
+
+ simdbg@8003c000 {
+ reg = <0x8003c000 200>;
+ status = "disabled";
+ };
+
+ simgpmisel@8003c200 {
+ reg = <0x8003c200 100>;
+ status = "disabled";
+ };
+
+ simsspsel@8003c300 {
+ reg = <0x8003c300 100>;
+ status = "disabled";
+ };
+
+ simmemsel@8003c400 {
+ reg = <0x8003c400 100>;
+ status = "disabled";
+ };
+
+ gpiomon@8003c500 {
+ reg = <0x8003c500 100>;
+ status = "disabled";
+ };
+
+ simenet@8003c700 {
+ reg = <0x8003c700 100>;
+ status = "disabled";
+ };
+
+ armjtag@8003c800 {
+ reg = <0x8003c800 100>;
+ status = "disabled";
+ };
+ };
+
+ apbx@80040000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80040000 0x40000>;
+ ranges;
+
+ clkctl@80040000 {
+ reg = <0x80040000 2000>;
+ status = "disabled";
+ };
+
+ saif0: saif@80042000 {
+ compatible = "fsl,imx28-saif";
+ reg = <0x80042000 2000>;
+ interrupts = <59 80>;
+ fsl,saif-dma-channel = <4>;
+ status = "disabled";
+ };
+
+ power@80044000 {
+ reg = <0x80044000 2000>;
+ status = "disabled";
+ };
+
+ saif1: saif@80046000 {
+ compatible = "fsl,imx28-saif";
+ reg = <0x80046000 2000>;
+ interrupts = <58 81>;
+ fsl,saif-dma-channel = <5>;
+ status = "disabled";
+ };
+
+ lradc@80050000 {
+ reg = <0x80050000 2000>;
+ status = "disabled";
+ };
+
+ spdif@80054000 {
+ reg = <0x80054000 2000>;
+ interrupts = <45 66>;
+ status = "disabled";
+ };
+
+ rtc@80056000 {
+ reg = <0x80056000 2000>;
+ interrupts = <28 29>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@80058000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-i2c";
+ reg = <0x80058000 2000>;
+ interrupts = <111 68>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@8005a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx28-i2c";
+ reg = <0x8005a000 2000>;
+ interrupts = <110 69>;
+ status = "disabled";
+ };
+
+ pwm@80064000 {
+ reg = <0x80064000 2000>;
+ status = "disabled";
+ };
+
+ timrot@80068000 {
+ reg = <0x80068000 2000>;
+ status = "disabled";
+ };
+
+ auart0: serial@8006a000 {
+ reg = <0x8006a000 0x2000>;
+ interrupts = <112 70 71>;
+ status = "disabled";
+ };
+
+ auart1: serial@8006c000 {
+ reg = <0x8006c000 0x2000>;
+ interrupts = <113 72 73>;
+ status = "disabled";
+ };
+
+ auart2: serial@8006e000 {
+ reg = <0x8006e000 0x2000>;
+ interrupts = <114 74 75>;
+ status = "disabled";
+ };
+
+ auart3: serial@80070000 {
+ reg = <0x80070000 0x2000>;
+ interrupts = <115 76 77>;
+ status = "disabled";
+ };
+
+ auart4: serial@80072000 {
+ reg = <0x80072000 0x2000>;
+ interrupts = <116 78 79>;
+ status = "disabled";
+ };
+
+ duart: serial@80074000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x80074000 0x1000>;
+ interrupts = <47>;
+ status = "disabled";
+ };
+
+ usbphy0: usbphy@8007c000 {
+ reg = <0x8007c000 0x2000>;
+ status = "disabled";
+ };
+
+ usbphy1: usbphy@8007e000 {
+ reg = <0x8007e000 0x2000>;
+ status = "disabled";
+ };
+ };
+ };
+
+ ahb@80080000 {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80080000 0x80000>;
+ ranges;
+
+ usbctrl0: usbctrl@80080000 {
+ reg = <0x80080000 0x10000>;
+ status = "disabled";
+ };
+
+ usbctrl1: usbctrl@80090000 {
+ reg = <0x80090000 0x10000>;
+ status = "disabled";
+ };
+
+ dflpt@800c0000 {
+ reg = <0x800c0000 0x10000>;
+ status = "disabled";
+ };
+
+ mac0: ethernet@800f0000 {
+ compatible = "fsl,imx28-fec";
+ reg = <0x800f0000 0x4000>;
+ interrupts = <101>;
+ status = "disabled";
+ };
+
+ mac1: ethernet@800f4000 {
+ compatible = "fsl,imx28-fec";
+ reg = <0x800f4000 0x4000>;
+ interrupts = <102>;
+ status = "disabled";
+ };
+
+ switch@800f8000 {
+ reg = <0x800f8000 0x8000>;
+ status = "disabled";
+ };
+
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index 9949e6060dee..de065b5976e6 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -17,10 +17,6 @@
model = "Freescale i.MX51 Babbage Board";
compatible = "fsl,imx51-babbage", "fsl,imx51";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
- };
-
memory {
reg = <0x90000000 0x20000000>;
};
@@ -40,7 +36,7 @@
status = "okay";
};
- uart3: uart@7000c000 {
+ uart3: serial@7000c000 {
fsl,uart-has-rtscts;
status = "okay";
};
@@ -166,6 +162,11 @@
};
};
};
+
+ ssi2: ssi@70014000 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+ };
};
wdog@73f98000 { /* WDOG1 */
@@ -177,12 +178,12 @@
reg = <0x73fa8000 0x4000>;
};
- uart1: uart@73fbc000 {
+ uart1: serial@73fbc000 {
fsl,uart-has-rtscts;
status = "okay";
};
- uart2: uart@73fc0000 {
+ uart2: serial@73fc0000 {
status = "okay";
};
};
@@ -195,13 +196,20 @@
i2c@83fc4000 { /* I2C2 */
status = "okay";
- codec: sgtl5000@0a {
+ sgtl5000: codec@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
+ clock-frequency = <26000000>;
+ VDDA-supply = <&vdig_reg>;
+ VDDIO-supply = <&vvideo_reg>;
};
};
- fec@83fec000 {
+ audmux@83fd0000 {
+ status = "okay";
+ };
+
+ ethernet@83fec000 {
phy-mode = "mii";
status = "okay";
};
@@ -218,4 +226,18 @@
gpio-key,wakeup;
};
};
+
+ sound {
+ compatible = "fsl,imx51-babbage-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx51-babbage-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ };
};
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 6663986fe1c8..bfa65abe8ef2 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -86,7 +86,7 @@
status = "disabled";
};
- uart3: uart@7000c000 {
+ uart3: serial@7000c000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x7000c000 0x4000>;
interrupts = <33>;
@@ -102,6 +102,15 @@
status = "disabled";
};
+ ssi2: ssi@70014000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupts = <30>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
esdhc@70020000 { /* ESDHC3 */
compatible = "fsl,imx51-esdhc";
reg = <0x70020000 0x4000>;
@@ -171,14 +180,14 @@
status = "disabled";
};
- uart1: uart@73fbc000 {
+ uart1: serial@73fbc000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fbc000 0x4000>;
interrupts = <31>;
status = "disabled";
};
- uart2: uart@73fc0000 {
+ uart2: serial@73fc0000 {
compatible = "fsl,imx51-uart", "fsl,imx21-uart";
reg = <0x73fc0000 0x4000>;
interrupts = <32>;
@@ -235,7 +244,31 @@
status = "disabled";
};
- fec@83fec000 {
+ ssi1: ssi@83fcc000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fcc000 0x4000>;
+ interrupts = <29>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ audmux@83fd0000 {
+ compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
+ reg = <0x83fd0000 0x4000>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@83fe8000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fe8000 0x4000>;
+ interrupts = <96>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ ethernet@83fec000 {
compatible = "fsl,imx51-fec", "fsl,imx27-fec";
reg = <0x83fec000 0x4000>;
interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
index 2dccce46ed81..5b8eafcdbeec 100644
--- a/arch/arm/boot/dts/imx53-ard.dts
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Automotive Reference Design Board";
compatible = "fsl,imx53-ard", "fsl,imx53";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
- };
-
memory {
reg = <0x70000000 0x40000000>;
};
@@ -44,7 +40,7 @@
reg = <0x53fa8000 0x4000>;
};
- uart1: uart@53fbc000 {
+ uart1: serial@53fbc000 {
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/imx53-evk.dts b/arch/arm/boot/dts/imx53-evk.dts
index 5bac4aa4800b..9c798034675e 100644
--- a/arch/arm/boot/dts/imx53-evk.dts
+++ b/arch/arm/boot/dts/imx53-evk.dts
@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Evaluation Kit";
compatible = "fsl,imx53-evk", "fsl,imx53";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
- };
-
memory {
reg = <0x70000000 0x80000000>;
};
@@ -75,7 +71,7 @@
reg = <0x53fa8000 0x4000>;
};
- uart1: uart@53fbc000 {
+ uart1: serial@53fbc000 {
status = "okay";
};
};
@@ -99,7 +95,7 @@
};
};
- fec@63fec000 {
+ ethernet@63fec000 {
phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
index 5c57c8672c36..2d803a9a6949 100644
--- a/arch/arm/boot/dts/imx53-qsb.dts
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Quick Start Board";
compatible = "fsl,imx53-qsb", "fsl,imx53";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
- };
-
memory {
reg = <0x70000000 0x40000000>;
};
@@ -33,6 +29,11 @@
status = "okay";
};
+ ssi2: ssi@50014000 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+ };
+
esdhc@50020000 { /* ESDHC3 */
cd-gpios = <&gpio3 11 0>;
wp-gpios = <&gpio3 12 0>;
@@ -49,7 +50,7 @@
reg = <0x53fa8000 0x4000>;
};
- uart1: uart@53fbc000 {
+ uart1: serial@53fbc000 {
status = "okay";
};
};
@@ -62,9 +63,11 @@
i2c@63fc4000 { /* I2C2 */
status = "okay";
- codec: sgtl5000@0a {
+ sgtl5000: codec@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
+ VDDA-supply = <&reg_3p2v>;
+ VDDIO-supply = <&reg_3p2v>;
};
};
@@ -77,12 +80,88 @@
};
pmic: dialog@48 {
- compatible = "dialog,da9053", "dialog,da9052";
+ compatible = "dlg,da9053-aa", "dlg,da9052";
reg = <0x48>;
+
+ regulators {
+ buck0 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2075000>;
+ };
+
+ buck1 {
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2075000>;
+ };
+
+ buck2 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ buck3 {
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ ldo4 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo5 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo6 {
+ regulator-min-microvolt = <1725000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo7 {
+ regulator-min-microvolt = <1725000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo8 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ };
+
+ ldo9 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ };
+
+ ldo10 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ };
+
+ ldo11 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ };
+
+ ldo12 {
+ regulator-min-microvolt = <1250000>;
+ regulator-max-microvolt = <3650000>;
+ };
+
+ ldo13 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3600000>;
+ };
+ };
};
};
- fec@63fec000 {
+ audmux@63fd0000 {
+ status = "okay";
+ };
+
+ ethernet@63fec000 {
phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>;
status = "okay";
@@ -122,4 +201,30 @@
linux,default-trigger = "heartbeat";
};
};
+
+ regulators {
+ compatible = "simple-bus";
+
+ reg_3p2v: 3p2v {
+ compatible = "regulator-fixed";
+ regulator-name = "3P2V";
+ regulator-min-microvolt = <3200000>;
+ regulator-max-microvolt = <3200000>;
+ regulator-always-on;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx53-qsb-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx53-qsb-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <5>;
+ };
};
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index c7ee86c2dfb5..08091029168e 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -17,10 +17,6 @@
model = "Freescale i.MX53 Smart Mobile Reference Design Board";
compatible = "fsl,imx53-smd", "fsl,imx53";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
- };
-
memory {
reg = <0x70000000 0x40000000>;
};
@@ -35,11 +31,11 @@
};
esdhc@50008000 { /* ESDHC2 */
- fsl,card-wired;
+ non-removable;
status = "okay";
};
- uart3: uart@5000c000 {
+ uart3: serial@5000c000 {
fsl,uart-has-rtscts;
status = "okay";
};
@@ -76,7 +72,7 @@
};
esdhc@50020000 { /* ESDHC3 */
- fsl,card-wired;
+ non-removable;
status = "okay";
};
};
@@ -90,11 +86,11 @@
reg = <0x53fa8000 0x4000>;
};
- uart1: uart@53fbc000 {
+ uart1: serial@53fbc000 {
status = "okay";
};
- uart2: uart@53fc0000 {
+ uart2: serial@53fc0000 {
status = "okay";
};
};
@@ -142,7 +138,7 @@
};
};
- fec@63fec000 {
+ ethernet@63fec000 {
phy-mode = "rmii";
phy-reset-gpios = <&gpio7 6 0>;
status = "okay";
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 5dd91b942c91..e3e869470cd3 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -88,7 +88,7 @@
status = "disabled";
};
- uart3: uart@5000c000 {
+ uart3: serial@5000c000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x5000c000 0x4000>;
interrupts = <33>;
@@ -104,6 +104,15 @@
status = "disabled";
};
+ ssi2: ssi@50014000 {
+ compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ reg = <0x50014000 0x4000>;
+ interrupts = <30>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
esdhc@50020000 { /* ESDHC3 */
compatible = "fsl,imx53-esdhc";
reg = <0x50020000 0x4000>;
@@ -173,14 +182,14 @@
status = "disabled";
};
- uart1: uart@53fbc000 {
+ uart1: serial@53fbc000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53fbc000 0x4000>;
interrupts = <31>;
status = "disabled";
};
- uart2: uart@53fc0000 {
+ uart2: serial@53fc0000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53fc0000 0x4000>;
interrupts = <32>;
@@ -226,7 +235,7 @@
status = "disabled";
};
- uart4: uart@53ff0000 {
+ uart4: serial@53ff0000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x53ff0000 0x4000>;
interrupts = <13>;
@@ -241,7 +250,7 @@
reg = <0x60000000 0x10000000>;
ranges;
- uart5: uart@63f90000 {
+ uart5: serial@63f90000 {
compatible = "fsl,imx53-uart", "fsl,imx21-uart";
reg = <0x63f90000 0x4000>;
interrupts = <86>;
@@ -290,7 +299,31 @@
status = "disabled";
};
- fec@63fec000 {
+ ssi1: ssi@63fcc000 {
+ compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ reg = <0x63fcc000 0x4000>;
+ interrupts = <29>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ audmux@63fd0000 {
+ compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
+ reg = <0x63fd0000 0x4000>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@63fe8000 {
+ compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
+ reg = <0x63fe8000 0x4000>;
+ interrupts = <96>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <47 46 45 44>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ ethernet@63fec000 {
compatible = "fsl,imx53-fec", "fsl,imx25-fec";
reg = <0x63fec000 0x4000>;
interrupts = <87>;
diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
index ce1c8238c897..db4c6096c562 100644
--- a/arch/arm/boot/dts/imx6q-arm2.dts
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -17,19 +17,14 @@
model = "Freescale i.MX6 Quad Armadillo2 Board";
compatible = "fsl,imx6q-arm2", "fsl,imx6q";
- chosen {
- bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
- };
-
memory {
reg = <0x10000000 0x80000000>;
};
soc {
aips-bus@02100000 { /* AIPS2 */
- enet@02188000 {
+ ethernet@02188000 {
phy-mode = "rgmii";
- local-mac-address = [00 04 9F 01 1B 61];
status = "okay";
};
@@ -37,16 +32,20 @@
cd-gpios = <&gpio6 11 0>;
wp-gpios = <&gpio6 14 0>;
vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
status = "okay";
};
usdhc@0219c000 { /* uSDHC4 */
- fsl,card-wired;
+ non-removable;
vmmc-supply = <&reg_3p3v>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4_1>;
status = "okay";
};
- uart4: uart@021f0000 {
+ uart4: serial@021f0000 {
status = "okay";
};
};
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
index 4663a4e5a285..e0ec92973e7e 100644
--- a/arch/arm/boot/dts/imx6q-sabrelite.dts
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -22,8 +22,30 @@
};
soc {
+ aips-bus@02000000 { /* AIPS1 */
+ spba-bus@02000000 {
+ ecspi@02008000 { /* eCSPI1 */
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 0>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf016b";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+ };
+
+ ssi1: ssi@02028000 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+ };
+ };
+
+ };
+
aips-bus@02100000 { /* AIPS2 */
- enet@02188000 {
+ ethernet@02188000 {
phy-mode = "rgmii";
phy-reset-gpios = <&gpio3 23 0>;
status = "okay";
@@ -43,13 +65,23 @@
status = "okay";
};
- uart2: uart@021e8000 {
+ audmux@021d8000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_1>;
+ };
+
+ uart2: serial@021e8000 {
status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_serial2_1>;
};
i2c@021a0000 { /* I2C1 */
status = "okay";
clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
codec: sgtl5000@0a {
compatible = "fsl,sgtl5000";
@@ -80,4 +112,18 @@
regulator-always-on;
};
};
+
+ sound {
+ compatible = "fsl,imx6q-sabrelite-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx6q-sabrelite-sgtl5000";
+ ssi-controller = <&ssi1>;
+ audio-codec = <&codec>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <1>;
+ mux-ext-port = <4>;
+ };
};
diff --git a/arch/arm/boot/dts/imx6q-sabresd.dts b/arch/arm/boot/dts/imx6q-sabresd.dts
new file mode 100644
index 000000000000..07509a181178
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabresd.dts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx6q.dtsi"
+
+/ {
+ model = "Freescale i.MX6Q SABRE Smart Device Board";
+ compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ soc {
+
+ aips-bus@02000000 { /* AIPS1 */
+ spba-bus@02000000 {
+ uart1: serial@02020000 {
+ status = "okay";
+ };
+ };
+ };
+
+ aips-bus@02100000 { /* AIPS2 */
+ ethernet@02188000 {
+ phy-mode = "rgmii";
+ status = "okay";
+ };
+
+ usdhc@02194000 { /* uSDHC2 */
+ cd-gpios = <&gpio2 2 0>;
+ wp-gpios = <&gpio2 3 0>;
+ status = "okay";
+ };
+
+ usdhc@02198000 { /* uSDHC3 */
+ cd-gpios = <&gpio2 0 0>;
+ wp-gpios = <&gpio2 1 0>;
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 4905f51a106f..8c90cbac945f 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -165,7 +165,7 @@
status = "disabled";
};
- uart1: uart@02020000 {
+ uart1: serial@02020000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>;
interrupts = <0 26 0x04>;
@@ -177,19 +177,31 @@
interrupts = <0 51 0x04>;
};
- ssi@02028000 { /* SSI1 */
+ ssi1: ssi@02028000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x02028000 0x4000>;
interrupts = <0 46 0x04>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <38 37>;
+ status = "disabled";
};
- ssi@0202c000 { /* SSI2 */
+ ssi2: ssi@0202c000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x0202c000 0x4000>;
interrupts = <0 47 0x04>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <42 41>;
+ status = "disabled";
};
- ssi@02030000 { /* SSI3 */
+ ssi3: ssi@02030000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
reg = <0x02030000 0x4000>;
interrupts = <0 48 0x04>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <46 45>;
+ status = "disabled";
};
asrc@02034000 {
@@ -346,6 +358,90 @@
compatible = "fsl,imx6q-anatop";
reg = <0x020c8000 0x1000>;
interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+
+ regulator-1p1@110 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x110>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <4>;
+ anatop-min-voltage = <800000>;
+ anatop-max-voltage = <1375000>;
+ };
+
+ regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ };
+
+ regulator-2p5@130 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd2p5";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x130>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2000000>;
+ anatop-max-voltage = <2750000>;
+ };
+
+ regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "cpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ regulator-vddpu@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <9>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
};
usbphy@020c9000 { /* USBPHY1 */
@@ -386,7 +482,62 @@
};
iomuxc@020e0000 {
+ compatible = "fsl,imx6q-iomuxc";
reg = <0x020e0000 0x4000>;
+
+ /* shared pinctrl settings */
+ audmux {
+ pinctrl_audmux_1: audmux-1 {
+ fsl,pins = <18 0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
+ 1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
+ 11 0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
+ 3 0x80000000>; /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <137 0x4001b8b1 /* MX6Q_PAD_EIM_D21__I2C1_SCL */
+ 196 0x4001b8b1>; /* MX6Q_PAD_EIM_D28__I2C1_SDA */
+ };
+ };
+
+ serial2 {
+ pinctrl_serial2_1: serial2grp-1 {
+ fsl,pins = <183 0x1b0b1 /* MX6Q_PAD_EIM_D26__UART2_TXD */
+ 191 0x1b0b1>; /* MX6Q_PAD_EIM_D27__UART2_RXD */
+ };
+ };
+
+ usdhc3 {
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <1273 0x17059 /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
+ 1281 0x10059 /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
+ 1289 0x17059 /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
+ 1297 0x17059 /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
+ 1305 0x17059 /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
+ 1312 0x17059 /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
+ 1265 0x17059 /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */
+ 1257 0x17059 /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */
+ 1249 0x17059 /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */
+ 1241 0x17059>; /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */
+ };
+ };
+
+ usdhc4 {
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ fsl,pins = <1386 0x17059 /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
+ 1392 0x10059 /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
+ 1462 0x17059 /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
+ 1470 0x17059 /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
+ 1478 0x17059 /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
+ 1486 0x17059 /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
+ 1493 0x17059 /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
+ 1501 0x17059 /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
+ 1509 0x17059 /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
+ 1517 0x17059>; /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
+ };
+ };
};
dcic@020e4000 { /* DCIC1 */
@@ -422,7 +573,7 @@
reg = <0x0217c000 0x4000>;
};
- enet@02188000 {
+ ethernet@02188000 {
compatible = "fsl,imx6q-fec";
reg = <0x02188000 0x4000>;
interrupts = <0 118 0x04 0 119 0x04>;
@@ -527,7 +678,9 @@
};
audmux@021d8000 {
+ compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
reg = <0x021d8000 0x4000>;
+ status = "disabled";
};
mipi@021dc000 { /* MIPI-CSI */
@@ -543,28 +696,28 @@
interrupts = <0 18 0x04>;
};
- uart2: uart@021e8000 {
+ uart2: serial@021e8000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021e8000 0x4000>;
interrupts = <0 27 0x04>;
status = "disabled";
};
- uart3: uart@021ec000 {
+ uart3: serial@021ec000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021ec000 0x4000>;
interrupts = <0 28 0x04>;
status = "disabled";
};
- uart4: uart@021f0000 {
+ uart4: serial@021f0000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f0000 0x4000>;
interrupts = <0 29 0x04>;
status = "disabled";
};
- uart5: uart@021f4000 {
+ uart5: serial@021f4000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x021f4000 0x4000>;
interrupts = <0 30 0x04>;
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index 8c756be4d7ad..5b4506c0a8c4 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -57,7 +57,7 @@
&mmc1 {
vmmc-supply = <&vmmc1>;
vmmc_aux-supply = <&vsim>;
- ti,bus-width = <8>;
+ bus-width = <8>;
};
&mmc2 {
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index e671361bc791..1efe0c587985 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -70,7 +70,7 @@
&mmc1 {
vmmc-supply = <&vmmc>;
- ti,bus-width = <8>;
+ bus-width = <8>;
};
&mmc2 {
@@ -87,5 +87,5 @@
&mmc5 {
ti,non-removable;
- ti,bus-width = <4>;
+ bus-width = <4>;
};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index e5eeb6f9c6e6..d08c4d137280 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -137,12 +137,12 @@
&mmc1 {
vmmc-supply = <&vmmc>;
- ti,bus-width = <8>;
+ bus-width = <8>;
};
&mmc2 {
vmmc-supply = <&vaux1>;
- ti,bus-width = <8>;
+ bus-width = <8>;
ti,non-removable;
};
@@ -155,6 +155,6 @@
};
&mmc5 {
- ti,bus-width = <4>;
+ bus-width = <4>;
ti,non-removable;
};
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts
new file mode 100644
index 000000000000..8314e4171884
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310-evb.dts
@@ -0,0 +1,292 @@
+/*
+ * DTS file for SPEAr1310 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear1310.dtsi"
+
+/ {
+ model = "ST SPEAr1310 Evaluation Board";
+ compatible = "st,spear1310-evb", "st,spear1310";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@e0700000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ i2c0-pmx {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ i2s1 {
+ st,pins = "i2s1_grp";
+ st,function = "i2s1";
+ };
+ gpio {
+ st,pins = "arm_gpio_grp";
+ st,function = "arm_gpio";
+ };
+ eth {
+ st,pins = "gmii_grp";
+ st,function = "gmii";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp";
+ st,function = "ssp0";
+ };
+ kbd {
+ st,pins = "keyboard_6x6_grp";
+ st,function = "keyboard";
+ };
+ sdhci {
+ st,pins = "sdhci_grp";
+ st,function = "sdhci";
+ };
+ smi-pmx {
+ st,pins = "smi_2_chips_grp";
+ st,function = "smi";
+ };
+ uart0 {
+ st,pins = "uart0_grp";
+ st,function = "uart0";
+ };
+ rs485 {
+ st,pins = "rs485_0_1_tdm_0_1_grp";
+ st,function = "rs485_0_1_tdm_0_1";
+ };
+ i2c1_2 {
+ st,pins = "i2c_1_2_grp";
+ st,function = "i2c_1_2";
+ };
+ pci {
+ st,pins = "pcie0_grp","pcie1_grp",
+ "pcie2_grp";
+ st,function = "pci";
+ };
+ smii {
+ st,pins = "smii_0_1_2_grp";
+ st,function = "smii_0_1_2";
+ };
+ nand {
+ st,pins = "nand_8bit_grp",
+ "nand_16bit_grp";
+ st,function = "nand";
+ };
+ };
+ };
+
+ ahci@b1000000 {
+ status = "okay";
+ };
+
+ cf@b2800000 {
+ status = "okay";
+ };
+
+ dma@ea800000 {
+ status = "okay";
+ };
+
+ dma@eb000000 {
+ status = "okay";
+ };
+
+ fsmc: flash@b0000000 {
+ status = "okay";
+ };
+
+ gmac0: eth@e2000000 {
+ status = "okay";
+ };
+
+ sdhci@b3000000 {
+ status = "okay";
+ };
+
+ smi: flash@ea000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@e6000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe6000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
+ };
+ };
+
+ spi0: spi@e0100000 {
+ status = "okay";
+ };
+
+ ehci@e4800000 {
+ status = "okay";
+ };
+
+ ehci@e5800000 {
+ status = "okay";
+ };
+
+ ohci@e4000000 {
+ status = "okay";
+ };
+
+ ohci@e5000000 {
+ status = "okay";
+ };
+
+ apb {
+ adc@e0080000 {
+ status = "okay";
+ };
+
+ gpio0: gpio@e0600000 {
+ status = "okay";
+ };
+
+ gpio1: gpio@e0680000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@e0280000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@5cd00000 {
+ status = "okay";
+ };
+
+ kbd@e0300000 {
+ linux,keymap = < 0x00000001
+ 0x00010002
+ 0x00020003
+ 0x00030004
+ 0x00040005
+ 0x00050006
+ 0x00060007
+ 0x00070008
+ 0x00080009
+ 0x0100000a
+ 0x0101000c
+ 0x0102000d
+ 0x0103000e
+ 0x0104000f
+ 0x01050010
+ 0x01060011
+ 0x01070012
+ 0x01080013
+ 0x02000014
+ 0x02010015
+ 0x02020016
+ 0x02030017
+ 0x02040018
+ 0x02050019
+ 0x0206001a
+ 0x0207001b
+ 0x0208001c
+ 0x0300001d
+ 0x0301001e
+ 0x0302001f
+ 0x03030020
+ 0x03040021
+ 0x03050022
+ 0x03060023
+ 0x03070024
+ 0x03080025
+ 0x04000026
+ 0x04010027
+ 0x04020028
+ 0x04030029
+ 0x0404002a
+ 0x0405002b
+ 0x0406002c
+ 0x0407002d
+ 0x0408002e
+ 0x0500002f
+ 0x05010030
+ 0x05020031
+ 0x05030032
+ 0x05040033
+ 0x05050034
+ 0x05060035
+ 0x05070036
+ 0x05080037
+ 0x06000038
+ 0x06010039
+ 0x0602003a
+ 0x0603003b
+ 0x0604003c
+ 0x0605003d
+ 0x0606003e
+ 0x0607003f
+ 0x06080040
+ 0x07000041
+ 0x07010042
+ 0x07020043
+ 0x07030044
+ 0x07040045
+ 0x07050046
+ 0x07060047
+ 0x07070048
+ 0x07080049
+ 0x0800004a
+ 0x0801004b
+ 0x0802004c
+ 0x0803004d
+ 0x0804004e
+ 0x0805004f
+ 0x08060050
+ 0x08070051
+ 0x08080052 >;
+ autorepeat;
+ st,mode = <0>;
+ status = "okay";
+ };
+
+ rtc@e0580000 {
+ status = "okay";
+ };
+
+ serial@e0000000 {
+ status = "okay";
+ };
+
+ wdt@ec800620 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi
new file mode 100644
index 000000000000..9e61da404d57
--- /dev/null
+++ b/arch/arm/boot/dts/spear1310.dtsi
@@ -0,0 +1,184 @@
+/*
+ * DTS file for all SPEAr1310 SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear13xx.dtsi"
+
+/ {
+ compatible = "st,spear1310";
+
+ ahb {
+ ahci@b1000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1000000 0x10000>;
+ interrupts = <0 68 0x4>;
+ status = "disabled";
+ };
+
+ ahci@b1800000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1800000 0x10000>;
+ interrupts = <0 69 0x4>;
+ status = "disabled";
+ };
+
+ ahci@b4000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb4000000 0x10000>;
+ interrupts = <0 70 0x4>;
+ status = "disabled";
+ };
+
+ gmac1: eth@5c400000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c400000 0x8000>;
+ interrupts = <0 95 0x4>;
+ interrupt-names = "macirq";
+ status = "disabled";
+ };
+
+ gmac2: eth@5c500000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c500000 0x8000>;
+ interrupts = <0 96 0x4>;
+ interrupt-names = "macirq";
+ status = "disabled";
+ };
+
+ gmac3: eth@5c600000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c600000 0x8000>;
+ interrupts = <0 97 0x4>;
+ interrupt-names = "macirq";
+ status = "disabled";
+ };
+
+ gmac4: eth@5c700000 {
+ compatible = "st,spear600-gmac";
+ reg = <0x5c700000 0x8000>;
+ interrupts = <0 98 0x4>;
+ interrupt-names = "macirq";
+ status = "disabled";
+ };
+
+ spi1: spi@5d400000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x5d400000 0x1000>;
+ interrupts = <0 99 0x4>;
+ status = "disabled";
+ };
+
+ apb {
+ i2c1: i2c@5cd00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5cd00000 0x1000>;
+ interrupts = <0 87 0x4>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@5ce00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5ce00000 0x1000>;
+ interrupts = <0 88 0x4>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@5cf00000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5cf00000 0x1000>;
+ interrupts = <0 89 0x4>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@5d000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d000000 0x1000>;
+ interrupts = <0 90 0x4>;
+ status = "disabled";
+ };
+
+ i2c5: i2c@5d100000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d100000 0x1000>;
+ interrupts = <0 91 0x4>;
+ status = "disabled";
+ };
+
+ i2c6: i2c@5d200000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d200000 0x1000>;
+ interrupts = <0 92 0x4>;
+ status = "disabled";
+ };
+
+ i2c7: i2c@5d300000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0x5d300000 0x1000>;
+ interrupts = <0 93 0x4>;
+ status = "disabled";
+ };
+
+ serial@5c800000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5c800000 0x1000>;
+ interrupts = <0 82 0x4>;
+ status = "disabled";
+ };
+
+ serial@5c900000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5c900000 0x1000>;
+ interrupts = <0 83 0x4>;
+ status = "disabled";
+ };
+
+ serial@5ca00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5ca00000 0x1000>;
+ interrupts = <0 84 0x4>;
+ status = "disabled";
+ };
+
+ serial@5cb00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5cb00000 0x1000>;
+ interrupts = <0 85 0x4>;
+ status = "disabled";
+ };
+
+ serial@5cc00000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0x5cc00000 0x1000>;
+ interrupts = <0 86 0x4>;
+ status = "disabled";
+ };
+
+ thermal@e07008c4 {
+ st,thermal-flags = <0x7000>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts
new file mode 100644
index 000000000000..0d8472e5ab9f
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340-evb.dts
@@ -0,0 +1,308 @@
+/*
+ * DTS file for SPEAr1340 Evaluation Baord
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "spear1340.dtsi"
+
+/ {
+ model = "ST SPEAr1340 Evaluation Board";
+ compatible = "st,spear1340-evb", "st,spear1340";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ memory {
+ reg = <0 0x40000000>;
+ };
+
+ ahb {
+ pinmux@e0700000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ pads_as_gpio {
+ st,pins = "pads_as_gpio_grp";
+ st,function = "pads_as_gpio";
+ };
+ fsmc {
+ st,pins = "fsmc_8bit_grp";
+ st,function = "fsmc";
+ };
+ kbd {
+ st,pins = "keyboard_row_col_grp",
+ "keyboard_col5_grp";
+ st,function = "keyboard";
+ };
+ uart0 {
+ st,pins = "uart0_grp", "uart0_enh_grp";
+ st,function = "uart0";
+ };
+ i2c0-pmx {
+ st,pins = "i2c0_grp";
+ st,function = "i2c0";
+ };
+ i2c1-pmx {
+ st,pins = "i2c1_grp";
+ st,function = "i2c1";
+ };
+ spdif-in {
+ st,pins = "spdif_in_grp";
+ st,function = "spdif_in";
+ };
+ spdif-out {
+ st,pins = "spdif_out_grp";
+ st,function = "spdif_out";
+ };
+ ssp0 {
+ st,pins = "ssp0_grp", "ssp0_cs1_grp",
+ "ssp0_cs3_grp";
+ st,function = "ssp0";
+ };
+ pwm {
+ st,pins = "pwm2_grp", "pwm3_grp";
+ st,function = "pwm";
+ };
+ smi-pmx {
+ st,pins = "smi_grp";
+ st,function = "smi";
+ };
+ i2s {
+ st,pins = "i2s_in_grp", "i2s_out_grp";
+ st,function = "i2s";
+ };
+ gmac {
+ st,pins = "gmii_grp", "rgmii_grp";
+ st,function = "gmac";
+ };
+ cam3 {
+ st,pins = "cam3_grp";
+ st,function = "cam3";
+ };
+ cec0 {
+ st,pins = "cec0_grp";
+ st,function = "cec0";
+ };
+ cec1 {
+ st,pins = "cec1_grp";
+ st,function = "cec1";
+ };
+ sdhci {
+ st,pins = "sdhci_grp";
+ st,function = "sdhci";
+ };
+ clcd {
+ st,pins = "clcd_grp";
+ st,function = "clcd";
+ };
+ sata {
+ st,pins = "sata_grp";
+ st,function = "sata";
+ };
+ };
+ };
+
+ dma@ea800000 {
+ status = "okay";
+ };
+
+ dma@eb000000 {
+ status = "okay";
+ };
+
+ fsmc: flash@b0000000 {
+ status = "okay";
+ };
+
+ gmac0: eth@e2000000 {
+ status = "okay";
+ };
+
+ sdhci@b3000000 {
+ status = "okay";
+ };
+
+ smi: flash@ea000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@e6000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xe6000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
+ };
+ };
+
+ spi0: spi@e0100000 {
+ status = "okay";
+ };
+
+ ehci@e4800000 {
+ status = "okay";
+ };
+
+ ehci@e5800000 {
+ status = "okay";
+ };
+
+ ohci@e4000000 {
+ status = "okay";
+ };
+
+ ohci@e5000000 {
+ status = "okay";
+ };
+
+ apb {
+ adc@e0080000 {
+ status = "okay";
+ };
+
+ gpio0: gpio@e0600000 {
+ status = "okay";
+ };
+
+ gpio1: gpio@e0680000 {
+ status = "okay";
+ };
+
+ i2c0: i2c@e0280000 {
+ status = "okay";
+ };
+
+ i2c1: i2c@b4000000 {
+ status = "okay";
+ };
+
+ kbd@e0300000 {
+ linux,keymap = < 0x00000001
+ 0x00010002
+ 0x00020003
+ 0x00030004
+ 0x00040005
+ 0x00050006
+ 0x00060007
+ 0x00070008
+ 0x00080009
+ 0x0100000a
+ 0x0101000c
+ 0x0102000d
+ 0x0103000e
+ 0x0104000f
+ 0x01050010
+ 0x01060011
+ 0x01070012
+ 0x01080013
+ 0x02000014
+ 0x02010015
+ 0x02020016
+ 0x02030017
+ 0x02040018
+ 0x02050019
+ 0x0206001a
+ 0x0207001b
+ 0x0208001c
+ 0x0300001d
+ 0x0301001e
+ 0x0302001f
+ 0x03030020
+ 0x03040021
+ 0x03050022
+ 0x03060023
+ 0x03070024
+ 0x03080025
+ 0x04000026
+ 0x04010027
+ 0x04020028
+ 0x04030029
+ 0x0404002a
+ 0x0405002b
+ 0x0406002c
+ 0x0407002d
+ 0x0408002e
+ 0x0500002f
+ 0x05010030
+ 0x05020031
+ 0x05030032
+ 0x05040033
+ 0x05050034
+ 0x05060035
+ 0x05070036
+ 0x05080037
+ 0x06000038
+ 0x06010039
+ 0x0602003a
+ 0x0603003b
+ 0x0604003c
+ 0x0605003d
+ 0x0606003e
+ 0x0607003f
+ 0x06080040
+ 0x07000041
+ 0x07010042
+ 0x07020043
+ 0x07030044
+ 0x07040045
+ 0x07050046
+ 0x07060047
+ 0x07070048
+ 0x07080049
+ 0x0800004a
+ 0x0801004b
+ 0x0802004c
+ 0x0803004d
+ 0x0804004e
+ 0x0805004f
+ 0x08060050
+ 0x08070051
+ 0x08080052 >;
+ autorepeat;
+ st,mode = <0>;
+ status = "okay";
+ };
+
+ rtc@e0580000 {
+ status = "okay";
+ };
+
+ serial@e0000000 {
+ status = "okay";
+ };
+
+ serial@b4100000 {
+ status = "okay";
+ };
+
+ wdt@ec800620 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
new file mode 100644
index 000000000000..a26fc47a55e8
--- /dev/null
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -0,0 +1,56 @@
+/*
+ * DTS file for all SPEAr1340 SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "spear13xx.dtsi"
+
+/ {
+ compatible = "st,spear1340";
+
+ ahb {
+ ahci@b1000000 {
+ compatible = "snps,spear-ahci";
+ reg = <0xb1000000 0x10000>;
+ interrupts = <0 72 0x4>;
+ status = "disabled";
+ };
+
+ spi1: spi@5d400000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0x5d400000 0x1000>;
+ interrupts = <0 99 0x4>;
+ status = "disabled";
+ };
+
+ apb {
+ i2c1: i2c@b4000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xb4000000 0x1000>;
+ interrupts = <0 104 0x4>;
+ status = "disabled";
+ };
+
+ serial@b4100000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xb4100000 0x1000>;
+ interrupts = <0 105 0x4>;
+ status = "disabled";
+ };
+
+ thermal@e07008c4 {
+ st,thermal-flags = <0x2a00>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
new file mode 100644
index 000000000000..1f8e1e1481df
--- /dev/null
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -0,0 +1,262 @@
+/*
+ * DTS file for all SPEAr13xx SoCs
+ *
+ * Copyright 2012 Viresh Kumar <viresh.kumar@st.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ gic: interrupt-controller@ec801000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = < 0xec801000 0x1000 >,
+ < 0xec800100 0x0100 >;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 8 0x04
+ 0 9 0x04>;
+ };
+
+ L2: l2-cache {
+ compatible = "arm,pl310-cache";
+ reg = <0xed000000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ memory {
+ name = "memory";
+ device_type = "memory";
+ reg = <0 0x40000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyAMA0,115200";
+ };
+
+ ahb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x50000000 0x50000000 0x10000000
+ 0xb0000000 0xb0000000 0x10000000
+ 0xe0000000 0xe0000000 0x10000000>;
+
+ sdhci@b3000000 {
+ compatible = "st,sdhci-spear";
+ reg = <0xb3000000 0x100>;
+ interrupts = <0 28 0x4>;
+ status = "disabled";
+ };
+
+ cf@b2800000 {
+ compatible = "arasan,cf-spear1340";
+ reg = <0xb2800000 0x100>;
+ interrupts = <0 29 0x4>;
+ status = "disabled";
+ };
+
+ dma@ea800000 {
+ compatible = "snps,dma-spear1340";
+ reg = <0xea800000 0x1000>;
+ interrupts = <0 19 0x4>;
+ status = "disabled";
+ };
+
+ dma@eb000000 {
+ compatible = "snps,dma-spear1340";
+ reg = <0xeb000000 0x1000>;
+ interrupts = <0 59 0x4>;
+ status = "disabled";
+ };
+
+ fsmc: flash@b0000000 {
+ compatible = "st,spear600-fsmc-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xb0000000 0x1000 /* FSMC Register */
+ 0xb0800000 0x0010>; /* NAND Base */
+ reg-names = "fsmc_regs", "nand_data";
+ interrupts = <0 20 0x4
+ 0 21 0x4
+ 0 22 0x4
+ 0 23 0x4>;
+ st,ale-off = <0x20000>;
+ st,cle-off = <0x10000>;
+ status = "disabled";
+ };
+
+ gmac0: eth@e2000000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe2000000 0x8000>;
+ interrupts = <0 23 0x4
+ 0 24 0x4>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ status = "disabled";
+ };
+
+ smi: flash@ea000000 {
+ compatible = "st,spear600-smi";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xea000000 0x1000>;
+ interrupts = <0 30 0x4>;
+ status = "disabled";
+ };
+
+ spi0: spi@e0100000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xe0100000 0x1000>;
+ interrupts = <0 31 0x4>;
+ status = "disabled";
+ };
+
+ ehci@e4800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe4800000 0x1000>;
+ interrupts = <0 64 0x4>;
+ status = "disabled";
+ };
+
+ ehci@e5800000 {
+ compatible = "st,spear600-ehci", "usb-ehci";
+ reg = <0xe5800000 0x1000>;
+ interrupts = <0 66 0x4>;
+ status = "disabled";
+ };
+
+ ohci@e4000000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe4000000 0x1000>;
+ interrupts = <0 65 0x4>;
+ status = "disabled";
+ };
+
+ ohci@e5000000 {
+ compatible = "st,spear600-ohci", "usb-ohci";
+ reg = <0xe5000000 0x1000>;
+ interrupts = <0 67 0x4>;
+ status = "disabled";
+ };
+
+ apb {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ ranges = <0x50000000 0x50000000 0x10000000
+ 0xb0000000 0xb0000000 0x10000000
+ 0xe0000000 0xe0000000 0x10000000>;
+
+ gpio0: gpio@e0600000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xe0600000 0x1000>;
+ interrupts = <0 24 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@e0680000 {
+ compatible = "arm,pl061", "arm,primecell";
+ reg = <0xe0680000 0x1000>;
+ interrupts = <0 25 0x4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ status = "disabled";
+ };
+
+ kbd@e0300000 {
+ compatible = "st,spear300-kbd";
+ reg = <0xe0300000 0x1000>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@e0280000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,designware-i2c";
+ reg = <0xe0280000 0x1000>;
+ interrupts = <0 41 0x4>;
+ status = "disabled";
+ };
+
+ rtc@e0580000 {
+ compatible = "st,spear-rtc";
+ reg = <0xe0580000 0x1000>;
+ interrupts = <0 36 0x4>;
+ status = "disabled";
+ };
+
+ serial@e0000000 {
+ compatible = "arm,pl011", "arm,primecell";
+ reg = <0xe0000000 0x1000>;
+ interrupts = <0 36 0x4>;
+ status = "disabled";
+ };
+
+ adc@e0080000 {
+ compatible = "st,spear600-adc";
+ reg = <0xe0080000 0x1000>;
+ interrupts = <0 44 0x4>;
+ status = "disabled";
+ };
+
+ timer@e0380000 {
+ compatible = "st,spear-timer";
+ reg = <0xe0380000 0x400>;
+ interrupts = <0 37 0x4>;
+ };
+
+ timer@ec800600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0xec800600 0x20>;
+ interrupts = <1 13 0x301>;
+ };
+
+ wdt@ec800620 {
+ compatible = "arm,cortex-a9-twd-wdt";
+ reg = <0xec800620 0x20>;
+ status = "disabled";
+ };
+
+ thermal@e07008c4 {
+ compatible = "st,thermal-spear1340";
+ reg = <0xe07008c4 0x4>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
index 910e264b87c0..fc82b1a26458 100644
--- a/arch/arm/boot/dts/spear300-evb.dts
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -87,6 +87,31 @@
smi: flash@fc000000 {
status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
+ };
};
spi0: spi@d0100000 {
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts
index 6d95317100ad..dc5e2d445a93 100644
--- a/arch/arm/boot/dts/spear310-evb.dts
+++ b/arch/arm/boot/dts/spear310-evb.dts
@@ -103,11 +103,27 @@
clock-rate=<50000000>;
flash@f8000000 {
- label = "m25p64";
- reg = <0xf8000000 0x800000>;
#address-cells = <1>;
#size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
};
};
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index 0c6463b71a37..6308fa3bec1e 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -110,6 +110,31 @@
smi: flash@fc000000 {
status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
+ };
};
spi0: spi@d0100000 {
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi
index 0ae7c8e86311..91072553963f 100644
--- a/arch/arm/boot/dts/spear3xx.dtsi
+++ b/arch/arm/boot/dts/spear3xx.dtsi
@@ -139,6 +139,12 @@
interrupts = <12>;
status = "disabled";
};
+
+ timer@f0000000 {
+ compatible = "st,spear-timer";
+ reg = <0xf0000000 0x400>;
+ interrupts = <2>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts
index 790a7a8a5ccd..1119c22c9a82 100644
--- a/arch/arm/boot/dts/spear600-evb.dts
+++ b/arch/arm/boot/dts/spear600-evb.dts
@@ -33,6 +33,35 @@
status = "okay";
};
+ smi: flash@fc000000 {
+ status = "okay";
+ clock-rate=<50000000>;
+
+ flash@f8000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xf8000000 0x800000>;
+ st,smi-fast-mode;
+
+ partition@0 {
+ label = "xloader";
+ reg = <0x0 0x10000>;
+ };
+ partition@10000 {
+ label = "u-boot";
+ reg = <0x10000 0x40000>;
+ };
+ partition@50000 {
+ label = "linux";
+ reg = <0x50000 0x2c0000>;
+ };
+ partition@310000 {
+ label = "rootfs";
+ reg = <0x310000 0x4f0000>;
+ };
+ };
+ };
+
apb {
serial@d0000000 {
status = "okay";
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
index d777e3a6f178..089f0a42c50e 100644
--- a/arch/arm/boot/dts/spear600.dtsi
+++ b/arch/arm/boot/dts/spear600.dtsi
@@ -177,6 +177,12 @@
interrupts = <28>;
status = "disabled";
};
+
+ timer@f0000000 {
+ compatible = "st,spear-timer";
+ reg = <0xf0000000 0x400>;
+ interrupts = <16>;
+ };
};
};
};
diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts
index 0a9f34a2c3aa..36321bceec46 100644
--- a/arch/arm/boot/dts/tegra-cardhu.dts
+++ b/arch/arm/boot/dts/tegra-cardhu.dts
@@ -7,10 +7,10 @@
compatible = "nvidia,cardhu", "nvidia,tegra30";
memory {
- reg = < 0x80000000 0x40000000 >;
+ reg = <0x80000000 0x40000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -51,64 +51,122 @@
nvidia,pull = <2>;
nvidia,tristate = <0>;
};
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2",
+ "dap2_sclk_pa3",
+ "dap2_din_pa4",
+ "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
};
};
serial@70006000 {
- clock-frequency = < 408000000 >;
- };
-
- serial@70006040 {
- status = "disable";
- };
-
- serial@70006200 {
- status = "disable";
- };
-
- serial@70006300 {
- status = "disable";
- };
-
- serial@70006400 {
- status = "disable";
+ status = "okay";
+ clock-frequency = <408000000>;
};
i2c@7000c000 {
+ status = "okay";
clock-frequency = <100000>;
};
i2c@7000c400 {
+ status = "okay";
clock-frequency = <100000>;
};
i2c@7000c500 {
+ status = "okay";
clock-frequency = <100000>;
+
+ /* ALS and Proximity sensor */
+ isl29028@44 {
+ compatible = "isil,isl29028";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <88 0x04>; /*gpio PL0 */
+ };
};
i2c@7000c700 {
+ status = "okay";
clock-frequency = <100000>;
};
i2c@7000d000 {
+ status = "okay";
clock-frequency = <100000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = <179 0x04>; /* gpio PW3 */
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ tps62361 {
+ compatible = "ti,tps62361";
+ reg = <0x60>;
+
+ regulator-name = "tps62361-vout";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ti,vsel0-state-high;
+ ti,vsel1-state-high;
+ };
+ };
+
+ ahub {
+ i2s@70080400 {
+ status = "okay";
+ };
};
sdhci@78000000 {
+ status = "okay";
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 155 0>; /* gpio PT3 */
power-gpios = <&gpio 31 0>; /* gpio PD7 */
+ bus-width = <4>;
};
- sdhci@78000200 {
- status = "disable";
+ sdhci@78000600 {
+ status = "okay";
+ support-8bit;
+ bus-width = <8>;
};
- sdhci@78000400 {
- status = "disable";
- };
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-cardhu",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Cardhu";
- sdhci@78000400 {
- support-8bit;
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 0>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
};
};
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index 1a0b1f182944..7de701365fce 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -6,11 +6,11 @@
model = "NVIDIA Tegra2 Harmony evaluation board";
compatible = "nvidia,harmony", "nvidia,tegra20";
- memory@0 {
- reg = < 0x00000000 0x40000000 >;
+ memory {
+ reg = <0x00000000 0x40000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -167,28 +167,28 @@
};
conf_ata {
nvidia,pins = "ata", "atb", "atc", "atd", "ate",
- "cdev1", "dap1", "dtb", "gma", "gmb",
- "gmc", "gmd", "gme", "gpu7", "gpv",
- "i2cp", "pta", "rm", "slxa", "slxk",
- "spia", "spib";
+ "cdev1", "cdev2", "dap1", "dtb", "gma",
+ "gmb", "gmc", "gmd", "gme", "gpu7",
+ "gpv", "i2cp", "pta", "rm", "slxa",
+ "slxk", "spia", "spib", "uac";
nvidia,pull = <0>;
nvidia,tristate = <0>;
};
- conf_cdev2 {
- nvidia,pins = "cdev2", "csus", "spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
- };
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
nvidia,pull = <0>;
};
+ conf_csus {
+ nvidia,pins = "csus", "spid", "spif";
+ nvidia,pull = <1>;
+ nvidia,tristate = <1>;
+ };
conf_crtp {
nvidia,pins = "crtp", "dap2", "dap3", "dap4",
"dtc", "dte", "dtf", "gpu", "sdio1",
"slxc", "slxd", "spdi", "spdo", "spig",
- "uac", "uda";
+ "uda";
nvidia,pull = <0>;
nvidia,tristate = <1>;
};
@@ -234,42 +234,81 @@
};
};
- pmc@7000f400 {
- nvidia,invert-interrupt;
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ clock-frequency = <216000000>;
};
i2c@7000c000 {
+ status = "okay";
clock-frequency = <400000>;
wm8903: wm8903@1a {
compatible = "wlf,wm8903";
reg = <0x1a>;
interrupt-parent = <&gpio>;
- interrupts = < 187 0x04 >;
+ interrupts = <187 0x04>;
gpio-controller;
#gpio-cells = <2>;
micdet-cfg = <0>;
micdet-delay = <100>;
- gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
};
};
i2c@7000c400 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000c500 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000d000 {
+ status = "okay";
clock-frequency = <400000>;
};
- i2s@70002a00 {
- status = "disable";
+ pmc {
+ nvidia,invert-interrupt;
+ };
+
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000200 {
+ status = "okay";
+ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+ power-gpios = <&gpio 155 0>; /* gpio PT3 */
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ cd-gpios = <&gpio 58 0>; /* gpio PH2 */
+ wp-gpios = <&gpio 59 0>; /* gpio PH3 */
+ power-gpios = <&gpio 70 0>; /* gpio PI6 */
+ support-8bit;
+ bus-width = <8>;
};
sound {
@@ -295,45 +334,4 @@
nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
};
-
- serial@70006000 {
- status = "disable";
- };
-
- serial@70006040 {
- status = "disable";
- };
-
- serial@70006200 {
- status = "disable";
- };
-
- serial@70006300 {
- clock-frequency = < 216000000 >;
- };
-
- serial@70006400 {
- status = "disable";
- };
-
- sdhci@c8000000 {
- status = "disable";
- };
-
- sdhci@c8000200 {
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
- wp-gpios = <&gpio 57 0>; /* gpio PH1 */
- power-gpios = <&gpio 155 0>; /* gpio PT3 */
- };
-
- sdhci@c8000400 {
- status = "disable";
- };
-
- sdhci@c8000600 {
- cd-gpios = <&gpio 58 0>; /* gpio PH2 */
- wp-gpios = <&gpio 59 0>; /* gpio PH3 */
- power-gpios = <&gpio 70 0>; /* gpio PI6 */
- support-8bit;
- };
};
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
index 10943fb2561c..bfeb117d5aea 100644
--- a/arch/arm/boot/dts/tegra-paz00.dts
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -6,11 +6,11 @@
model = "Toshiba AC100 / Dynabook AZ";
compatible = "compal,paz00", "nvidia,tegra20";
- memory@0 {
+ memory {
reg = <0x00000000 0x20000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -159,18 +159,14 @@
};
conf_ata {
nvidia,pins = "ata", "atb", "atc", "atd", "ate",
- "cdev1", "dap1", "dap2", "dtf", "gma",
- "gmb", "gmc", "gmd", "gme", "gpu",
- "gpu7", "gpv", "i2cp", "pta", "rm",
- "sdio1", "slxk", "spdo", "uac", "uda";
+ "cdev1", "cdev2", "dap1", "dap2", "dtf",
+ "gma", "gmb", "gmc", "gmd", "gme",
+ "gpu", "gpu7", "gpv", "i2cp", "pta",
+ "rm", "sdio1", "slxk", "spdo", "uac",
+ "uda";
nvidia,pull = <0>;
nvidia,tristate = <0>;
};
- conf_cdev2 {
- nvidia,pins = "cdev2";
- nvidia,pull = <1>;
- nvidia,tristate = <0>;
- };
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
@@ -230,7 +226,22 @@
};
};
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006000 {
+ status = "okay";
+ clock-frequency = <216000000>;
+ };
+
+ serial@70006200 {
+ status = "okay";
+ clock-frequency = <216000000>;
+ };
+
i2c@7000c000 {
+ status = "okay";
clock-frequency = <400000>;
alc5632: alc5632@1e {
@@ -242,25 +253,23 @@
};
i2c@7000c400 {
+ status = "okay";
clock-frequency = <400000>;
};
- i2c@7000c500 {
- status = "disable";
- };
-
- nvec@7000c500 {
- #address-cells = <1>;
- #size-cells = <0>;
+ nvec {
compatible = "nvidia,nvec";
- reg = <0x7000C500 0x100>;
+ reg = <0x7000c500 0x100>;
interrupts = <0 92 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
clock-frequency = <80000>;
- request-gpios = <&gpio 170 0>;
+ request-gpios = <&gpio 170 0>; /* gpio PV2 */
slave-addr = <138>;
};
i2c@7000d000 {
+ status = "okay";
clock-frequency = <400000>;
adt7461@4c {
@@ -269,66 +278,31 @@
};
};
- i2s@70002a00 {
- status = "disable";
- };
-
- sound {
- compatible = "nvidia,tegra-audio-alc5632-paz00",
- "nvidia,tegra-audio-alc5632";
-
- nvidia,model = "Compal PAZ00";
-
- nvidia,audio-routing =
- "Int Spk", "SPKOUT",
- "Int Spk", "SPKOUTN",
- "Headset Mic", "MICBIAS1",
- "MIC1", "Headset Mic",
- "Headset Stereophone", "HPR",
- "Headset Stereophone", "HPL",
- "DMICDAT", "Digital Mic";
-
- nvidia,audio-codec = <&alc5632>;
- nvidia,i2s-controller = <&tegra_i2s1>;
- nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
- };
-
- serial@70006000 {
- clock-frequency = <216000000>;
+ usb@c5000000 {
+ status = "okay";
};
- serial@70006040 {
- status = "disable";
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
};
- serial@70006200 {
- clock-frequency = <216000000>;
- };
-
- serial@70006300 {
- status = "disable";
- };
-
- serial@70006400 {
- status = "disable";
+ usb@c5008000 {
+ status = "okay";
};
sdhci@c8000000 {
+ status = "okay";
cd-gpios = <&gpio 173 0>; /* gpio PV5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 169 0>; /* gpio PV1 */
- };
-
- sdhci@c8000200 {
- status = "disable";
- };
-
- sdhci@c8000400 {
- status = "disable";
+ bus-width = <4>;
};
sdhci@c8000600 {
+ status = "okay";
support-8bit;
+ bus-width = <8>;
};
gpio-keys {
@@ -347,8 +321,28 @@
wifi {
label = "wifi-led";
- gpios = <&gpio 24 0>;
+ gpios = <&gpio 24 0>; /* gpio PD0 */
linux,default-trigger = "rfkill0";
};
};
+
+ sound {
+ compatible = "nvidia,tegra-audio-alc5632-paz00",
+ "nvidia,tegra-audio-alc5632";
+
+ nvidia,model = "Compal PAZ00";
+
+ nvidia,audio-routing =
+ "Int Spk", "SPKOUT",
+ "Int Spk", "SPKOUTN",
+ "Headset Mic", "MICBIAS1",
+ "MIC1", "Headset Mic",
+ "Headset Stereophone", "HPR",
+ "Headset Stereophone", "HPL",
+ "DMICDAT", "Digital Mic";
+
+ nvidia,audio-codec = <&alc5632>;
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+ };
};
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index ec33116f5df9..89cb7f2acd92 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -7,11 +7,10 @@
compatible = "nvidia,seaboard", "nvidia,tegra20";
memory {
- device_type = "memory";
- reg = < 0x00000000 0x40000000 >;
+ reg = <0x00000000 0x40000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -100,7 +99,7 @@
};
hdint {
nvidia,pins = "hdint", "lpw0", "lpw2", "lsc1",
- "lsck", "lsda", "pta";
+ "lsck", "lsda";
nvidia,function = "hdmi";
};
i2cp {
@@ -134,6 +133,10 @@
nvidia,pins = "pmc";
nvidia,function = "pwr_on";
};
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
rm {
nvidia,pins = "rm";
nvidia,function = "i2c1";
@@ -254,108 +257,148 @@
};
};
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ clock-frequency = <216000000>;
+ };
+
i2c@7000c000 {
+ status = "okay";
clock-frequency = <400000>;
wm8903: wm8903@1a {
compatible = "wlf,wm8903";
reg = <0x1a>;
interrupt-parent = <&gpio>;
- interrupts = < 187 0x04 >;
+ interrupts = <187 0x04>;
gpio-controller;
#gpio-cells = <2>;
micdet-cfg = <0>;
micdet-delay = <100>;
- gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ /* ALS and proximity sensor */
+ isl29018@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <202 0x04>; /* GPIO PZ2 */
+ };
+
+ gyrometer@68 {
+ compatible = "invn,mpu3050";
+ reg = <0x68>;
+ interrupt-parent = <&gpio>;
+ interrupts = <204 0x04>; /* gpio PZ4 */
};
};
i2c@7000c400 {
- clock-frequency = <400000>;
+ status = "okay";
+ clock-frequency = <100000>;
+
+ smart-battery@b {
+ compatible = "ti,bq20z75", "smart-battery-1.1";
+ reg = <0xb>;
+ ti,i2c-retry-count = <2>;
+ ti,poll-retry-count = <10>;
+ };
};
i2c@7000c500 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000d000 {
+ status = "okay";
clock-frequency = <400000>;
- adt7461@4c {
- compatible = "adt7461";
+ temperature-sensor@4c {
+ compatible = "nct1008";
reg = <0x4c>;
};
- };
-
- i2s@70002a00 {
- status = "disable";
- };
-
- sound {
- compatible = "nvidia,tegra-audio-wm8903-seaboard",
- "nvidia,tegra-audio-wm8903";
- nvidia,model = "NVIDIA Tegra Seaboard";
-
- nvidia,audio-routing =
- "Headphone Jack", "HPOUTR",
- "Headphone Jack", "HPOUTL",
- "Int Spk", "ROP",
- "Int Spk", "RON",
- "Int Spk", "LOP",
- "Int Spk", "LON",
- "Mic Jack", "MICBIAS",
- "IN1R", "Mic Jack";
-
- nvidia,i2s-controller = <&tegra_i2s1>;
- nvidia,audio-codec = <&wm8903>;
-
- nvidia,spkr-en-gpios = <&wm8903 2 0>;
- nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
- };
- serial@70006000 {
- status = "disable";
- };
-
- serial@70006040 {
- status = "disable";
+ magnetometer@c {
+ compatible = "ak8975";
+ reg = <0xc>;
+ interrupt-parent = <&gpio>;
+ interrupts = <109 0x04>; /* gpio PN5 */
+ };
};
- serial@70006200 {
- status = "disable";
- };
+ emc {
+ emc-table@190000 {
+ reg = <190000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <190000>;
+ nvidia,emc-registers = <0x0000000c 0x00000026
+ 0x00000009 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000c 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x0000059f
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x0000000b 0x000000c8
+ 0x00000003 0x00000007 0x00000004 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xa06204ae
+ 0x007dc010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
- serial@70006300 {
- clock-frequency = < 216000000 >;
+ emc-table@380000 {
+ reg = <380000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = <380000>;
+ nvidia,emc-registers = <0x00000017 0x0000004b
+ 0x00000012 0x00000006 0x00000004 0x00000005
+ 0x00000003 0x0000000c 0x00000006 0x00000006
+ 0x00000003 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x00000b5f
+ 0x00000000 0x00000003 0x00000003 0x00000006
+ 0x00000006 0x00000001 0x00000011 0x000000c8
+ 0x00000003 0x0000000e 0x00000007 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xe044048b
+ 0x007d8010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000>;
+ };
};
- serial@70006400 {
- status = "disable";
+ usb@c5000000 {
+ status = "okay";
+ nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+ dr_mode = "otg";
};
- sdhci@c8000000 {
- status = "disable";
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
};
- sdhci@c8000200 {
- status = "disable";
+ usb@c5008000 {
+ status = "okay";
};
sdhci@c8000400 {
+ status = "okay";
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
power-gpios = <&gpio 70 0>; /* gpio PI6 */
+ bus-width = <4>;
};
sdhci@c8000600 {
+ status = "okay";
support-8bit;
- };
-
- usb@c5000000 {
- nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
- dr_mode = "otg";
+ bus-width = <8>;
};
gpio-keys {
@@ -378,41 +421,25 @@
};
};
- emc@7000f400 {
- emc-table@190000 {
- reg = < 190000 >;
- compatible = "nvidia,tegra20-emc-table";
- clock-frequency = < 190000 >;
- nvidia,emc-registers = < 0x0000000c 0x00000026
- 0x00000009 0x00000003 0x00000004 0x00000004
- 0x00000002 0x0000000c 0x00000003 0x00000003
- 0x00000002 0x00000001 0x00000004 0x00000005
- 0x00000004 0x00000009 0x0000000d 0x0000059f
- 0x00000000 0x00000003 0x00000003 0x00000003
- 0x00000003 0x00000001 0x0000000b 0x000000c8
- 0x00000003 0x00000007 0x00000004 0x0000000f
- 0x00000002 0x00000000 0x00000000 0x00000002
- 0x00000000 0x00000000 0x00000083 0xa06204ae
- 0x007dc010 0x00000000 0x00000000 0x00000000
- 0x00000000 0x00000000 0x00000000 0x00000000 >;
- };
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-seaboard",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Seaboard";
- emc-table@380000 {
- reg = < 380000 >;
- compatible = "nvidia,tegra20-emc-table";
- clock-frequency = < 380000 >;
- nvidia,emc-registers = < 0x00000017 0x0000004b
- 0x00000012 0x00000006 0x00000004 0x00000005
- 0x00000003 0x0000000c 0x00000006 0x00000006
- 0x00000003 0x00000001 0x00000004 0x00000005
- 0x00000004 0x00000009 0x0000000d 0x00000b5f
- 0x00000000 0x00000003 0x00000003 0x00000006
- 0x00000006 0x00000001 0x00000011 0x000000c8
- 0x00000003 0x0000000e 0x00000007 0x0000000f
- 0x00000002 0x00000000 0x00000000 0x00000002
- 0x00000000 0x00000000 0x00000083 0xe044048b
- 0x007d8010 0x00000000 0x00000000 0x00000000
- 0x00000000 0x00000000 0x00000000 0x00000000 >;
- };
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1R", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 0>;
+ nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
};
};
diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 98efd5b0d7f9..9de5636023f6 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -6,11 +6,11 @@
model = "Compulab TrimSlice board";
compatible = "compulab,trimslice", "nvidia,tegra20";
- memory@0 {
- reg = < 0x00000000 0x40000000 >;
+ memory {
+ reg = <0x00000000 0x40000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -182,23 +182,23 @@
nvidia,tristate = <1>;
};
conf_atb {
- nvidia,pins = "atb", "cdev1", "dap1", "gma",
- "gmc", "gmd", "gpu", "gpu7", "gpv",
- "sdio1", "slxa", "slxk", "uac";
+ nvidia,pins = "atb", "cdev1", "cdev2", "dap1",
+ "gma", "gmc", "gmd", "gpu", "gpu7",
+ "gpv", "sdio1", "slxa", "slxk", "uac";
nvidia,pull = <0>;
nvidia,tristate = <0>;
};
- conf_cdev2 {
- nvidia,pins = "cdev2", "csus", "spia", "spib",
- "spid", "spif";
- nvidia,pull = <1>;
- nvidia,tristate = <1>;
- };
conf_ck32 {
nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
"pmcc", "pmcd", "pmce", "xm2c", "xm2d";
nvidia,pull = <0>;
};
+ conf_csus {
+ nvidia,pins = "csus", "spia", "spib",
+ "spid", "spif";
+ nvidia,pull = <1>;
+ nvidia,tristate = <1>;
+ };
conf_ddc {
nvidia,pins = "ddc", "dtf", "rm", "sdc", "sdd";
nvidia,pull = <2>;
@@ -240,68 +240,67 @@
};
};
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006000 {
+ status = "okay";
+ clock-frequency = <216000000>;
+ };
+
i2c@7000c000 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000c400 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000c500 {
+ status = "okay";
clock-frequency = <400000>;
- };
-
- i2c@7000d000 {
- status = "disable";
- };
-
- i2s@70002800 {
- status = "disable";
- };
-
- i2s@70002a00 {
- status = "disable";
- };
-
- das@70000c00 {
- status = "disable";
- };
- serial@70006000 {
- clock-frequency = < 216000000 >;
- };
+ codec: codec@1a {
+ compatible = "ti,tlv320aic23";
+ reg = <0x1a>;
+ };
- serial@70006040 {
- status = "disable";
+ rtc@56 {
+ compatible = "emmicro,em3027";
+ reg = <0x56>;
+ };
};
- serial@70006200 {
- status = "disable";
+ usb@c5000000 {
+ status = "okay";
};
- serial@70006300 {
- status = "disable";
+ usb@c5004000 {
+ nvidia,phy-reset-gpio = <&gpio 168 0>; /* gpio PV0 */
};
- serial@70006400 {
- status = "disable";
+ usb@c5008000 {
+ status = "okay";
};
sdhci@c8000000 {
- status = "disable";
+ status = "okay";
+ bus-width = <4>;
};
- sdhci@c8000200 {
- status = "disable";
- };
-
- sdhci@c8000400 {
- status = "disable";
+ sdhci@c8000600 {
+ status = "okay";
+ cd-gpios = <&gpio 121 0>; /* gpio PP1 */
+ wp-gpios = <&gpio 122 0>; /* gpio PP2 */
+ bus-width = <4>;
};
- sdhci@c8000600 {
- cd-gpios = <&gpio 121 0>;
- wp-gpios = <&gpio 122 0>;
+ sound {
+ compatible = "nvidia,tegra-audio-trimslice";
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&codec>;
};
};
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
index 71eb2e50a668..445343b0fbdd 100644
--- a/arch/arm/boot/dts/tegra-ventana.dts
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -7,10 +7,10 @@
compatible = "nvidia,ventana", "nvidia,tegra20";
memory {
- reg = < 0x00000000 0x40000000 >;
+ reg = <0x00000000 0x40000000>;
};
- pinmux@70000000 {
+ pinmux {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
@@ -240,38 +240,82 @@
};
};
+ i2s@70002800 {
+ status = "okay";
+ };
+
+ serial@70006300 {
+ status = "okay";
+ clock-frequency = <216000000>;
+ };
+
i2c@7000c000 {
+ status = "okay";
clock-frequency = <400000>;
wm8903: wm8903@1a {
compatible = "wlf,wm8903";
reg = <0x1a>;
interrupt-parent = <&gpio>;
- interrupts = < 187 0x04 >;
+ interrupts = <187 0x04>;
gpio-controller;
#gpio-cells = <2>;
micdet-cfg = <0>;
micdet-delay = <100>;
- gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+ gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+ };
+
+ /* ALS and proximity sensor */
+ isl29018@44 {
+ compatible = "isil,isl29018";
+ reg = <0x44>;
+ interrupt-parent = <&gpio>;
+ interrupts = <202 0x04>; /*gpio PZ2 */
};
};
i2c@7000c400 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000c500 {
+ status = "okay";
clock-frequency = <400000>;
};
i2c@7000d000 {
+ status = "okay";
clock-frequency = <400000>;
};
- i2s@70002a00 {
- status = "disable";
+ usb@c5000000 {
+ status = "okay";
+ };
+
+ usb@c5004000 {
+ status = "okay";
+ nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+ };
+
+ usb@c5008000 {
+ status = "okay";
+ };
+
+ sdhci@c8000400 {
+ status = "okay";
+ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+ power-gpios = <&gpio 70 0>; /* gpio PI6 */
+ bus-width = <4>;
+ };
+
+ sdhci@c8000600 {
+ status = "okay";
+ support-8bit;
+ bus-width = <8>;
};
sound {
@@ -294,45 +338,7 @@
nvidia,spkr-en-gpios = <&wm8903 2 0>;
nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
- nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+ nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */
nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
};
-
- serial@70006000 {
- status = "disable";
- };
-
- serial@70006040 {
- status = "disable";
- };
-
- serial@70006200 {
- status = "disable";
- };
-
- serial@70006300 {
- clock-frequency = < 216000000 >;
- };
-
- serial@70006400 {
- status = "disable";
- };
-
- sdhci@c8000000 {
- status = "disable";
- };
-
- sdhci@c8000200 {
- status = "disable";
- };
-
- sdhci@c8000400 {
- cd-gpios = <&gpio 69 0>; /* gpio PI5 */
- wp-gpios = <&gpio 57 0>; /* gpio PH1 */
- power-gpios = <&gpio 70 0>; /* gpio PI6 */
- };
-
- sdhci@c8000600 {
- support-8bit;
- };
};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 108e894a8926..c417d67e9027 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,207 +4,242 @@
compatible = "nvidia,tegra20";
interrupt-parent = <&intc>;
- pmc@7000f400 {
- compatible = "nvidia,tegra20-pmc";
- reg = <0x7000e400 0x400>;
- };
-
- intc: interrupt-controller@50041000 {
+ intc: interrupt-controller {
compatible = "arm,cortex-a9-gic";
+ reg = <0x50041000 0x1000
+ 0x50040100 0x0100>;
interrupt-controller;
#interrupt-cells = <3>;
- reg = < 0x50041000 0x1000 >,
- < 0x50040100 0x0100 >;
};
- pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupts = <0 56 0x04
- 0 57 0x04>;
- };
-
- apbdma: dma@6000a000 {
+ apbdma: dma {
compatible = "nvidia,tegra20-apbdma";
reg = <0x6000a000 0x1200>;
- interrupts = < 0 104 0x04
- 0 105 0x04
- 0 106 0x04
- 0 107 0x04
- 0 108 0x04
- 0 109 0x04
- 0 110 0x04
- 0 111 0x04
- 0 112 0x04
- 0 113 0x04
- 0 114 0x04
- 0 115 0x04
- 0 116 0x04
- 0 117 0x04
- 0 118 0x04
- 0 119 0x04 >;
- };
-
- i2c@7000c000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra20-i2c";
- reg = <0x7000C000 0x100>;
- interrupts = < 0 38 0x04 >;
- };
-
- i2c@7000c400 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra20-i2c";
- reg = <0x7000C400 0x100>;
- interrupts = < 0 84 0x04 >;
+ interrupts = <0 104 0x04
+ 0 105 0x04
+ 0 106 0x04
+ 0 107 0x04
+ 0 108 0x04
+ 0 109 0x04
+ 0 110 0x04
+ 0 111 0x04
+ 0 112 0x04
+ 0 113 0x04
+ 0 114 0x04
+ 0 115 0x04
+ 0 116 0x04
+ 0 117 0x04
+ 0 118 0x04
+ 0 119 0x04>;
+ };
+
+ ahb {
+ compatible = "nvidia,tegra20-ahb";
+ reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
+ };
+
+ gpio: gpio {
+ compatible = "nvidia,tegra20-gpio";
+ reg = <0x6000d000 0x1000>;
+ interrupts = <0 32 0x04
+ 0 33 0x04
+ 0 34 0x04
+ 0 35 0x04
+ 0 55 0x04
+ 0 87 0x04
+ 0 89 0x04>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
};
- i2c@7000c500 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra20-i2c";
- reg = <0x7000C500 0x100>;
- interrupts = < 0 92 0x04 >;
+ pinmux: pinmux {
+ compatible = "nvidia,tegra20-pinmux";
+ reg = <0x70000014 0x10 /* Tri-state registers */
+ 0x70000080 0x20 /* Mux registers */
+ 0x700000a0 0x14 /* Pull-up/down registers */
+ 0x70000868 0xa8>; /* Pad control registers */
};
- i2c@7000d000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra20-i2c-dvc";
- reg = <0x7000D000 0x200>;
- interrupts = < 0 53 0x04 >;
+ das {
+ compatible = "nvidia,tegra20-das";
+ reg = <0x70000c00 0x80>;
};
tegra_i2s1: i2s@70002800 {
compatible = "nvidia,tegra20-i2s";
reg = <0x70002800 0x200>;
- interrupts = < 0 13 0x04 >;
- nvidia,dma-request-selector = < &apbdma 2 >;
+ interrupts = <0 13 0x04>;
+ nvidia,dma-request-selector = <&apbdma 2>;
+ status = "disable";
};
tegra_i2s2: i2s@70002a00 {
compatible = "nvidia,tegra20-i2s";
reg = <0x70002a00 0x200>;
- interrupts = < 0 3 0x04 >;
- nvidia,dma-request-selector = < &apbdma 1 >;
- };
-
- das@70000c00 {
- compatible = "nvidia,tegra20-das";
- reg = <0x70000c00 0x80>;
- };
-
- gpio: gpio@6000d000 {
- compatible = "nvidia,tegra20-gpio";
- reg = < 0x6000d000 0x1000 >;
- interrupts = < 0 32 0x04
- 0 33 0x04
- 0 34 0x04
- 0 35 0x04
- 0 55 0x04
- 0 87 0x04
- 0 89 0x04 >;
- #gpio-cells = <2>;
- gpio-controller;
- #interrupt-cells = <2>;
- interrupt-controller;
- };
-
- pinmux: pinmux@70000000 {
- compatible = "nvidia,tegra20-pinmux";
- reg = < 0x70000014 0x10 /* Tri-state registers */
- 0x70000080 0x20 /* Mux registers */
- 0x700000a0 0x14 /* Pull-up/down registers */
- 0x70000868 0xa8 >; /* Pad control registers */
+ interrupts = <0 3 0x04>;
+ nvidia,dma-request-selector = <&apbdma 1>;
+ status = "disable";
};
serial@70006000 {
compatible = "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
- interrupts = < 0 36 0x04 >;
+ interrupts = <0 36 0x04>;
+ status = "disable";
};
serial@70006040 {
compatible = "nvidia,tegra20-uart";
reg = <0x70006040 0x40>;
reg-shift = <2>;
- interrupts = < 0 37 0x04 >;
+ interrupts = <0 37 0x04>;
+ status = "disable";
};
serial@70006200 {
compatible = "nvidia,tegra20-uart";
reg = <0x70006200 0x100>;
reg-shift = <2>;
- interrupts = < 0 46 0x04 >;
+ interrupts = <0 46 0x04>;
+ status = "disable";
};
serial@70006300 {
compatible = "nvidia,tegra20-uart";
reg = <0x70006300 0x100>;
reg-shift = <2>;
- interrupts = < 0 90 0x04 >;
+ interrupts = <0 90 0x04>;
+ status = "disable";
};
serial@70006400 {
compatible = "nvidia,tegra20-uart";
reg = <0x70006400 0x100>;
reg-shift = <2>;
- interrupts = < 0 91 0x04 >;
+ interrupts = <0 91 0x04>;
+ status = "disable";
};
- emc@7000f400 {
+ i2c@7000c000 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <0 38 0x04>;
#address-cells = <1>;
#size-cells = <0>;
- compatible = "nvidia,tegra20-emc";
- reg = <0x7000f400 0x200>;
+ status = "disable";
};
- sdhci@c8000000 {
- compatible = "nvidia,tegra20-sdhci";
- reg = <0xc8000000 0x200>;
- interrupts = < 0 14 0x04 >;
+ i2c@7000c400 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <0 84 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
};
- sdhci@c8000200 {
- compatible = "nvidia,tegra20-sdhci";
- reg = <0xc8000200 0x200>;
- interrupts = < 0 15 0x04 >;
+ i2c@7000c500 {
+ compatible = "nvidia,tegra20-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <0 92 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
};
- sdhci@c8000400 {
- compatible = "nvidia,tegra20-sdhci";
- reg = <0xc8000400 0x200>;
- interrupts = < 0 19 0x04 >;
+ i2c@7000d000 {
+ compatible = "nvidia,tegra20-i2c-dvc";
+ reg = <0x7000d000 0x200>;
+ interrupts = <0 53 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
};
- sdhci@c8000600 {
- compatible = "nvidia,tegra20-sdhci";
- reg = <0xc8000600 0x200>;
- interrupts = < 0 31 0x04 >;
+ pmc {
+ compatible = "nvidia,tegra20-pmc";
+ reg = <0x7000e400 0x400>;
+ };
+
+ mc {
+ compatible = "nvidia,tegra20-mc";
+ reg = <0x7000f000 0x024
+ 0x7000f03c 0x3c4>;
+ interrupts = <0 77 0x04>;
+ };
+
+ gart {
+ compatible = "nvidia,tegra20-gart";
+ reg = <0x7000f024 0x00000018 /* controller registers */
+ 0x58000000 0x02000000>; /* GART aperture */
+ };
+
+ emc {
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f400 0x200>;
+ #address-cells = <1>;
+ #size-cells = <0>;
};
usb@c5000000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5000000 0x4000>;
- interrupts = < 0 20 0x04 >;
+ interrupts = <0 20 0x04>;
phy_type = "utmi";
nvidia,has-legacy-mode;
+ status = "disable";
};
usb@c5004000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5004000 0x4000>;
- interrupts = < 0 21 0x04 >;
+ interrupts = <0 21 0x04>;
phy_type = "ulpi";
+ status = "disable";
};
usb@c5008000 {
compatible = "nvidia,tegra20-ehci", "usb-ehci";
reg = <0xc5008000 0x4000>;
- interrupts = < 0 97 0x04 >;
+ interrupts = <0 97 0x04>;
phy_type = "utmi";
+ status = "disable";
+ };
+
+ sdhci@c8000000 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000000 0x200>;
+ interrupts = <0 14 0x04>;
+ status = "disable";
};
-};
+ sdhci@c8000200 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000200 0x200>;
+ interrupts = <0 15 0x04>;
+ status = "disable";
+ };
+
+ sdhci@c8000400 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000400 0x200>;
+ interrupts = <0 19 0x04>;
+ status = "disable";
+ };
+
+ sdhci@c8000600 {
+ compatible = "nvidia,tegra20-sdhci";
+ reg = <0xc8000600 0x200>;
+ interrupts = <0 31 0x04>;
+ status = "disable";
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 56 0x04
+ 0 57 0x04>;
+ };
+};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 62a7b39f1c9a..2dcc09e784b5 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,183 +4,268 @@
compatible = "nvidia,tegra30";
interrupt-parent = <&intc>;
- pmc@7000f400 {
- compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
- reg = <0x7000e400 0x400>;
- };
-
- intc: interrupt-controller@50041000 {
+ intc: interrupt-controller {
compatible = "arm,cortex-a9-gic";
+ reg = <0x50041000 0x1000
+ 0x50040100 0x0100>;
interrupt-controller;
#interrupt-cells = <3>;
- reg = < 0x50041000 0x1000 >,
- < 0x50040100 0x0100 >;
};
- pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupts = <0 144 0x04
- 0 145 0x04
- 0 146 0x04
- 0 147 0x04>;
- };
-
- apbdma: dma@6000a000 {
+ apbdma: dma {
compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
reg = <0x6000a000 0x1400>;
- interrupts = < 0 104 0x04
- 0 105 0x04
- 0 106 0x04
- 0 107 0x04
- 0 108 0x04
- 0 109 0x04
- 0 110 0x04
- 0 111 0x04
- 0 112 0x04
- 0 113 0x04
- 0 114 0x04
- 0 115 0x04
- 0 116 0x04
- 0 117 0x04
- 0 118 0x04
- 0 119 0x04
- 0 128 0x04
- 0 129 0x04
- 0 130 0x04
- 0 131 0x04
- 0 132 0x04
- 0 133 0x04
- 0 134 0x04
- 0 135 0x04
- 0 136 0x04
- 0 137 0x04
- 0 138 0x04
- 0 139 0x04
- 0 140 0x04
- 0 141 0x04
- 0 142 0x04
- 0 143 0x04 >;
- };
-
- i2c@7000c000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000C000 0x100>;
- interrupts = < 0 38 0x04 >;
- };
-
- i2c@7000c400 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000C400 0x100>;
- interrupts = < 0 84 0x04 >;
- };
-
- i2c@7000c500 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000C500 0x100>;
- interrupts = < 0 92 0x04 >;
+ interrupts = <0 104 0x04
+ 0 105 0x04
+ 0 106 0x04
+ 0 107 0x04
+ 0 108 0x04
+ 0 109 0x04
+ 0 110 0x04
+ 0 111 0x04
+ 0 112 0x04
+ 0 113 0x04
+ 0 114 0x04
+ 0 115 0x04
+ 0 116 0x04
+ 0 117 0x04
+ 0 118 0x04
+ 0 119 0x04
+ 0 128 0x04
+ 0 129 0x04
+ 0 130 0x04
+ 0 131 0x04
+ 0 132 0x04
+ 0 133 0x04
+ 0 134 0x04
+ 0 135 0x04
+ 0 136 0x04
+ 0 137 0x04
+ 0 138 0x04
+ 0 139 0x04
+ 0 140 0x04
+ 0 141 0x04
+ 0 142 0x04
+ 0 143 0x04>;
};
- i2c@7000c700 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000c700 0x100>;
- interrupts = < 0 120 0x04 >;
+ ahb: ahb {
+ compatible = "nvidia,tegra30-ahb";
+ reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
};
- i2c@7000d000 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000D000 0x100>;
- interrupts = < 0 53 0x04 >;
- };
-
- gpio: gpio@6000d000 {
+ gpio: gpio {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
- reg = < 0x6000d000 0x1000 >;
- interrupts = < 0 32 0x04
- 0 33 0x04
- 0 34 0x04
- 0 35 0x04
- 0 55 0x04
- 0 87 0x04
- 0 89 0x04
- 0 125 0x04 >;
+ reg = <0x6000d000 0x1000>;
+ interrupts = <0 32 0x04
+ 0 33 0x04
+ 0 34 0x04
+ 0 35 0x04
+ 0 55 0x04
+ 0 87 0x04
+ 0 89 0x04
+ 0 125 0x04>;
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
};
+ pinmux: pinmux {
+ compatible = "nvidia,tegra30-pinmux";
+ reg = <0x70000868 0xd0 /* Pad control registers */
+ 0x70003000 0x3e0>; /* Mux registers */
+ };
+
serial@70006000 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006000 0x40>;
reg-shift = <2>;
- interrupts = < 0 36 0x04 >;
+ interrupts = <0 36 0x04>;
+ status = "disable";
};
serial@70006040 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006040 0x40>;
reg-shift = <2>;
- interrupts = < 0 37 0x04 >;
+ interrupts = <0 37 0x04>;
+ status = "disable";
};
serial@70006200 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006200 0x100>;
reg-shift = <2>;
- interrupts = < 0 46 0x04 >;
+ interrupts = <0 46 0x04>;
+ status = "disable";
};
serial@70006300 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006300 0x100>;
reg-shift = <2>;
- interrupts = < 0 90 0x04 >;
+ interrupts = <0 90 0x04>;
+ status = "disable";
};
serial@70006400 {
compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
reg = <0x70006400 0x100>;
reg-shift = <2>;
- interrupts = < 0 91 0x04 >;
+ interrupts = <0 91 0x04>;
+ status = "disable";
+ };
+
+ i2c@7000c000 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c000 0x100>;
+ interrupts = <0 38 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
+ };
+
+ i2c@7000c400 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c400 0x100>;
+ interrupts = <0 84 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
+ };
+
+ i2c@7000c500 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c500 0x100>;
+ interrupts = <0 92 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
+ };
+
+ i2c@7000c700 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000c700 0x100>;
+ interrupts = <0 120 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
+ };
+
+ i2c@7000d000 {
+ compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+ reg = <0x7000d000 0x100>;
+ interrupts = <0 53 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disable";
+ };
+
+ pmc {
+ compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+ reg = <0x7000e400 0x400>;
+ };
+
+ mc {
+ compatible = "nvidia,tegra30-mc";
+ reg = <0x7000f000 0x010
+ 0x7000f03c 0x1b4
+ 0x7000f200 0x028
+ 0x7000f284 0x17c>;
+ interrupts = <0 77 0x04>;
+ };
+
+ smmu {
+ compatible = "nvidia,tegra30-smmu";
+ reg = <0x7000f010 0x02c
+ 0x7000f1f0 0x010
+ 0x7000f228 0x05c>;
+ nvidia,#asids = <4>; /* # of ASIDs */
+ dma-window = <0 0x40000000>; /* IOVA start & length */
+ nvidia,ahb = <&ahb>;
+ };
+
+ ahub {
+ compatible = "nvidia,tegra30-ahub";
+ reg = <0x70080000 0x200
+ 0x70080200 0x100>;
+ interrupts = <0 103 0x04>;
+ nvidia,dma-request-selector = <&apbdma 1>;
+
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ tegra_i2s0: i2s@70080300 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080300 0x100>;
+ nvidia,ahub-cif-ids = <4 4>;
+ status = "disable";
+ };
+
+ tegra_i2s1: i2s@70080400 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080400 0x100>;
+ nvidia,ahub-cif-ids = <5 5>;
+ status = "disable";
+ };
+
+ tegra_i2s2: i2s@70080500 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080500 0x100>;
+ nvidia,ahub-cif-ids = <6 6>;
+ status = "disable";
+ };
+
+ tegra_i2s3: i2s@70080600 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080600 0x100>;
+ nvidia,ahub-cif-ids = <7 7>;
+ status = "disable";
+ };
+
+ tegra_i2s4: i2s@70080700 {
+ compatible = "nvidia,tegra30-i2s";
+ reg = <0x70080700 0x100>;
+ nvidia,ahub-cif-ids = <8 8>;
+ status = "disable";
+ };
};
sdhci@78000000 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000000 0x200>;
- interrupts = < 0 14 0x04 >;
+ interrupts = <0 14 0x04>;
+ status = "disable";
};
sdhci@78000200 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000200 0x200>;
- interrupts = < 0 15 0x04 >;
+ interrupts = <0 15 0x04>;
+ status = "disable";
};
sdhci@78000400 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000400 0x200>;
- interrupts = < 0 19 0x04 >;
+ interrupts = <0 19 0x04>;
+ status = "disable";
};
sdhci@78000600 {
compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
reg = <0x78000600 0x200>;
- interrupts = < 0 31 0x04 >;
+ interrupts = <0 31 0x04>;
+ status = "disable";
};
- pinmux: pinmux@70000000 {
- compatible = "nvidia,tegra30-pinmux";
- reg = < 0x70000868 0xd0 /* Pad control registers */
- 0x70003000 0x3e0 >; /* Mux registers */
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 144 0x04
+ 0 145 0x04
+ 0 146 0x04
+ 0 147 0x04>;
};
};
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 595ecd290ebf..9d7eb530f95f 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_
read_lock_irqsave(&device_info->lock, flags);
list_for_each_entry(b, &device_info->safe_buffers, node)
- if (b->safe_dma_addr == safe_dma_addr) {
+ if (b->safe_dma_addr <= safe_dma_addr &&
+ b->safe_dma_addr + b->size > safe_dma_addr) {
rb = b;
break;
}
@@ -254,7 +255,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
if (buf == NULL) {
dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
__func__, ptr);
- return ~0;
+ return DMA_ERROR_CODE;
}
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,
* substitute the safe buffer for the unsafe one.
* (basically move the buffer from an unsafe area to a safe one)
*/
-dma_addr_t __dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir)
+static dma_addr_t dmabounce_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
dma_addr_t dma_addr;
int ret;
@@ -320,21 +322,20 @@ dma_addr_t __dma_map_page(struct device *dev, struct page *page,
ret = needs_bounce(dev, dma_addr, size);
if (ret < 0)
- return ~0;
+ return DMA_ERROR_CODE;
if (ret == 0) {
- __dma_page_cpu_to_dev(page, offset, size, dir);
+ arm_dma_ops.sync_single_for_device(dev, dma_addr, size, dir);
return dma_addr;
}
if (PageHighMem(page)) {
dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n");
- return ~0;
+ return DMA_ERROR_CODE;
}
return map_single(dev, page_address(page) + offset, size, dir);
}
-EXPORT_SYMBOL(__dma_map_page);
/*
* see if a mapped address was really a "safe" buffer and if so, copy
@@ -342,8 +343,8 @@ EXPORT_SYMBOL(__dma_map_page);
* the safe buffer. (basically return things back to the way they
* should be)
*/
-void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction dir)
+static void dmabounce_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct safe_buffer *buf;
@@ -352,19 +353,18 @@ void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
buf = find_safe_buffer_dev(dev, dma_addr, __func__);
if (!buf) {
- __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)),
- dma_addr & ~PAGE_MASK, size, dir);
+ arm_dma_ops.sync_single_for_cpu(dev, dma_addr, size, dir);
return;
}
unmap_single(dev, buf, size, dir);
}
-EXPORT_SYMBOL(__dma_unmap_page);
-int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
- unsigned long off, size_t sz, enum dma_data_direction dir)
+static int __dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
+ size_t sz, enum dma_data_direction dir)
{
struct safe_buffer *buf;
+ unsigned long off;
dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
__func__, addr, off, sz, dir);
@@ -373,6 +373,8 @@ int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
if (!buf)
return 1;
+ off = addr - buf->safe_dma_addr;
+
BUG_ON(buf->direction != dir);
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,
}
return 0;
}
-EXPORT_SYMBOL(dmabounce_sync_for_cpu);
-int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
- unsigned long off, size_t sz, enum dma_data_direction dir)
+static void dmabounce_sync_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (!__dmabounce_sync_for_cpu(dev, handle, size, dir))
+ return;
+
+ arm_dma_ops.sync_single_for_cpu(dev, handle, size, dir);
+}
+
+static int __dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
+ size_t sz, enum dma_data_direction dir)
{
struct safe_buffer *buf;
+ unsigned long off;
dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
__func__, addr, off, sz, dir);
@@ -402,6 +413,8 @@ int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
if (!buf)
return 1;
+ off = addr - buf->safe_dma_addr;
+
BUG_ON(buf->direction != dir);
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,
}
return 0;
}
-EXPORT_SYMBOL(dmabounce_sync_for_device);
+
+static void dmabounce_sync_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ if (!__dmabounce_sync_for_device(dev, handle, size, dir))
+ return;
+
+ arm_dma_ops.sync_single_for_device(dev, handle, size, dir);
+}
+
+static int dmabounce_set_mask(struct device *dev, u64 dma_mask)
+{
+ if (dev->archdata.dmabounce)
+ return 0;
+
+ return arm_dma_ops.set_dma_mask(dev, dma_mask);
+}
+
+static struct dma_map_ops dmabounce_ops = {
+ .alloc = arm_dma_alloc,
+ .free = arm_dma_free,
+ .mmap = arm_dma_mmap,
+ .map_page = dmabounce_map_page,
+ .unmap_page = dmabounce_unmap_page,
+ .sync_single_for_cpu = dmabounce_sync_for_cpu,
+ .sync_single_for_device = dmabounce_sync_for_device,
+ .map_sg = arm_dma_map_sg,
+ .unmap_sg = arm_dma_unmap_sg,
+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_dma_sync_sg_for_device,
+ .set_dma_mask = dmabounce_set_mask,
+};
static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
const char *name, unsigned long size)
@@ -479,6 +523,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
#endif
dev->archdata.dmabounce = device_info;
+ set_dma_ops(dev, &dmabounce_ops);
dev_info(dev, "dmabounce: registered device\n");
@@ -497,6 +542,7 @@ void dmabounce_unregister_dev(struct device *dev)
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
dev->archdata.dmabounce = NULL;
+ set_dma_ops(dev, NULL);
if (!device_info) {
dev_warn(dev,
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index 09a02963cf58..ebda45bd5763 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
CONFIG_MACH_PCA100=y
CONFIG_MACH_MXT_TD60=y
CONFIG_MACH_IMX27IPCAM=y
+CONFIG_MACH_IMX27_DT=y
CONFIG_MXC_IRQ_PRIOR=y
CONFIG_MXC_PWM=y
CONFIG_NO_HZ=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index dc6f6411bbf5..12617f7296e6 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -64,6 +64,12 @@ CONFIG_IPV6=y
# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SST25L=y
# CONFIG_STANDALONE is not set
CONFIG_CONNECTOR=y
CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 1ebbf451c48d..5406c23a02e3 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -22,6 +22,7 @@ CONFIG_BLK_DEV_INTEGRITY=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_MXS=y
+CONFIG_MACH_MXS_DT=y
CONFIG_MACH_MX23EVK=y
CONFIG_MACH_MX28EVK=y
CONFIG_MACH_STMP378X_DEVB=y
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig
new file mode 100644
index 000000000000..c328ac65479a
--- /dev/null
+++ b/arch/arm/configs/prima2_defconfig
@@ -0,0 +1,69 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_ARCH_PRIMA2=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_KEXEC=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM_RUNTIME=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_SIRFSOC=y
+CONFIG_SERIAL_SIRFSOC_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SIRF=y
+CONFIG_SPI=y
+CONFIG_SPI_SIRF=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_DMADEVICES=y
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
+CONFIG_SIRF_DMA=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_INFO=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig
new file mode 100644
index 000000000000..1fdb82694ca2
--- /dev/null
+++ b/arch/arm/configs/spear13xx_defconfig
@@ -0,0 +1,95 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR13XX=y
+CONFIG_MACH_SPEAR1310=y
+CONFIG_MACH_SPEAR1340=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+# CONFIG_SMP_ON_UP is not set
+# CONFIG_ARM_CPU_TOPOLOGY is not set
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_FSMC=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_PATA_ARASAN_CF=y
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_SPEAR=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_I2C=y
+CONFIG_I2C_DESIGNWARE_PLATFORM=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_MPCORE_WATCHDOG=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SPEAR=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_DW_DMAC=y
+CONFIG_DMATEST=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_INFO=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
index 7ed42912d69a..865980c5f212 100644
--- a/arch/arm/configs/spear3xx_defconfig
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -14,6 +14,9 @@ CONFIG_BINFMT_MISC=y
CONFIG_NET=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_FSMC=y
CONFIG_BLK_DEV_RAM=y
@@ -73,6 +76,7 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
index cf94bc73a0e0..a2a1265f86b6 100644
--- a/arch/arm/configs/spear6xx_defconfig
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -8,11 +8,13 @@ CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_PLAT_SPEAR=y
CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BOARD_SPEAR600_DT=y
CONFIG_BINFMT_MISC=y
CONFIG_NET=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_MTD=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_FSMC=y
CONFIG_BLK_DEV_RAM=y
@@ -64,6 +66,7 @@ CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
CONFIG_NLS_DEFAULT="utf8"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=m
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 351d6708c3ae..1198dd61c7c4 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -45,6 +45,7 @@ CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
+CONFIG_PM_RUNTIME=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -91,6 +92,8 @@ CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
# CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MPU3050=y
# CONFIG_VT is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_DEVKMEM is not set
@@ -103,12 +106,15 @@ CONFIG_I2C=y
CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
CONFIG_SPI_TEGRA=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_SBS=y
CONFIG_SENSORS_LM90=y
CONFIG_MFD_TPS6586X=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS6586X=y
CONFIG_SOUND=y
CONFIG_SND=y
@@ -133,16 +139,19 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_TEGRA=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EM3027=y
CONFIG_RTC_DRV_TEGRA=y
CONFIG_STAGING=y
-CONFIG_IIO=y
CONFIG_SENSORS_ISL29018=y
+CONFIG_SENSORS_ISL29028=y
CONFIG_SENSORS_AK8975=y
CONFIG_MFD_NVEC=y
CONFIG_KEYBOARD_NVEC=y
CONFIG_SERIO_NVEC_PS2=y
CONFIG_TEGRA_IOMMU_GART=y
CONFIG_TEGRA_IOMMU_SMMU=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 7aa368003b05..b69c0d3285f8 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -7,12 +7,16 @@
#define ASMARM_DEVICE_H
struct dev_archdata {
+ struct dma_map_ops *dma_ops;
#ifdef CONFIG_DMABOUNCE
struct dmabounce_device_info *dmabounce;
#endif
#ifdef CONFIG_IOMMU_API
void *iommu; /* private IOMMU data */
#endif
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+ struct dma_iommu_mapping *mapping;
+#endif
};
struct 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 000000000000..3ed37b4d93da
--- /dev/null
+++ b/arch/arm/include/asm/dma-contiguous.h
@@ -0,0 +1,15 @@
+#ifndef ASMARM_DMA_CONTIGUOUS_H
+#define ASMARM_DMA_CONTIGUOUS_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_CMA
+
+#include <linux/types.h>
+#include <asm-generic/dma-contiguous.h>
+
+void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
+
+#endif
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
new file mode 100644
index 000000000000..799b09409fad
--- /dev/null
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -0,0 +1,34 @@
+#ifndef ASMARM_DMA_IOMMU_H
+#define ASMARM_DMA_IOMMU_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/kmemcheck.h>
+
+struct dma_iommu_mapping {
+ /* iommu specific data */
+ struct iommu_domain *domain;
+
+ void *bitmap;
+ size_t bits;
+ unsigned int order;
+ dma_addr_t base;
+
+ spinlock_t lock;
+ struct kref kref;
+};
+
+struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
+ int order);
+
+void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
+
+int arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping);
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index cb3b7c981c4b..bbef15d04890 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -5,11 +5,35 @@
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
+#include <linux/dma-attrs.h>
#include <linux/dma-debug.h>
#include <asm-generic/dma-coherent.h>
#include <asm/memory.h>
+#define DMA_ERROR_CODE (~0)
+extern struct dma_map_ops arm_dma_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ if (dev && dev->archdata.dma_ops)
+ return dev->archdata.dma_ops;
+ return &arm_dma_ops;
+}
+
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+{
+ BUG_ON(!dev);
+ dev->archdata.dma_ops = ops;
+}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return get_dma_ops(dev)->set_dma_mask(dev, mask);
+}
+
#ifdef __arch_page_to_dma
#error Please update to __arch_pfn_to_dma
#endif
@@ -62,68 +86,11 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
#endif
/*
- * The DMA API is built upon the notion of "buffer ownership". A buffer
- * is either exclusively owned by the CPU (and therefore may be accessed
- * by it) or exclusively owned by the DMA device. These helper functions
- * represent the transitions between these two ownership states.
- *
- * Note, however, that on later ARMs, this notion does not work due to
- * speculative prefetches. We model our approach on the assumption that
- * the CPU does do speculative prefetches, which means we clean caches
- * before transfers and delay cache invalidation until transfer completion.
- *
- * Private support functions: these are not part of the API and are
- * liable to change. Drivers must not use these.
- */
-static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
- enum dma_data_direction dir)
-{
- extern void ___dma_single_cpu_to_dev(const void *, size_t,
- enum dma_data_direction);
-
- if (!arch_is_coherent())
- ___dma_single_cpu_to_dev(kaddr, size, dir);
-}
-
-static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
- enum dma_data_direction dir)
-{
- extern void ___dma_single_dev_to_cpu(const void *, size_t,
- enum dma_data_direction);
-
- if (!arch_is_coherent())
- ___dma_single_dev_to_cpu(kaddr, size, dir);
-}
-
-static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
- size_t size, enum dma_data_direction dir)
-{
- extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
- size_t, enum dma_data_direction);
-
- if (!arch_is_coherent())
- ___dma_page_cpu_to_dev(page, off, size, dir);
-}
-
-static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
- size_t size, enum dma_data_direction dir)
-{
- extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
- size_t, enum dma_data_direction);
-
- if (!arch_is_coherent())
- ___dma_page_dev_to_cpu(page, off, size, dir);
-}
-
-extern int dma_supported(struct device *, u64);
-extern int dma_set_mask(struct device *, u64);
-
-/*
* DMA errors are defined by all-bits-set in the DMA address.
*/
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- return dma_addr == ~0;
+ return dma_addr == DMA_ERROR_CODE;
}
/*
@@ -141,69 +108,118 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
{
}
+extern int dma_supported(struct device *dev, u64 mask);
+
/**
- * dma_alloc_coherent - allocate consistent memory for DMA
+ * arm_dma_alloc - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @size: required memory size
* @handle: bus-specific DMA address
+ * @attrs: optinal attributes that specific mapping properties
*
- * Allocate some uncached, unbuffered memory for a device for
- * performing DMA. This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
+ * Allocate some memory for a device for performing DMA. This function
+ * allocates pages, and will return the CPU-viewed address, and sets @handle
+ * to be the device-viewed address.
*/
-extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
+extern void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs);
+
+#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ void *cpu_addr;
+ BUG_ON(!ops);
+
+ cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
+ debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
+ return cpu_addr;
+}
/**
- * dma_free_coherent - free memory allocated by dma_alloc_coherent
+ * arm_dma_free - free memory allocated by arm_dma_alloc
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @size: size of memory originally requested in dma_alloc_coherent
* @cpu_addr: CPU-view address returned from dma_alloc_coherent
* @handle: device-view address returned from dma_alloc_coherent
+ * @attrs: optinal attributes that specific mapping properties
*
* Free (and unmap) a DMA buffer previously allocated by
- * dma_alloc_coherent().
+ * arm_dma_alloc().
*
* References to memory and mappings associated with cpu_addr/handle
* during and after this call executing are illegal.
*/
-extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
+extern void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs);
+
+#define dma_free_coherent(d, s, c, h) dma_free_attrs(d, s, c, h, NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ BUG_ON(!ops);
+
+ debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
+ ops->free(dev, size, cpu_addr, dma_handle, attrs);
+}
/**
- * dma_mmap_coherent - map a coherent DMA allocation into user space
+ * arm_dma_mmap - map a coherent DMA allocation into user space
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @vma: vm_area_struct describing requested user mapping
* @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent
* @handle: device-view address returned from dma_alloc_coherent
* @size: size of memory originally requested in dma_alloc_coherent
+ * @attrs: optinal attributes that specific mapping properties
*
* Map a coherent DMA buffer previously allocated by dma_alloc_coherent
* into user space. The coherent DMA buffer must not be freed by the
* driver until the user space mapping has been released.
*/
-int dma_mmap_coherent(struct device *, struct vm_area_struct *,
- void *, dma_addr_t, size_t);
+extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs);
+#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
-/**
- * dma_alloc_writecombine - allocate writecombining memory for DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @size: required memory size
- * @handle: bus-specific DMA address
- *
- * Allocate some uncached, buffered memory for a device for
- * performing DMA. This function allocates pages, and will
- * return the CPU-viewed address, and sets @handle to be the
- * device-viewed address.
- */
-extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
- gfp_t);
+static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr,
+ size_t size, struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ BUG_ON(!ops);
+ return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+}
+
+static inline void *dma_alloc_writecombine(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ DEFINE_DMA_ATTRS(attrs);
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ return dma_alloc_attrs(dev, size, dma_handle, flag, &attrs);
+}
-#define dma_free_writecombine(dev,size,cpu_addr,handle) \
- dma_free_coherent(dev,size,cpu_addr,handle)
+static inline void dma_free_writecombine(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle)
+{
+ DEFINE_DMA_ATTRS(attrs);
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
+}
-int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
- void *, dma_addr_t, size_t);
+static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ DEFINE_DMA_ATTRS(attrs);
+ dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+ return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
+}
/*
* 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 *,
*/
extern void __init init_consistent_dma_size(unsigned long size);
-
-#ifdef CONFIG_DMABOUNCE
/*
* For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
* 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,
*/
extern void dmabounce_unregister_dev(struct device *);
-/*
- * The DMA API, implemented by dmabounce.c. See below for descriptions.
- */
-extern dma_addr_t __dma_map_page(struct device *, struct page *,
- unsigned long, size_t, enum dma_data_direction);
-extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
- enum dma_data_direction);
-
-/*
- * Private functions
- */
-int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
- size_t, enum dma_data_direction);
-int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
- size_t, enum dma_data_direction);
-#else
-static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr,
- unsigned long offset, size_t size, enum dma_data_direction dir)
-{
- return 1;
-}
-static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
- unsigned long offset, size_t size, enum dma_data_direction dir)
-{
- return 1;
-}
-
-
-static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir)
-{
- __dma_page_cpu_to_dev(page, offset, size, dir);
- return pfn_to_dma(dev, page_to_pfn(page)) + offset;
-}
-
-static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
- handle & ~PAGE_MASK, size, dir);
-}
-#endif /* CONFIG_DMABOUNCE */
-
-/**
- * dma_map_single - map a single buffer for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @cpu_addr: CPU direct mapped address of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed. The CPU
- * can regain ownership by calling dma_unmap_single() or
- * dma_sync_single_for_cpu().
- */
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction dir)
-{
- unsigned long offset;
- struct page *page;
- dma_addr_t addr;
-
- BUG_ON(!virt_addr_valid(cpu_addr));
- BUG_ON(!virt_addr_valid(cpu_addr + size - 1));
- BUG_ON(!valid_dma_direction(dir));
-
- page = virt_to_page(cpu_addr);
- offset = (unsigned long)cpu_addr & ~PAGE_MASK;
- addr = __dma_map_page(dev, page, offset, size, dir);
- debug_dma_map_page(dev, page, offset, size, dir, addr, true);
-
- return addr;
-}
-
-/**
- * dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
- * Ensure that any data held in the cache is appropriately discarded
- * or written back.
- *
- * The device owns this memory once this call has completed. The CPU
- * can regain ownership by calling dma_unmap_page().
- */
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size, enum dma_data_direction dir)
-{
- dma_addr_t addr;
-
- BUG_ON(!valid_dma_direction(dir));
-
- addr = __dma_map_page(dev, page, offset, size, dir);
- debug_dma_map_page(dev, page, offset, size, dir, addr, false);
-
- return addr;
-}
-
-/**
- * dma_unmap_single - unmap a single buffer previously mapped
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer (same as passed to dma_map_single)
- * @dir: DMA transfer direction (same as passed to dma_map_single)
- *
- * Unmap a single streaming mode DMA translation. The handle and size
- * must match what was provided in the previous dma_map_single() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- debug_dma_unmap_page(dev, handle, size, dir, true);
- __dma_unmap_page(dev, handle, size, dir);
-}
-
-/**
- * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer (same as passed to dma_map_page)
- * @dir: DMA transfer direction (same as passed to dma_map_page)
- *
- * Unmap a page streaming mode DMA translation. The handle and size
- * must match what was provided in the previous dma_map_page() call.
- * All other usages are undefined.
- *
- * After this call, reads by the CPU to the buffer are guaranteed to see
- * whatever the device wrote there.
- */
-static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- debug_dma_unmap_page(dev, handle, size, dir, false);
- __dma_unmap_page(dev, handle, size, dir);
-}
-
-/**
- * dma_sync_single_range_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @offset: offset of region to start sync
- * @size: size of region to sync
- * @dir: DMA transfer direction (same as passed to dma_map_single)
- *
- * Make physical memory consistent for a single streaming mode DMA
- * translation after a transfer.
- *
- * If you perform a dma_map_single() but wish to interrogate the
- * buffer using the cpu, yet do not wish to teardown the PCI dma
- * mapping, you must call this function before doing so. At the
- * next point you give the PCI dma address back to the card, you
- * must first the perform a dma_sync_for_device, and then the
- * device again owns the buffer.
- */
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t handle, unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- BUG_ON(!valid_dma_direction(dir));
-
- debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
-
- if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
- return;
-
- __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
-}
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t handle, unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- BUG_ON(!valid_dma_direction(dir));
-
- debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
-
- if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
- return;
-
- __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
- dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
- dma_sync_single_range_for_device(dev, handle, 0, size, dir);
-}
/*
* The scatter list versions of the above methods.
*/
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-extern void dma_unmap_sg(struct device *, struct scatterlist *, int,
+extern int arm_dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction, struct dma_attrs *attrs);
+extern void arm_dma_unmap_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction, struct dma_attrs *attrs);
+extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
enum dma_data_direction);
-extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-
#endif /* __KERNEL__ */
#endif
diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h
index 33c78d7af2e1..4eea2107214b 100644
--- a/arch/arm/include/asm/hardware/pl080.h
+++ b/arch/arm/include/asm/hardware/pl080.h
@@ -102,6 +102,8 @@
#define PL080_WIDTH_16BIT (0x1)
#define PL080_WIDTH_32BIT (0x2)
+#define PL080N_CONFIG_ITPROT (1 << 20)
+#define PL080N_CONFIG_SECPROT (1 << 19)
#define PL080_CONFIG_HALT (1 << 18)
#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */
#define PL080_CONFIG_LOCK (1 << 16)
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index d7692cafde7f..0b1c94b8c652 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -43,6 +43,7 @@ struct machine_desc {
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
void (*init_machine)(void);
+ void (*init_late)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
void (*handle_irq)(struct pt_regs *);
#endif
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index b36f3654bf54..a6efcdd6fd25 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -30,6 +30,7 @@ struct map_desc {
#define MT_MEMORY_DTCM 12
#define MT_MEMORY_ITCM 13
#define MT_MEMORY_SO 14
+#define MT_MEMORY_DMA_READY 15
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ebfac782593f..e15d83bb4ea3 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -81,6 +81,7 @@ __setup("fpe=", fpe_setup);
extern void paging_init(struct machine_desc *desc);
extern void sanity_check_meminfo(void);
extern void reboot_setup(char *str);
+extern void setup_dma_zone(struct machine_desc *desc);
unsigned int processor_id;
EXPORT_SYMBOL(processor_id);
@@ -800,6 +801,14 @@ static int __init customize_machine(void)
}
arch_initcall(customize_machine);
+static int __init init_machine_late(void)
+{
+ if (machine_desc->init_late)
+ machine_desc->init_late();
+ return 0;
+}
+late_initcall(init_machine_late);
+
#ifdef CONFIG_KEXEC
static inline unsigned long long get_total_mem(void)
{
@@ -939,12 +948,8 @@ void __init setup_arch(char **cmdline_p)
machine_desc = mdesc;
machine_name = mdesc->name;
-#ifdef CONFIG_ZONE_DMA
- if (mdesc->dma_zone_size) {
- extern unsigned long arm_dma_zone_size;
- arm_dma_zone_size = mdesc->dma_zone_size;
- }
-#endif
+ setup_dma_zone(mdesc);
+
if (mdesc->restart_mode)
reboot_setup(&mdesc->restart_mode);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index f6747246d649..933fc9afe7d0 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)
atslave->dma_dev = &at_hdmac_device.dev;
atslave->cfg = ATC_FIFOCFG_HALFFIFO
| ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
- atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
if (mmc_id == 0) /* MCI0 */
atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
| 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 fff48d1a0f4e..cab0997be3de 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 {
/**
* struct at_dma_slave - Controller-specific information about a slave
* @dma_dev: required DMA master device
- * @tx_reg: physical address of data register used for
- * memory-to-peripheral transfers
- * @rx_reg: physical address of data register used for
- * peripheral-to-memory transfers
- * @reg_width: peripheral register width
* @cfg: Platform-specific initializer for the CFG register
- * @ctrla: Platform-specific initializer for the CTRLA register
*/
struct at_dma_slave {
struct device *dma_dev;
u32 cfg;
- u32 ctrla;
};
@@ -64,24 +57,5 @@ struct at_dma_slave {
#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)
#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28)
-/* Platform-configurable bits in CTRLA */
-#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */
-#define ATC_SCSIZE_1 (0x0 << 16)
-#define ATC_SCSIZE_4 (0x1 << 16)
-#define ATC_SCSIZE_8 (0x2 << 16)
-#define ATC_SCSIZE_16 (0x3 << 16)
-#define ATC_SCSIZE_32 (0x4 << 16)
-#define ATC_SCSIZE_64 (0x5 << 16)
-#define ATC_SCSIZE_128 (0x6 << 16)
-#define ATC_SCSIZE_256 (0x7 << 16)
-#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */
-#define ATC_DCSIZE_1 (0x0 << 20)
-#define ATC_DCSIZE_4 (0x1 << 20)
-#define ATC_DCSIZE_8 (0x2 << 20)
-#define ATC_DCSIZE_16 (0x3 << 20)
-#define ATC_DCSIZE_32 (0x4 << 20)
-#define ATC_DCSIZE_64 (0x5 << 20)
-#define ATC_DCSIZE_128 (0x6 << 20)
-#define ATC_DCSIZE_256 (0x7 << 20)
#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 dc1afe5be20c..0031864e7f11 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")
.init_irq = cp_intc_init,
.timer = &davinci_timer,
.init_machine = da830_evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index 09f61073c8d9..0149fb453be3 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")
.init_irq = cp_intc_init,
.timer = &davinci_timer,
.init_machine = da850_evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index 82ed753fb360..1c7b1f46a8f3 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = dm355_evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
index d74a8b3445fb..8e7703213b08 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = dm355_leopard_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 5bce2b83bb4f..688a9c556dc9 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = dm365_evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 3683306e0245..d34ed55912b2 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = davinci_evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index d72ab948d630..958679a20e13 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
@@ -798,6 +799,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = evm_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
index 672d820e2aa4..beecde3a1d2f 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")
.init_irq = cp_intc_init,
.timer = &davinci_timer,
.init_machine = mityomapl138_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
index a772bb45570a..5de69f2fcca9 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = davinci_ntosd2_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
index 45e815760a27..dc1208e9e664 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")
.init_irq = cp_intc_init,
.timer = &davinci_timer,
.init_machine = omapl138_hawk_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = da8xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
index 76e675096104..9078acf94bac 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")
.init_irq = davinci_irq_init,
.timer = &davinci_timer,
.init_machine = davinci_sffsdr_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = davinci_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
index 5f14e30b00d8..ac4e003ad863 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")
.init_irq = cp_intc_init,
.timer = &davinci_timer,
.init_machine = tnetv107x_evm_board_init,
+ .init_late = davinci_init_late,
.dma_zone_size = SZ_128M,
.restart = tnetv107x_restart,
MACHINE_END
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 008772e3b843..34668ead53c7 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -213,7 +213,7 @@ EXPORT_SYMBOL(clk_unregister);
/*
* Disable any unused clocks left on by the bootloader
*/
-static int __init clk_disable_unused(void)
+int __init davinci_clk_disable_unused(void)
{
struct clk *ck;
@@ -237,7 +237,6 @@ static int __init clk_disable_unused(void)
return 0;
}
-late_initcall(clk_disable_unused);
#endif
static 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 cb9b2e47510c..64b0f65a8639 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)
err:
panic("davinci_common_init: SoC Initialization failed\n");
}
+
+void __init davinci_init_late(void)
+{
+ davinci_cpufreq_init();
+ davinci_pm_init();
+ davinci_clk_disable_unused();
+}
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
index 031048fec9f5..4729eaab0f40 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 = {
.remove = __exit_p(davinci_cpufreq_remove),
};
-static int __init davinci_cpufreq_init(void)
+int __init davinci_cpufreq_init(void)
{
return platform_driver_probe(&davinci_cpufreq_driver,
davinci_cpufreq_probe);
}
-late_initcall(davinci_cpufreq_init);
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 95ce019c9b98..a685e9706b7b 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -353,9 +353,10 @@ static int irq2ctlr(int irq)
*****************************************************************************/
static irqreturn_t dma_irq_handler(int irq, void *data)
{
- int i;
int ctlr;
- unsigned int cnt = 0;
+ u32 sh_ier;
+ u32 sh_ipr;
+ u32 bank;
ctlr = irq2ctlr(irq);
if (ctlr < 0)
@@ -363,41 +364,39 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
dev_dbg(data, "dma_irq_handler\n");
- if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) &&
- (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
- return IRQ_NONE;
+ sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 0);
+ if (!sh_ipr) {
+ sh_ipr = edma_shadow0_read_array(ctlr, SH_IPR, 1);
+ if (!sh_ipr)
+ return IRQ_NONE;
+ sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 1);
+ bank = 1;
+ } else {
+ sh_ier = edma_shadow0_read_array(ctlr, SH_IER, 0);
+ bank = 0;
+ }
- while (1) {
- int j;
- if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
- edma_shadow0_read_array(ctlr, SH_IER, 0))
- j = 0;
- else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
- edma_shadow0_read_array(ctlr, SH_IER, 1))
- j = 1;
- else
- break;
- dev_dbg(data, "IPR%d %08x\n", j,
- edma_shadow0_read_array(ctlr, SH_IPR, j));
- for (i = 0; i < 32; i++) {
- int k = (j << 5) + i;
- if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
- && (edma_shadow0_read_array(ctlr,
- SH_IER, j) & BIT(i))) {
- /* Clear the corresponding IPR bits */
- edma_shadow0_write_array(ctlr, SH_ICR, j,
- BIT(i));
- if (edma_cc[ctlr]->intr_data[k].callback)
- edma_cc[ctlr]->intr_data[k].callback(
- k, DMA_COMPLETE,
- edma_cc[ctlr]->intr_data[k].
- data);
- }
+ do {
+ u32 slot;
+ u32 channel;
+
+ dev_dbg(data, "IPR%d %08x\n", bank, sh_ipr);
+
+ slot = __ffs(sh_ipr);
+ sh_ipr &= ~(BIT(slot));
+
+ if (sh_ier & BIT(slot)) {
+ channel = (bank << 5) | slot;
+ /* Clear the corresponding IPR bits */
+ edma_shadow0_write_array(ctlr, SH_ICR, bank,
+ BIT(slot));
+ if (edma_cc[ctlr]->intr_data[channel].callback)
+ edma_cc[ctlr]->intr_data[channel].callback(
+ channel, DMA_COMPLETE,
+ edma_cc[ctlr]->intr_data[channel].data);
}
- cnt++;
- if (cnt > 10)
- break;
- }
+ } while (sh_ipr);
+
edma_shadow0_write(ctlr, SH_IEVAL, 1);
return IRQ_HANDLED;
}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 5cd39a4e0c96..bdc4aa8e672a 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;
extern void davinci_common_init(struct davinci_soc_info *soc_info);
extern void davinci_init_ide(void);
void davinci_restart(char mode, const char *cmd);
+void davinci_init_late(void);
+
+#ifdef CONFIG_DAVINCI_RESET_CLOCKS
+int davinci_clk_disable_unused(void);
+#else
+static inline int davinci_clk_disable_unused(void) { return 0; }
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+int davinci_cpufreq_init(void);
+#else
+static inline int davinci_cpufreq_init(void) { return 0; }
+#endif
+
+#ifdef CONFIG_SUSPEND
+int davinci_pm_init(void);
+#else
+static inline int davinci_pm_init(void) { return 0; }
+#endif
/* standard place to map on-chip SRAMs; they *may* support DMA */
#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 cf94552d5274..34290d14754b 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 @@
#define UART_SHIFT 2
- .pushsection .data
-davinci_uart_phys: .word 0
-davinci_uart_virt: .word 0
- .popsection
-
- .macro addruart, rp, rv, tmp
-
- /* Use davinci_uart_phys/virt if already configured */
-10: adr \rp, 99f @ get effective addr of 99f
- ldr \rv, [\rp] @ get absolute addr of 99f
- sub \rv, \rv, \rp @ offset between the two
- ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys
- sub \tmp, \rp, \rv @ make it effective
- ldr \rp, [\tmp, #0] @ davinci_uart_phys
- ldr \rv, [\tmp, #4] @ davinci_uart_virt
- cmp \rp, #0 @ is port configured?
- cmpne \rv, #0
- bne 100f @ already configured
-
- /* Check the debug UART address set in uncompress.h */
- and \rp, pc, #0xff000000
- ldr \rv, =DAVINCI_UART_INFO_OFS
- add \rp, \rp, \rv
-
- /* Copy uart phys address from decompressor uart info */
- ldr \rv, [\rp, #0]
- str \rv, [\tmp, #0]
-
- /* Copy uart virt address from decompressor uart info */
- ldr \rv, [\rp, #4]
- str \rv, [\tmp, #4]
-
- b 10b
+#if defined(CONFIG_DEBUG_DAVINCI_DMx_UART0)
+#define UART_BASE DAVINCI_UART0_BASE
+#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART0)
+#define UART_BASE DA8XX_UART0_BASE
+#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART1)
+#define UART_BASE DA8XX_UART1_BASE
+#elif defined(CONFIG_DEBUG_DAVINCI_DA8XX_UART2)
+#define UART_BASE DA8XX_UART2_BASE
+#elif defined(CONFIG_DEBUG_DAVINCI_TNETV107X_UART1)
+#define UART_BASE TNETV107X_UART2_BASE
+#define UART_VIRTBASE TNETV107X_UART2_VIRT
+#else
+#error "Select a specifc port for DEBUG_LL"
+#endif
- .align
-99: .word .
- .word davinci_uart_phys
- .ltorg
+#ifndef UART_VIRTBASE
+#define UART_VIRTBASE IO_ADDRESS(UART_BASE)
+#endif
-100:
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =UART_BASE
+ ldr \rv, =UART_VIRTBASE
.endm
.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 2184691ebc2f..16bb42291d39 100644
--- a/arch/arm/mach-davinci/include/mach/hardware.h
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -22,7 +22,7 @@
/*
* I/O mapping
*/
-#define IO_PHYS 0x01c00000UL
+#define IO_PHYS UL(0x01c00000)
#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
#define IO_SIZE 0x00400000
#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 e347d88fef91..46b3cd11c3c2 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -15,16 +15,6 @@
#include <mach/hardware.h>
-/*
- * Stolen area that contains debug uart physical and virtual addresses. These
- * addresses are filled in by the uncompress.h code, and are used by the debug
- * macros in debug-macro.S.
- *
- * This area sits just below the page tables (see arch/arm/kernel/head.S).
- * We define it as a relative offset from start of usable RAM.
- */
-#define DAVINCI_UART_INFO_OFS 0x3ff8
-
#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#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 da2fb2c2155a..18cfd4977155 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)
barrier();
}
-static inline void set_uart_info(u32 phys, void * __iomem virt)
+static inline void set_uart_info(u32 phys)
{
- /*
- * Get address of some.bss variable and round it down
- * a la CONFIG_AUTO_ZRELADDR.
- */
- u32 ram_start = (u32)&uart & 0xf8000000;
- u32 *uart_info = (u32 *)(ram_start + DAVINCI_UART_INFO_OFS);
-
uart = (u32 *)phys;
- uart_info[0] = phys;
- uart_info[1] = (u32)virt;
}
-#define _DEBUG_LL_ENTRY(machine, phys, virt) \
- if (machine_is_##machine()) { \
- set_uart_info(phys, virt); \
- break; \
+#define _DEBUG_LL_ENTRY(machine, phys) \
+ { \
+ if (machine_is_##machine()) { \
+ set_uart_info(phys); \
+ break; \
+ } \
}
#define DEBUG_LL_DAVINCI(machine, port) \
- _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \
- IO_ADDRESS(DAVINCI_UART##port##_BASE))
+ _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE)
#define DEBUG_LL_DA8XX(machine, port) \
- _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \
- IO_ADDRESS(DA8XX_UART##port##_BASE))
+ _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE)
#define DEBUG_LL_TNETV107X(machine, port) \
- _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \
- TNETV107X_UART##port##_VIRT)
+ _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE)
static inline void __arch_decomp_setup(unsigned long arch_id)
{
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
index 04c49f7543ef..eb8360b33aa9 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 = {
.remove = __exit_p(davinci_pm_remove),
};
-static int __init davinci_pm_init(void)
+int __init davinci_pm_init(void)
{
return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
}
-late_initcall(davinci_pm_init);
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 42ab1e7c4ecc..9493076fc594 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
#include <linux/ata_platform.h>
#include <linux/gpio.h>
#include <asm/page.h>
@@ -68,6 +68,19 @@ void __init dove_map_io(void)
}
/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static struct clk *tclk;
+
+static void __init clk_init(void)
+{
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ get_tclk());
+
+ orion_clkdev_init(tclk);
+}
+
+/*****************************************************************************
* EHCI0
****************************************************************************/
void __init dove_ehci0_init(void)
@@ -89,8 +102,7 @@ void __init dove_ehci1_init(void)
void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge00_init(eth_data,
- DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
- 0, get_tclk());
+ DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0);
}
/*****************************************************************************
@@ -116,7 +128,7 @@ void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
void __init dove_uart0_init(void)
{
orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE,
- IRQ_DOVE_UART_0, get_tclk());
+ IRQ_DOVE_UART_0, tclk);
}
/*****************************************************************************
@@ -125,7 +137,7 @@ void __init dove_uart0_init(void)
void __init dove_uart1_init(void)
{
orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
- IRQ_DOVE_UART_1, get_tclk());
+ IRQ_DOVE_UART_1, tclk);
}
/*****************************************************************************
@@ -134,7 +146,7 @@ void __init dove_uart1_init(void)
void __init dove_uart2_init(void)
{
orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
- IRQ_DOVE_UART_2, get_tclk());
+ IRQ_DOVE_UART_2, tclk);
}
/*****************************************************************************
@@ -143,7 +155,7 @@ void __init dove_uart2_init(void)
void __init dove_uart3_init(void)
{
orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
- IRQ_DOVE_UART_3, get_tclk());
+ IRQ_DOVE_UART_3, tclk);
}
/*****************************************************************************
@@ -151,12 +163,12 @@ void __init dove_uart3_init(void)
****************************************************************************/
void __init dove_spi0_init(void)
{
- orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk());
+ orion_spi_init(DOVE_SPI0_PHYS_BASE);
}
void __init dove_spi1_init(void)
{
- orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk());
+ orion_spi_1_init(DOVE_SPI1_PHYS_BASE);
}
/*****************************************************************************
@@ -272,18 +284,17 @@ void __init dove_sdio1_init(void)
void __init dove_init(void)
{
- int tclk;
-
- tclk = get_tclk();
-
printk(KERN_INFO "Dove 88AP510 SoC, ");
- printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+ printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
#ifdef CONFIG_CACHE_TAUROS2
tauros2_init();
#endif
dove_setup_cpu_mbus();
+ /* Setup root of clk tree */
+ clk_init();
+
/* internal devices that every board has */
dove_rtc_init();
dove_xor0_init();
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
index ea77ae430b2d..bc2867f11346 100644
--- a/arch/arm/mach-dove/dove-db-setup.c
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -20,7 +20,6 @@
#include <linux/i2c.h>
#include <linux/pci.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h>
#include <linux/gpio.h>
#include <asm/mach-types.h>
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 2d45947a3034..a472777e9eba 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = adssphere_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 66b1494f23a6..4dd07a0e3604 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)
fail_gpio_d:
gpio_free(EP93XX_GPIO_LINE_C(i));
fail_gpio_c:
- for ( ; i >= 0; --i) {
+ for (--i; i >= 0; --i) {
gpio_free(EP93XX_GPIO_LINE_C(i));
gpio_free(EP93XX_GPIO_LINE_D(i));
}
@@ -834,3 +834,8 @@ void ep93xx_restart(char mode, const char *cmd)
while (1)
;
}
+
+void __init ep93xx_init_late(void)
+{
+ crunch_init();
+}
diff --git a/arch/arm/mach-ep93xx/crunch.c b/arch/arm/mach-ep93xx/crunch.c
index 74753e2df603..a4a2ab9648c9 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 = {
.notifier_call = crunch_do,
};
-static int __init crunch_init(void)
+int __init crunch_init(void)
{
thread_register_notifier(&crunch_notifier_block);
elf_hwcap |= HWCAP_CRUNCH;
return 0;
}
-
-late_initcall(crunch_init);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index da9047d726f0..d74c5cddb98b 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -268,6 +269,7 @@ MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -281,6 +283,7 @@ MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -294,6 +297,7 @@ MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -307,6 +311,7 @@ MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -320,6 +325,7 @@ MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -333,6 +339,7 @@ MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -346,6 +353,7 @@ MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = edb93xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index fcdffbe49dcc..437c34111155 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = gesbc9312_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 602bd87fd0ab..1ecb040d98bf 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);
extern struct sys_timer ep93xx_timer;
void ep93xx_restart(char, const char *);
+void ep93xx_init_late(void);
+
+#ifdef CONFIG_CRUNCH
+int crunch_init(void);
+#else
+static inline int crunch_init(void) { return 0; }
+#endif
#endif
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index dc431c5f04ce..3d7cdab725b2 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -98,6 +99,7 @@ MACHINE_START(MICRO9M, "Contec Micro9-Mid")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -111,6 +113,7 @@ MACHINE_START(MICRO9L, "Contec Micro9-Lite")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
@@ -124,6 +127,7 @@ MACHINE_START(MICRO9S, "Contec Micro9-Slim")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
#endif
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index f40c2987e545..33dc07917417 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = simone_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index 0c00852ef160..eb282378fa78 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = snappercl15_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index 5ea790942e94..d4ef339d961e 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = ts72xx_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index ba156eb225e8..2905a4929bdc 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")
.handle_irq = vic_handle_irq,
.timer = &ep93xx_timer,
.init_machine = vision_init_machine,
+ .init_late = ep93xx_init_late,
.restart = ep93xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 15b05b89cc39..43ebe9094411 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -61,6 +61,7 @@ config SOC_EXYNOS5250
bool "SAMSUNG EXYNOS5250"
default y
depends on ARCH_EXYNOS5
+ select SAMSUNG_DMADEV
help
Enable EXYNOS5250 SoC support
@@ -70,7 +71,7 @@ config EXYNOS4_MCT
help
Use MCT (Multi Core Timer) as kernel timers
-config EXYNOS4_DEV_DMA
+config EXYNOS_DEV_DMA
bool
help
Compile in amba device definitions for DMA controller
@@ -80,15 +81,20 @@ config EXYNOS4_DEV_AHCI
help
Compile in platform device definitions for AHCI
+config EXYNOS_DEV_DRM
+ bool
+ help
+ Compile in platform device definitions for core DRM device
+
config EXYNOS4_SETUP_FIMD0
bool
help
Common setup code for FIMD0.
-config EXYNOS4_DEV_SYSMMU
+config EXYNOS_DEV_SYSMMU
bool
help
- Common setup code for SYSTEM MMU in EXYNOS4
+ Common setup code for SYSTEM MMU in EXYNOS platforms
config EXYNOS4_DEV_DWMCI
bool
@@ -161,7 +167,7 @@ config EXYNOS4_SETUP_USB_PHY
help
Common setup code for USB PHY controller
-config EXYNOS4_SETUP_SPI
+config EXYNOS_SETUP_SPI
bool
help
Common setup code for SPI GPIO configurations.
@@ -201,12 +207,12 @@ config MACH_SMDKV310
select S3C_DEV_HSMMC3
select SAMSUNG_DEV_BACKLIGHT
select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
select EXYNOS4_DEV_AHCI
select SAMSUNG_DEV_KEYPAD
select EXYNOS4_DEV_DMA
select SAMSUNG_DEV_PWM
select EXYNOS4_DEV_USB_OHCI
- select EXYNOS4_DEV_SYSMMU
select EXYNOS4_SETUP_FIMD0
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_KEYPAD
@@ -224,8 +230,7 @@ config MACH_ARMLEX4210
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select EXYNOS4_DEV_AHCI
- select EXYNOS4_DEV_DMA
- select EXYNOS4_DEV_SYSMMU
+ select EXYNOS_DEV_DMA
select EXYNOS4_SETUP_SDHCI
help
Machine support for Samsung ARMLEX4210 based on EXYNOS4210
@@ -256,6 +261,7 @@ config MACH_UNIVERSAL_C210
select S5P_DEV_MFC
select S5P_DEV_ONENAND
select S5P_DEV_TV
+ select EXYNOS_DEV_SYSMMU
select EXYNOS4_DEV_DMA
select EXYNOS_DEV_DRM
select EXYNOS4_SETUP_FIMD0
@@ -332,6 +338,7 @@ config MACH_ORIGEN
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select EXYNOS_DEV_DRM
+ select EXYNOS_DEV_SYSMMU
select EXYNOS4_DEV_DMA
select EXYNOS4_DEV_USB_OHCI
select EXYNOS4_SETUP_FIMD0
@@ -360,7 +367,8 @@ config MACH_SMDK4212
select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
- select EXYNOS4_DEV_DMA
+ select EXYNOS_DEV_SYSMMU
+ select EXYNOS_DEV_DMA
select EXYNOS4_SETUP_I2C1
select EXYNOS4_SETUP_I2C3
select EXYNOS4_SETUP_I2C7
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 8631840d1b5e..440a637c76f1 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
obj-y += dev-uart.o
obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
-obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
+obj-$(CONFIG_EXYNOS_DEV_DMA) += dma.o
obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
+obj-$(CONFIG_EXYNOS_DEV_DRM) += dev-drm.o
+obj-$(CONFIG_EXYNOS_DEV_SYSMMU) += dev-sysmmu.o
obj-$(CONFIG_ARCH_EXYNOS) += setup-i2c0.o
obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
@@ -68,4 +69,4 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
-obj-$(CONFIG_EXYNOS4_SETUP_SPI) += setup-spi.o
+obj-$(CONFIG_EXYNOS_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
index b9862e22bf10..31bd181b0514 100644
--- a/arch/arm/mach-exynos/Makefile.boot
+++ b/arch/arm/mach-exynos/Makefile.boot
@@ -1,2 +1,5 @@
zreladdr-y += 0x40008000
params_phys-y := 0x40000100
+
+dtb-$(CONFIG_MACH_EXYNOS4_DT) += exynos4210-origen.dtb exynos4210-smdkv310.dtb
+dtb-$(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 6efd1e5919fd..bcb7db453145 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)
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
}
-static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
+int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
}
@@ -198,6 +198,11 @@ static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
}
+int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
+}
+
static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
@@ -678,61 +683,55 @@ static struct clk exynos4_init_clocks_off[] = {
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit = (1 << 14),
}, {
- .name = "SYSMMU_MDMA",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
.enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 5),
+ .ctrlbit = (1 << 4),
}, {
- .name = "SYSMMU_FIMC0",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5),
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 7),
}, {
- .name = "SYSMMU_FIMC1",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6),
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 8),
}, {
- .name = "SYSMMU_FIMC2",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7),
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 9),
}, {
- .name = "SYSMMU_FIMC3",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8),
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 10),
}, {
- .name = "SYSMMU_JPEG",
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = "SYSMMU_FIMD0",
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10),
.enable = exynos4_clk_ip_lcd0_ctrl,
.ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_FIMD1",
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_PCIe",
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 18),
- }, {
- .name = "SYSMMU_G2D",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "SYSMMU_ROTATOR",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_TV",
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_MFC_L",
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "SYSMMU_MFC_R",
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 2),
}
};
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
index cb71c29c14d1..28a119701182 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[];
extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index 3b131e4b6ef5..b8689ff60baf 100644
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -26,6 +26,7 @@
#include <mach/hardware.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
#include "common.h"
#include "clock-exynos4.h"
@@ -94,6 +95,16 @@ static struct clk init_clocks_off[] = {
.devname = "exynos4-fb.1",
.enable = exynos4_clk_ip_lcd1_ctrl,
.ctrlbit = (1 << 0),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11),
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 4),
},
};
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index 3ecc01e06f74..da397d21bbcf 100644
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -26,6 +26,7 @@
#include <mach/hardware.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/sysmmu.h>
#include "common.h"
#include "clock-exynos4.h"
@@ -39,6 +40,16 @@ static struct sleep_save exynos4212_clock_save[] = {
};
#endif
+static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
+}
+
+static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
+}
+
static struct clk *clk_src_mpll_user_list[] = {
[0] = &clk_fin_mpll,
[1] = &exynos4_clk_mout_mpll.clk,
@@ -66,7 +77,32 @@ static struct clksrc_clk clksrcs[] = {
};
static struct clk init_clocks_off[] = {
- /* nothing here yet */
+ {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (7 << 8),
+ }, {
+ .name = SYSMMU_CLOCK_NAME2,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "flite",
+ .devname = "exynos-fimc-lite.0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "flite",
+ .devname = "exynos-fimc-lite.1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 3),
+ }
};
#ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 7ac6ff4c46bd..5aa460b01fdf 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)
return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
}
+static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
+}
+
static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
{
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)
return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
}
+static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
+}
+
+static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable);
+}
+
+static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
+}
+
/* Core list of CMU_CPU side */
static struct clksrc_clk exynos5_clk_mout_apll = {
@@ -145,11 +165,29 @@ static struct clksrc_clk exynos5_clk_sclk_apll = {
.reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
};
+static struct clksrc_clk exynos5_clk_mout_bpll_fout = {
+ .clk = {
+ .name = "mout_bpll_fout",
+ },
+ .sources = &clk_src_bpll_fout,
+ .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos5_clk_src_bpll_list[] = {
+ [0] = &clk_fin_bpll,
+ [1] = &exynos5_clk_mout_bpll_fout.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_bpll = {
+ .sources = exynos5_clk_src_bpll_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_list),
+};
+
static struct clksrc_clk exynos5_clk_mout_bpll = {
.clk = {
.name = "mout_bpll",
},
- .sources = &clk_src_bpll,
+ .sources = &exynos5_clk_src_bpll,
.reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
};
@@ -187,11 +225,29 @@ static struct clksrc_clk exynos5_clk_mout_epll = {
.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
};
+static struct clksrc_clk exynos5_clk_mout_mpll_fout = {
+ .clk = {
+ .name = "mout_mpll_fout",
+ },
+ .sources = &clk_src_mpll_fout,
+ .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos5_clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos5_clk_mout_mpll_fout.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_mpll = {
+ .sources = exynos5_clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_list),
+};
+
struct clksrc_clk exynos5_clk_mout_mpll = {
.clk = {
.name = "mout_mpll",
},
- .sources = &clk_src_mpll,
+ .sources = &exynos5_clk_src_mpll,
.reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
};
@@ -454,6 +510,11 @@ static struct clk exynos5_init_clocks_off[] = {
.enable = exynos5_clk_ip_peris_ctrl,
.ctrlbit = (1 << 20),
}, {
+ .name = "watchdog",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peris_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
.name = "hsmmc",
.devname = "exynos4-sdhci.0",
.parent = &exynos5_clk_aclk_200.clk,
@@ -630,6 +691,76 @@ static struct clk exynos5_init_clocks_off[] = {
.parent = &exynos5_clk_aclk_66.clk,
.enable = exynos5_clk_ip_peric_ctrl,
.ctrlbit = (1 << 14),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
+ .enable = &exynos5_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1),
+ .enable = &exynos5_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
+ .enable = &exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 9)
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
+ .enable = &exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
+ .enable = &exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = (1 << 6)
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = &exynos5_clk_ip_isp0_ctrl,
+ .ctrlbit = (0x3F << 8),
+ }, {
+ .name = SYSMMU_CLOCK_NAME2,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = &exynos5_clk_ip_isp1_ctrl,
+ .ctrlbit = (0xF << 4),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(2d, 14),
+ .enable = &exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = (1 << 7)
}
};
@@ -941,10 +1072,12 @@ static struct clksrc_clk *exynos5_sysclks[] = {
&exynos5_clk_mout_apll,
&exynos5_clk_sclk_apll,
&exynos5_clk_mout_bpll,
+ &exynos5_clk_mout_bpll_fout,
&exynos5_clk_mout_bpll_user,
&exynos5_clk_mout_cpll,
&exynos5_clk_mout_epll,
&exynos5_clk_mout_mpll,
+ &exynos5_clk_mout_mpll_fout,
&exynos5_clk_mout_mpll_user,
&exynos5_clk_vpllsrc,
&exynos5_clk_sclk_vpll,
@@ -1008,7 +1141,9 @@ static struct clk *exynos5_clks[] __initdata = {
&exynos5_clk_sclk_hdmi27m,
&exynos5_clk_sclk_hdmiphy,
&clk_fout_bpll,
+ &clk_fout_bpll_div2,
&clk_fout_cpll,
+ &clk_fout_mpll_div2,
&exynos5_clk_armclk,
};
@@ -1173,8 +1308,10 @@ void __init_or_cpufreq exynos5_setup_clocks(void)
clk_fout_apll.ops = &exynos5_fout_apll_ops;
clk_fout_bpll.rate = bpll;
+ clk_fout_bpll_div2.rate = bpll >> 1;
clk_fout_cpll.rate = cpll;
clk_fout_mpll.rate = mpll;
+ clk_fout_mpll_div2.rate = mpll >> 1;
clk_fout_epll.rate = epll;
clk_fout_vpll.rate = vpll;
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 5ccd6e80a607..742edd3bbec3 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -19,6 +19,9 @@
#include <linux/serial_core.h>
#include <linux/of.h>
#include <linux/of_irq.h>
+#include <linux/export.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
#include <asm/proc-fns.h>
#include <asm/exception.h>
@@ -265,12 +268,12 @@ static struct map_desc exynos5_iodesc[] __initdata = {
}, {
.virtual = (unsigned long)S5P_VA_GIC_CPU,
.pfn = __phys_to_pfn(EXYNOS5_PA_GIC_CPU),
- .length = SZ_64K,
+ .length = SZ_8K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GIC_DIST,
.pfn = __phys_to_pfn(EXYNOS5_PA_GIC_DIST),
- .length = SZ_64K,
+ .length = SZ_4K,
.type = MT_DEVICE,
},
};
@@ -285,6 +288,11 @@ void exynos5_restart(char mode, const char *cmd)
__raw_writel(0x1, EXYNOS_SWRESET);
}
+void __init exynos_init_late(void)
+{
+ exynos_pm_late_initcall();
+}
+
/*
* exynos_map_io
*
@@ -399,6 +407,7 @@ struct combiner_chip_data {
void __iomem *base;
};
+static struct irq_domain *combiner_irq_domain;
static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
static inline void __iomem *combiner_base(struct irq_data *data)
@@ -411,14 +420,14 @@ static inline void __iomem *combiner_base(struct irq_data *data)
static void combiner_mask_irq(struct irq_data *data)
{
- u32 mask = 1 << (data->irq % 32);
+ u32 mask = 1 << (data->hwirq % 32);
__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
}
static void combiner_unmask_irq(struct irq_data *data)
{
- u32 mask = 1 << (data->irq % 32);
+ u32 mask = 1 << (data->hwirq % 32);
__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
}
@@ -474,49 +483,131 @@ static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int i
irq_set_chained_handler(irq, combiner_handle_cascade_irq);
}
-static void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
- unsigned int irq_start)
+static void __init combiner_init_one(unsigned int combiner_nr,
+ void __iomem *base)
{
- unsigned int i;
- unsigned int max_nr;
-
- if (soc_is_exynos5250())
- max_nr = EXYNOS5_MAX_COMBINER_NR;
- else
- max_nr = EXYNOS4_MAX_COMBINER_NR;
-
- if (combiner_nr >= max_nr)
- BUG();
-
combiner_data[combiner_nr].base = base;
- combiner_data[combiner_nr].irq_offset = irq_start;
+ combiner_data[combiner_nr].irq_offset = irq_find_mapping(
+ combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
/* Disable all interrupts */
-
__raw_writel(combiner_data[combiner_nr].irq_mask,
base + COMBINER_ENABLE_CLEAR);
+}
+
+#ifdef CONFIG_OF
+static int combiner_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *controller,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ if (d->of_node != controller)
+ return -EINVAL;
+
+ if (intsize < 2)
+ return -EINVAL;
+
+ *out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1];
+ *out_type = 0;
+
+ return 0;
+}
+#else
+static int combiner_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *controller,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ return -EINVAL;
+}
+#endif
+
+static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
+ irq_set_chip_data(irq, &combiner_data[hw >> 3]);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops combiner_irq_domain_ops = {
+ .xlate = combiner_irq_domain_xlate,
+ .map = combiner_irq_domain_map,
+};
+
+void __init combiner_init(void __iomem *combiner_base, struct device_node *np)
+{
+ int i, irq, irq_base;
+ unsigned int max_nr, nr_irq;
+
+ if (np) {
+ if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
+ pr_warning("%s: number of combiners not specified, "
+ "setting default as %d.\n",
+ __func__, EXYNOS4_MAX_COMBINER_NR);
+ max_nr = EXYNOS4_MAX_COMBINER_NR;
+ }
+ } else {
+ max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
+ EXYNOS4_MAX_COMBINER_NR;
+ }
+ nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
- /* Setup the Linux IRQ subsystem */
+ irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
+ if (IS_ERR_VALUE(irq_base)) {
+ irq_base = COMBINER_IRQ(0, 0);
+ pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
+ }
- for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
- + MAX_IRQ_IN_COMBINER; i++) {
- irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq);
- irq_set_chip_data(i, &combiner_data[combiner_nr]);
- set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
+ &combiner_irq_domain_ops, &combiner_data);
+ if (WARN_ON(!combiner_irq_domain)) {
+ pr_warning("%s: irq domain init failed\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < max_nr; i++) {
+ combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
+ irq = IRQ_SPI(i);
+#ifdef CONFIG_OF
+ if (np)
+ irq = irq_of_parse_and_map(np, i);
+#endif
+ combiner_cascade_irq(i, irq);
}
}
#ifdef CONFIG_OF
+int __init combiner_of_init(struct device_node *np, struct device_node *parent)
+{
+ void __iomem *combiner_base;
+
+ combiner_base = of_iomap(np, 0);
+ if (!combiner_base) {
+ pr_err("%s: failed to map combiner registers\n", __func__);
+ return -ENXIO;
+ }
+
+ combiner_init(combiner_base, np);
+
+ return 0;
+}
+
static const struct of_device_id exynos4_dt_irq_match[] = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+ { .compatible = "samsung,exynos4210-combiner",
+ .data = combiner_of_init, },
{},
};
#endif
void __init exynos4_init_irq(void)
{
- int irq;
unsigned int gic_bank_offset;
gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
@@ -528,12 +619,8 @@ void __init exynos4_init_irq(void)
of_irq_init(exynos4_dt_irq_match);
#endif
- for (irq = 0; irq < EXYNOS4_MAX_COMBINER_NR; irq++) {
-
- combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
- COMBINER_IRQ(irq, 0));
- combiner_cascade_irq(irq, IRQ_SPI(irq));
- }
+ if (!of_have_populated_dt())
+ combiner_init(S5P_VA_COMBINER_BASE, NULL);
/*
* The parameters of s5p_init_irq() are for VIC init.
@@ -545,18 +632,9 @@ void __init exynos4_init_irq(void)
void __init exynos5_init_irq(void)
{
- int irq;
-
#ifdef CONFIG_OF
of_irq_init(exynos4_dt_irq_match);
#endif
-
- for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) {
- combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
- COMBINER_IRQ(irq, 0));
- combiner_cascade_irq(irq, IRQ_SPI(irq));
- }
-
/*
* The parameters of s5p_init_irq() are for VIC init.
* Theses parameters should be NULL and 0 because EXYNOS4
@@ -565,30 +643,18 @@ void __init exynos5_init_irq(void)
s5p_init_irq(NULL, 0);
}
-struct bus_type exynos4_subsys = {
- .name = "exynos4-core",
- .dev_name = "exynos4-core",
-};
-
-struct bus_type exynos5_subsys = {
- .name = "exynos5-core",
- .dev_name = "exynos5-core",
+struct bus_type exynos_subsys = {
+ .name = "exynos-core",
+ .dev_name = "exynos-core",
};
static struct device exynos4_dev = {
- .bus = &exynos4_subsys,
-};
-
-static struct device exynos5_dev = {
- .bus = &exynos5_subsys,
+ .bus = &exynos_subsys,
};
static int __init exynos_core_init(void)
{
- if (soc_is_exynos5250())
- return subsys_system_register(&exynos5_subsys, NULL);
- else
- return subsys_system_register(&exynos4_subsys, NULL);
+ return subsys_system_register(&exynos_subsys, NULL);
}
core_initcall(exynos_core_init);
@@ -675,10 +741,7 @@ static int __init exynos_init(void)
{
printk(KERN_INFO "EXYNOS: Initializing architecture\n");
- if (soc_is_exynos5250())
- return device_register(&exynos5_dev);
- else
- return device_register(&exynos4_dev);
+ return device_register(&exynos4_dev);
}
/* uart registration process */
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 677b5467df18..aed2eeb06517 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -19,6 +19,13 @@ void exynos4_init_irq(void);
void exynos5_init_irq(void);
void exynos4_restart(char mode, const char *cmd);
void exynos5_restart(char mode, const char *cmd);
+void exynos_init_late(void);
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS
+int exynos_pm_late_initcall(void);
+#else
+static int exynos_pm_late_initcall(void) { return 0; }
+#endif
#ifdef CONFIG_ARCH_EXYNOS4
void 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 000000000000..17c9c6ecc2e0
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-drm.c
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/arm/mach-exynos/dev-drm.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - core DRM device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+
+static u64 exynos_drm_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_drm = {
+ .name = "exynos-drm",
+ .dev = {
+ .dma_mask = &exynos_drm_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
index 781563fcb156..c5b1ea301df0 100644
--- a/arch/arm/mach-exynos/dev-sysmmu.c
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-exynos4/dev-sysmmu.c
+/* linux/arch/arm/mach-exynos/dev-sysmmu.c
*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * EXYNOS4 - System MMU support
+ * EXYNOS - System MMU support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,222 +12,263 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/export.h>
+
+#include <plat/cpu.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <mach/sysmmu.h>
-#include <plat/s5p-clock.h>
-
-/* These names must be equal to the clock names in mach-exynos4/clock.c */
-const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
- "SYSMMU_MDMA" ,
- "SYSMMU_SSS" ,
- "SYSMMU_FIMC0" ,
- "SYSMMU_FIMC1" ,
- "SYSMMU_FIMC2" ,
- "SYSMMU_FIMC3" ,
- "SYSMMU_JPEG" ,
- "SYSMMU_FIMD0" ,
- "SYSMMU_FIMD1" ,
- "SYSMMU_PCIe" ,
- "SYSMMU_G2D" ,
- "SYSMMU_ROTATOR",
- "SYSMMU_MDMA2" ,
- "SYSMMU_TV" ,
- "SYSMMU_MFC_L" ,
- "SYSMMU_MFC_R" ,
-};
-static struct resource exynos4_sysmmu_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_SYSMMU_MDMA,
- .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_SYSMMU_MDMA0_0,
- .end = IRQ_SYSMMU_MDMA0_0,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = EXYNOS4_PA_SYSMMU_SSS,
- .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [3] = {
- .start = IRQ_SYSMMU_SSS_0,
- .end = IRQ_SYSMMU_SSS_0,
- .flags = IORESOURCE_IRQ,
- },
- [4] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC0,
- .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [5] = {
- .start = IRQ_SYSMMU_FIMC0_0,
- .end = IRQ_SYSMMU_FIMC0_0,
- .flags = IORESOURCE_IRQ,
- },
- [6] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC1,
- .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [7] = {
- .start = IRQ_SYSMMU_FIMC1_0,
- .end = IRQ_SYSMMU_FIMC1_0,
- .flags = IORESOURCE_IRQ,
- },
- [8] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC2,
- .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [9] = {
- .start = IRQ_SYSMMU_FIMC2_0,
- .end = IRQ_SYSMMU_FIMC2_0,
- .flags = IORESOURCE_IRQ,
- },
- [10] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC3,
- .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [11] = {
- .start = IRQ_SYSMMU_FIMC3_0,
- .end = IRQ_SYSMMU_FIMC3_0,
- .flags = IORESOURCE_IRQ,
- },
- [12] = {
- .start = EXYNOS4_PA_SYSMMU_JPEG,
- .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [13] = {
- .start = IRQ_SYSMMU_JPEG_0,
- .end = IRQ_SYSMMU_JPEG_0,
- .flags = IORESOURCE_IRQ,
- },
- [14] = {
- .start = EXYNOS4_PA_SYSMMU_FIMD0,
- .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [15] = {
- .start = IRQ_SYSMMU_LCD0_M0_0,
- .end = IRQ_SYSMMU_LCD0_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [16] = {
- .start = EXYNOS4_PA_SYSMMU_FIMD1,
- .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [17] = {
- .start = IRQ_SYSMMU_LCD1_M1_0,
- .end = IRQ_SYSMMU_LCD1_M1_0,
- .flags = IORESOURCE_IRQ,
- },
- [18] = {
- .start = EXYNOS4_PA_SYSMMU_PCIe,
- .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [19] = {
- .start = IRQ_SYSMMU_PCIE_0,
- .end = IRQ_SYSMMU_PCIE_0,
- .flags = IORESOURCE_IRQ,
- },
- [20] = {
- .start = EXYNOS4_PA_SYSMMU_G2D,
- .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [21] = {
- .start = IRQ_SYSMMU_2D_0,
- .end = IRQ_SYSMMU_2D_0,
- .flags = IORESOURCE_IRQ,
- },
- [22] = {
- .start = EXYNOS4_PA_SYSMMU_ROTATOR,
- .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [23] = {
- .start = IRQ_SYSMMU_ROTATOR_0,
- .end = IRQ_SYSMMU_ROTATOR_0,
- .flags = IORESOURCE_IRQ,
- },
- [24] = {
- .start = EXYNOS4_PA_SYSMMU_MDMA2,
- .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [25] = {
- .start = IRQ_SYSMMU_MDMA1_0,
- .end = IRQ_SYSMMU_MDMA1_0,
- .flags = IORESOURCE_IRQ,
- },
- [26] = {
- .start = EXYNOS4_PA_SYSMMU_TV,
- .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [27] = {
- .start = IRQ_SYSMMU_TV_M0_0,
- .end = IRQ_SYSMMU_TV_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [28] = {
- .start = EXYNOS4_PA_SYSMMU_MFC_L,
- .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [29] = {
- .start = IRQ_SYSMMU_MFC_M0_0,
- .end = IRQ_SYSMMU_MFC_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [30] = {
- .start = EXYNOS4_PA_SYSMMU_MFC_R,
- .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [31] = {
- .start = IRQ_SYSMMU_MFC_M1_0,
- .end = IRQ_SYSMMU_MFC_M1_0,
- .flags = IORESOURCE_IRQ,
- },
-};
+static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
+
+#define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
+static struct sysmmu_platform_data platdata_##ipname = { \
+ .dbgname = #ipname, \
+}; \
+struct platform_device SYSMMU_PLATDEV(ipname) = \
+{ \
+ .name = SYSMMU_DEVNAME_BASE, \
+ .id = devid, \
+ .dev = { \
+ .dma_mask = &exynos_sysmmu_dma_mask, \
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
+ .platform_data = &platdata_##ipname, \
+ }, \
+}
+
+SYSMMU_PLATFORM_DEVICE(mfc_l, 0);
+SYSMMU_PLATFORM_DEVICE(mfc_r, 1);
+SYSMMU_PLATFORM_DEVICE(tv, 2);
+SYSMMU_PLATFORM_DEVICE(jpeg, 3);
+SYSMMU_PLATFORM_DEVICE(rot, 4);
+SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */
+SYSMMU_PLATFORM_DEVICE(fimc1, 6);
+SYSMMU_PLATFORM_DEVICE(fimc2, 7);
+SYSMMU_PLATFORM_DEVICE(fimc3, 8);
+SYSMMU_PLATFORM_DEVICE(gsc0, 5);
+SYSMMU_PLATFORM_DEVICE(gsc1, 6);
+SYSMMU_PLATFORM_DEVICE(gsc2, 7);
+SYSMMU_PLATFORM_DEVICE(gsc3, 8);
+SYSMMU_PLATFORM_DEVICE(isp, 9);
+SYSMMU_PLATFORM_DEVICE(fimd0, 10);
+SYSMMU_PLATFORM_DEVICE(fimd1, 11);
+SYSMMU_PLATFORM_DEVICE(camif0, 12);
+SYSMMU_PLATFORM_DEVICE(camif1, 13);
+SYSMMU_PLATFORM_DEVICE(2d, 14);
+
+#define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
+
+#define SYSMMU_RESOURCE(core, ipname) \
+ static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
+
+#define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
+ DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \
+ DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem)
+
+#define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
+ SYSMMU_RESOURCE(core, ipname) { \
+ DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
+ }
-struct platform_device exynos4_device_sysmmu = {
- .name = "s5p-sysmmu",
- .id = 32,
- .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource),
- .resource = exynos4_sysmmu_resource,
+struct sysmmu_resource_map {
+ struct platform_device *pdev;
+ struct resource *res;
+ u32 rnum;
+ struct device *pdd;
+ char *clocknames;
};
-EXPORT_SYMBOL(exynos4_device_sysmmu);
-static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
-{
- sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
- if (IS_ERR(sysmmu_clk[ips]))
- sysmmu_clk[ips] = NULL;
- else
- clk_put(sysmmu_clk[ips]);
+#define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME, \
}
-void sysmmu_clk_enable(sysmmu_ips ips)
-{
- if (sysmmu_clk[ips])
- clk_enable(sysmmu_clk[ips]);
+#define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
+}
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME, \
+ .pdd = &exynos##core##_device_pd[pd].dev, \
+}
+
+#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
+ .pdd = &exynos##core##_device_pd[pd].dev, \
}
+#else
+#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \
+ SYSMMU_RESOURCE_MAPPING(core, ipname, resname)
+#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \
+ SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata)
+
+#endif /* CONFIG_EXYNOS_DEV_PD */
+
+#ifdef CONFIG_ARCH_EXYNOS4
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, 2D_ACP, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r, MFC_R, MFC_M0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l, MFC_L, MFC_M1);
+SYSMMU_RESOURCE(EXYNOS4, isp) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_ISP, FIMC_ISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_DRC, FIMC_DRC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_FD, FIMC_FD),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV),
+ SYSMMU_RESOURCE_MAPPING_PD(4, mfc_r, mfc_r, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_PD(4, mfc_l, mfc_l, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0),
+ SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp),
+ SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP),
+ SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP),
+ SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP),
+};
+#endif /* CONFIG_ARCH_EXYNOS4 */
-void sysmmu_clk_disable(sysmmu_ips ips)
+#ifdef CONFIG_ARCH_EXYNOS5
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r, MFC_R, MFC_R);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l, MFC_L, MFC_L);
+SYSMMU_RESOURCE(EXYNOS5, isp) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg),
+ SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1),
+ SYSMMU_RESOURCE_MAPPING(5, 2d, 2d),
+ SYSMMU_RESOURCE_MAPPING(5, rot, rot),
+ SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1),
+ SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, mfc_r, mfc_r, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_PD(5, mfc_l, mfc_l, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata),
+};
+#endif /* CONFIG_ARCH_EXYNOS5 */
+
+static int __init init_sysmmu_platform_device(void)
{
- if (sysmmu_clk[ips])
- clk_disable(sysmmu_clk[ips]);
+ int i, j;
+ struct sysmmu_resource_map *resmap[2] = {NULL, NULL};
+ int nmap[2] = {0, 0};
+
+#ifdef CONFIG_ARCH_EXYNOS5
+ if (soc_is_exynos5250()) {
+ resmap[0] = sysmmu_resmap5;
+ nmap[0] = ARRAY_SIZE(sysmmu_resmap5);
+ nmap[1] = 0;
+ }
+#endif
+
+#ifdef CONFIG_ARCH_EXYNOS4
+ if (resmap[0] == NULL) {
+ resmap[0] = sysmmu_resmap4;
+ nmap[0] = ARRAY_SIZE(sysmmu_resmap4);
+ }
+
+ if (soc_is_exynos4210()) {
+ resmap[1] = sysmmu_resmap4210;
+ nmap[1] = ARRAY_SIZE(sysmmu_resmap4210);
+ }
+
+ if (soc_is_exynos4412() || soc_is_exynos4212()) {
+ resmap[1] = sysmmu_resmap4212;
+ nmap[1] = ARRAY_SIZE(sysmmu_resmap4212);
+ }
+#endif
+
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < nmap[j]; i++) {
+ struct sysmmu_resource_map *map;
+ struct sysmmu_platform_data *platdata;
+
+ map = &resmap[j][i];
+
+ map->pdev->dev.parent = map->pdd;
+
+ platdata = map->pdev->dev.platform_data;
+ platdata->clockname = map->clocknames;
+
+ if (platform_device_add_resources(map->pdev, map->res,
+ map->rnum)) {
+ pr_err("%s: Failed to add device resources for "
+ "%s.%d\n", __func__,
+ map->pdev->name, map->pdev->id);
+ continue;
+ }
+
+ if (platform_device_register(map->pdev)) {
+ pr_err("%s: Failed to register %s.%d\n",
+ __func__, map->pdev->name,
+ map->pdev->id);
+ }
+ }
+ }
+
+ return 0;
}
+arch_initcall(init_sysmmu_platform_device);
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 69aaa4503205..f60b66dbcf84 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -103,10 +103,45 @@ static u8 exynos4212_pdma0_peri[] = {
DMACH_MIPI_HSI5,
};
-struct dma_pl330_platdata exynos4_pdma0_pdata;
+static u8 exynos5250_pdma0_peri[] = {
+ DMACH_PCM0_RX,
+ DMACH_PCM0_TX,
+ DMACH_PCM2_RX,
+ DMACH_PCM2_TX,
+ DMACH_SPI0_RX,
+ DMACH_SPI0_TX,
+ DMACH_SPI2_RX,
+ DMACH_SPI2_TX,
+ DMACH_I2S0S_TX,
+ DMACH_I2S0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S2_RX,
+ DMACH_I2S2_TX,
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART2_RX,
+ DMACH_UART2_TX,
+ DMACH_UART4_RX,
+ DMACH_UART4_TX,
+ DMACH_SLIMBUS0_RX,
+ DMACH_SLIMBUS0_TX,
+ DMACH_SLIMBUS2_RX,
+ DMACH_SLIMBUS2_TX,
+ DMACH_SLIMBUS4_RX,
+ DMACH_SLIMBUS4_TX,
+ DMACH_AC97_MICIN,
+ DMACH_AC97_PCMIN,
+ DMACH_AC97_PCMOUT,
+ DMACH_MIPI_HSI0,
+ DMACH_MIPI_HSI2,
+ DMACH_MIPI_HSI4,
+ DMACH_MIPI_HSI6,
+};
+
+static struct dma_pl330_platdata exynos_pdma0_pdata;
-static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330,
- EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos4_pdma0_pdata);
+static AMBA_AHB_DEVICE(exynos_pdma0, "dma-pl330.0", 0x00041330,
+ EXYNOS4_PA_PDMA0, {EXYNOS4_IRQ_PDMA0}, &exynos_pdma0_pdata);
static u8 exynos4210_pdma1_peri[] = {
DMACH_PCM0_RX,
@@ -169,10 +204,45 @@ static u8 exynos4212_pdma1_peri[] = {
DMACH_MIPI_HSI7,
};
-static struct dma_pl330_platdata exynos4_pdma1_pdata;
+static u8 exynos5250_pdma1_peri[] = {
+ DMACH_PCM0_RX,
+ DMACH_PCM0_TX,
+ DMACH_PCM1_RX,
+ DMACH_PCM1_TX,
+ DMACH_SPI1_RX,
+ DMACH_SPI1_TX,
+ DMACH_PWM,
+ DMACH_SPDIF,
+ DMACH_I2S0S_TX,
+ DMACH_I2S0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S1_RX,
+ DMACH_I2S1_TX,
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART1_RX,
+ DMACH_UART1_TX,
+ DMACH_UART3_RX,
+ DMACH_UART3_TX,
+ DMACH_SLIMBUS1_RX,
+ DMACH_SLIMBUS1_TX,
+ DMACH_SLIMBUS3_RX,
+ DMACH_SLIMBUS3_TX,
+ DMACH_SLIMBUS5_RX,
+ DMACH_SLIMBUS5_TX,
+ DMACH_SLIMBUS0AUX_RX,
+ DMACH_SLIMBUS0AUX_TX,
+ DMACH_DISP1,
+ DMACH_MIPI_HSI1,
+ DMACH_MIPI_HSI3,
+ DMACH_MIPI_HSI5,
+ DMACH_MIPI_HSI7,
+};
-static AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330,
- EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos4_pdma1_pdata);
+static struct dma_pl330_platdata exynos_pdma1_pdata;
+
+static AMBA_AHB_DEVICE(exynos_pdma1, "dma-pl330.1", 0x00041330,
+ EXYNOS4_PA_PDMA1, {EXYNOS4_IRQ_PDMA1}, &exynos_pdma1_pdata);
static u8 mdma_peri[] = {
DMACH_MTOM_0,
@@ -185,46 +255,63 @@ static u8 mdma_peri[] = {
DMACH_MTOM_7,
};
-static struct dma_pl330_platdata exynos4_mdma1_pdata = {
+static struct dma_pl330_platdata exynos_mdma1_pdata = {
.nr_valid_peri = ARRAY_SIZE(mdma_peri),
.peri_id = mdma_peri,
};
-static AMBA_AHB_DEVICE(exynos4_mdma1, "dma-pl330.2", 0x00041330,
- EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos4_mdma1_pdata);
+static AMBA_AHB_DEVICE(exynos_mdma1, "dma-pl330.2", 0x00041330,
+ EXYNOS4_PA_MDMA1, {EXYNOS4_IRQ_MDMA1}, &exynos_mdma1_pdata);
-static int __init exynos4_dma_init(void)
+static int __init exynos_dma_init(void)
{
if (of_have_populated_dt())
return 0;
if (soc_is_exynos4210()) {
- exynos4_pdma0_pdata.nr_valid_peri =
+ exynos_pdma0_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4210_pdma0_peri);
- exynos4_pdma0_pdata.peri_id = exynos4210_pdma0_peri;
- exynos4_pdma1_pdata.nr_valid_peri =
+ exynos_pdma0_pdata.peri_id = exynos4210_pdma0_peri;
+ exynos_pdma1_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4210_pdma1_peri);
- exynos4_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
+ exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
- exynos4_pdma0_pdata.nr_valid_peri =
+ exynos_pdma0_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4212_pdma0_peri);
- exynos4_pdma0_pdata.peri_id = exynos4212_pdma0_peri;
- exynos4_pdma1_pdata.nr_valid_peri =
+ exynos_pdma0_pdata.peri_id = exynos4212_pdma0_peri;
+ exynos_pdma1_pdata.nr_valid_peri =
ARRAY_SIZE(exynos4212_pdma1_peri);
- exynos4_pdma1_pdata.peri_id = exynos4212_pdma1_peri;
+ exynos_pdma1_pdata.peri_id = exynos4212_pdma1_peri;
+ } else if (soc_is_exynos5250()) {
+ exynos_pdma0_pdata.nr_valid_peri =
+ ARRAY_SIZE(exynos5250_pdma0_peri);
+ exynos_pdma0_pdata.peri_id = exynos5250_pdma0_peri;
+ exynos_pdma1_pdata.nr_valid_peri =
+ ARRAY_SIZE(exynos5250_pdma1_peri);
+ exynos_pdma1_pdata.peri_id = exynos5250_pdma1_peri;
+
+ exynos_pdma0_device.res.start = EXYNOS5_PA_PDMA0;
+ exynos_pdma0_device.res.end = EXYNOS5_PA_PDMA0 + SZ_4K;
+ exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA0;
+ exynos_pdma1_device.res.start = EXYNOS5_PA_PDMA1;
+ exynos_pdma1_device.res.end = EXYNOS5_PA_PDMA1 + SZ_4K;
+ exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_PDMA1;
+ exynos_mdma1_device.res.start = EXYNOS5_PA_MDMA1;
+ exynos_mdma1_device.res.end = EXYNOS5_PA_MDMA1 + SZ_4K;
+ exynos_pdma0_device.irq[0] = EXYNOS5_IRQ_MDMA1;
}
- dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
- dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
- amba_device_register(&exynos4_pdma0_device, &iomem_resource);
+ dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask);
+ amba_device_register(&exynos_pdma0_device, &iomem_resource);
- dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
- dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
- amba_device_register(&exynos4_pdma1_device, &iomem_resource);
+ dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask);
+ dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask);
+ amba_device_register(&exynos_pdma1_device, &iomem_resource);
- dma_cap_set(DMA_MEMCPY, exynos4_mdma1_pdata.cap_mask);
- amba_device_register(&exynos4_mdma1_device, &iomem_resource);
+ dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask);
+ amba_device_register(&exynos_mdma1_device, &iomem_resource);
return 0;
}
-arch_initcall(exynos4_dma_init);
+arch_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 d7498afe036a..eb24f1eb8e3b 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 {
#define EXYNOS5_GPIO_B2_NR (4)
#define EXYNOS5_GPIO_B3_NR (4)
#define EXYNOS5_GPIO_C0_NR (7)
-#define EXYNOS5_GPIO_C1_NR (7)
+#define EXYNOS5_GPIO_C1_NR (4)
#define EXYNOS5_GPIO_C2_NR (7)
#define EXYNOS5_GPIO_C3_NR (7)
-#define EXYNOS5_GPIO_D0_NR (8)
+#define EXYNOS5_GPIO_C4_NR (7)
+#define EXYNOS5_GPIO_D0_NR (4)
#define EXYNOS5_GPIO_D1_NR (8)
#define EXYNOS5_GPIO_Y0_NR (6)
#define EXYNOS5_GPIO_Y1_NR (4)
@@ -199,7 +200,8 @@ enum exynos5_gpio_number {
EXYNOS5_GPIO_C1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C0),
EXYNOS5_GPIO_C2_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C1),
EXYNOS5_GPIO_C3_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C2),
- EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
+ EXYNOS5_GPIO_C4_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C3),
+ EXYNOS5_GPIO_D0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_C4),
EXYNOS5_GPIO_D1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D0),
EXYNOS5_GPIO_Y0_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_D1),
EXYNOS5_GPIO_Y1_START = EXYNOS_GPIO_NEXT(EXYNOS5_GPIO_Y0),
@@ -242,6 +244,7 @@ enum exynos5_gpio_number {
#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr))
#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr))
#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr))
+#define EXYNOS5_GPC4(_nr) (EXYNOS5_GPIO_C4_START + (_nr))
#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr))
#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr))
#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 c02dae7bf4a3..7a4b4789eb72 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -154,6 +154,13 @@
#define EXYNOS4_IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
#define EXYNOS4_IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE0_0 COMBINER_IRQ(16, 0)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_LITE1_0 COMBINER_IRQ(16, 1)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_ISP_0 COMBINER_IRQ(16, 2)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_DRC_0 COMBINER_IRQ(16, 3)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_FD_0 COMBINER_IRQ(16, 4)
+#define EXYNOS4_IRQ_SYSMMU_FIMC_CX_0 COMBINER_IRQ(16, 5)
+
#define EXYNOS4_IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0)
#define EXYNOS4_IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
#define EXYNOS4_IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
@@ -221,24 +228,6 @@
#define IRQ_KEYPAD EXYNOS4_IRQ_KEYPAD
#define IRQ_PMU EXYNOS4_IRQ_PMU
-#define IRQ_SYSMMU_MDMA0_0 EXYNOS4_IRQ_SYSMMU_MDMA0_0
-#define IRQ_SYSMMU_SSS_0 EXYNOS4_IRQ_SYSMMU_SSS_0
-#define IRQ_SYSMMU_FIMC0_0 EXYNOS4_IRQ_SYSMMU_FIMC0_0
-#define IRQ_SYSMMU_FIMC1_0 EXYNOS4_IRQ_SYSMMU_FIMC1_0
-#define IRQ_SYSMMU_FIMC2_0 EXYNOS4_IRQ_SYSMMU_FIMC2_0
-#define IRQ_SYSMMU_FIMC3_0 EXYNOS4_IRQ_SYSMMU_FIMC3_0
-#define IRQ_SYSMMU_JPEG_0 EXYNOS4_IRQ_SYSMMU_JPEG_0
-#define IRQ_SYSMMU_2D_0 EXYNOS4_IRQ_SYSMMU_2D_0
-
-#define IRQ_SYSMMU_ROTATOR_0 EXYNOS4_IRQ_SYSMMU_ROTATOR_0
-#define IRQ_SYSMMU_MDMA1_0 EXYNOS4_IRQ_SYSMMU_MDMA1_0
-#define IRQ_SYSMMU_LCD0_M0_0 EXYNOS4_IRQ_SYSMMU_LCD0_M0_0
-#define IRQ_SYSMMU_LCD1_M1_0 EXYNOS4_IRQ_SYSMMU_LCD1_M1_0
-#define IRQ_SYSMMU_TV_M0_0 EXYNOS4_IRQ_SYSMMU_TV_M0_0
-#define IRQ_SYSMMU_MFC_M0_0 EXYNOS4_IRQ_SYSMMU_MFC_M0_0
-#define IRQ_SYSMMU_MFC_M1_0 EXYNOS4_IRQ_SYSMMU_MFC_M1_0
-#define IRQ_SYSMMU_PCIE_0 EXYNOS4_IRQ_SYSMMU_PCIE_0
-
#define IRQ_FIMD0_FIFO EXYNOS4_IRQ_FIMD0_FIFO
#define IRQ_FIMD0_VSYNC EXYNOS4_IRQ_FIMD0_VSYNC
#define IRQ_FIMD0_SYSTEM EXYNOS4_IRQ_FIMD0_SYSTEM
@@ -298,6 +287,7 @@
#define EXYNOS5_IRQ_MIPICSI1 IRQ_SPI(80)
#define EXYNOS5_IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81)
#define EXYNOS5_IRQ_MIPIDSI0 IRQ_SPI(82)
+#define EXYNOS5_IRQ_WDT_IOP IRQ_SPI(83)
#define EXYNOS5_IRQ_ROTATOR IRQ_SPI(84)
#define EXYNOS5_IRQ_GSC0 IRQ_SPI(85)
#define EXYNOS5_IRQ_GSC1 IRQ_SPI(86)
@@ -306,8 +296,8 @@
#define EXYNOS5_IRQ_JPEG IRQ_SPI(89)
#define EXYNOS5_IRQ_EFNFCON_DMA IRQ_SPI(90)
#define EXYNOS5_IRQ_2D IRQ_SPI(91)
-#define EXYNOS5_IRQ_SFMC0 IRQ_SPI(92)
-#define EXYNOS5_IRQ_SFMC1 IRQ_SPI(93)
+#define EXYNOS5_IRQ_EFNFCON_0 IRQ_SPI(92)
+#define EXYNOS5_IRQ_EFNFCON_1 IRQ_SPI(93)
#define EXYNOS5_IRQ_MIXER IRQ_SPI(94)
#define EXYNOS5_IRQ_HDMI IRQ_SPI(95)
#define EXYNOS5_IRQ_MFC IRQ_SPI(96)
@@ -321,7 +311,7 @@
#define EXYNOS5_IRQ_PCM2 IRQ_SPI(104)
#define EXYNOS5_IRQ_SPDIF IRQ_SPI(105)
#define EXYNOS5_IRQ_ADC0 IRQ_SPI(106)
-
+#define EXYNOS5_IRQ_ADC1 IRQ_SPI(107)
#define EXYNOS5_IRQ_SATA_PHY IRQ_SPI(108)
#define EXYNOS5_IRQ_SATA_PMEMREQ IRQ_SPI(109)
#define EXYNOS5_IRQ_CAM_C IRQ_SPI(110)
@@ -330,8 +320,9 @@
#define EXYNOS5_IRQ_DP1_INTP1 IRQ_SPI(113)
#define EXYNOS5_IRQ_CEC IRQ_SPI(114)
#define EXYNOS5_IRQ_SATA IRQ_SPI(115)
-#define EXYNOS5_IRQ_NFCON IRQ_SPI(116)
+#define EXYNOS5_IRQ_MCT_L0 IRQ_SPI(120)
+#define EXYNOS5_IRQ_MCT_L1 IRQ_SPI(121)
#define EXYNOS5_IRQ_MMC44 IRQ_SPI(123)
#define EXYNOS5_IRQ_MDMA1 IRQ_SPI(124)
#define EXYNOS5_IRQ_FIMC_LITE0 IRQ_SPI(125)
@@ -339,7 +330,6 @@
#define EXYNOS5_IRQ_RP_TIMER IRQ_SPI(127)
#define EXYNOS5_IRQ_PMU COMBINER_IRQ(1, 2)
-#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(1, 6)
#define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0)
#define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1)
@@ -350,6 +340,8 @@
#define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6)
#define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7)
+#define EXYNOS5_IRQ_SYSMMU_LITE2_0 COMBINER_IRQ(3, 0)
+#define EXYNOS5_IRQ_SYSMMU_LITE2_1 COMBINER_IRQ(3, 1)
#define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2)
#define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3)
#define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4)
@@ -373,8 +365,8 @@
#define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0)
#define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1)
-#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(6, 2)
-#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(6, 3)
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(6, 2)
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(6, 3)
#define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4)
#define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5)
#define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6)
@@ -386,11 +378,9 @@
#define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3)
#define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4)
#define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5)
-#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6)
-#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7)
-#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(8, 5)
-#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(8, 6)
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(8, 5)
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(8, 6)
#define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4)
#define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5)
@@ -406,17 +396,24 @@
#define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6)
#define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7)
+#define EXYNOS5_IRQ_MDMA1_ABORT COMBINER_IRQ(13, 1)
+
+#define EXYNOS5_IRQ_MDMA0_ABORT COMBINER_IRQ(15, 3)
+
#define EXYNOS5_IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4)
#define EXYNOS5_IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5)
#define EXYNOS5_IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6)
+#define EXYNOS5_IRQ_ARMIOP_GIC COMBINER_IRQ(19, 0)
+#define EXYNOS5_IRQ_ARMISP_GIC COMBINER_IRQ(19, 1)
+#define EXYNOS5_IRQ_IOP_GIC COMBINER_IRQ(19, 3)
+#define EXYNOS5_IRQ_ISP_GIC COMBINER_IRQ(19, 4)
+
+#define EXYNOS5_IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)
+
#define EXYNOS5_IRQ_EINT0 COMBINER_IRQ(23, 0)
-#define EXYNOS5_IRQ_MCT_L0 COMBINER_IRQ(23, 1)
-#define EXYNOS5_IRQ_MCT_L1 COMBINER_IRQ(23, 2)
#define EXYNOS5_IRQ_MCT_G0 COMBINER_IRQ(23, 3)
#define EXYNOS5_IRQ_MCT_G1 COMBINER_IRQ(23, 4)
-#define EXYNOS5_IRQ_MCT_G2 COMBINER_IRQ(23, 5)
-#define EXYNOS5_IRQ_MCT_G3 COMBINER_IRQ(23, 6)
#define EXYNOS5_IRQ_EINT1 COMBINER_IRQ(24, 0)
#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
@@ -447,7 +444,7 @@
#define EXYNOS5_MAX_COMBINER_NR 32
-#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 13
+#define EXYNOS5_IRQ_GPIO1_NR_GROUPS 14
#define EXYNOS5_IRQ_GPIO2_NR_GROUPS 9
#define EXYNOS5_IRQ_GPIO3_NR_GROUPS 5
#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 e009a66477f4..ca4aa89aa46b 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -34,6 +34,9 @@
#define EXYNOS4_PA_JPEG 0x11840000
+/* x = 0...1 */
+#define EXYNOS4_PA_FIMC_LITE(x) (0x12390000 + ((x) * 0x10000))
+
#define EXYNOS4_PA_G2D 0x12800000
#define EXYNOS4_PA_I2S0 0x03830000
@@ -78,8 +81,8 @@
#define EXYNOS4_PA_GIC_CPU 0x10480000
#define EXYNOS4_PA_GIC_DIST 0x10490000
-#define EXYNOS5_PA_GIC_CPU 0x10480000
-#define EXYNOS5_PA_GIC_DIST 0x10490000
+#define EXYNOS5_PA_GIC_CPU 0x10482000
+#define EXYNOS5_PA_GIC_DIST 0x10481000
#define EXYNOS4_PA_COREPERI 0x10500000
#define EXYNOS4_PA_TWD 0x10500600
@@ -95,6 +98,7 @@
#define EXYNOS5_PA_PDMA1 0x121B0000
#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000
+#define EXYNOS4_PA_SYSMMU_2D_ACP 0x10A40000
#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
@@ -103,6 +107,12 @@
#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
+#define EXYNOS4_PA_SYSMMU_FIMC_ISP 0x12260000
+#define EXYNOS4_PA_SYSMMU_FIMC_DRC 0x12270000
+#define EXYNOS4_PA_SYSMMU_FIMC_FD 0x122A0000
+#define EXYNOS4_PA_SYSMMU_ISPCPU 0x122B0000
+#define EXYNOS4_PA_SYSMMU_FIMC_LITE0 0x123B0000
+#define EXYNOS4_PA_SYSMMU_FIMC_LITE1 0x123C0000
#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000
#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
@@ -110,6 +120,37 @@
#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
+
+#define EXYNOS5_PA_SYSMMU_MDMA1 0x10A40000
+#define EXYNOS5_PA_SYSMMU_SSS 0x10A50000
+#define EXYNOS5_PA_SYSMMU_2D 0x10A60000
+#define EXYNOS5_PA_SYSMMU_MFC_L 0x11200000
+#define EXYNOS5_PA_SYSMMU_MFC_R 0x11210000
+#define EXYNOS5_PA_SYSMMU_ROTATOR 0x11D40000
+#define EXYNOS5_PA_SYSMMU_MDMA2 0x11D50000
+#define EXYNOS5_PA_SYSMMU_JPEG 0x11F20000
+#define EXYNOS5_PA_SYSMMU_IOP 0x12360000
+#define EXYNOS5_PA_SYSMMU_RTIC 0x12370000
+#define EXYNOS5_PA_SYSMMU_GPS 0x12630000
+#define EXYNOS5_PA_SYSMMU_ISP 0x13260000
+#define EXYNOS5_PA_SYSMMU_DRC 0x12370000
+#define EXYNOS5_PA_SYSMMU_SCALERC 0x13280000
+#define EXYNOS5_PA_SYSMMU_SCALERP 0x13290000
+#define EXYNOS5_PA_SYSMMU_FD 0x132A0000
+#define EXYNOS5_PA_SYSMMU_ISPCPU 0x132B0000
+#define EXYNOS5_PA_SYSMMU_ODC 0x132C0000
+#define EXYNOS5_PA_SYSMMU_DIS0 0x132D0000
+#define EXYNOS5_PA_SYSMMU_DIS1 0x132E0000
+#define EXYNOS5_PA_SYSMMU_3DNR 0x132F0000
+#define EXYNOS5_PA_SYSMMU_LITE0 0x13C40000
+#define EXYNOS5_PA_SYSMMU_LITE1 0x13C50000
+#define EXYNOS5_PA_SYSMMU_GSC0 0x13E80000
+#define EXYNOS5_PA_SYSMMU_GSC1 0x13E90000
+#define EXYNOS5_PA_SYSMMU_GSC2 0x13EA0000
+#define EXYNOS5_PA_SYSMMU_GSC3 0x13EB0000
+#define EXYNOS5_PA_SYSMMU_FIMD1 0x14640000
+#define EXYNOS5_PA_SYSMMU_TV 0x14650000
+
#define EXYNOS4_PA_SPI0 0x13920000
#define EXYNOS4_PA_SPI1 0x13930000
#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 d9578a58ae7f..b78b5f3ad9c0 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 @@
#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800)
#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900)
+#define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800)
+#define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804)
+
#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */
#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31)
@@ -303,6 +306,8 @@
#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558)
#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800)
+#define EXYNOS5_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x0C800)
+#define EXYNOS5_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x0C804)
#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920)
#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928)
#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C)
@@ -317,6 +322,8 @@
#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200)
#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500)
+#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24)
+
#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030)
#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 d457d052a420..4dbb8629b200 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 @@
#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
-/* Only for EXYNOS4212 */
+/* Only for EXYNOS4x12 */
#define S5P_ISP_ARM_LOWPWR S5P_PMUREG(0x1050)
#define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR S5P_PMUREG(0x1054)
#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR S5P_PMUREG(0x1058)
@@ -221,4 +221,12 @@
#define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8)
#define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48)
+/* Only for EXYNOS4412 */
+#define S5P_ARM_CORE2_LOWPWR S5P_PMUREG(0x1020)
+#define S5P_DIS_IRQ_CORE2 S5P_PMUREG(0x1024)
+#define S5P_DIS_IRQ_CENTRAL2 S5P_PMUREG(0x1028)
+#define S5P_ARM_CORE3_LOWPWR S5P_PMUREG(0x1030)
+#define S5P_DIS_IRQ_CORE3 S5P_PMUREG(0x1034)
+#define S5P_DIS_IRQ_CENTRAL3 S5P_PMUREG(0x1038)
+
#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 68ff6ad08a2b..000000000000
--- a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - System MMU register
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_SYSMMU_H
-#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
-
-#define S5P_MMU_CTRL 0x000
-#define S5P_MMU_CFG 0x004
-#define S5P_MMU_STATUS 0x008
-#define S5P_MMU_FLUSH 0x00C
-#define S5P_PT_BASE_ADDR 0x014
-#define S5P_INT_STATUS 0x018
-#define S5P_INT_CLEAR 0x01C
-#define S5P_PAGE_FAULT_ADDR 0x024
-#define S5P_AW_FAULT_ADDR 0x028
-#define S5P_AR_FAULT_ADDR 0x02C
-#define S5P_DEFAULT_SLAVE_ADDR 0x030
-
-#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 576efdf6d091..c71a5fba6a84 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 @@
#define __ASM_ARCH_SPI_CLKS_H __FILE__
/* Must source from SCLK_SPI */
-#define EXYNOS4_SPI_SRCCLK_SCLK 0
+#define EXYNOS_SPI_SRCCLK_SCLK 0
#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 6a5fbb534e82..998daf2add92 100644
--- a/arch/arm/mach-exynos/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -1,46 +1,66 @@
-/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * Samsung sysmmu driver for EXYNOS4
+ * EXYNOS - System MMU support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARM_ARCH_SYSMMU_H
-#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
-
-enum exynos4_sysmmu_ips {
- SYSMMU_MDMA,
- SYSMMU_SSS,
- SYSMMU_FIMC0,
- SYSMMU_FIMC1,
- SYSMMU_FIMC2,
- SYSMMU_FIMC3,
- SYSMMU_JPEG,
- SYSMMU_FIMD0,
- SYSMMU_FIMD1,
- SYSMMU_PCIe,
- SYSMMU_G2D,
- SYSMMU_ROTATOR,
- SYSMMU_MDMA2,
- SYSMMU_TV,
- SYSMMU_MFC_L,
- SYSMMU_MFC_R,
- EXYNOS4_SYSMMU_TOTAL_IPNUM,
+ */
+
+#ifndef _ARM_MACH_EXYNOS_SYSMMU_H_
+#define _ARM_MACH_EXYNOS_SYSMMU_H_
+
+struct sysmmu_platform_data {
+ char *dbgname;
+ /* comma(,) separated list of clock names for clock gating */
+ char *clockname;
};
-#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM
+#define SYSMMU_DEVNAME_BASE "exynos-sysmmu"
+
+#define SYSMMU_CLOCK_NAME "sysmmu"
+#define SYSMMU_CLOCK_NAME2 "sysmmu_mc"
+
+#ifdef CONFIG_EXYNOS_DEV_SYSMMU
+#include <linux/device.h>
+struct platform_device;
+
+#define SYSMMU_PLATDEV(ipname) exynos_device_sysmmu_##ipname
+
+extern struct platform_device SYSMMU_PLATDEV(mfc_l);
+extern struct platform_device SYSMMU_PLATDEV(mfc_r);
+extern struct platform_device SYSMMU_PLATDEV(tv);
+extern struct platform_device SYSMMU_PLATDEV(jpeg);
+extern struct platform_device SYSMMU_PLATDEV(rot);
+extern struct platform_device SYSMMU_PLATDEV(fimc0);
+extern struct platform_device SYSMMU_PLATDEV(fimc1);
+extern struct platform_device SYSMMU_PLATDEV(fimc2);
+extern struct platform_device SYSMMU_PLATDEV(fimc3);
+extern struct platform_device SYSMMU_PLATDEV(gsc0);
+extern struct platform_device SYSMMU_PLATDEV(gsc1);
+extern struct platform_device SYSMMU_PLATDEV(gsc2);
+extern struct platform_device SYSMMU_PLATDEV(gsc3);
+extern struct platform_device SYSMMU_PLATDEV(isp);
+extern struct platform_device SYSMMU_PLATDEV(fimd0);
+extern struct platform_device SYSMMU_PLATDEV(fimd1);
+extern struct platform_device SYSMMU_PLATDEV(camif0);
+extern struct platform_device SYSMMU_PLATDEV(camif1);
+extern struct platform_device SYSMMU_PLATDEV(2d);
-extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
+#ifdef CONFIG_IOMMU_API
+static inline void platform_set_sysmmu(
+ struct device *sysmmu, struct device *dev)
+{
+ dev->archdata.iommu = sysmmu;
+}
+#endif
-typedef enum exynos4_sysmmu_ips sysmmu_ips;
+#else /* !CONFIG_EXYNOS_DEV_SYSMMU */
+#define platform_set_sysmmu(dev, sysmmu) do { } while (0)
+#endif
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
-void sysmmu_clk_enable(sysmmu_ips ips);
-void sysmmu_clk_disable(sysmmu_ips ips);
+#define SYSMMU_CLOCK_DEVNAME(ipname, id) (SYSMMU_DEVNAME_BASE "." #id)
-#endif /* __ASM_ARM_ARCH_SYSMMU_H */
+#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 fed7116418eb..5a3daa0168d8 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 = {
&s3c_device_hsmmc3,
&s3c_device_rtc,
&s3c_device_wdt,
- &exynos4_device_sysmmu,
&samsung_asoc_dma,
&armlex4210_smsc911x,
&exynos4_device_ahci,
@@ -204,6 +203,7 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210")
.map_io = armlex4210_map_io,
.handle_irq = gic_handle_irq,
.init_machine = armlex4210_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.restart = exynos4_restart,
MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 8245f1c761d9..e7e9743543ac 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)")
.map_io = exynos4210_dt_map_io,
.handle_irq = gic_handle_irq,
.init_machine = exynos4210_dt_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.dt_compat = exynos4210_dt_compat,
.restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 4711c8920e37..7b1e11a228cc 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 = {
"exynos4210-uart.2", NULL),
OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
"exynos4210-uart.3", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
+ "s3c2440-i2c.0", NULL),
+ OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
+ "s3c2440-i2c.1", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
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)")
.map_io = exynos5250_dt_map_io,
.handle_irq = gic_handle_irq,
.init_machine = exynos5250_dt_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.dt_compat = exynos5250_dt_compat,
.restart = exynos5_restart,
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 6c31f2ad765d..972983e392bc 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")
.map_io = nuri_map_io,
.handle_irq = gic_handle_irq,
.init_machine = nuri_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.reserve = &nuri_reserve,
.restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 26124a38bcbd..a7f7fd567dde 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")
.map_io = origen_map_io,
.handle_irq = gic_handle_irq,
.init_machine = origen_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.reserve = &origen_reserve,
.restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index fe772d893cc9..fb09c70e195a 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")
.map_io = smdk4x12_map_io,
.handle_irq = gic_handle_irq,
.init_machine = smdk4x12_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.restart = exynos4_restart,
.reserve = &smdk4x12_reserve,
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 5af96064ca51..70df1a0c2118 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 = {
&s5p_device_mfc_l,
&s5p_device_mfc_r,
&exynos4_device_spdif,
- &exynos4_device_sysmmu,
&samsung_asoc_dma,
&samsung_asoc_idma,
&s5p_device_fimd0,
@@ -412,6 +411,7 @@ MACHINE_START(SMDKC210, "SMDKC210")
.map_io = smdkv310_map_io,
.handle_irq = gic_handle_irq,
.init_machine = smdkv310_machine_init,
+ .init_late = exynos_init_late,
.timer = &exynos4_timer,
.restart = exynos4_restart,
MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 6b731b863275..083b44de9c10 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")
.map_io = universal_map_io,
.handle_irq = gic_handle_irq,
.init_machine = universal_machine_init,
+ .init_late = exynos_init_late,
.timer = &s5p_timer,
.reserve = &universal_reserve,
.restart = exynos4_restart,
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 897d9a9cf226..b601fb8a408b 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)
{
struct mct_clock_event_device *mevt;
unsigned int cpu = smp_processor_id();
+ int mct_lx_irq;
mevt = this_cpu_ptr(&percpu_mct_tick);
mevt->evt = evt;
@@ -414,14 +415,18 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
if (mct_int_type == MCT_INT_SPI) {
if (cpu == 0) {
+ mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L0 :
+ EXYNOS5_IRQ_MCT_L0;
mct_tick0_event_irq.dev_id = mevt;
- evt->irq = EXYNOS4_IRQ_MCT_L0;
- setup_irq(EXYNOS4_IRQ_MCT_L0, &mct_tick0_event_irq);
+ evt->irq = mct_lx_irq;
+ setup_irq(mct_lx_irq, &mct_tick0_event_irq);
} else {
+ mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L1 :
+ EXYNOS5_IRQ_MCT_L1;
mct_tick1_event_irq.dev_id = mevt;
- evt->irq = EXYNOS4_IRQ_MCT_L1;
- setup_irq(EXYNOS4_IRQ_MCT_L1, &mct_tick1_event_irq);
- irq_set_affinity(EXYNOS4_IRQ_MCT_L1, cpumask_of(1));
+ evt->irq = mct_lx_irq;
+ setup_irq(mct_lx_irq, &mct_tick1_event_irq);
+ irq_set_affinity(mct_lx_irq, cpumask_of(1));
}
} else {
enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0);
@@ -473,7 +478,7 @@ static void __init exynos4_timer_resources(void)
static void __init exynos4_timer_init(void)
{
- if (soc_is_exynos4210())
+ if ((soc_is_exynos4210()) || (soc_is_exynos5250()))
mct_int_type = MCT_INT_SPI;
else
mct_int_type = MCT_INT_PPI;
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 428cfeb57724..563dea9a6dbb 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)
static struct subsys_interface exynos4_pm_interface = {
.name = "exynos4_pm",
- .subsys = &exynos4_subsys,
+ .subsys = &exynos_subsys,
.add_dev = exynos4_pm_add,
};
@@ -313,7 +313,7 @@ static int exynos4_pm_suspend(void)
tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
- if (soc_is_exynos4212()) {
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
tmp &= ~(S5P_USE_STANDBYWFI_ISP_ARM |
S5P_USE_STANDBYWFE_ISP_ARM);
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index 13b306808b42..e9fafcf163de 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)
}
arch_initcall(exynos4_pm_init_power_domain);
-static __init int exynos_pm_late_initcall(void)
+int __init exynos_pm_late_initcall(void)
{
pm_genpd_poweroff_unused();
return 0;
}
-late_initcall(exynos_pm_late_initcall);
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index bba48f5c3e8f..77c6815eebee 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[] = {
{ PMU_TABLE_END,},
};
-static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
+static struct exynos4_pmu_conf exynos4x12_pmu_config[] = {
{ S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
{ S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
{ S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
@@ -202,6 +202,16 @@ static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
{ PMU_TABLE_END,},
};
+static struct exynos4_pmu_conf exynos4412_pmu_config[] = {
+ { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } },
+ { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } },
+ { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } },
+ { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } },
+ { PMU_TABLE_END,},
+};
+
void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
{
unsigned int i;
@@ -209,6 +219,12 @@ void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++)
__raw_writel(exynos4_pmu_config[i].val[mode],
exynos4_pmu_config[i].reg);
+
+ if (soc_is_exynos4412()) {
+ for (i = 0; exynos4412_pmu_config[i].reg != PMU_TABLE_END ; i++)
+ __raw_writel(exynos4412_pmu_config[i].val[mode],
+ exynos4412_pmu_config[i].reg);
+ }
}
static int __init exynos4_pmu_init(void)
@@ -218,9 +234,9 @@ static int __init exynos4_pmu_init(void)
if (soc_is_exynos4210()) {
exynos4_pmu_config = exynos4210_pmu_config;
pr_info("EXYNOS4210 PMU Initialize\n");
- } else if (soc_is_exynos4212()) {
- exynos4_pmu_config = exynos4212_pmu_config;
- pr_info("EXYNOS4212 PMU Initialize\n");
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ exynos4_pmu_config = exynos4x12_pmu_config;
+ pr_info("EXYNOS4x12 PMU Initialize\n");
} else {
pr_info("EXYNOS4: PMU not supported\n");
}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index cca8c0c74794..0021f726b153 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -34,6 +34,7 @@ config ARCH_MX53
config SOC_IMX1
bool
select ARCH_MX1
+ select COMMON_CLK
select CPU_ARM920T
select IMX_HAVE_IOMUX_V1
select MXC_AVIC
@@ -42,12 +43,14 @@ config SOC_IMX21
bool
select MACH_MX21
select CPU_ARM926T
+ select COMMON_CLK
select IMX_HAVE_IOMUX_V1
select MXC_AVIC
config SOC_IMX25
bool
select ARCH_MX25
+ select COMMON_CLK
select CPU_ARM926T
select ARCH_MXC_IOMUX_V3
select MXC_AVIC
@@ -56,6 +59,7 @@ config SOC_IMX27
bool
select MACH_MX27
select CPU_ARM926T
+ select COMMON_CLK
select IMX_HAVE_IOMUX_V1
select MXC_AVIC
@@ -64,12 +68,14 @@ config SOC_IMX31
select CPU_V6
select IMX_HAVE_PLATFORM_MXC_RNGA
select MXC_AVIC
+ select COMMON_CLK
select SMP_ON_UP if SMP
config SOC_IMX35
bool
select CPU_V6
select ARCH_MXC_IOMUX_V3
+ select COMMON_CLK
select HAVE_EPIT
select MXC_AVIC
select SMP_ON_UP if SMP
@@ -77,6 +83,7 @@ config SOC_IMX35
config SOC_IMX5
select CPU_V7
select MXC_TZIC
+ select COMMON_CLK
select ARCH_MXC_IOMUX_V3
select ARCH_HAS_CPUFREQ
select ARCH_MX5
@@ -815,6 +822,7 @@ config SOC_IMX6Q
bool "i.MX6 Quad support"
select ARM_CPU_SUSPEND if PM
select ARM_GIC
+ select COMMON_CLK
select CPU_V7
select HAVE_ARM_SCU
select HAVE_IMX_GPC
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 4937c070a57e..ff29421414f2 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,15 +1,18 @@
-obj-$(CONFIG_SOC_IMX1) += clock-imx1.o mm-imx1.o
-obj-$(CONFIG_SOC_IMX21) += clock-imx21.o mm-imx21.o
+obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o
+obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o
-obj-$(CONFIG_SOC_IMX25) += clock-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
+obj-$(CONFIG_SOC_IMX25) += clk-imx25.o mm-imx25.o ehci-imx25.o cpu-imx25.o
obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o
-obj-$(CONFIG_SOC_IMX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
+obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o
-obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
-obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clock-imx35.o ehci-imx35.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o
-obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clock-mx51-mx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
+obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o pm-imx5.o cpu_op-mx51.o
+
+obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \
+ clk-pfd.o clk-busy.o
# Support for CMOS sensor interface
obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
@@ -70,7 +73,7 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
AFLAGS_head-v7.o :=-Wa,-march=armv7-a
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
+obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 3851d8a27875..05541cf4a878 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
dtb-$(CONFIG_MACH_IMX53_DT) += imx53-ard.dtb imx53-evk.dtb \
imx53-qsb.dtb imx53-smd.dtb
dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \
- imx6q-sabrelite.dtb
+ imx6q-sabrelite.dtb \
+ 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 000000000000..1a7a8dd045a1
--- /dev/null
+++ b/arch/arm/mach-imx/clk-busy.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include "clk.h"
+
+static int clk_busy_wait(void __iomem *reg, u8 shift)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+
+ while (readl_relaxed(reg) & (1 << shift))
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+struct clk_busy_divider {
+ struct clk_divider div;
+ const struct clk_ops *div_ops;
+ void __iomem *reg;
+ u8 shift;
+};
+
+static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw)
+{
+ struct clk_divider *div = container_of(hw, struct clk_divider, hw);
+
+ return container_of(div, struct clk_busy_divider, div);
+}
+
+static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+ return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate);
+}
+
+static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+
+ return busy->div_ops->round_rate(&busy->div.hw, rate, prate);
+}
+
+static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_busy_divider *busy = to_clk_busy_divider(hw);
+ int ret;
+
+ ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate);
+ if (!ret)
+ ret = clk_busy_wait(busy->reg, busy->shift);
+
+ return ret;
+}
+
+static struct clk_ops clk_busy_divider_ops = {
+ .recalc_rate = clk_busy_divider_recalc_rate,
+ .round_rate = clk_busy_divider_round_rate,
+ .set_rate = clk_busy_divider_set_rate,
+};
+
+struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift)
+{
+ struct clk_busy_divider *busy;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+ if (!busy)
+ return ERR_PTR(-ENOMEM);
+
+ busy->reg = busy_reg;
+ busy->shift = busy_shift;
+
+ busy->div.reg = reg;
+ busy->div.shift = shift;
+ busy->div.width = width;
+ busy->div.lock = &imx_ccm_lock;
+ busy->div_ops = &clk_divider_ops;
+
+ init.name = name;
+ init.ops = &clk_busy_divider_ops;
+ init.flags = CLK_SET_RATE_PARENT;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ busy->div.hw.init = &init;
+
+ clk = clk_register(NULL, &busy->div.hw);
+ if (!clk)
+ kfree(busy);
+
+ return clk;
+}
+
+struct clk_busy_mux {
+ struct clk_mux mux;
+ const struct clk_ops *mux_ops;
+ void __iomem *reg;
+ u8 shift;
+};
+
+static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw)
+{
+ struct clk_mux *mux = container_of(hw, struct clk_mux, hw);
+
+ return container_of(mux, struct clk_busy_mux, mux);
+}
+
+static u8 clk_busy_mux_get_parent(struct clk_hw *hw)
+{
+ struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+
+ return busy->mux_ops->get_parent(&busy->mux.hw);
+}
+
+static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_busy_mux *busy = to_clk_busy_mux(hw);
+ int ret;
+
+ ret = busy->mux_ops->set_parent(&busy->mux.hw, index);
+ if (!ret)
+ ret = clk_busy_wait(busy->reg, busy->shift);
+
+ return ret;
+}
+
+struct clk_ops clk_busy_mux_ops = {
+ .get_parent = clk_busy_mux_get_parent,
+ .set_parent = clk_busy_mux_set_parent,
+};
+
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+ u8 width, void __iomem *busy_reg, u8 busy_shift,
+ const char **parent_names, int num_parents)
+{
+ struct clk_busy_mux *busy;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ busy = kzalloc(sizeof(*busy), GFP_KERNEL);
+ if (!busy)
+ return ERR_PTR(-ENOMEM);
+
+ busy->reg = busy_reg;
+ busy->shift = busy_shift;
+
+ busy->mux.reg = reg;
+ busy->mux.shift = shift;
+ busy->mux.width = width;
+ busy->mux.lock = &imx_ccm_lock;
+ busy->mux_ops = &clk_mux_ops;
+
+ init.name = name;
+ init.ops = &clk_busy_mux_ops;
+ init.flags = 0;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+
+ busy->mux.hw.init = &init;
+
+ clk = clk_register(NULL, &busy->mux.hw);
+ if (IS_ERR(clk))
+ kfree(busy);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c
new file mode 100644
index 000000000000..3c1b8ff9a0a6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-gate2.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com>
+ * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Gated clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+/**
+ * DOC: basic gatable clock which can gate and ungate it's ouput
+ *
+ * Traits of this clock:
+ * prepare - clk_(un)prepare only ensures parent is (un)prepared
+ * enable - clk_enable and clk_disable are functional & control gating
+ * rate - inherits rate from parent. No clk_set_rate support
+ * parent - fixed parent. No clk_set_parent support
+ */
+
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static int clk_gate2_enable(struct clk_hw *hw)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ u32 reg;
+ unsigned long flags = 0;
+
+ if (gate->lock)
+ spin_lock_irqsave(gate->lock, flags);
+
+ reg = readl(gate->reg);
+ reg |= 3 << gate->bit_idx;
+ writel(reg, gate->reg);
+
+ if (gate->lock)
+ spin_unlock_irqrestore(gate->lock, flags);
+
+ return 0;
+}
+
+static void clk_gate2_disable(struct clk_hw *hw)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ u32 reg;
+ unsigned long flags = 0;
+
+ if (gate->lock)
+ spin_lock_irqsave(gate->lock, flags);
+
+ reg = readl(gate->reg);
+ reg &= ~(3 << gate->bit_idx);
+ writel(reg, gate->reg);
+
+ if (gate->lock)
+ spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int clk_gate2_is_enabled(struct clk_hw *hw)
+{
+ u32 reg;
+ struct clk_gate *gate = to_clk_gate(hw);
+
+ reg = readl(gate->reg);
+
+ if (((reg >> gate->bit_idx) & 3) == 3)
+ return 1;
+
+ return 0;
+}
+
+static struct clk_ops clk_gate2_ops = {
+ .enable = clk_gate2_enable,
+ .disable = clk_gate2_disable,
+ .is_enabled = clk_gate2_is_enabled,
+};
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate2_flags, spinlock_t *lock)
+{
+ struct clk_gate *gate;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
+ if (!gate)
+ return ERR_PTR(-ENOMEM);
+
+ /* struct clk_gate assignments */
+ gate->reg = reg;
+ gate->bit_idx = bit_idx;
+ gate->flags = clk_gate2_flags;
+ gate->lock = lock;
+
+ init.name = name;
+ init.ops = &clk_gate2_ops;
+ init.flags = flags;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ init.num_parents = parent_name ? 1 : 0;
+
+ gate->hw.init = &init;
+
+ clk = clk_register(dev, &gate->hw);
+ if (IS_ERR(clk))
+ kfree(clk);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c
new file mode 100644
index 000000000000..0f0beb580b73
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx1.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include "clk.h"
+
+/* CCM register addresses */
+#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
+
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_PCDR IO_ADDR_CCM(0x20)
+
+/* SCM register addresses */
+#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
+
+#define SCM_GCCR IO_ADDR_SCM(0xc)
+
+static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", };
+static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", "prem",
+ "fclk", };
+enum imx1_clks {
+ dummy, clk32, clk16m_ext, clk16m, clk32_premult, prem, mpll, spll, mcu,
+ fclk, hclk, clk48m, per1, per2, per3, clko, dma_gate, csi_gate,
+ mma_gate, usbd_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx1_clocks_init(unsigned long fref)
+{
+ int i;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[clk32] = imx_clk_fixed("clk32", fref);
+ clk[clk16m_ext] = imx_clk_fixed("clk16m_ext", 16000000);
+ clk[clk16m] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17);
+ clk[clk32_premult] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1);
+ clk[prem] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks,
+ ARRAY_SIZE(prem_sel_clks));
+ clk[mpll] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0);
+ clk[spll] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0);
+ clk[mcu] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1);
+ clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 15, 1);
+ clk[hclk] = imx_clk_divider("hclk", "spll", CCM_CSCR, 10, 4);
+ clk[clk48m] = imx_clk_divider("clk48m", "spll", CCM_CSCR, 26, 3);
+ clk[per1] = imx_clk_divider("per1", "spll", CCM_PCDR, 0, 4);
+ clk[per2] = imx_clk_divider("per2", "spll", CCM_PCDR, 4, 4);
+ clk[per3] = imx_clk_divider("per3", "spll", CCM_PCDR, 16, 7);
+ clk[clko] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks,
+ ARRAY_SIZE(clko_sel_clks));
+ clk[dma_gate] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 4);
+ clk[csi_gate] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2);
+ clk[mma_gate] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1);
+ clk[usbd_gate] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("imx1 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[dma_gate], "ahb", "imx-dma");
+ clk_register_clkdev(clk[csi_gate], NULL, "mx1-camera.0");
+ clk_register_clkdev(clk[mma_gate], "mma", NULL);
+ clk_register_clkdev(clk[usbd_gate], NULL, "imx_udc.0");
+ clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[hclk], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[per1], "per", "imx1-uart.0");
+ clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.0");
+ clk_register_clkdev(clk[per1], "per", "imx1-uart.1");
+ clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.1");
+ clk_register_clkdev(clk[per1], "per", "imx1-uart.2");
+ clk_register_clkdev(clk[hclk], "ipg", "imx1-uart.2");
+ clk_register_clkdev(clk[hclk], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[per2], "per", "imx1-cspi.0");
+ clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.0");
+ clk_register_clkdev(clk[per2], "per", "imx1-cspi.1");
+ clk_register_clkdev(clk[dummy], "ipg", "imx1-cspi.1");
+ clk_register_clkdev(clk[per2], NULL, "imx-mmc.0");
+ clk_register_clkdev(clk[per2], "per", "imx-fb.0");
+ clk_register_clkdev(clk[dummy], "ipg", "imx-fb.0");
+ clk_register_clkdev(clk[dummy], "ahb", "imx-fb.0");
+ clk_register_clkdev(clk[hclk], "mshc", NULL);
+ clk_register_clkdev(clk[per3], "ssi", NULL);
+ clk_register_clkdev(clk[clk32], NULL, "mxc_rtc.0");
+ clk_register_clkdev(clk[clko], "clko", NULL);
+
+ mxc_timer_init(NULL, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
+ MX1_TIM1_INT);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c
new file mode 100644
index 000000000000..4e4f384ee8dd
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx21.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include "clk.h"
+
+#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
+
+static const char *mpll_sel_clks[] = { "fpm", "ckih", };
+static const char *spll_sel_clks[] = { "fpm", "ckih", };
+
+enum imx21_clks {
+ ckil, ckih, fpm, mpll_sel, spll_sel, mpll, spll, fclk, hclk, ipg, per1,
+ per2, per3, per4, uart1_ipg_gate, uart2_ipg_gate, uart3_ipg_gate,
+ uart4_ipg_gate, gpt1_ipg_gate, gpt2_ipg_gate, gpt3_ipg_gate,
+ pwm_ipg_gate, sdhc1_ipg_gate, sdhc2_ipg_gate, lcdc_ipg_gate,
+ lcdc_hclk_gate, cspi3_ipg_gate, cspi2_ipg_gate, cspi1_ipg_gate,
+ per4_gate, csi_hclk_gate, usb_div, usb_gate, usb_hclk_gate, ssi1_gate,
+ ssi2_gate, nfc_div, nfc_gate, dma_gate, dma_hclk_gate, brom_gate,
+ emma_gate, emma_hclk_gate, slcdc_gate, slcdc_hclk_gate, wdog_gate,
+ gpio_gate, i2c_gate, kpp_gate, owire_gate, rtc_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+ int i;
+
+ clk[ckil] = imx_clk_fixed("ckil", lref);
+ clk[ckih] = imx_clk_fixed("ckih", href);
+ clk[fpm] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
+ clk[mpll_sel] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks,
+ ARRAY_SIZE(mpll_sel_clks));
+ clk[spll_sel] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks,
+ ARRAY_SIZE(spll_sel_clks));
+ clk[mpll] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0);
+ clk[spll] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0);
+ clk[fclk] = imx_clk_divider("fclk", "mpll", CCM_CSCR, 29, 3);
+ clk[hclk] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
+ clk[ipg] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
+ clk[per1] = imx_clk_divider("per1", "mpll", CCM_PCDR1, 0, 6);
+ clk[per2] = imx_clk_divider("per2", "mpll", CCM_PCDR1, 8, 6);
+ clk[per3] = imx_clk_divider("per3", "mpll", CCM_PCDR1, 16, 6);
+ clk[per4] = imx_clk_divider("per4", "mpll", CCM_PCDR1, 24, 6);
+ clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
+ clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
+ clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
+ clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
+ clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
+ clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
+ clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
+ clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
+ clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
+ clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
+ clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
+ clk[lcdc_hclk_gate] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
+ clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
+ clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
+ clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
+ clk[per4_gate] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
+ clk[csi_hclk_gate] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
+ clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 26, 3);
+ clk[usb_gate] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
+ clk[usb_hclk_gate] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
+ clk[ssi1_gate] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
+ clk[ssi2_gate] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
+ clk[nfc_div] = imx_clk_divider("nfc_div", "ipg", CCM_PCDR0, 12, 4);
+ clk[nfc_gate] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
+ clk[dma_gate] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
+ clk[dma_hclk_gate] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
+ clk[brom_gate] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
+ clk[emma_gate] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
+ clk[emma_hclk_gate] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
+ clk[slcdc_gate] = imx_clk_gate("slcdc_gate", "ipg", CCM_PCCR0, 25);
+ clk[slcdc_hclk_gate] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
+ clk[wdog_gate] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
+ clk[gpio_gate] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
+ clk[i2c_gate] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
+ clk[kpp_gate] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
+ clk[owire_gate] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
+ clk[rtc_gate] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX21 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[per1], "per1", NULL);
+ clk_register_clkdev(clk[per2], "per2", NULL);
+ clk_register_clkdev(clk[per3], "per3", NULL);
+ clk_register_clkdev(clk[per4], "per4", NULL);
+ clk_register_clkdev(clk[per1], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[per1], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[per1], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[per1], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[per1], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
+ clk_register_clkdev(clk[per1], "per", "imx-gpt.1");
+ clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
+ clk_register_clkdev(clk[per1], "per", "imx-gpt.2");
+ clk_register_clkdev(clk[pwm_ipg_gate], "pwm", "mxc_pwm.0");
+ clk_register_clkdev(clk[per2], "per", "imx21-cspi.0");
+ clk_register_clkdev(clk[cspi1_ipg_gate], "ipg", "imx21-cspi.0");
+ clk_register_clkdev(clk[per2], "per", "imx21-cspi.1");
+ clk_register_clkdev(clk[cspi2_ipg_gate], "ipg", "imx21-cspi.1");
+ clk_register_clkdev(clk[per2], "per", "imx21-cspi.2");
+ clk_register_clkdev(clk[cspi3_ipg_gate], "ipg", "imx21-cspi.2");
+ clk_register_clkdev(clk[per3], "per", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_hclk_gate], "ahb", "imx-fb.0");
+ clk_register_clkdev(clk[usb_gate], "per", "imx21-hcd.0");
+ clk_register_clkdev(clk[usb_hclk_gate], "ahb", "imx21-hcd.0");
+ clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand.0");
+ clk_register_clkdev(clk[dma_hclk_gate], "ahb", "imx-dma");
+ clk_register_clkdev(clk[dma_gate], "ipg", "imx-dma");
+ clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[i2c_gate], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[kpp_gate], NULL, "mxc-keypad");
+ clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
+ clk_register_clkdev(clk[brom_gate], "brom", NULL);
+ clk_register_clkdev(clk[emma_gate], "emma", NULL);
+ clk_register_clkdev(clk[slcdc_gate], "slcdc", NULL);
+ clk_register_clkdev(clk[gpio_gate], "gpio", NULL);
+ clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
+ clk_register_clkdev(clk[csi_hclk_gate], "csi", NULL);
+ clk_register_clkdev(clk[ssi1_gate], "ssi1", NULL);
+ clk_register_clkdev(clk[ssi2_gate], "ssi2", NULL);
+ clk_register_clkdev(clk[sdhc1_ipg_gate], "sdhc1", NULL);
+ clk_register_clkdev(clk[sdhc2_ipg_gate], "sdhc2", NULL);
+
+ mxc_timer_init(NULL, MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
+ MX21_INT_GPT1);
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
new file mode 100644
index 000000000000..d9833bb5fd61
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+#include "clk.h"
+
+#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+
+#define CCM_MPCTL 0x00
+#define CCM_UPCTL 0x04
+#define CCM_CCTL 0x08
+#define CCM_CGCR0 0x0C
+#define CCM_CGCR1 0x10
+#define CCM_CGCR2 0x14
+#define CCM_PCDR0 0x18
+#define CCM_PCDR1 0x1C
+#define CCM_PCDR2 0x20
+#define CCM_PCDR3 0x24
+#define CCM_RCSR 0x28
+#define CCM_CRDR 0x2C
+#define CCM_DCVR0 0x30
+#define CCM_DCVR1 0x34
+#define CCM_DCVR2 0x38
+#define CCM_DCVR3 0x3c
+#define CCM_LTR0 0x40
+#define CCM_LTR1 0x44
+#define CCM_LTR2 0x48
+#define CCM_LTR3 0x4c
+#define CCM_MCR 0x64
+
+#define ccm(x) (CRM_BASE + (x))
+
+static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", };
+static const char *per_sel_clks[] = { "ahb", "upll", };
+
+enum mx25_clks {
+ dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg,
+ per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel,
+ per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel,
+ per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5,
+ per6, per7, per8, per9, per10, per11, per12, per13, per14, per15,
+ csi_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, gpt_ipg_per, i2c_ipg_per,
+ lcdc_ipg_per, nfc_ipg_per, ssi1_ipg_per, ssi2_ipg_per, uart_ipg_per,
+ csi_ahb, esdhc1_ahb, esdhc2_ahb, fec_ahb, lcdc_ahb, sdma_ahb,
+ usbotg_ahb, can1_ipg, can2_ipg, csi_ipg, cspi1_ipg, cspi2_ipg,
+ cspi3_ipg, dryice_ipg, esdhc1_ipg, esdhc2_ipg, fec_ipg, iim_ipg,
+ kpp_ipg, lcdc_ipg, pwm1_ipg, pwm2_ipg, pwm3_ipg, pwm4_ipg, sdma_ipg,
+ ssi1_ipg, ssi2_ipg, tsc_ipg, uart1_ipg, uart2_ipg, uart3_ipg,
+ uart4_ipg, uart5_ipg, wdt_ipg, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx25_clocks_init(void)
+{
+ int i;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[osc] = imx_clk_fixed("osc", 24000000);
+ clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL));
+ clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL));
+ clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4);
+ clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+ clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2);
+ clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2);
+ clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6);
+ clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks));
+ clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6);
+ clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6);
+ clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6);
+ clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6);
+ clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6);
+ clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6);
+ clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6);
+ clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6);
+ clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6);
+ clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6);
+ clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6);
+ clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6);
+ clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6);
+ clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6);
+ clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6);
+ clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6);
+ clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0);
+ clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3);
+ clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4);
+ clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5);
+ clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6);
+ clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7);
+ clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8);
+ clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13);
+ clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14);
+ clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15);
+ clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18);
+ clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21);
+ clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22);
+ clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23);
+ clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24);
+ clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26);
+ clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28);
+ clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2);
+ clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3);
+ clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4);
+ clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5);
+ clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6);
+ clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7);
+ clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8);
+ clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13);
+ clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14);
+ clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15);
+ clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26);
+ clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28);
+ clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29);
+ clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31);
+ clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0);
+ clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1);
+ clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2);
+ clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6);
+ clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11);
+ clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12);
+ clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13);
+ clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14);
+ clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15);
+ clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16);
+ clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17);
+ clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18);
+ clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX25 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ /* i.mx25 has the i.mx21 type uart */
+ clk_register_clkdev(clk[uart1_ipg], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_ipg], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_ipg], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[uart4_ipg], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[uart5_ipg], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[uart_ipg_per], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[nfc_ipg_per], NULL, "mxc_nand.0");
+ /* i.mx25 has the i.mx35 type cspi */
+ clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
+ clk_register_clkdev(clk[cspi2_ipg], NULL, "imx35-cspi.1");
+ clk_register_clkdev(clk[cspi3_ipg], NULL, "imx35-cspi.2");
+ clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.0");
+ clk_register_clkdev(clk[per10], "per", "mxc_pwm.0");
+ clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.1");
+ clk_register_clkdev(clk[per10], "per", "mxc_pwm.1");
+ clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.2");
+ clk_register_clkdev(clk[per10], "per", "mxc_pwm.2");
+ clk_register_clkdev(clk[pwm1_ipg], "ipg", "mxc_pwm.3");
+ clk_register_clkdev(clk[per10], "per", "mxc_pwm.3");
+ clk_register_clkdev(clk[kpp_ipg], NULL, "imx-keypad");
+ clk_register_clkdev(clk[tsc_ipg], NULL, "mx25-adc");
+ clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.1");
+ clk_register_clkdev(clk[i2c_ipg_per], NULL, "imx-i2c.2");
+ clk_register_clkdev(clk[fec_ipg], "ipg", "imx25-fec.0");
+ clk_register_clkdev(clk[fec_ahb], "ahb", "imx25-fec.0");
+ clk_register_clkdev(clk[dryice_ipg], NULL, "imxdi_rtc.0");
+ clk_register_clkdev(clk[lcdc_ipg_per], "per", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");
+ clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0");
+ clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1");
+ clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1");
+ clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");
+ clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");
+ clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0");
+ clk_register_clkdev(clk[esdhc2_ipg_per], "per", "sdhci-esdhc-imx25.1");
+ clk_register_clkdev(clk[esdhc2_ipg], "ipg", "sdhci-esdhc-imx25.1");
+ clk_register_clkdev(clk[esdhc2_ahb], "ahb", "sdhci-esdhc-imx25.1");
+ clk_register_clkdev(clk[csi_ipg_per], "per", "mx2-camera.0");
+ clk_register_clkdev(clk[csi_ipg], "ipg", "mx2-camera.0");
+ clk_register_clkdev(clk[csi_ahb], "ahb", "mx2-camera.0");
+ clk_register_clkdev(clk[dummy], "audmux", NULL);
+ clk_register_clkdev(clk[can1_ipg], NULL, "flexcan.0");
+ clk_register_clkdev(clk[can2_ipg], NULL, "flexcan.1");
+ /* i.mx25 has the i.mx35 type sdma */
+ clk_register_clkdev(clk[sdma_ipg], "ipg", "imx35-sdma");
+ clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
+ clk_register_clkdev(clk[iim_ipg], "iim", NULL);
+
+ mxc_timer_init(NULL, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
new file mode 100644
index 000000000000..50a7ebd8d1b2
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -0,0 +1,290 @@
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include "clk.h"
+
+#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
+
+#define CCM_CSCR_UPDATE_DIS (1 << 31)
+#define CCM_CSCR_SSI2 (1 << 23)
+#define CCM_CSCR_SSI1 (1 << 22)
+#define CCM_CSCR_VPU (1 << 21)
+#define CCM_CSCR_MSHC (1 << 20)
+#define CCM_CSCR_SPLLRES (1 << 19)
+#define CCM_CSCR_MPLLRES (1 << 18)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN (1 << 0)
+
+/* i.MX27 TO 2+ */
+#define CCM_CSCR_ARM_SRC (1 << 15)
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+static const char *vpu_sel_clks[] = { "spll", "mpll_main2", };
+static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", };
+static const char *clko_sel_clks[] = {
+ "ckil", "prem", "ckih", "ckih",
+ "ckih", "mpll", "spll", "cpu_div",
+ "ahb", "ipg", "per1_div", "per2_div",
+ "per3_div", "per4_div", "ssi1_div", "ssi2_div",
+ "nfc_div", "mshc_div", "vpu_div", "60m",
+ "32k", "usb_div", "dptc",
+};
+
+static const char *ssi_sel_clks[] = { "spll", "mpll", };
+
+enum mx27_clks {
+ dummy, ckih, ckil, mpll, spll, mpll_main2, ahb, ipg, nfc_div, per1_div,
+ per2_div, per3_div, per4_div, vpu_sel, vpu_div, usb_div, cpu_sel,
+ clko_sel, cpu_div, clko_div, ssi1_sel, ssi2_sel, ssi1_div, ssi2_div,
+ clko_en, ssi2_ipg_gate, ssi1_ipg_gate, slcdc_ipg_gate, sdhc3_ipg_gate,
+ sdhc2_ipg_gate, sdhc1_ipg_gate, scc_ipg_gate, sahara_ipg_gate,
+ rtc_ipg_gate, pwm_ipg_gate, owire_ipg_gate, lcdc_ipg_gate,
+ kpp_ipg_gate, iim_ipg_gate, i2c2_ipg_gate, i2c1_ipg_gate,
+ gpt6_ipg_gate, gpt5_ipg_gate, gpt4_ipg_gate, gpt3_ipg_gate,
+ gpt2_ipg_gate, gpt1_ipg_gate, gpio_ipg_gate, fec_ipg_gate,
+ emma_ipg_gate, dma_ipg_gate, cspi3_ipg_gate, cspi2_ipg_gate,
+ cspi1_ipg_gate, nfc_baud_gate, ssi2_baud_gate, ssi1_baud_gate,
+ vpu_baud_gate, per4_gate, per3_gate, per2_gate, per1_gate,
+ usb_ahb_gate, slcdc_ahb_gate, sahara_ahb_gate, lcdc_ahb_gate,
+ vpu_ahb_gate, fec_ahb_gate, emma_ahb_gate, emi_ahb_gate, dma_ahb_gate,
+ csi_ahb_gate, brom_ahb_gate, ata_ahb_gate, wdog_ipg_gate, usb_ipg_gate,
+ uart6_ipg_gate, uart5_ipg_gate, uart4_ipg_gate, uart3_ipg_gate,
+ uart2_ipg_gate, uart1_ipg_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx27_clocks_init(unsigned long fref)
+{
+ int i;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[ckih] = imx_clk_fixed("ckih", fref);
+ clk[ckil] = imx_clk_fixed("ckil", 32768);
+ clk[mpll] = imx_clk_pllv1("mpll", "ckih", CCM_MPCTL0);
+ clk[spll] = imx_clk_pllv1("spll", "ckih", CCM_SPCTL0);
+ clk[mpll_main2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2);
+ clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+ } else {
+ clk[ahb] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4);
+ clk[ipg] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1);
+ }
+
+ clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4);
+ clk[per1_div] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6);
+ clk[per2_div] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6);
+ clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6);
+ clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6);
+ clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks));
+ clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3);
+ clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3);
+ clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks));
+ clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks));
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2);
+ else
+ clk[cpu_div] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3);
+ clk[clko_div] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3);
+ clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
+ clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
+ clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3);
+ clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0);
+ clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0);
+ clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1);
+ clk[slcdc_ipg_gate] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2);
+ clk[sdhc3_ipg_gate] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3);
+ clk[sdhc2_ipg_gate] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4);
+ clk[sdhc1_ipg_gate] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5);
+ clk[scc_ipg_gate] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6);
+ clk[sahara_ipg_gate] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7);
+ clk[rtc_ipg_gate] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9);
+ clk[pwm_ipg_gate] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11);
+ clk[owire_ipg_gate] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12);
+ clk[lcdc_ipg_gate] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14);
+ clk[kpp_ipg_gate] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15);
+ clk[iim_ipg_gate] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16);
+ clk[i2c2_ipg_gate] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17);
+ clk[i2c1_ipg_gate] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18);
+ clk[gpt6_ipg_gate] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19);
+ clk[gpt5_ipg_gate] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20);
+ clk[gpt4_ipg_gate] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21);
+ clk[gpt3_ipg_gate] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22);
+ clk[gpt2_ipg_gate] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23);
+ clk[gpt1_ipg_gate] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24);
+ clk[gpio_ipg_gate] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25);
+ clk[fec_ipg_gate] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26);
+ clk[emma_ipg_gate] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27);
+ clk[dma_ipg_gate] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28);
+ clk[cspi3_ipg_gate] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29);
+ clk[cspi2_ipg_gate] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30);
+ clk[cspi1_ipg_gate] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31);
+ clk[nfc_baud_gate] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3);
+ clk[ssi2_baud_gate] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4);
+ clk[ssi1_baud_gate] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5);
+ clk[vpu_baud_gate] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6);
+ clk[per4_gate] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7);
+ clk[per3_gate] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8);
+ clk[per2_gate] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9);
+ clk[per1_gate] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10);
+ clk[usb_ahb_gate] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11);
+ clk[slcdc_ahb_gate] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12);
+ clk[sahara_ahb_gate] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13);
+ clk[lcdc_ahb_gate] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15);
+ clk[vpu_ahb_gate] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16);
+ clk[fec_ahb_gate] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17);
+ clk[emma_ahb_gate] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18);
+ clk[emi_ahb_gate] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19);
+ clk[dma_ahb_gate] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20);
+ clk[csi_ahb_gate] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21);
+ clk[brom_ahb_gate] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22);
+ clk[ata_ahb_gate] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23);
+ clk[wdog_ipg_gate] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24);
+ clk[usb_ipg_gate] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25);
+ clk[uart6_ipg_gate] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26);
+ clk[uart5_ipg_gate] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27);
+ clk[uart4_ipg_gate] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28);
+ clk[uart3_ipg_gate] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29);
+ clk[uart2_ipg_gate] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30);
+ clk[uart1_ipg_gate] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX27 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[uart6_ipg_gate], "ipg", "imx21-uart.5");
+ clk_register_clkdev(clk[per1_gate], "per", "imx21-uart.5");
+ clk_register_clkdev(clk[gpt1_ipg_gate], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[gpt2_ipg_gate], "ipg", "imx-gpt.1");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.1");
+ clk_register_clkdev(clk[gpt3_ipg_gate], "ipg", "imx-gpt.2");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.2");
+ clk_register_clkdev(clk[gpt4_ipg_gate], "ipg", "imx-gpt.3");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.3");
+ clk_register_clkdev(clk[gpt5_ipg_gate], "ipg", "imx-gpt.4");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.4");
+ clk_register_clkdev(clk[gpt6_ipg_gate], "ipg", "imx-gpt.5");
+ clk_register_clkdev(clk[per1_gate], "per", "imx-gpt.5");
+ clk_register_clkdev(clk[pwm_ipg_gate], NULL, "mxc_pwm.0");
+ clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.0");
+ clk_register_clkdev(clk[sdhc1_ipg_gate], "ipg", "mxc-mmc.0");
+ clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.1");
+ clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.1");
+ clk_register_clkdev(clk[per2_gate], "per", "mxc-mmc.2");
+ clk_register_clkdev(clk[sdhc2_ipg_gate], "ipg", "mxc-mmc.2");
+ clk_register_clkdev(clk[cspi1_ipg_gate], NULL, "imx27-cspi.0");
+ clk_register_clkdev(clk[cspi2_ipg_gate], NULL, "imx27-cspi.1");
+ clk_register_clkdev(clk[cspi3_ipg_gate], NULL, "imx27-cspi.2");
+ clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0");
+ clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0");
+ clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0");
+ clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
+ clk_register_clkdev(clk[nfc_baud_gate], NULL, "mxc_nand.0");
+ clk_register_clkdev(clk[vpu_baud_gate], "per", "imx-vpu");
+ clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "imx-vpu");
+ clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx-dma");
+ clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx-dma");
+ clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
+ clk_register_clkdev(clk[fec_ahb_gate], "ahb", "imx27-fec.0");
+ clk_register_clkdev(clk[wdog_ipg_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[i2c1_ipg_gate], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1");
+ clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0");
+ clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad");
+ clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma");
+ clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma");
+ clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL);
+ clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL);
+ clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL);
+ clk_register_clkdev(clk[ata_ahb_gate], "ata", NULL);
+ clk_register_clkdev(clk[rtc_ipg_gate], "rtc", NULL);
+ clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL);
+ clk_register_clkdev(clk[cpu_div], "cpu", NULL);
+ clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL);
+ clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1");
+
+ mxc_timer_init(NULL, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+ MX27_INT_GPT1);
+
+ clk_prepare_enable(clk[emi_ahb_gate]);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+int __init mx27_clocks_init_dt(void)
+{
+ struct device_node *np;
+ u32 fref = 26000000; /* default */
+
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
+ continue;
+
+ if (!of_property_read_u32(np, "clock-frequency", &fref))
+ break;
+ }
+
+ return mx27_clocks_init(fref);
+}
+#endif
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
new file mode 100644
index 000000000000..a854b9cae5ea
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/mx31.h>
+#include <mach/common.h>
+
+#include "clk.h"
+#include "crmregs-imx3.h"
+
+static const char *mcu_main_sel[] = { "spll", "mpll", };
+static const char *per_sel[] = { "per_div", "ipg", };
+static const char *csi_sel[] = { "upll", "spll", };
+static const char *fir_sel[] = { "mcu_main", "upll", "spll" };
+
+enum mx31_clks {
+ ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, per_div,
+ per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre,
+ fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate,
+ iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate,
+ uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate,
+ mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
+ sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
+ uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
+ gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+ void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
+ int i;
+
+ clk[ckih] = imx_clk_fixed("ckih", fref);
+ clk[ckil] = imx_clk_fixed("ckil", 32768);
+ clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL);
+ clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL);
+ clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL);
+ clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
+ clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3);
+ clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3);
+ clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3);
+ clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2);
+ clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5);
+ clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel));
+ clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel));
+ clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel));
+ clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9);
+ clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2);
+ clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3);
+ clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3);
+ clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6);
+ clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0);
+ clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2);
+ clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4);
+ clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6);
+ clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8);
+ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10);
+ clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12);
+ clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14);
+ clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16);
+ clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18);
+ clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20);
+ clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22);
+ clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24);
+ clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26);
+ clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28);
+ clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30);
+ clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0);
+ clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2);
+ clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4);
+ clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6);
+ clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8);
+ clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10);
+ clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12);
+ clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14);
+ clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16);
+ clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18);
+ clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20);
+ clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22);
+ clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24);
+ clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26);
+ clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28);
+ clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30);
+ clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0);
+ clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2);
+ clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4);
+ clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6);
+ clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8);
+ clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10);
+ clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("imx31 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0");
+ clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1");
+ clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2");
+ clk_register_clkdev(clk[pwm_gate], "pwm", NULL);
+ clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[rtc_gate], "rtc", NULL);
+ clk_register_clkdev(clk[epit1_gate], "epit", NULL);
+ clk_register_clkdev(clk[epit2_gate], "epit", NULL);
+ clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0");
+ clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
+ clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
+ clk_register_clkdev(clk[kpp_gate], "kpp", NULL);
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
+ /* i.mx31 has the i.mx21 type uart */
+ clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
+ clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+ clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0");
+ clk_register_clkdev(clk[sdhc1_gate], NULL, "mxc-mmc.0");
+ clk_register_clkdev(clk[sdhc2_gate], NULL, "mxc-mmc.1");
+ clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");
+ clk_register_clkdev(clk[firi_gate], "firi", NULL);
+ clk_register_clkdev(clk[ata_gate], NULL, "pata_imx");
+ clk_register_clkdev(clk[rtic_gate], "rtic", NULL);
+ clk_register_clkdev(clk[rng_gate], "rng", NULL);
+ clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma");
+ clk_register_clkdev(clk[iim_gate], "iim", NULL);
+
+ clk_set_parent(clk[csi], clk[upll]);
+ clk_prepare_enable(clk[emi_gate]);
+ clk_prepare_enable(clk[iim_gate]);
+ mx31_revision();
+ clk_disable_unprepare(clk[iim_gate]);
+
+ mxc_timer_init(NULL, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
+ MX31_INT_GPT);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
new file mode 100644
index 000000000000..a9e60bf7dd75
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include "crmregs-imx3.h"
+#include "clk.h"
+
+struct arm_ahb_div {
+ unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+ { .arm = 1, .ahb = 4, .sel = 0},
+ { .arm = 1, .ahb = 3, .sel = 1},
+ { .arm = 2, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 1, .sel = 0},
+ { .arm = 1, .ahb = 5, .sel = 0},
+ { .arm = 1, .ahb = 8, .sel = 0},
+ { .arm = 1, .ahb = 6, .sel = 1},
+ { .arm = 2, .ahb = 4, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static char hsp_div_532[] = { 4, 8, 3, 0 };
+static char hsp_div_400[] = { 3, 6, 3, 0 };
+
+static const char *std_sel[] = {"ppll", "arm"};
+static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+
+enum mx35_clks {
+ ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+ arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
+ esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
+ spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
+ ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate,
+ audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate,
+ edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate,
+ esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate,
+ gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate,
+ kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate,
+ rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
+ ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
+ wdog_gate, max_gate, admux_gate, csi_gate, iim_gate, gpu2d_gate,
+ clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx35_clocks_init()
+{
+ void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
+ u32 pdr0, consumer_sel, hsp_sel;
+ struct arm_ahb_div *aad;
+ unsigned char *hsp_div;
+ int i;
+
+ pdr0 = __raw_readl(base + MXC_CCM_PDR0);
+ consumer_sel = (pdr0 >> 16) & 0xf;
+ aad = &clk_consumer[consumer_sel];
+ if (!aad->arm) {
+ pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel);
+ /*
+ * We are basically stuck. Continue with a default entry and hope we
+ * get far enough to actually show the above message
+ */
+ aad = &clk_consumer[0];
+ }
+
+ clk[ckih] = imx_clk_fixed("ckih", 24000000);
+ clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL);
+ clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL);
+
+ clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4);
+
+ if (aad->sel)
+ clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm);
+ else
+ clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm);
+
+ if (clk_get_rate(clk[arm]) > 400000000)
+ hsp_div = hsp_div_532;
+ else
+ hsp_div = hsp_div_400;
+
+ hsp_sel = (pdr0 >> 20) & 0x3;
+ if (!hsp_div[hsp_sel]) {
+ pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel);
+ hsp_sel = 0;
+ }
+
+ clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]);
+
+ clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb);
+ clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2);
+
+ clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6);
+ clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3);
+ clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel));
+
+ clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6);
+
+ clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6);
+ clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6);
+ clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
+
+ clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
+ clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
+
+ clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3);
+ clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6);
+ clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3);
+ clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6);
+
+ clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel));
+ clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6);
+
+ clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4);
+
+ clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0);
+ clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2);
+ clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4);
+ clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6);
+ clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8);
+ clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10);
+ clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12);
+ clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14);
+ clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16);
+ clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18);
+ clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20);
+ clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22);
+ clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24);
+ clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26);
+ clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28);
+ clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30);
+
+ clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0);
+ clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2);
+ clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4);
+ clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6);
+ clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8);
+ clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10);
+ clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12);
+ clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14);
+ clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16);
+ clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18);
+ clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20);
+ clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22);
+ clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24);
+ clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26);
+ clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28);
+ clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30);
+
+ clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0);
+ clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2);
+ clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4);
+ clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6);
+ clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8);
+ clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10);
+ clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12);
+ clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14);
+ clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16);
+ clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18);
+ clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20);
+ clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22);
+ clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24);
+ clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26);
+ clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30);
+
+ clk[csi_gate] = imx_clk_gate2("csi_gate", "ipg", base + MX35_CCM_CGR3, 0);
+ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2);
+ clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX35 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+
+ clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
+ clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
+ clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
+ clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0");
+ clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0");
+ clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1");
+ clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1");
+ clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0");
+ clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1");
+ clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0");
+ clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1");
+ clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2");
+ clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2");
+ clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2");
+ /* i.mx35 has the i.mx27 type fec */
+ clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
+ clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
+ clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+ clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core");
+ clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");
+ clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");
+ clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0");
+ clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1");
+ clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1");
+ /* i.mx35 has the i.mx21 type uart */
+ clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[nfc_div], NULL, "mxc_nand.0");
+
+ clk_prepare_enable(clk[spba_gate]);
+ clk_prepare_enable(clk[gpio1_gate]);
+ clk_prepare_enable(clk[gpio2_gate]);
+ clk_prepare_enable(clk[gpio3_gate]);
+ clk_prepare_enable(clk[iim_gate]);
+ clk_prepare_enable(clk[emi_gate]);
+
+ imx_print_silicon_rev("i.MX35", mx35_revision());
+
+#ifdef CONFIG_MXC_USE_EPIT
+ epit_timer_init(&epit1_clk,
+ MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
+ mxc_timer_init(NULL, MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR),
+ MX35_INT_GPT);
+#endif
+
+ return 0;
+}
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 000000000000..fcd94f3b0f0e
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include "crm-regs-imx5.h"
+#include "clk.h"
+
+/* Low-power Audio Playback Mode clock */
+static const char *lp_apm_sel[] = { "osc", };
+
+/* This is used multiple times */
+static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", };
+static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", };
+static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", };
+static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", };
+static const char *per_root_sel[] = { "per_podf", "ipg", };
+static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", };
+static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", };
+static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", };
+static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", };
+static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", };
+static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", };
+static const char *emi_slow_sel[] = { "main_bus", "ahb", };
+static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", };
+static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", };
+static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0", };
+static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", };
+static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", };
+static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1", };
+static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", };
+static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", };
+static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", };
+static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", };
+static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", };
+
+enum imx5_clks {
+ dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
+ uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s,
+ emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred,
+ usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di,
+ tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate,
+ uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate,
+ gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate,
+ gpt_gate, fec_gate, usboh3_per_gate, esdhc1_ipg_gate, esdhc2_ipg_gate,
+ esdhc3_ipg_gate, esdhc4_ipg_gate, ssi1_ipg_gate, ssi2_ipg_gate,
+ ssi3_ipg_gate, ecspi1_ipg_gate, ecspi1_per_gate, ecspi2_ipg_gate,
+ ecspi2_per_gate, cspi_ipg_gate, sdma_gate, emi_slow_gate, ipu_s,
+ ipu_gate, nfc_gate, ipu_di1_gate, vpu_s, vpu_gate,
+ vpu_reference_gate, uart4_ipg_gate, uart4_per_gate, uart5_ipg_gate,
+ uart5_per_gate, tve_gate, tve_pred, esdhc1_per_gate, esdhc2_per_gate,
+ esdhc3_per_gate, esdhc4_per_gate, usb_phy_gate, hsi2c_gate,
+ mipi_hsc1_gate, mipi_hsc2_gate, mipi_esc_gate, mipi_hsp_gate,
+ ldb_di1_div_3_5, ldb_di1_div, ldb_di0_div_3_5, ldb_di0_div,
+ ldb_di1_gate, can2_serial_gate, can2_ipg_gate, i2c3_gate, lp_apm,
+ periph_apm, main_bus, ahb_max, aips_tz1, aips_tz2, tmax1, tmax2,
+ tmax3, spba, uart_sel, esdhc_a_sel, esdhc_b_sel, esdhc_a_podf,
+ esdhc_b_podf, ecspi_sel, usboh3_sel, usb_phy_sel, iim_gate,
+ usboh3_gate, emi_fast_gate, ipu_di0_gate,gpc_dvfs, pll1_sw, pll2_sw,
+ pll3_sw, ipu_di0_sel, ipu_di1_sel, tve_ext_sel, mx51_mipi, pll4_sw,
+ ldb_di1_sel, di_pll4_podf, ldb_di0_sel, ldb_di0_gate, usb_phy1_gate,
+ usb_phy2_gate, per_lp_apm, per_pred1, per_pred2, per_podf, per_root,
+ ssi_apm, ssi1_root_sel, ssi2_root_sel, ssi3_root_sel, ssi_ext1_sel,
+ ssi_ext2_sel, ssi_ext1_com_sel, ssi_ext2_com_sel, ssi1_root_pred,
+ ssi1_root_podf, ssi2_root_pred, ssi2_root_podf, ssi_ext1_pred,
+ ssi_ext1_podf, ssi_ext2_pred, ssi_ext2_podf, ssi1_root_gate,
+ ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate,
+ clk_max
+};
+
+static struct clk *clk[clk_max];
+
+static void __init mx5_clocks_common_init(unsigned long rate_ckil,
+ unsigned long rate_osc, unsigned long rate_ckih1,
+ unsigned long rate_ckih2)
+{
+ int i;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+ clk[ckil] = imx_clk_fixed("ckil", rate_ckil);
+ clk[osc] = imx_clk_fixed("osc", rate_osc);
+ clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1);
+ clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2);
+
+ clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
+ lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
+ clk[periph_apm] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2,
+ periph_apm_sel, ARRAY_SIZE(periph_apm_sel));
+ clk[main_bus] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1,
+ main_bus_sel, ARRAY_SIZE(main_bus_sel));
+ clk[per_lp_apm] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCDR, 1, 1,
+ per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel));
+ clk[per_pred1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2);
+ clk[per_pred2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3);
+ clk[per_podf] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3);
+ clk[per_root] = imx_clk_mux("per_root", MXC_CCM_CBCDR, 1, 0,
+ per_root_sel, ARRAY_SIZE(per_root_sel));
+ clk[ahb] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3);
+ clk[ahb_max] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28);
+ clk[aips_tz1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24);
+ clk[aips_tz2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26);
+ clk[tmax1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0);
+ clk[tmax2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2);
+ clk[tmax3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4);
+ clk[spba] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0);
+ clk[ipg] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2);
+ clk[axi_a] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3);
+ clk[axi_b] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3);
+ clk[uart_sel] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[uart_pred] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3);
+ clk[uart_root] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3);
+
+ clk[esdhc_a_sel] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[esdhc_b_sel] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[esdhc_a_pred] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3);
+ clk[esdhc_a_podf] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3);
+ clk[esdhc_b_pred] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3);
+ clk[esdhc_b_podf] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3);
+ clk[esdhc_c_s] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel));
+ clk[esdhc_d_s] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel));
+
+ clk[emi_sel] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1,
+ emi_slow_sel, ARRAY_SIZE(emi_slow_sel));
+ clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3);
+ clk[nfc_podf] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3);
+ clk[ecspi_sel] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[ecspi_pred] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3);
+ clk[ecspi_podf] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6);
+ clk[usboh3_sel] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2,
+ standard_pll_sel, ARRAY_SIZE(standard_pll_sel));
+ clk[usboh3_pred] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3);
+ clk[usboh3_podf] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2);
+ clk[usb_phy_pred] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3);
+ clk[usb_phy_podf] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3);
+ clk[usb_phy_sel] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1,
+ usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str));
+ clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3);
+ clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3);
+ clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */
+ clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel));
+ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30);
+ clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6);
+ clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8);
+ clk[uart2_ipg_gate] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10);
+ clk[uart2_per_gate] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12);
+ clk[uart3_ipg_gate] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14);
+ clk[uart3_per_gate] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16);
+ clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18);
+ clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20);
+ clk[gpt_ipg_gate] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 20);
+ clk[pwm1_ipg_gate] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10);
+ clk[pwm1_hf_gate] = imx_clk_gate2("pwm1_hf_gate", "ipg", MXC_CCM_CCGR2, 12);
+ clk[pwm2_ipg_gate] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14);
+ clk[pwm2_hf_gate] = imx_clk_gate2("pwm2_hf_gate", "ipg", MXC_CCM_CCGR2, 16);
+ clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", MXC_CCM_CCGR2, 18);
+ clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24);
+ clk[usboh3_gate] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26);
+ clk[usboh3_per_gate] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28);
+ clk[esdhc1_ipg_gate] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0);
+ clk[esdhc2_ipg_gate] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4);
+ clk[esdhc3_ipg_gate] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8);
+ clk[esdhc4_ipg_gate] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12);
+ clk[ssi1_ipg_gate] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16);
+ clk[ssi2_ipg_gate] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20);
+ clk[ssi3_ipg_gate] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24);
+ clk[ecspi1_ipg_gate] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18);
+ clk[ecspi1_per_gate] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20);
+ clk[ecspi2_ipg_gate] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22);
+ clk[ecspi2_per_gate] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24);
+ clk[cspi_ipg_gate] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26);
+ clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30);
+ clk[emi_fast_gate] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14);
+ clk[emi_slow_gate] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16);
+ clk[ipu_s] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel));
+ clk[ipu_gate] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10);
+ clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20);
+ clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10);
+ clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12);
+ clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel));
+ clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6);
+ clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8);
+ clk[uart4_ipg_gate] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8);
+ clk[uart4_per_gate] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10);
+ clk[uart5_ipg_gate] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12);
+ clk[uart5_per_gate] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14);
+ clk[gpc_dvfs] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24);
+
+ clk[ssi_apm] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels));
+ clk[ssi1_root_sel] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[ssi2_root_sel] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[ssi3_root_sel] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels));
+ clk[ssi_ext1_sel] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ clk[ssi_ext2_sel] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels));
+ 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));
+ 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));
+ clk[ssi1_root_pred] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3);
+ clk[ssi1_root_podf] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6);
+ clk[ssi2_root_pred] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3);
+ clk[ssi2_root_podf] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6);
+ clk[ssi_ext1_pred] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3);
+ clk[ssi_ext1_podf] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6);
+ clk[ssi_ext2_pred] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3);
+ clk[ssi_ext2_podf] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6);
+ clk[ssi1_root_gate] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18);
+ clk[ssi2_root_gate] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22);
+ clk[ssi3_root_gate] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26);
+ clk[ssi_ext1_gate] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28);
+ clk[ssi_ext2_gate] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX5 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[gpt_ipg_gate], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[uart1_per_gate], "per", "imx21-uart.0");
+ clk_register_clkdev(clk[uart1_ipg_gate], "ipg", "imx21-uart.0");
+ clk_register_clkdev(clk[uart2_per_gate], "per", "imx21-uart.1");
+ clk_register_clkdev(clk[uart2_ipg_gate], "ipg", "imx21-uart.1");
+ clk_register_clkdev(clk[uart3_per_gate], "per", "imx21-uart.2");
+ clk_register_clkdev(clk[uart3_ipg_gate], "ipg", "imx21-uart.2");
+ clk_register_clkdev(clk[uart4_per_gate], "per", "imx21-uart.3");
+ clk_register_clkdev(clk[uart4_ipg_gate], "ipg", "imx21-uart.3");
+ clk_register_clkdev(clk[uart5_per_gate], "per", "imx21-uart.4");
+ clk_register_clkdev(clk[uart5_ipg_gate], "ipg", "imx21-uart.4");
+ clk_register_clkdev(clk[ecspi1_per_gate], "per", "imx51-ecspi.0");
+ clk_register_clkdev(clk[ecspi1_ipg_gate], "ipg", "imx51-ecspi.0");
+ clk_register_clkdev(clk[ecspi2_per_gate], "per", "imx51-ecspi.1");
+ clk_register_clkdev(clk[ecspi2_ipg_gate], "ipg", "imx51-ecspi.1");
+ clk_register_clkdev(clk[cspi_ipg_gate], NULL, "imx51-cspi.0");
+ clk_register_clkdev(clk[pwm1_ipg_gate], "pwm", "mxc_pwm.0");
+ clk_register_clkdev(clk[pwm2_ipg_gate], "pwm", "mxc_pwm.1");
+ clk_register_clkdev(clk[i2c1_gate], NULL, "imx-i2c.0");
+ clk_register_clkdev(clk[i2c2_gate], NULL, "imx-i2c.1");
+ clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.0");
+ clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.0");
+ clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.0");
+ clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.1");
+ clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.1");
+ clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.1");
+ clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
+ clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
+ clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
+ clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[nfc_gate], NULL, "mxc_nand");
+ clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
+ clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
+ clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "imx-ssi.2");
+ clk_register_clkdev(clk[ssi_ext1_gate], "ssi_ext1", NULL);
+ clk_register_clkdev(clk[ssi_ext2_gate], "ssi_ext2", NULL);
+ clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma");
+ clk_register_clkdev(clk[cpu_podf], "cpu", NULL);
+ clk_register_clkdev(clk[iim_gate], "iim", NULL);
+ clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0");
+ clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1");
+ clk_register_clkdev(clk[dummy], NULL, "imx-keypad");
+ clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0");
+ clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0");
+
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(clk[esdhc_a_sel], clk[pll2_sw]);
+ clk_set_parent(clk[esdhc_b_sel], clk[pll2_sw]);
+
+ /* move usb phy clk to 24MHz */
+ clk_set_parent(clk[usb_phy_sel], clk[osc]);
+
+ clk_prepare_enable(clk[gpc_dvfs]);
+ clk_prepare_enable(clk[ahb_max]); /* esdhc3 */
+ clk_prepare_enable(clk[aips_tz1]);
+ clk_prepare_enable(clk[aips_tz2]); /* fec */
+ clk_prepare_enable(clk[spba]);
+ clk_prepare_enable(clk[emi_fast_gate]); /* fec */
+ clk_prepare_enable(clk[tmax1]);
+ clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */
+ clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */
+}
+
+int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
+ unsigned long rate_ckih1, unsigned long rate_ckih2)
+{
+ int i;
+
+ clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX51_DPLL1_BASE);
+ clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX51_DPLL2_BASE);
+ clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX51_DPLL3_BASE);
+ clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+ mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel));
+ clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+ mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel));
+ clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+ mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel));
+ clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30);
+ clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3);
+ clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+ clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6);
+ clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10);
+ clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+ clk[usb_phy_gate] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0);
+ clk[hsi2c_gate] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22);
+ clk[mipi_hsc1_gate] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6);
+ clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
+ clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
+ clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX51 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
+
+ clk_register_clkdev(clk[hsi2c_gate], NULL, "imx-i2c.2");
+ clk_register_clkdev(clk[mx51_mipi], "mipi_hsp", NULL);
+ clk_register_clkdev(clk[vpu_gate], NULL, "imx51-vpu.0");
+ clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0");
+ clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL);
+ clk_register_clkdev(clk[ipu_gate], "bus", "imx51-ipu");
+ clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx51-ipu");
+ clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx51-ipu");
+ clk_register_clkdev(clk[ipu_gate], "hsp", "imx51-ipu");
+ clk_register_clkdev(clk[usb_phy_gate], "phy", "mxc-ehci.0");
+ clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx51.0");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.0");
+ clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx51.0");
+ clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx51.1");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.1");
+ clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx51.1");
+ clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx51.2");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.2");
+ clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx51.2");
+ clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx51.3");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx51.3");
+ clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx51.3");
+ clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi");
+ clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi");
+ clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi");
+
+ /* set the usboh3 parent to pll2_sw */
+ clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
+
+ /* set SDHC root clock to 166.25MHZ*/
+ clk_set_rate(clk[esdhc_a_podf], 166250000);
+ clk_set_rate(clk[esdhc_b_podf], 166250000);
+
+ /* System timer */
+ mxc_timer_init(NULL, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+ MX51_INT_GPT);
+
+ clk_prepare_enable(clk[iim_gate]);
+ imx_print_silicon_rev("i.MX51", mx51_revision());
+ clk_disable_unprepare(clk[iim_gate]);
+
+ return 0;
+}
+
+int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
+ unsigned long rate_ckih1, unsigned long rate_ckih2)
+{
+ int i;
+ unsigned long r;
+
+ clk[pll1_sw] = imx_clk_pllv2("pll1_sw", "osc", MX53_DPLL1_BASE);
+ clk[pll2_sw] = imx_clk_pllv2("pll2_sw", "osc", MX53_DPLL2_BASE);
+ clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE);
+ clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE);
+
+ clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1,
+ mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel));
+ clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1);
+ clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3);
+ clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1,
+ mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel));
+ clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1);
+ clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28);
+ clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30);
+ clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3,
+ mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel));
+ clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3,
+ mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel));
+ clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1,
+ mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel));
+ clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30);
+ clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3);
+ clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2);
+ clk[esdhc2_per_gate] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6);
+ clk[esdhc3_per_gate] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10);
+ clk[esdhc4_per_gate] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14);
+ clk[usb_phy1_gate] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10);
+ clk[usb_phy2_gate] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12);
+ clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "ipg", MXC_CCM_CCGR4, 6);
+ clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 8);
+ clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX53 clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ mx5_clocks_common_init(rate_ckil, rate_osc, rate_ckih1, rate_ckih2);
+
+ clk_register_clkdev(clk[vpu_gate], NULL, "imx53-vpu.0");
+ clk_register_clkdev(clk[i2c3_gate], NULL, "imx-i2c.2");
+ clk_register_clkdev(clk[fec_gate], NULL, "imx25-fec.0");
+ clk_register_clkdev(clk[ipu_gate], "bus", "imx53-ipu");
+ clk_register_clkdev(clk[ipu_di0_gate], "di0", "imx53-ipu");
+ clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx53-ipu");
+ clk_register_clkdev(clk[ipu_gate], "hsp", "imx53-ipu");
+ clk_register_clkdev(clk[usb_phy1_gate], "usb_phy1", "mxc-ehci.0");
+ clk_register_clkdev(clk[esdhc1_ipg_gate], "ipg", "sdhci-esdhc-imx53.0");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.0");
+ clk_register_clkdev(clk[esdhc1_per_gate], "per", "sdhci-esdhc-imx53.0");
+ clk_register_clkdev(clk[esdhc2_ipg_gate], "ipg", "sdhci-esdhc-imx53.1");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.1");
+ clk_register_clkdev(clk[esdhc2_per_gate], "per", "sdhci-esdhc-imx53.1");
+ clk_register_clkdev(clk[esdhc3_ipg_gate], "ipg", "sdhci-esdhc-imx53.2");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.2");
+ clk_register_clkdev(clk[esdhc3_per_gate], "per", "sdhci-esdhc-imx53.2");
+ clk_register_clkdev(clk[esdhc4_ipg_gate], "ipg", "sdhci-esdhc-imx53.3");
+ clk_register_clkdev(clk[dummy], "ahb", "sdhci-esdhc-imx53.3");
+ clk_register_clkdev(clk[esdhc4_per_gate], "per", "sdhci-esdhc-imx53.3");
+ clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
+ clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
+ clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
+
+ /* set SDHC root clock to 200MHZ*/
+ clk_set_rate(clk[esdhc_a_podf], 200000000);
+ clk_set_rate(clk[esdhc_b_podf], 200000000);
+
+ /* System timer */
+ mxc_timer_init(NULL, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+ MX53_INT_GPT);
+
+ clk_prepare_enable(clk[iim_gate]);
+ imx_print_silicon_rev("i.MX53", mx53_revision());
+ clk_disable_unprepare(clk[iim_gate]);
+
+ r = clk_round_rate(clk[usboh3_per_gate], 54000000);
+ clk_set_rate(clk[usboh3_per_gate], r);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
+ unsigned long *ckih1, unsigned long *ckih2)
+{
+ struct device_node *np;
+
+ /* retrieve the freqency of fixed clocks from device tree */
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ u32 rate;
+ if (of_property_read_u32(np, "clock-frequency", &rate))
+ continue;
+
+ if (of_device_is_compatible(np, "fsl,imx-ckil"))
+ *ckil = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-osc"))
+ *osc = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
+ *ckih1 = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
+ *ckih2 = rate;
+ }
+}
+
+int __init mx51_clocks_init_dt(void)
+{
+ unsigned long ckil, osc, ckih1, ckih2;
+
+ clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+ return mx51_clocks_init(ckil, osc, ckih1, ckih2);
+}
+
+int __init mx53_clocks_init_dt(void)
+{
+ unsigned long ckil, osc, ckih1, ckih2;
+
+ clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+ return mx53_clocks_init(ckil, osc, ckih1, ckih2);
+}
+#endif
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
new file mode 100644
index 000000000000..cab02d0a15d6
--- /dev/null
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <mach/common.h>
+#include "clk.h"
+
+#define CCGR0 0x68
+#define CCGR1 0x6c
+#define CCGR2 0x70
+#define CCGR3 0x74
+#define CCGR4 0x78
+#define CCGR5 0x7c
+#define CCGR6 0x80
+#define CCGR7 0x84
+
+#define CLPCR 0x54
+#define BP_CLPCR_LPM 0
+#define BM_CLPCR_LPM (0x3 << 0)
+#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
+#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define BM_CLPCR_SBYOS (0x1 << 6)
+#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define BM_CLPCR_VSTBY (0x1 << 8)
+#define BP_CLPCR_STBY_COUNT 9
+#define BM_CLPCR_STBY_COUNT (0x3 << 9)
+#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
+#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
+#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
+#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
+#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
+#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
+#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
+#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
+#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
+#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
+
+static void __iomem *ccm_base;
+
+void __init imx6q_clock_map_io(void) { }
+
+int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
+{
+ u32 val = readl_relaxed(ccm_base + CLPCR);
+
+ val &= ~BM_CLPCR_LPM;
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ val |= 0x1 << BP_CLPCR_LPM;
+ break;
+ case STOP_POWER_ON:
+ val |= 0x2 << BP_CLPCR_LPM;
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ val |= 0x1 << BP_CLPCR_LPM;
+ val &= ~BM_CLPCR_VSTBY;
+ val &= ~BM_CLPCR_SBYOS;
+ break;
+ case STOP_POWER_OFF:
+ val |= 0x2 << BP_CLPCR_LPM;
+ val |= 0x3 << BP_CLPCR_STBY_COUNT;
+ val |= BM_CLPCR_VSTBY;
+ val |= BM_CLPCR_SBYOS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel_relaxed(val, ccm_base + CLPCR);
+
+ return 0;
+}
+
+static const char *step_sels[] = { "osc", "pll2_pfd2_396m", };
+static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
+static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", };
+static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", };
+static const char *periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };
+static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", };
+static const char *gpu_axi_sels[] = { "axi", "ahb", };
+static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", };
+static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", };
+static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", };
+static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", };
+static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", };
+static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", };
+static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", };
+static const char *pcie_axi_sels[] = { "axi", "ahb", };
+static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", };
+static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", };
+static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *vdo_axi_sels[] = { "axi", "ahb", };
+static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video",
+ "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0",
+ "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", };
+
+static const char * const clks_init_on[] __initconst = {
+ "mmdc_ch0_axi", "mmdc_ch1_axi", "usboh3",
+};
+
+enum mx6q_clks {
+ dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m,
+ pll3_pfd0_720m, pll3_pfd1_540m, pll3_pfd2_508m, pll3_pfd3_454m,
+ pll2_198m, pll3_120m, pll3_80m, pll3_60m, twd, step, pll1_sw,
+ periph_pre, periph2_pre, periph_clk2_sel, periph2_clk2_sel, axi_sel,
+ esai_sel, asrc_sel, spdif_sel, gpu2d_axi, gpu3d_axi, gpu2d_core_sel,
+ gpu3d_core_sel, gpu3d_shader_sel, ipu1_sel, ipu2_sel, ldb_di0_sel,
+ ldb_di1_sel, ipu1_di0_pre_sel, ipu1_di1_pre_sel, ipu2_di0_pre_sel,
+ ipu2_di1_pre_sel, ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel,
+ ipu2_di1_sel, hsi_tx_sel, pcie_axi_sel, ssi1_sel, ssi2_sel, ssi3_sel,
+ usdhc1_sel, usdhc2_sel, usdhc3_sel, usdhc4_sel, enfc_sel, emi_sel,
+ emi_slow_sel, vdo_axi_sel, vpu_axi_sel, cko1_sel, periph, periph2,
+ periph_clk2, periph2_clk2, ipg, ipg_per, esai_pred, esai_podf,
+ asrc_pred, asrc_podf, spdif_pred, spdif_podf, can_root, ecspi_root,
+ gpu2d_core_podf, gpu3d_core_podf, gpu3d_shader, ipu1_podf, ipu2_podf,
+ ldb_di0_podf, ldb_di1_podf, ipu1_di0_pre, ipu1_di1_pre, ipu2_di0_pre,
+ ipu2_di1_pre, hsi_tx_podf, ssi1_pred, ssi1_podf, ssi2_pred, ssi2_podf,
+ ssi3_pred, ssi3_podf, uart_serial_podf, usdhc1_podf, usdhc2_podf,
+ usdhc3_podf, usdhc4_podf, enfc_pred, enfc_podf, emi_podf,
+ emi_slow_podf, vpu_axi_podf, cko1_podf, axi, mmdc_ch0_axi_podf,
+ mmdc_ch1_axi_podf, arm, ahb, apbh_dma, asrc, can1_ipg, can1_serial,
+ can2_ipg, can2_serial, ecspi1, ecspi2, ecspi3, ecspi4, ecspi5, enet,
+ esai, gpt_ipg, gpt_ipg_per, gpu2d_core, gpu3d_core, hdmi_iahb,
+ hdmi_isfr, i2c1, i2c2, i2c3, iim, enfc, ipu1, ipu1_di0, ipu1_di1, ipu2,
+ ipu2_di0, ldb_di0, ldb_di1, ipu2_di1, hsi_tx, mlb, mmdc_ch0_axi,
+ mmdc_ch1_axi, ocram, openvg_axi, pcie_axi, pwm1, pwm2, pwm3, pwm4,
+ gpmi_bch_apb, gpmi_bch, gpmi_io, gpmi_apb, sata, sdma, spba, ssi1,
+ ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
+ usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
+ pll4_audio, pll5_video, pll6_mlb, pll7_usb_host, pll8_enet, ssi1_ipg,
+ ssi2_ipg, ssi3_ipg, clk_max
+};
+
+static struct clk *clk[clk_max];
+
+int __init mx6q_clocks_init(void)
+{
+ struct device_node *np;
+ void __iomem *base;
+ struct clk *c;
+ int i, irq;
+
+ clk[dummy] = imx_clk_fixed("dummy", 0);
+
+ /* retrieve the freqency of fixed clocks from device tree */
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ u32 rate;
+ if (of_property_read_u32(np, "clock-frequency", &rate))
+ continue;
+
+ if (of_device_is_compatible(np, "fsl,imx-ckil"))
+ clk[ckil] = imx_clk_fixed("ckil", rate);
+ else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
+ clk[ckih] = imx_clk_fixed("ckih", rate);
+ else if (of_device_is_compatible(np, "fsl,imx-osc"))
+ clk[osc] = imx_clk_fixed("osc", rate);
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+
+ /* type name parent_name base gate_mask div_mask */
+ clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x2000, 0x7f);
+ clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x2000, 0x1);
+ clk[pll3_usb_otg] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x2000, 0x3);
+ clk[pll4_audio] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x2000, 0x7f);
+ clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x2000, 0x7f);
+ clk[pll6_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll6_mlb", "osc", base + 0xd0, 0x2000, 0x0);
+ clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x2000, 0x3);
+ clk[pll8_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll8_enet", "osc", base + 0xe0, 0x182000, 0x3);
+
+ /* name parent_name reg idx */
+ clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0);
+ clk[pll2_pfd1_594m] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1);
+ clk[pll2_pfd2_396m] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2);
+ clk[pll3_pfd0_720m] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0);
+ clk[pll3_pfd1_540m] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1);
+ clk[pll3_pfd2_508m] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
+ clk[pll3_pfd3_454m] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
+
+ /* name parent_name mult div */
+ clk[pll2_198m] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2);
+ clk[pll3_120m] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
+ clk[pll3_80m] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
+ clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
+ clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2);
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+ ccm_base = base;
+
+ /* name reg shift width parent_names num_parents */
+ clk[step] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
+ clk[pll1_sw] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
+ clk[periph_pre] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clk[periph2_pre] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels));
+ clk[periph_clk2_sel] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clk[periph2_clk2_sel] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
+ clk[axi_sel] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels));
+ clk[esai_sel] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clk[asrc_sel] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clk[spdif_sel] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
+ clk[gpu2d_axi] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ clk[gpu3d_axi] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels));
+ clk[gpu2d_core_sel] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels));
+ clk[gpu3d_core_sel] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels));
+ clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
+ clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
+ clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels));
+ clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
+ clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels));
+ 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));
+ 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));
+ 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));
+ 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));
+ clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels));
+ clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels));
+ clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels));
+ clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels));
+ clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels));
+ clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels));
+ clk[ssi1_sel] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clk[ssi2_sel] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clk[ssi3_sel] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
+ clk[usdhc1_sel] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clk[usdhc2_sel] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clk[usdhc3_sel] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clk[usdhc4_sel] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
+ clk[enfc_sel] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels));
+ clk[emi_sel] = imx_clk_mux("emi_sel", base + 0x1c, 27, 2, emi_sels, ARRAY_SIZE(emi_sels));
+ clk[emi_slow_sel] = imx_clk_mux("emi_slow_sel", base + 0x1c, 29, 2, emi_sels, ARRAY_SIZE(emi_sels));
+ clk[vdo_axi_sel] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels));
+ clk[vpu_axi_sel] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels));
+ clk[cko1_sel] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels));
+
+ /* name reg shift width busy: reg, shift parent_names num_parents */
+ clk[periph] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
+ clk[periph2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
+
+ /* name parent_name reg shift width */
+ clk[periph_clk2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3);
+ clk[periph2_clk2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3);
+ clk[ipg] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
+ clk[ipg_per] = imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6);
+ clk[esai_pred] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3);
+ clk[esai_podf] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3);
+ clk[asrc_pred] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3);
+ clk[asrc_podf] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3);
+ clk[spdif_pred] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3);
+ clk[spdif_podf] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3);
+ clk[can_root] = imx_clk_divider("can_root", "pll3_usb_otg", base + 0x20, 2, 6);
+ clk[ecspi_root] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6);
+ clk[gpu2d_core_podf] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3);
+ clk[gpu3d_core_podf] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3);
+ clk[gpu3d_shader] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3);
+ clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3);
+ clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3);
+ clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_sel", base + 0x20, 10, 1);
+ clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_sel", base + 0x20, 11, 1);
+ clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3);
+ clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3);
+ clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3);
+ clk[ipu2_di1_pre] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3);
+ clk[hsi_tx_podf] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3);
+ clk[ssi1_pred] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
+ clk[ssi1_podf] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
+ clk[ssi2_pred] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
+ clk[ssi2_podf] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
+ clk[ssi3_pred] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
+ clk[ssi3_podf] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
+ clk[uart_serial_podf] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6);
+ clk[usdhc1_podf] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
+ clk[usdhc2_podf] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
+ clk[usdhc3_podf] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
+ clk[usdhc4_podf] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
+ clk[enfc_pred] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3);
+ clk[enfc_podf] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6);
+ clk[emi_podf] = imx_clk_divider("emi_podf", "emi_sel", base + 0x1c, 20, 3);
+ clk[emi_slow_podf] = imx_clk_divider("emi_slow_podf", "emi_slow_sel", base + 0x1c, 23, 3);
+ clk[vpu_axi_podf] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3);
+ clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3);
+
+ /* name parent_name reg shift width busy: reg, shift */
+ clk[axi] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0);
+ clk[mmdc_ch0_axi_podf] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4);
+ clk[mmdc_ch1_axi_podf] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
+ clk[arm] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
+ clk[ahb] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
+
+ /* name parent_name reg shift */
+ clk[apbh_dma] = imx_clk_gate2("apbh_dma", "ahb", base + 0x68, 4);
+ clk[asrc] = imx_clk_gate2("asrc", "asrc_podf", base + 0x68, 6);
+ clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
+ clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
+ clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
+ clk[can2_serial] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
+ clk[ecspi1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
+ clk[ecspi2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
+ clk[ecspi3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
+ clk[ecspi4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
+ clk[ecspi5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
+ clk[enet] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
+ clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
+ clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
+ clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
+ clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
+ clk[gpu3d_core] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
+ clk[hdmi_iahb] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
+ clk[hdmi_isfr] = imx_clk_gate2("hdmi_isfr", "pll3_pfd1_540m", base + 0x70, 4);
+ clk[i2c1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6);
+ clk[i2c2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8);
+ clk[i2c3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10);
+ clk[iim] = imx_clk_gate2("iim", "ipg", base + 0x70, 12);
+ clk[enfc] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14);
+ clk[ipu1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0);
+ clk[ipu1_di0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2);
+ clk[ipu1_di1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4);
+ clk[ipu2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6);
+ clk[ipu2_di0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8);
+ clk[ldb_di0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12);
+ clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
+ clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
+ clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
+ clk[mlb] = imx_clk_gate2("mlb", "pll6_mlb", base + 0x74, 18);
+ clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
+ clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
+ clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
+ clk[openvg_axi] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30);
+ clk[pcie_axi] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);
+ clk[pwm1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16);
+ clk[pwm2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18);
+ clk[pwm3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20);
+ clk[pwm4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22);
+ clk[gpmi_bch_apb] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24);
+ clk[gpmi_bch] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26);
+ clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28);
+ clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30);
+ clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4);
+ clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6);
+ clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
+ clk[ssi1_ipg] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18);
+ clk[ssi2_ipg] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20);
+ clk[ssi3_ipg] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22);
+ clk[uart_ipg] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24);
+ clk[uart_serial] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26);
+ clk[usboh3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+ clk[usdhc1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
+ clk[usdhc2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
+ clk[usdhc3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
+ clk[usdhc4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
+ clk[vdo_axi] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
+ clk[vpu_axi] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
+ clk[cko1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
+
+ for (i = 0; i < ARRAY_SIZE(clk); i++)
+ if (IS_ERR(clk[i]))
+ pr_err("i.MX6q clk %d: register failed with %ld\n",
+ i, PTR_ERR(clk[i]));
+
+ clk_register_clkdev(clk[mmdc_ch0_axi], NULL, "mmdc_ch0_axi");
+ clk_register_clkdev(clk[mmdc_ch1_axi], NULL, "mmdc_ch1_axi");
+ clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0");
+ clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0");
+ clk_register_clkdev(clk[twd], NULL, "smp_twd");
+ clk_register_clkdev(clk[usboh3], NULL, "usboh3");
+ clk_register_clkdev(clk[uart_serial], "per", "2020000.serial");
+ clk_register_clkdev(clk[uart_ipg], "ipg", "2020000.serial");
+ clk_register_clkdev(clk[uart_serial], "per", "21e8000.serial");
+ clk_register_clkdev(clk[uart_ipg], "ipg", "21e8000.serial");
+ clk_register_clkdev(clk[uart_serial], "per", "21ec000.serial");
+ clk_register_clkdev(clk[uart_ipg], "ipg", "21ec000.serial");
+ clk_register_clkdev(clk[uart_serial], "per", "21f0000.serial");
+ clk_register_clkdev(clk[uart_ipg], "ipg", "21f0000.serial");
+ clk_register_clkdev(clk[uart_serial], "per", "21f4000.serial");
+ clk_register_clkdev(clk[uart_ipg], "ipg", "21f4000.serial");
+ clk_register_clkdev(clk[enet], NULL, "2188000.ethernet");
+ clk_register_clkdev(clk[usdhc1], NULL, "2190000.usdhc");
+ clk_register_clkdev(clk[usdhc2], NULL, "2194000.usdhc");
+ clk_register_clkdev(clk[usdhc3], NULL, "2198000.usdhc");
+ clk_register_clkdev(clk[usdhc4], NULL, "219c000.usdhc");
+ clk_register_clkdev(clk[i2c1], NULL, "21a0000.i2c");
+ clk_register_clkdev(clk[i2c2], NULL, "21a4000.i2c");
+ clk_register_clkdev(clk[i2c3], NULL, "21a8000.i2c");
+ clk_register_clkdev(clk[ecspi1], NULL, "2008000.ecspi");
+ clk_register_clkdev(clk[ecspi2], NULL, "200c000.ecspi");
+ clk_register_clkdev(clk[ecspi3], NULL, "2010000.ecspi");
+ clk_register_clkdev(clk[ecspi4], NULL, "2014000.ecspi");
+ clk_register_clkdev(clk[ecspi5], NULL, "2018000.ecspi");
+ clk_register_clkdev(clk[sdma], NULL, "20ec000.sdma");
+ clk_register_clkdev(clk[dummy], NULL, "20bc000.wdog");
+ clk_register_clkdev(clk[dummy], NULL, "20c0000.wdog");
+ clk_register_clkdev(clk[ssi1_ipg], NULL, "2028000.ssi");
+ clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL);
+ clk_register_clkdev(clk[ahb], "ahb", NULL);
+ clk_register_clkdev(clk[cko1], "cko1", NULL);
+
+ for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) {
+ c = clk_get_sys(clks_init_on[i], NULL);
+ if (IS_ERR(c)) {
+ pr_err("%s: failed to get clk %s", __func__,
+ clks_init_on[i]);
+ return PTR_ERR(c);
+ }
+ clk_prepare_enable(c);
+ }
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
+ base = of_iomap(np, 0);
+ WARN_ON(!base);
+ irq = irq_of_parse_and_map(np, 0);
+ mxc_timer_init(NULL, base, irq);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c
new file mode 100644
index 000000000000..e2ed4160f329
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pfd.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include "clk.h"
+
+/**
+ * struct clk_pfd - IMX PFD clock
+ * @clk_hw: clock source
+ * @reg: PFD register address
+ * @idx: the index of PFD encoded in the register
+ *
+ * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd
+ * data encoded, and member idx is used to specify the one. And each
+ * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc.
+ */
+struct clk_pfd {
+ struct clk_hw hw;
+ void __iomem *reg;
+ u8 idx;
+};
+
+#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw)
+
+#define SET 0x4
+#define CLR 0x8
+#define OTG 0xc
+
+static int clk_pfd_enable(struct clk_hw *hw)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR);
+
+ return 0;
+}
+
+static void clk_pfd_disable(struct clk_hw *hw)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+
+ writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET);
+}
+
+static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+ u64 tmp = parent_rate;
+ u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f;
+
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ u64 tmp = *prate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+ tmp = *prate;
+ tmp *= 18;
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pfd *pfd = to_clk_pfd(hw);
+ u64 tmp = parent_rate;
+ u8 frac;
+
+ tmp = tmp * 18 + rate / 2;
+ do_div(tmp, rate);
+ frac = tmp;
+ if (frac < 12)
+ frac = 12;
+ else if (frac > 35)
+ frac = 35;
+
+ writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR);
+ writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pfd_ops = {
+ .enable = clk_pfd_enable,
+ .disable = clk_pfd_disable,
+ .recalc_rate = clk_pfd_recalc_rate,
+ .round_rate = clk_pfd_round_rate,
+ .set_rate = clk_pfd_set_rate,
+};
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx)
+{
+ struct clk_pfd *pfd;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pfd = kzalloc(sizeof(*pfd), GFP_KERNEL);
+ if (!pfd)
+ return ERR_PTR(-ENOMEM);
+
+ pfd->reg = reg;
+ pfd->idx = idx;
+
+ init.name = name;
+ init.ops = &clk_pfd_ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pfd->hw.init = &init;
+
+ clk = clk_register(NULL, &pfd->hw);
+ if (IS_ERR(clk))
+ kfree(pfd);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c
new file mode 100644
index 000000000000..2d856f9ccf59
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv1.c
@@ -0,0 +1,66 @@
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include "clk.h"
+
+/**
+ * pll v1
+ *
+ * @clk_hw clock source
+ * @parent the parent clock name
+ * @base base address of pll registers
+ *
+ * PLL clock version 1, found on i.MX1/21/25/27/31/35
+ */
+struct clk_pllv1 {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk))
+
+static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv1 *pll = to_clk_pllv1(hw);
+
+ return mxc_decode_pll(readl(pll->base), parent_rate);
+}
+
+struct clk_ops clk_pllv1_ops = {
+ .recalc_rate = clk_pllv1_recalc_rate,
+};
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv1 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kmalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+
+ init.name = name;
+ init.ops = &clk_pllv1_ops;
+ init.flags = 0;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c
new file mode 100644
index 000000000000..4685919deb63
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv2.c
@@ -0,0 +1,249 @@
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#include <asm/div64.h>
+
+#include "clk.h"
+
+#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk))
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
+
+struct clk_pllv2 {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ void __iomem *pllbase;
+ s64 temp;
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+
+ pllbase = pll->base;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * parent_rate;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ u32 reg;
+ void __iomem *pllbase;
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+ unsigned long pll_hfsm, dp_ctl;
+
+ pllbase = pll->base;
+
+ quad_parent_rate = 4 * parent_rate;
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -EINVAL;
+ pdf--;
+
+ temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+ do_div(temp64, quad_parent_rate/1000000);
+ mfn = (long)temp64;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ if (pll_hfsm == 0) {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ } else {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+
+ return 0;
+}
+
+static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ return rate;
+}
+
+static int clk_pllv2_prepare(struct clk_hw *hw)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ u32 reg;
+ void __iomem *pllbase;
+ int i = 0;
+
+ pllbase = pll->base;
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ if (reg & MXC_PLL_DP_CTL_LRF)
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: pll locking failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void clk_pllv2_unprepare(struct clk_hw *hw)
+{
+ struct clk_pllv2 *pll = to_clk_pllv2(hw);
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = pll->base;
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+struct clk_ops clk_pllv2_ops = {
+ .prepare = clk_pllv2_prepare,
+ .unprepare = clk_pllv2_unprepare,
+ .recalc_rate = clk_pllv2_recalc_rate,
+ .round_rate = clk_pllv2_round_rate,
+ .set_rate = clk_pllv2_set_rate,
+};
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base)
+{
+ struct clk_pllv2 *pll;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ pll->base = base;
+
+ init.name = name;
+ init.ops = &clk_pllv2_ops;
+ init.flags = 0;
+ init.parent_names = &parent;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c
new file mode 100644
index 000000000000..36aac947bce1
--- /dev/null
+++ b/arch/arm/mach-imx/clk-pllv3.c
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include "clk.h"
+
+#define PLL_NUM_OFFSET 0x10
+#define PLL_DENOM_OFFSET 0x20
+
+#define BM_PLL_POWER (0x1 << 12)
+#define BM_PLL_ENABLE (0x1 << 13)
+#define BM_PLL_BYPASS (0x1 << 16)
+#define BM_PLL_LOCK (0x1 << 31)
+
+/**
+ * struct clk_pllv3 - IMX PLL clock version 3
+ * @clk_hw: clock source
+ * @base: base address of PLL registers
+ * @powerup_set: set POWER bit to power up the PLL
+ * @gate_mask: mask of gate bits
+ * @div_mask: mask of divider bits
+ *
+ * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
+ * is actually a multiplier, and always sits at bit 0.
+ */
+struct clk_pllv3 {
+ struct clk_hw hw;
+ void __iomem *base;
+ bool powerup_set;
+ u32 gate_mask;
+ u32 div_mask;
+};
+
+#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw)
+
+static int clk_pllv3_prepare(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long timeout = jiffies + msecs_to_jiffies(10);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ val &= ~BM_PLL_BYPASS;
+ if (pll->powerup_set)
+ val |= BM_PLL_POWER;
+ else
+ val &= ~BM_PLL_POWER;
+ writel_relaxed(val, pll->base);
+
+ /* Wait for PLL to lock */
+ while (!(readl_relaxed(pll->base) & BM_PLL_LOCK))
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static void clk_pllv3_unprepare(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ val |= BM_PLL_BYPASS;
+ if (pll->powerup_set)
+ val &= ~BM_PLL_POWER;
+ else
+ val |= BM_PLL_POWER;
+ writel_relaxed(val, pll->base);
+}
+
+static int clk_pllv3_enable(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ val |= pll->gate_mask;
+ writel_relaxed(val, pll->base);
+
+ return 0;
+}
+
+static void clk_pllv3_disable(struct clk_hw *hw)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val;
+
+ val = readl_relaxed(pll->base);
+ val &= ~pll->gate_mask;
+ writel_relaxed(val, pll->base);
+}
+
+static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ return (div == 1) ? parent_rate * 22 : parent_rate * 20;
+}
+
+static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+
+ return (rate >= parent_rate * 22) ? parent_rate * 22 :
+ parent_rate * 20;
+}
+
+static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val, div;
+
+ if (rate == parent_rate * 22)
+ div = 1;
+ else if (rate == parent_rate * 20)
+ div = 0;
+ else
+ return -EINVAL;
+
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_recalc_rate,
+ .round_rate = clk_pllv3_round_rate,
+ .set_rate = clk_pllv3_set_rate,
+};
+
+static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ return parent_rate * div / 2;
+}
+
+static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 div;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+ div = rate * 2 / parent_rate;
+
+ return parent_rate * div / 2;
+}
+
+static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long min_rate = parent_rate * 54 / 2;
+ unsigned long max_rate = parent_rate * 108 / 2;
+ u32 val, div;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate * 2 / parent_rate;
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_sys_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_sys_recalc_rate,
+ .round_rate = clk_pllv3_sys_round_rate,
+ .set_rate = clk_pllv3_sys_set_rate,
+};
+
+static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
+ u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ return (parent_rate * div) + ((parent_rate / mfd) * mfn);
+}
+
+static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ unsigned long parent_rate = *prate;
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 div;
+ u32 mfn, mfd = 1000000;
+ s64 temp64;
+
+ if (rate > max_rate)
+ rate = max_rate;
+ else if (rate < min_rate)
+ rate = min_rate;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ return parent_rate * div + parent_rate / mfd * mfn;
+}
+
+static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ unsigned long min_rate = parent_rate * 27;
+ unsigned long max_rate = parent_rate * 54;
+ u32 val, div;
+ u32 mfn, mfd = 1000000;
+ s64 temp64;
+
+ if (rate < min_rate || rate > max_rate)
+ return -EINVAL;
+
+ div = rate / parent_rate;
+ temp64 = (u64) (rate - div * parent_rate);
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+ writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET);
+ writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_av_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_av_recalc_rate,
+ .round_rate = clk_pllv3_av_round_rate,
+ .set_rate = clk_pllv3_av_set_rate,
+};
+
+static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 div = readl_relaxed(pll->base) & pll->div_mask;
+
+ switch (div) {
+ case 0:
+ return 25000000;
+ case 1:
+ return 50000000;
+ case 2:
+ return 100000000;
+ case 3:
+ return 125000000;
+ }
+
+ return 0;
+}
+
+static long clk_pllv3_enet_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+ if (rate >= 125000000)
+ rate = 125000000;
+ else if (rate >= 100000000)
+ rate = 100000000;
+ else if (rate >= 50000000)
+ rate = 50000000;
+ else
+ rate = 25000000;
+ return rate;
+}
+
+static int clk_pllv3_enet_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_pllv3 *pll = to_clk_pllv3(hw);
+ u32 val, div;
+
+ switch (rate) {
+ case 25000000:
+ div = 0;
+ break;
+ case 50000000:
+ div = 1;
+ break;
+ case 100000000:
+ div = 2;
+ break;
+ case 125000000:
+ div = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = readl_relaxed(pll->base);
+ val &= ~pll->div_mask;
+ val |= div;
+ writel_relaxed(val, pll->base);
+
+ return 0;
+}
+
+static const struct clk_ops clk_pllv3_enet_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+ .recalc_rate = clk_pllv3_enet_recalc_rate,
+ .round_rate = clk_pllv3_enet_round_rate,
+ .set_rate = clk_pllv3_enet_set_rate,
+};
+
+static const struct clk_ops clk_pllv3_mlb_ops = {
+ .prepare = clk_pllv3_prepare,
+ .unprepare = clk_pllv3_unprepare,
+ .enable = clk_pllv3_enable,
+ .disable = clk_pllv3_disable,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent_name, void __iomem *base,
+ u32 gate_mask, u32 div_mask)
+{
+ struct clk_pllv3 *pll;
+ const struct clk_ops *ops;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+ if (!pll)
+ return ERR_PTR(-ENOMEM);
+
+ switch (type) {
+ case IMX_PLLV3_SYS:
+ ops = &clk_pllv3_sys_ops;
+ break;
+ case IMX_PLLV3_USB:
+ ops = &clk_pllv3_ops;
+ pll->powerup_set = true;
+ break;
+ case IMX_PLLV3_AV:
+ ops = &clk_pllv3_av_ops;
+ break;
+ case IMX_PLLV3_ENET:
+ ops = &clk_pllv3_enet_ops;
+ break;
+ case IMX_PLLV3_MLB:
+ ops = &clk_pllv3_mlb_ops;
+ break;
+ default:
+ ops = &clk_pllv3_ops;
+ }
+ pll->base = base;
+ pll->gate_mask = gate_mask;
+ pll->div_mask = div_mask;
+
+ init.name = name;
+ init.ops = ops;
+ init.flags = 0;
+ init.parent_names = &parent_name;
+ init.num_parents = 1;
+
+ pll->hw.init = &init;
+
+ clk = clk_register(NULL, &pll->hw);
+ if (IS_ERR(clk))
+ kfree(pll);
+
+ return clk;
+}
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
new file mode 100644
index 000000000000..1bf64fe2523c
--- /dev/null
+++ b/arch/arm/mach-imx/clk.h
@@ -0,0 +1,83 @@
+#ifndef __MACH_IMX_CLK_H
+#define __MACH_IMX_CLK_H
+
+#include <linux/spinlock.h>
+#include <linux/clk-provider.h>
+#include <mach/clock.h>
+
+struct clk *imx_clk_pllv1(const char *name, const char *parent,
+ void __iomem *base);
+
+struct clk *imx_clk_pllv2(const char *name, const char *parent,
+ void __iomem *base);
+
+enum imx_pllv3_type {
+ IMX_PLLV3_GENERIC,
+ IMX_PLLV3_SYS,
+ IMX_PLLV3_USB,
+ IMX_PLLV3_AV,
+ IMX_PLLV3_ENET,
+ IMX_PLLV3_MLB,
+};
+
+struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
+ const char *parent_name, void __iomem *base, u32 gate_mask,
+ u32 div_mask);
+
+struct clk *clk_register_gate2(struct device *dev, const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate_flags, spinlock_t *lock);
+
+static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock);
+}
+
+struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+ void __iomem *reg, u8 idx);
+
+struct clk *imx_clk_busy_divider(const char *name, const char *parent_name,
+ void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift);
+
+struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
+ u8 width, void __iomem *busy_reg, u8 busy_shift,
+ const char **parent_names, int num_parents);
+
+static inline struct clk *imx_clk_fixed(const char *name, int rate)
+{
+ return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
+}
+
+static inline struct clk *imx_clk_divider(const char *name, const char *parent,
+ void __iomem *reg, u8 shift, u8 width)
+{
+ return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+ reg, shift, width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_gate(const char *name, const char *parent,
+ void __iomem *reg, u8 shift)
+{
+ return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
+ shift, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
+ u8 shift, u8 width, const char **parents, int num_parents)
+{
+ return clk_register_mux(NULL, name, parents, num_parents, 0, reg, shift,
+ width, 0, &imx_ccm_lock);
+}
+
+static inline struct clk *imx_clk_fixed_factor(const char *name,
+ const char *parent, unsigned int mult, unsigned int div)
+{
+ return clk_register_fixed_factor(NULL, name, parent,
+ CLK_SET_RATE_PARENT, mult, div);
+}
+
+#endif
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
deleted file mode 100644
index 4aabeb241563..000000000000
--- a/arch/arm/mach-imx/clock-imx1.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/math64.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
-#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
-
-/* CCM register addresses */
-#define CCM_CSCR IO_ADDR_CCM(0x0)
-#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
-#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
-#define CCM_PCDR IO_ADDR_CCM(0x20)
-
-#define CCM_CSCR_CLKO_OFFSET 29
-#define CCM_CSCR_CLKO_MASK (0x7 << 29)
-#define CCM_CSCR_USB_OFFSET 26
-#define CCM_CSCR_USB_MASK (0x7 << 26)
-#define CCM_CSCR_OSC_EN_SHIFT 17
-#define CCM_CSCR_SYSTEM_SEL (1 << 16)
-#define CCM_CSCR_BCLK_OFFSET 10
-#define CCM_CSCR_BCLK_MASK (0xf << 10)
-#define CCM_CSCR_PRESC (1 << 15)
-
-#define CCM_PCDR_PCLK3_OFFSET 16
-#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
-#define CCM_PCDR_PCLK2_OFFSET 4
-#define CCM_PCDR_PCLK2_MASK (0xf << 4)
-#define CCM_PCDR_PCLK1_OFFSET 0
-#define CCM_PCDR_PCLK1_MASK 0xf
-
-#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
-
-/* SCM register addresses */
-#define SCM_GCCR IO_ADDR_SCM(0xc)
-
-#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
-#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
-#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
-#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
-
-static int _clk_enable(struct clk *clk)
-{
- unsigned int reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void _clk_disable(struct clk *clk)
-{
- unsigned int reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-}
-
-static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size,
- struct clk *parent)
-{
- int i;
-
- for (i = 0; i < size; i++)
- if (parent == clk_arr[i])
- return i;
-
- return -EINVAL;
-}
-
-static unsigned long
-_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit)
-{
- int div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > limit)
- div = limit;
-
- return parent_rate / div;
-}
-
-static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
-{
- return clk->parent->round_rate(clk->parent, rate);
-}
-
-static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
-{
- return clk->parent->set_rate(clk->parent, rate);
-}
-
-static unsigned long clk16m_get_rate(struct clk *clk)
-{
- return 16000000;
-}
-
-static struct clk clk16m = {
- .get_rate = clk16m_get_rate,
- .enable = _clk_enable,
- .enable_reg = CCM_CSCR,
- .enable_shift = CCM_CSCR_OSC_EN_SHIFT,
- .disable = _clk_disable,
-};
-
-/* in Hz */
-static unsigned long clk32_rate;
-
-static unsigned long clk32_get_rate(struct clk *clk)
-{
- return clk32_rate;
-}
-
-static struct clk clk32 = {
- .get_rate = clk32_get_rate,
-};
-
-static unsigned long clk32_premult_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) * 512;
-}
-
-static struct clk clk32_premult = {
- .parent = &clk32,
- .get_rate = clk32_premult_get_rate,
-};
-
-static const struct clk *prem_clk_clocks[] = {
- &clk32_premult,
- &clk16m,
-};
-
-static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- int i;
- unsigned int reg = __raw_readl(CCM_CSCR);
-
- i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks),
- parent);
-
- switch (i) {
- case 0:
- reg &= ~CCM_CSCR_SYSTEM_SEL;
- break;
- case 1:
- reg |= CCM_CSCR_SYSTEM_SEL;
- break;
- default:
- return i;
- }
-
- __raw_writel(reg, CCM_CSCR);
-
- return 0;
-}
-
-static struct clk prem_clk = {
- .set_parent = prem_clk_set_parent,
-};
-
-static unsigned long system_clk_get_rate(struct clk *clk)
-{
- return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
- clk_get_rate(clk->parent));
-}
-
-static struct clk system_clk = {
- .parent = &prem_clk,
- .get_rate = system_clk_get_rate,
-};
-
-static unsigned long mcu_clk_get_rate(struct clk *clk)
-{
- return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
- clk_get_rate(clk->parent));
-}
-
-static struct clk mcu_clk = {
- .parent = &clk32_premult,
- .get_rate = mcu_clk_get_rate,
-};
-
-static unsigned long fclk_get_rate(struct clk *clk)
-{
- unsigned long fclk = clk_get_rate(clk->parent);
-
- if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC)
- fclk /= 2;
-
- return fclk;
-}
-
-static struct clk fclk = {
- .parent = &mcu_clk,
- .get_rate = fclk_get_rate,
-};
-
-/*
- * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
- */
-static unsigned long hclk_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
- CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1);
-}
-
-static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_simple_round_rate(clk, rate, 16);
-}
-
-static int hclk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- unsigned int reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 16 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_CSCR);
- reg &= ~CCM_CSCR_BCLK_MASK;
- reg |= div << CCM_CSCR_BCLK_OFFSET;
- __raw_writel(reg, CCM_CSCR);
-
- return 0;
-}
-
-static struct clk hclk = {
- .parent = &system_clk,
- .get_rate = hclk_get_rate,
- .round_rate = hclk_round_rate,
- .set_rate = hclk_set_rate,
-};
-
-static unsigned long clk48m_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
- CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1);
-}
-
-static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_simple_round_rate(clk, rate, 8);
-}
-
-static int clk48m_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- unsigned int reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 8 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_CSCR);
- reg &= ~CCM_CSCR_USB_MASK;
- reg |= div << CCM_CSCR_USB_OFFSET;
- __raw_writel(reg, CCM_CSCR);
-
- return 0;
-}
-
-static struct clk clk48m = {
- .parent = &system_clk,
- .get_rate = clk48m_get_rate,
- .round_rate = clk48m_round_rate,
- .set_rate = clk48m_set_rate,
-};
-
-/*
- * get peripheral clock 1 ( UART[12], Timer[12], PWM )
- */
-static unsigned long perclk1_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
- CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1);
-}
-
-static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_simple_round_rate(clk, rate, 16);
-}
-
-static int perclk1_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- unsigned int reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 16 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_PCDR);
- reg &= ~CCM_PCDR_PCLK1_MASK;
- reg |= div << CCM_PCDR_PCLK1_OFFSET;
- __raw_writel(reg, CCM_PCDR);
-
- return 0;
-}
-
-/*
- * get peripheral clock 2 ( LCD, SD, SPI[12] )
- */
-static unsigned long perclk2_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
- CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1);
-}
-
-static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_simple_round_rate(clk, rate, 16);
-}
-
-static int perclk2_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- unsigned int reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 16 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_PCDR);
- reg &= ~CCM_PCDR_PCLK2_MASK;
- reg |= div << CCM_PCDR_PCLK2_OFFSET;
- __raw_writel(reg, CCM_PCDR);
-
- return 0;
-}
-
-/*
- * get peripheral clock 3 ( SSI )
- */
-static unsigned long perclk3_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
- CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1);
-}
-
-static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_simple_round_rate(clk, rate, 128);
-}
-
-static int perclk3_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- unsigned int reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 128 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_PCDR);
- reg &= ~CCM_PCDR_PCLK3_MASK;
- reg |= div << CCM_PCDR_PCLK3_OFFSET;
- __raw_writel(reg, CCM_PCDR);
-
- return 0;
-}
-
-static struct clk perclk[] = {
- {
- .id = 0,
- .parent = &system_clk,
- .get_rate = perclk1_get_rate,
- .round_rate = perclk1_round_rate,
- .set_rate = perclk1_set_rate,
- }, {
- .id = 1,
- .parent = &system_clk,
- .get_rate = perclk2_get_rate,
- .round_rate = perclk2_round_rate,
- .set_rate = perclk2_set_rate,
- }, {
- .id = 2,
- .parent = &system_clk,
- .get_rate = perclk3_get_rate,
- .round_rate = perclk3_round_rate,
- .set_rate = perclk3_set_rate,
- }
-};
-
-static const struct clk *clko_clocks[] = {
- &perclk[0],
- &hclk,
- &clk48m,
- &clk16m,
- &prem_clk,
- &fclk,
-};
-
-static int clko_set_parent(struct clk *clk, struct clk *parent)
-{
- int i;
- unsigned int reg;
-
- i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent);
- if (i < 0)
- return i;
-
- reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK;
- reg |= i << CCM_CSCR_CLKO_OFFSET;
- __raw_writel(reg, CCM_CSCR);
-
- if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) {
- clk->set_rate = _clk_parent_set_rate;
- clk->round_rate = _clk_parent_round_rate;
- } else {
- clk->set_rate = NULL;
- clk->round_rate = NULL;
- }
-
- return 0;
-}
-
-static struct clk clko_clk = {
- .set_parent = clko_set_parent,
-};
-
-static struct clk dma_clk = {
- .parent = &hclk,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- .enable = _clk_enable,
- .enable_reg = SCM_GCCR,
- .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk csi_clk = {
- .parent = &hclk,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- .enable = _clk_enable,
- .enable_reg = SCM_GCCR,
- .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk mma_clk = {
- .parent = &hclk,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- .enable = _clk_enable,
- .enable_reg = SCM_GCCR,
- .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk usbd_clk = {
- .parent = &clk48m,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- .enable = _clk_enable,
- .enable_reg = SCM_GCCR,
- .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk gpt_clk = {
- .parent = &perclk[0],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk uart_clk = {
- .parent = &perclk[0],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk i2c_clk = {
- .parent = &hclk,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk spi_clk = {
- .parent = &perclk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk sdhc_clk = {
- .parent = &perclk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk lcdc_clk = {
- .parent = &perclk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk mshc_clk = {
- .parent = &hclk,
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk ssi_clk = {
- .parent = &perclk[2],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
-};
-
-static struct clk rtc_clk = {
- .parent = &clk32,
-};
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-static struct clk_lookup lookups[] __initdata = {
- _REGISTER_CLOCK(NULL, "dma", dma_clk)
- _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
- _REGISTER_CLOCK(NULL, "mma", mma_clk)
- _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
- _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
- _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk)
- _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk)
- _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
- _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
- _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
- _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
- _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
- _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
- _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
- _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
-};
-
-int __init mx1_clocks_init(unsigned long fref)
-{
- unsigned int reg;
-
- /* disable clocks we are able to */
- __raw_writel(0, SCM_GCCR);
-
- clk32_rate = fref;
- reg = __raw_readl(CCM_CSCR);
-
- /* detect clock reference for system PLL */
- if (reg & CCM_CSCR_SYSTEM_SEL) {
- prem_clk.parent = &clk16m;
- } else {
- /* ensure that oscillator is disabled */
- reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT);
- __raw_writel(reg, CCM_CSCR);
- prem_clk.parent = &clk32_premult;
- }
-
- /* detect reference for CLKO */
- reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
- clko_clk.parent = (struct clk *)clko_clocks[reg];
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- clk_enable(&hclk);
- clk_enable(&fclk);
-
- mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
- MX1_TIM1_INT);
-
- return 0;
-}
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
deleted file mode 100644
index ee15d8c9db08..000000000000
--- a/arch/arm/mach-imx/clock-imx21.c
+++ /dev/null
@@ -1,1239 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <asm/div64.h>
-
-#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
-
-/* Register offsets */
-#define CCM_CSCR IO_ADDR_CCM(0x0)
-#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
-#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
-#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
-#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
-#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
-#define CCM_PCDR0 IO_ADDR_CCM(0x18)
-#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
-#define CCM_PCCR0 IO_ADDR_CCM(0x20)
-#define CCM_PCCR1 IO_ADDR_CCM(0x24)
-#define CCM_CCSR IO_ADDR_CCM(0x28)
-#define CCM_PMCTL IO_ADDR_CCM(0x2c)
-#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
-#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
-
-#define CCM_CSCR_PRESC_OFFSET 29
-#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
-
-#define CCM_CSCR_USB_OFFSET 26
-#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
-#define CCM_CSCR_SD_OFFSET 24
-#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
-#define CCM_CSCR_SPLLRES (1 << 22)
-#define CCM_CSCR_MPLLRES (1 << 21)
-#define CCM_CSCR_SSI2_OFFSET 20
-#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
-#define CCM_CSCR_SSI1_OFFSET 19
-#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
-#define CCM_CSCR_FIR_OFFSET 18
-#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
-#define CCM_CSCR_SP (1 << 17)
-#define CCM_CSCR_MCU (1 << 16)
-#define CCM_CSCR_BCLK_OFFSET 10
-#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
-#define CCM_CSCR_IPDIV_OFFSET 9
-#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
-
-#define CCM_CSCR_OSC26MDIV (1 << 4)
-#define CCM_CSCR_OSC26M (1 << 3)
-#define CCM_CSCR_FPM (1 << 2)
-#define CCM_CSCR_SPEN (1 << 1)
-#define CCM_CSCR_MPEN 1
-
-#define CCM_MPCTL0_CPLM (1 << 31)
-#define CCM_MPCTL0_PD_OFFSET 26
-#define CCM_MPCTL0_PD_MASK (0xf << 26)
-#define CCM_MPCTL0_MFD_OFFSET 16
-#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
-#define CCM_MPCTL0_MFI_OFFSET 10
-#define CCM_MPCTL0_MFI_MASK (0xf << 10)
-#define CCM_MPCTL0_MFN_OFFSET 0
-#define CCM_MPCTL0_MFN_MASK 0x3ff
-
-#define CCM_MPCTL1_LF (1 << 15)
-#define CCM_MPCTL1_BRMO (1 << 6)
-
-#define CCM_SPCTL0_CPLM (1 << 31)
-#define CCM_SPCTL0_PD_OFFSET 26
-#define CCM_SPCTL0_PD_MASK (0xf << 26)
-#define CCM_SPCTL0_MFD_OFFSET 16
-#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
-#define CCM_SPCTL0_MFI_OFFSET 10
-#define CCM_SPCTL0_MFI_MASK (0xf << 10)
-#define CCM_SPCTL0_MFN_OFFSET 0
-#define CCM_SPCTL0_MFN_MASK 0x3ff
-
-#define CCM_SPCTL1_LF (1 << 15)
-#define CCM_SPCTL1_BRMO (1 << 6)
-
-#define CCM_OSC26MCTL_PEAK_OFFSET 16
-#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
-#define CCM_OSC26MCTL_AGC_OFFSET 8
-#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
-#define CCM_OSC26MCTL_ANATEST_OFFSET 0
-#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
-
-#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
-#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
-#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
-#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
-#define CCM_PCDR0_NFCDIV_OFFSET 12
-#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
-#define CCM_PCDR0_48MDIV_OFFSET 5
-#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
-#define CCM_PCDR0_FIRIDIV_OFFSET 0
-#define CCM_PCDR0_FIRIDIV_MASK 0x1f
-#define CCM_PCDR1_PERDIV4_OFFSET 24
-#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
-#define CCM_PCDR1_PERDIV3_OFFSET 16
-#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
-#define CCM_PCDR1_PERDIV2_OFFSET 8
-#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
-#define CCM_PCDR1_PERDIV1_OFFSET 0
-#define CCM_PCDR1_PERDIV1_MASK 0x3f
-
-#define CCM_PCCR_HCLK_CSI_OFFSET 31
-#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_DMA_OFFSET 30
-#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_BROM_OFFSET 28
-#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_EMMA_OFFSET 27
-#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_LCDC_OFFSET 26
-#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
-#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
-#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
-#define CCM_PCCR_HCLK_BMI_OFFSET 23
-#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
-#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
-#define CCM_PCCR_PERCLK4_OFFSET 22
-#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
-#define CCM_PCCR_SLCDC_OFFSET 21
-#define CCM_PCCR_SLCDC_REG CCM_PCCR0
-#define CCM_PCCR_FIRI_BAUD_OFFSET 20
-#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
-#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_NFC_OFFSET 19
-#define CCM_PCCR_NFC_REG CCM_PCCR0
-#define CCM_PCCR_LCDC_OFFSET 18
-#define CCM_PCCR_LCDC_REG CCM_PCCR0
-#define CCM_PCCR_SSI1_BAUD_OFFSET 17
-#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_SSI2_BAUD_OFFSET 16
-#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
-#define CCM_PCCR_EMMA_OFFSET 15
-#define CCM_PCCR_EMMA_REG CCM_PCCR0
-#define CCM_PCCR_USBOTG_OFFSET 14
-#define CCM_PCCR_USBOTG_REG CCM_PCCR0
-#define CCM_PCCR_DMA_OFFSET 13
-#define CCM_PCCR_DMA_REG CCM_PCCR0
-#define CCM_PCCR_I2C1_OFFSET 12
-#define CCM_PCCR_I2C1_REG CCM_PCCR0
-#define CCM_PCCR_GPIO_OFFSET 11
-#define CCM_PCCR_GPIO_REG CCM_PCCR0
-#define CCM_PCCR_SDHC2_OFFSET 10
-#define CCM_PCCR_SDHC2_REG CCM_PCCR0
-#define CCM_PCCR_SDHC1_OFFSET 9
-#define CCM_PCCR_SDHC1_REG CCM_PCCR0
-#define CCM_PCCR_FIRI_OFFSET 8
-#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
-#define CCM_PCCR_FIRI_REG CCM_PCCR0
-#define CCM_PCCR_SSI2_IPG_OFFSET 7
-#define CCM_PCCR_SSI2_REG CCM_PCCR0
-#define CCM_PCCR_SSI1_IPG_OFFSET 6
-#define CCM_PCCR_SSI1_REG CCM_PCCR0
-#define CCM_PCCR_CSPI2_OFFSET 5
-#define CCM_PCCR_CSPI2_REG CCM_PCCR0
-#define CCM_PCCR_CSPI1_OFFSET 4
-#define CCM_PCCR_CSPI1_REG CCM_PCCR0
-#define CCM_PCCR_UART4_OFFSET 3
-#define CCM_PCCR_UART4_REG CCM_PCCR0
-#define CCM_PCCR_UART3_OFFSET 2
-#define CCM_PCCR_UART3_REG CCM_PCCR0
-#define CCM_PCCR_UART2_OFFSET 1
-#define CCM_PCCR_UART2_REG CCM_PCCR0
-#define CCM_PCCR_UART1_OFFSET 0
-#define CCM_PCCR_UART1_REG CCM_PCCR0
-
-#define CCM_PCCR_OWIRE_OFFSET 31
-#define CCM_PCCR_OWIRE_REG CCM_PCCR1
-#define CCM_PCCR_KPP_OFFSET 30
-#define CCM_PCCR_KPP_REG CCM_PCCR1
-#define CCM_PCCR_RTC_OFFSET 29
-#define CCM_PCCR_RTC_REG CCM_PCCR1
-#define CCM_PCCR_PWM_OFFSET 28
-#define CCM_PCCR_PWM_REG CCM_PCCR1
-#define CCM_PCCR_GPT3_OFFSET 27
-#define CCM_PCCR_GPT3_REG CCM_PCCR1
-#define CCM_PCCR_GPT2_OFFSET 26
-#define CCM_PCCR_GPT2_REG CCM_PCCR1
-#define CCM_PCCR_GPT1_OFFSET 25
-#define CCM_PCCR_GPT1_REG CCM_PCCR1
-#define CCM_PCCR_WDT_OFFSET 24
-#define CCM_PCCR_WDT_REG CCM_PCCR1
-#define CCM_PCCR_CSPI3_OFFSET 23
-#define CCM_PCCR_CSPI3_REG CCM_PCCR1
-
-#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
-#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
-#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
-#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
-#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
-#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
-#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
-#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
-#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
-#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
-#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
-#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
-#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
-#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
-#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
-#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
-#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
-#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
-#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
-#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
-#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
-#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
-#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
-#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
-#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
-#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
-#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
-#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
-#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
-#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
-#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
-#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
-#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
-#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
-#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
-#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
-#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
-
-#define CCM_CCSR_32KSR (1 << 15)
-
-#define CCM_CCSR_CLKMODE1 (1 << 9)
-#define CCM_CCSR_CLKMODE0 (1 << 8)
-
-#define CCM_CCSR_CLKOSEL_OFFSET 0
-#define CCM_CCSR_CLKOSEL_MASK 0x1f
-
-#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
-#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
-
-static int _clk_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
- return 0;
-}
-
-static void _clk_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-}
-
-static unsigned long _clk_generic_round_rate(struct clk *clk,
- unsigned long rate,
- u32 max_divisor)
-{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > max_divisor)
- div = max_divisor;
-
- return parent_rate / div;
-}
-
-static int _clk_spll_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_CSCR);
- reg |= CCM_CSCR_SPEN;
- __raw_writel(reg, CCM_CSCR);
-
- while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
- ;
- return 0;
-}
-
-static void _clk_spll_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_CSCR);
- reg &= ~CCM_CSCR_SPEN;
- __raw_writel(reg, CCM_CSCR);
-}
-
-
-#define CSCR() (__raw_readl(CCM_CSCR))
-#define PCDR0() (__raw_readl(CCM_PCDR0))
-#define PCDR1() (__raw_readl(CCM_PCDR1))
-
-static unsigned long _clk_perclkx_round_rate(struct clk *clk,
- unsigned long rate)
-{
- return _clk_generic_round_rate(clk, rate, 64);
-}
-
-static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->id < 0 || clk->id > 3)
- return -EINVAL;
-
- div = parent_rate / rate;
- if (div > 64 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
- div--;
-
- reg =
- __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
- (clk->id << 3));
- reg |= div << (clk->id << 3);
- __raw_writel(reg, CCM_PCDR1);
-
- return 0;
-}
-
-static unsigned long _clk_usb_recalc(struct clk *clk)
-{
- unsigned long usb_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
-
- return parent_rate / (usb_pdf + 1U);
-}
-
-static unsigned long _clk_usb_round_rate(struct clk *clk,
- unsigned long rate)
-{
- return _clk_generic_round_rate(clk, rate, 8);
-}
-
-static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (div > 8 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
- div--;
-
- reg = CSCR() & ~CCM_CSCR_USB_MASK;
- reg |= div << CCM_CSCR_USB_OFFSET;
- __raw_writel(reg, CCM_CSCR);
-
- return 0;
-}
-
-static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
-{
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
-
- return 2UL * parent_rate / pdf;
-}
-
-static unsigned long _clk_ssi1_recalc(struct clk *clk)
-{
- return _clk_ssix_recalc(clk,
- (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
- >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
-}
-
-static unsigned long _clk_ssi2_recalc(struct clk *clk)
-{
- return _clk_ssix_recalc(clk,
- (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
- CCM_PCDR0_SSI2BAUDDIV_OFFSET);
-}
-
-static unsigned long _clk_nfc_recalc(struct clk *clk)
-{
- unsigned long nfc_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
- >> CCM_PCDR0_NFCDIV_OFFSET;
-
- return parent_rate / (nfc_pdf + 1);
-}
-
-static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
-{
- return clk->parent->round_rate(clk->parent, rate);
-}
-
-static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
-{
- return clk->parent->set_rate(clk->parent, rate);
-}
-
-static unsigned long external_high_reference; /* in Hz */
-
-static unsigned long get_high_reference_clock_rate(struct clk *clk)
-{
- return external_high_reference;
-}
-
-/*
- * the high frequency external clock reference
- * Default case is 26MHz.
- */
-static struct clk ckih_clk = {
- .get_rate = get_high_reference_clock_rate,
-};
-
-static unsigned long external_low_reference; /* in Hz */
-
-static unsigned long get_low_reference_clock_rate(struct clk *clk)
-{
- return external_low_reference;
-}
-
-/*
- * the low frequency external clock reference
- * Default case is 32.768kHz.
- */
-static struct clk ckil_clk = {
- .get_rate = get_low_reference_clock_rate,
-};
-
-
-static unsigned long _clk_fpm_recalc(struct clk *clk)
-{
- return clk_get_rate(clk->parent) * 512;
-}
-
-/* Output of frequency pre multiplier */
-static struct clk fpm_clk = {
- .parent = &ckil_clk,
- .get_rate = _clk_fpm_recalc,
-};
-
-static unsigned long get_mpll_clk(struct clk *clk)
-{
- uint32_t reg;
- unsigned long ref_clk;
- unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
- unsigned long long temp;
-
- ref_clk = clk_get_rate(clk->parent);
-
- reg = __raw_readl(CCM_MPCTL0);
- pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
- mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
- mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
- mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
-
- mfi = (mfi <= 5) ? 5 : mfi;
- temp = 2LL * ref_clk * mfn;
- do_div(temp, mfd + 1);
- temp = 2LL * ref_clk * mfi + temp;
- do_div(temp, pdf + 1);
-
- return (unsigned long)temp;
-}
-
-static struct clk mpll_clk = {
- .parent = &ckih_clk,
- .get_rate = get_mpll_clk,
-};
-
-static unsigned long _clk_fclk_get_rate(struct clk *clk)
-{
- unsigned long parent_rate;
- u32 div;
-
- div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
- parent_rate = clk_get_rate(clk->parent);
-
- return parent_rate / (div+1);
-}
-
-static struct clk fclk_clk = {
- .parent = &mpll_clk,
- .get_rate = _clk_fclk_get_rate
-};
-
-static unsigned long get_spll_clk(struct clk *clk)
-{
- uint32_t reg;
- unsigned long ref_clk;
- unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
- unsigned long long temp;
-
- ref_clk = clk_get_rate(clk->parent);
-
- reg = __raw_readl(CCM_SPCTL0);
- pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
- mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
- mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
- mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
-
- mfi = (mfi <= 5) ? 5 : mfi;
- temp = 2LL * ref_clk * mfn;
- do_div(temp, mfd + 1);
- temp = 2LL * ref_clk * mfi + temp;
- do_div(temp, pdf + 1);
-
- return (unsigned long)temp;
-}
-
-static struct clk spll_clk = {
- .parent = &ckih_clk,
- .get_rate = get_spll_clk,
- .enable = _clk_spll_enable,
- .disable = _clk_spll_disable,
-};
-
-static unsigned long get_hclk_clk(struct clk *clk)
-{
- unsigned long rate;
- unsigned long bclk_pdf;
-
- bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
- >> CCM_CSCR_BCLK_OFFSET;
-
- rate = clk_get_rate(clk->parent);
- return rate / (bclk_pdf + 1);
-}
-
-static struct clk hclk_clk = {
- .parent = &fclk_clk,
- .get_rate = get_hclk_clk,
-};
-
-static unsigned long get_ipg_clk(struct clk *clk)
-{
- unsigned long rate;
- unsigned long ipg_pdf;
-
- ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
-
- rate = clk_get_rate(clk->parent);
- return rate / (ipg_pdf + 1);
-}
-
-static struct clk ipg_clk = {
- .parent = &hclk_clk,
- .get_rate = get_ipg_clk,
-};
-
-static unsigned long _clk_perclkx_recalc(struct clk *clk)
-{
- unsigned long perclk_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->id < 0 || clk->id > 3)
- return 0;
-
- perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
-
- return parent_rate / (perclk_pdf + 1);
-}
-
-static struct clk per_clk[] = {
- {
- .id = 0,
- .parent = &mpll_clk,
- .get_rate = _clk_perclkx_recalc,
- }, {
- .id = 1,
- .parent = &mpll_clk,
- .get_rate = _clk_perclkx_recalc,
- }, {
- .id = 2,
- .parent = &mpll_clk,
- .round_rate = _clk_perclkx_round_rate,
- .set_rate = _clk_perclkx_set_rate,
- .get_rate = _clk_perclkx_recalc,
- /* Enable/Disable done via lcd_clkc[1] */
- }, {
- .id = 3,
- .parent = &mpll_clk,
- .round_rate = _clk_perclkx_round_rate,
- .set_rate = _clk_perclkx_set_rate,
- .get_rate = _clk_perclkx_recalc,
- /* Enable/Disable done via csi_clk[1] */
- },
-};
-
-static struct clk uart_ipg_clk[];
-
-static struct clk uart_clk[] = {
- {
- .id = 0,
- .parent = &per_clk[0],
- .secondary = &uart_ipg_clk[0],
- }, {
- .id = 1,
- .parent = &per_clk[0],
- .secondary = &uart_ipg_clk[1],
- }, {
- .id = 2,
- .parent = &per_clk[0],
- .secondary = &uart_ipg_clk[2],
- }, {
- .id = 3,
- .parent = &per_clk[0],
- .secondary = &uart_ipg_clk[3],
- },
-};
-
-static struct clk uart_ipg_clk[] = {
- {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_UART1_REG,
- .enable_shift = CCM_PCCR_UART1_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_UART2_REG,
- .enable_shift = CCM_PCCR_UART2_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_UART3_REG,
- .enable_shift = CCM_PCCR_UART3_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 3,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_UART4_REG,
- .enable_shift = CCM_PCCR_UART4_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt_ipg_clk[];
-
-static struct clk gpt_clk[] = {
- {
- .id = 0,
- .parent = &per_clk[0],
- .secondary = &gpt_ipg_clk[0],
- }, {
- .id = 1,
- .parent = &per_clk[0],
- .secondary = &gpt_ipg_clk[1],
- }, {
- .id = 2,
- .parent = &per_clk[0],
- .secondary = &gpt_ipg_clk[2],
- },
-};
-
-static struct clk gpt_ipg_clk[] = {
- {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_GPT1_REG,
- .enable_shift = CCM_PCCR_GPT1_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_GPT2_REG,
- .enable_shift = CCM_PCCR_GPT2_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_GPT3_REG,
- .enable_shift = CCM_PCCR_GPT3_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk pwm_clk[] = {
- {
- .parent = &per_clk[0],
- .secondary = &pwm_clk[1],
- }, {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_PWM_REG,
- .enable_shift = CCM_PCCR_PWM_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk sdhc_ipg_clk[];
-
-static struct clk sdhc_clk[] = {
- {
- .id = 0,
- .parent = &per_clk[1],
- .secondary = &sdhc_ipg_clk[0],
- }, {
- .id = 1,
- .parent = &per_clk[1],
- .secondary = &sdhc_ipg_clk[1],
- },
-};
-
-static struct clk sdhc_ipg_clk[] = {
- {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SDHC1_REG,
- .enable_shift = CCM_PCCR_SDHC1_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SDHC2_REG,
- .enable_shift = CCM_PCCR_SDHC2_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk cspi_ipg_clk[];
-
-static struct clk cspi_clk[] = {
- {
- .id = 0,
- .parent = &per_clk[1],
- .secondary = &cspi_ipg_clk[0],
- }, {
- .id = 1,
- .parent = &per_clk[1],
- .secondary = &cspi_ipg_clk[1],
- }, {
- .id = 2,
- .parent = &per_clk[1],
- .secondary = &cspi_ipg_clk[2],
- },
-};
-
-static struct clk cspi_ipg_clk[] = {
- {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_CSPI1_REG,
- .enable_shift = CCM_PCCR_CSPI1_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_CSPI2_REG,
- .enable_shift = CCM_PCCR_CSPI2_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 3,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_CSPI3_REG,
- .enable_shift = CCM_PCCR_CSPI3_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk lcdc_clk[] = {
- {
- .parent = &per_clk[2],
- .secondary = &lcdc_clk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- }, {
- .parent = &ipg_clk,
- .secondary = &lcdc_clk[2],
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_LCDC_REG,
- .enable_shift = CCM_PCCR_LCDC_OFFSET,
- .disable = _clk_disable,
- }, {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
- .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk csi_clk[] = {
- {
- .parent = &per_clk[3],
- .secondary = &csi_clk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- }, {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_CSI_REG,
- .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk usb_clk[] = {
- {
- .parent = &spll_clk,
- .secondary = &usb_clk[1],
- .get_rate = _clk_usb_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_USBOTG_REG,
- .enable_shift = CCM_PCCR_USBOTG_OFFSET,
- .disable = _clk_disable,
- .round_rate = _clk_usb_round_rate,
- .set_rate = _clk_usb_set_rate,
- }, {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
- .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
- .disable = _clk_disable,
- }
-};
-
-static struct clk ssi_ipg_clk[];
-
-static struct clk ssi_clk[] = {
- {
- .id = 0,
- .parent = &mpll_clk,
- .secondary = &ssi_ipg_clk[0],
- .get_rate = _clk_ssi1_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
- .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &mpll_clk,
- .secondary = &ssi_ipg_clk[1],
- .get_rate = _clk_ssi2_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
- .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk ssi_ipg_clk[] = {
- {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SSI1_REG,
- .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
- .disable = _clk_disable,
- }, {
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SSI2_REG,
- .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-
-static struct clk nfc_clk = {
- .parent = &fclk_clk,
- .get_rate = _clk_nfc_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_NFC_REG,
- .enable_shift = CCM_PCCR_NFC_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk dma_clk[] = {
- {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_DMA_REG,
- .enable_shift = CCM_PCCR_DMA_OFFSET,
- .disable = _clk_disable,
- .secondary = &dma_clk[1],
- }, {
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_DMA_REG,
- .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk brom_clk = {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_BROM_REG,
- .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk emma_clk[] = {
- {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_EMMA_REG,
- .enable_shift = CCM_PCCR_EMMA_OFFSET,
- .disable = _clk_disable,
- .secondary = &emma_clk[1],
- }, {
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
- .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
- .disable = _clk_disable,
- }
-};
-
-static struct clk slcdc_clk[] = {
- {
- .parent = &hclk_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_SLCDC_REG,
- .enable_shift = CCM_PCCR_SLCDC_OFFSET,
- .disable = _clk_disable,
- .secondary = &slcdc_clk[1],
- }, {
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
- .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
- .disable = _clk_disable,
- }
-};
-
-static struct clk wdog_clk = {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_WDT_REG,
- .enable_shift = CCM_PCCR_WDT_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk gpio_clk = {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_GPIO_REG,
- .enable_shift = CCM_PCCR_GPIO_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk i2c_clk = {
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_I2C1_REG,
- .enable_shift = CCM_PCCR_I2C1_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk kpp_clk = {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_KPP_REG,
- .enable_shift = CCM_PCCR_KPP_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk owire_clk = {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_OWIRE_REG,
- .enable_shift = CCM_PCCR_OWIRE_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk rtc_clk = {
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR_RTC_REG,
- .enable_shift = CCM_PCCR_RTC_OFFSET,
- .disable = _clk_disable,
-};
-
-static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
-{
- return _clk_generic_round_rate(clk, rate, 8);
-}
-
-static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 8 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
- div--;
-
- reg = __raw_readl(CCM_PCDR0);
-
- if (clk->parent == &usb_clk[0]) {
- reg &= ~CCM_PCDR0_48MDIV_MASK;
- reg |= div << CCM_PCDR0_48MDIV_OFFSET;
- }
- __raw_writel(reg, CCM_PCDR0);
-
- return 0;
-}
-
-static unsigned long _clk_clko_recalc(struct clk *clk)
-{
- u32 div = 0;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->parent == &usb_clk[0]) /* 48M */
- div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
- >> CCM_PCDR0_48MDIV_OFFSET;
- div++;
-
- return parent_rate / div;
-}
-
-static struct clk clko_clk;
-
-static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
-
- if (parent == &ckil_clk)
- reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &fpm_clk)
- reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ckih_clk)
- reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == mpll_clk.parent)
- reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == spll_clk.parent)
- reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &mpll_clk)
- reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &spll_clk)
- reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &fclk_clk)
- reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &hclk_clk)
- reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ipg_clk)
- reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[0])
- reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[1])
- reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[2])
- reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[3])
- reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ssi_clk[0])
- reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ssi_clk[1])
- reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &nfc_clk)
- reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &usb_clk[0])
- reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &clko_clk)
- reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
- else
- return -EINVAL;
-
- __raw_writel(reg, CCM_CCSR);
-
- return 0;
-}
-
-static struct clk clko_clk = {
- .get_rate = _clk_clko_recalc,
- .set_rate = _clk_clko_set_rate,
- .round_rate = _clk_clko_round_rate,
- .set_parent = _clk_clko_set_parent,
-};
-
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-static struct clk_lookup lookups[] = {
-/* It's unlikely that any driver wants one of them directly:
- _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
- _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
- _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
- _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
- _REGISTER_CLOCK(NULL, "spll", spll_clk)
- _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
- _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
- _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
-*/
- _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
- _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
- _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
- _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
- _REGISTER_CLOCK(NULL, "clko", clko_clk)
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0])
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1])
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2])
- _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3])
- _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
- _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
- _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
- _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
- _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
- _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
- _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
- _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
- _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
- _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
- _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
- _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
- _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
- _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
- _REGISTER_CLOCK(NULL, "brom", brom_clk)
- _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
- _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
- _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
- _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
- _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
- _REGISTER_CLOCK(NULL, "owire", owire_clk)
- _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
-};
-
-/*
- * must be called very early to get information about the
- * available clock rate when the timer framework starts
- */
-int __init mx21_clocks_init(unsigned long lref, unsigned long href)
-{
- u32 cscr;
-
- external_low_reference = lref;
- external_high_reference = href;
-
- /* detect clock reference for both system PLL */
- cscr = CSCR();
- if (cscr & CCM_CSCR_MCU)
- mpll_clk.parent = &ckih_clk;
- else
- mpll_clk.parent = &fpm_clk;
-
- if (cscr & CCM_CSCR_SP)
- spll_clk.parent = &ckih_clk;
- else
- spll_clk.parent = &fpm_clk;
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* Turn off all clock gates */
- __raw_writel(0, CCM_PCCR0);
- __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
-
- /* This turns of the serial PLL as well */
- spll_clk.disable(&spll_clk);
-
- /* This will propagate to all children and init all the clock rates. */
- clk_enable(&per_clk[0]);
- clk_enable(&gpio_clk);
-
-#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
- clk_enable(&uart_clk[0]);
-#endif
-
- mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
- MX21_INT_GPT1);
- return 0;
-}
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
deleted file mode 100644
index b0fec74c8c91..000000000000
--- a/arch/arm/mach-imx/clock-imx25.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (C) 2009 by Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/mx25.h>
-
-#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
-
-#define CCM_MPCTL 0x00
-#define CCM_UPCTL 0x04
-#define CCM_CCTL 0x08
-#define CCM_CGCR0 0x0C
-#define CCM_CGCR1 0x10
-#define CCM_CGCR2 0x14
-#define CCM_PCDR0 0x18
-#define CCM_PCDR1 0x1C
-#define CCM_PCDR2 0x20
-#define CCM_PCDR3 0x24
-#define CCM_RCSR 0x28
-#define CCM_CRDR 0x2C
-#define CCM_DCVR0 0x30
-#define CCM_DCVR1 0x34
-#define CCM_DCVR2 0x38
-#define CCM_DCVR3 0x3c
-#define CCM_LTR0 0x40
-#define CCM_LTR1 0x44
-#define CCM_LTR2 0x48
-#define CCM_LTR3 0x4c
-
-static unsigned long get_rate_mpll(void)
-{
- ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
-
- return mxc_decode_pll(mpctl, 24000000);
-}
-
-static unsigned long get_rate_upll(void)
-{
- ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
-
- return mxc_decode_pll(mpctl, 24000000);
-}
-
-unsigned long get_rate_arm(struct clk *clk)
-{
- unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
- unsigned long rate = get_rate_mpll();
-
- if (cctl & (1 << 14))
- rate = (rate * 3) >> 2;
-
- return rate / ((cctl >> 30) + 1);
-}
-
-static unsigned long get_rate_ahb(struct clk *clk)
-{
- unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
-
- return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
-}
-
-static unsigned long get_rate_ipg(struct clk *clk)
-{
- return get_rate_ahb(NULL) >> 1;
-}
-
-static unsigned long get_rate_per(int per)
-{
- unsigned long ofs = (per & 0x3) * 8;
- unsigned long reg = per & ~0x3;
- unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
- unsigned long fref;
-
- if (readl(CRM_BASE + 0x64) & (1 << per))
- fref = get_rate_upll();
- else
- fref = get_rate_ahb(NULL);
-
- return fref / (val + 1);
-}
-
-static unsigned long get_rate_uart(struct clk *clk)
-{
- return get_rate_per(15);
-}
-
-static unsigned long get_rate_ssi2(struct clk *clk)
-{
- return get_rate_per(14);
-}
-
-static unsigned long get_rate_ssi1(struct clk *clk)
-{
- return get_rate_per(13);
-}
-
-static unsigned long get_rate_i2c(struct clk *clk)
-{
- return get_rate_per(6);
-}
-
-static unsigned long get_rate_nfc(struct clk *clk)
-{
- return get_rate_per(8);
-}
-
-static unsigned long get_rate_gpt(struct clk *clk)
-{
- return get_rate_per(5);
-}
-
-static unsigned long get_rate_lcdc(struct clk *clk)
-{
- return get_rate_per(7);
-}
-
-static unsigned long get_rate_esdhc1(struct clk *clk)
-{
- return get_rate_per(3);
-}
-
-static unsigned long get_rate_esdhc2(struct clk *clk)
-{
- return get_rate_per(4);
-}
-
-static unsigned long get_rate_csi(struct clk *clk)
-{
- return get_rate_per(0);
-}
-
-static unsigned long get_rate_otg(struct clk *clk)
-{
- unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
- unsigned long rate = get_rate_upll();
-
- return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
-}
-
-static int clk_cgcr_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void clk_cgcr_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-}
-
-#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = CRM_BASE + er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .set_rate = sr, \
- .enable = clk_cgcr_enable, \
- .disable = clk_cgcr_disable, \
- .secondary = s, \
- }
-
-/*
- * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
- * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
- * taken from the Freescale released BSP.
- *
- * bit reg offset clock
- *
- * 0 CGCR1 0 AUDMUX
- * 12 CGCR1 12 ESAI
- * 16 CGCR1 16 GPIO1
- * 17 CGCR1 17 GPIO2
- * 18 CGCR1 18 GPIO3
- * 23 CGCR1 23 I2C1
- * 24 CGCR1 24 I2C2
- * 25 CGCR1 25 I2C3
- * 27 CGCR1 27 IOMUXC
- * 28 CGCR1 28 KPP
- * 30 CGCR1 30 OWIRE
- * 36 CGCR2 4 RTIC
- * 51 CGCR2 19 WDOG
- */
-
-DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
-DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
-DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
-DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
- &esdhc1_ahb_clk);
-DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
-DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
- &esdhc2_ahb_clk);
-DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
-DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
-DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
-DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
-DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
-DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
-DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
-DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
-DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
-DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
-DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
-DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
-DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
-DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
-DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
-DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
-DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
-DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
-DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
- &esdhc1_per_clk);
-DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
- &esdhc2_per_clk);
-DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
-DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
-DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
-DEFINE_CLOCK(iim_clk, 0, CCM_CGCR1, 26, NULL, NULL, NULL);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- /* i.mx25 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
- _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- /* i.mx25 has the i.mx35 type cspi */
- _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk)
- _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
- _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
- _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
- _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
- _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
- _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
- _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
- _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk)
- _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
- _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
- _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
- _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
- /* i.mx25 has the i.mx35 type sdma */
- _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
- _REGISTER_CLOCK(NULL, "iim", iim_clk)
-};
-
-int __init mx25_clocks_init(void)
-{
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* Turn off all clocks except the ones we need to survive, namely:
- * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
- * SCC
- */
- __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
- __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
- __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
-#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
- clk_enable(&uart1_clk);
-#endif
-
- /* Clock source for lcdc and csi is upll */
- __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
- CRM_BASE + 0x64);
-
- /* Clock source for gpt is ahb_div */
- __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64);
-
- clk_enable(&iim_clk);
- imx_print_silicon_rev("i.MX25", mx25_revision());
- clk_disable(&iim_clk);
-
- mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
-
- return 0;
-}
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
deleted file mode 100644
index 98e04f5a87dd..000000000000
--- a/arch/arm/mach-imx/clock-imx27.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/clkdev.h>
-#include <linux/of.h>
-
-#include <asm/div64.h>
-
-#include <mach/clock.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-
-#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
-
-/* Register offsets */
-#define CCM_CSCR IO_ADDR_CCM(0x0)
-#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
-#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
-#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
-#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
-#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
-#define CCM_PCDR0 IO_ADDR_CCM(0x18)
-#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
-#define CCM_PCCR0 IO_ADDR_CCM(0x20)
-#define CCM_PCCR1 IO_ADDR_CCM(0x24)
-#define CCM_CCSR IO_ADDR_CCM(0x28)
-#define CCM_PMCTL IO_ADDR_CCM(0x2c)
-#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
-#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
-
-#define CCM_CSCR_UPDATE_DIS (1 << 31)
-#define CCM_CSCR_SSI2 (1 << 23)
-#define CCM_CSCR_SSI1 (1 << 22)
-#define CCM_CSCR_VPU (1 << 21)
-#define CCM_CSCR_MSHC (1 << 20)
-#define CCM_CSCR_SPLLRES (1 << 19)
-#define CCM_CSCR_MPLLRES (1 << 18)
-#define CCM_CSCR_SP (1 << 17)
-#define CCM_CSCR_MCU (1 << 16)
-#define CCM_CSCR_OSC26MDIV (1 << 4)
-#define CCM_CSCR_OSC26M (1 << 3)
-#define CCM_CSCR_FPM (1 << 2)
-#define CCM_CSCR_SPEN (1 << 1)
-#define CCM_CSCR_MPEN (1 << 0)
-
-/* i.MX27 TO 2+ */
-#define CCM_CSCR_ARM_SRC (1 << 15)
-
-#define CCM_SPCTL1_LF (1 << 15)
-#define CCM_SPCTL1_BRMO (1 << 6)
-
-static struct clk mpll_main1_clk, mpll_main2_clk;
-
-static int clk_pccr_enable(struct clk *clk)
-{
- unsigned long reg;
-
- if (!clk->enable_reg)
- return 0;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void clk_pccr_disable(struct clk *clk)
-{
- unsigned long reg;
-
- if (!clk->enable_reg)
- return;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-}
-
-static int clk_spll_enable(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_CSCR);
- reg |= CCM_CSCR_SPEN;
- __raw_writel(reg, CCM_CSCR);
-
- while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
-
- return 0;
-}
-
-static void clk_spll_disable(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_CSCR);
- reg &= ~CCM_CSCR_SPEN;
- __raw_writel(reg, CCM_CSCR);
-}
-
-static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
-{
- int cscr = __raw_readl(CCM_CSCR);
-
- if (clk->parent == parent)
- return 0;
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
- if (parent == &mpll_main1_clk) {
- cscr |= CCM_CSCR_ARM_SRC;
- } else {
- if (parent == &mpll_main2_clk)
- cscr &= ~CCM_CSCR_ARM_SRC;
- else
- return -EINVAL;
- }
- __raw_writel(cscr, CCM_CSCR);
- clk->parent = parent;
- return 0;
- }
- return -ENODEV;
-}
-
-static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
-{
- int div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > 4)
- div = 4;
-
- return parent_rate / div;
-}
-
-static int set_rate_cpu(struct clk *clk, unsigned long rate)
-{
- unsigned int div;
- uint32_t reg;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 4 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- div--;
-
- reg = __raw_readl(CCM_CSCR);
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
- reg &= ~(3 << 12);
- reg |= div << 12;
- reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
- __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
- } else {
- printk(KERN_ERR "Can't set CPU frequency!\n");
- }
-
- return 0;
-}
-
-static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
-{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > 64)
- div = 64;
-
- return parent_rate / div;
-}
-
-static int set_rate_per(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->id < 0 || clk->id > 3)
- return -EINVAL;
-
- div = parent_rate / rate;
- if (div > 64 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
- div--;
-
- reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
- reg |= div << (clk->id << 3);
- __raw_writel(reg, CCM_PCDR1);
-
- return 0;
-}
-
-static unsigned long get_rate_usb(struct clk *clk)
-{
- unsigned long usb_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
-
- return parent_rate / (usb_pdf + 1U);
-}
-
-static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
-{
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- pdf += 4; /* MX27 TO2+ */
- else
- pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
-
- return 2UL * parent_rate / pdf;
-}
-
-static unsigned long get_rate_ssi1(struct clk *clk)
-{
- return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
-}
-
-static unsigned long get_rate_ssi2(struct clk *clk)
-{
- return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
-}
-
-static unsigned long get_rate_nfc(struct clk *clk)
-{
- unsigned long nfc_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
- else
- nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
-
- return parent_rate / (nfc_pdf + 1);
-}
-
-static unsigned long get_rate_vpu(struct clk *clk)
-{
- unsigned long vpu_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
- vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
- vpu_pdf += 4;
- } else {
- vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
- vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
- }
-
- return 2UL * parent_rate / vpu_pdf;
-}
-
-static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
-{
- return clk->parent->round_rate(clk->parent, rate);
-}
-
-static unsigned long get_rate_parent(struct clk *clk)
-{
- return clk_get_rate(clk->parent);
-}
-
-static int set_rate_parent(struct clk *clk, unsigned long rate)
-{
- return clk->parent->set_rate(clk->parent, rate);
-}
-
-/* in Hz */
-static unsigned long external_high_reference = 26000000;
-
-static unsigned long get_rate_high_reference(struct clk *clk)
-{
- return external_high_reference;
-}
-
-/* in Hz */
-static unsigned long external_low_reference = 32768;
-
-static unsigned long get_rate_low_reference(struct clk *clk)
-{
- return external_low_reference;
-}
-
-static unsigned long get_rate_fpm(struct clk *clk)
-{
- return clk_get_rate(clk->parent) * 1024;
-}
-
-static unsigned long get_rate_mpll(struct clk *clk)
-{
- return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
- clk_get_rate(clk->parent));
-}
-
-static unsigned long get_rate_mpll_main(struct clk *clk)
-{
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- /* i.MX27 TO2:
- * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
- * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
- */
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1)
- return 2UL * parent_rate / 3UL;
-
- return parent_rate;
-}
-
-static unsigned long get_rate_spll(struct clk *clk)
-{
- uint32_t reg;
- unsigned long rate;
-
- rate = clk_get_rate(clk->parent);
-
- reg = __raw_readl(CCM_SPCTL0);
-
- /* On TO2 we have to write the value back. Otherwise we
- * read 0 from this register the next time.
- */
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- __raw_writel(reg, CCM_SPCTL0);
-
- return mxc_decode_pll(reg, rate);
-}
-
-static unsigned long get_rate_cpu(struct clk *clk)
-{
- u32 div;
- unsigned long rate;
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
- else
- div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
-
- rate = clk_get_rate(clk->parent);
- return rate / (div + 1);
-}
-
-static unsigned long get_rate_ahb(struct clk *clk)
-{
- unsigned long rate, bclk_pdf;
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
- else
- bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
-
- rate = clk_get_rate(clk->parent);
- return rate / (bclk_pdf + 1);
-}
-
-static unsigned long get_rate_ipg(struct clk *clk)
-{
- unsigned long rate, ipg_pdf;
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
- return clk_get_rate(clk->parent);
- else
- ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
-
- rate = clk_get_rate(clk->parent);
- return rate / (ipg_pdf + 1);
-}
-
-static unsigned long get_rate_per(struct clk *clk)
-{
- unsigned long perclk_pdf, parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->id < 0 || clk->id > 3)
- return 0;
-
- perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
-
- return parent_rate / (perclk_pdf + 1);
-}
-
-/*
- * the high frequency external clock reference
- * Default case is 26MHz. Could be changed at runtime
- * with a call to change_external_high_reference()
- */
-static struct clk ckih_clk = {
- .get_rate = get_rate_high_reference,
-};
-
-static struct clk mpll_clk = {
- .parent = &ckih_clk,
- .get_rate = get_rate_mpll,
-};
-
-/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
- * It provides the clock source whose rate is same as MPLL
- */
-static struct clk mpll_main1_clk = {
- .id = 0,
- .parent = &mpll_clk,
- .get_rate = get_rate_mpll_main,
-};
-
-/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
- * It provides the clock source whose rate is same MPLL * 2 / 3
- */
-static struct clk mpll_main2_clk = {
- .id = 1,
- .parent = &mpll_clk,
- .get_rate = get_rate_mpll_main,
-};
-
-static struct clk ahb_clk = {
- .parent = &mpll_main2_clk,
- .get_rate = get_rate_ahb,
-};
-
-static struct clk ipg_clk = {
- .parent = &ahb_clk,
- .get_rate = get_rate_ipg,
-};
-
-static struct clk cpu_clk = {
- .parent = &mpll_main2_clk,
- .set_parent = clk_cpu_set_parent,
- .round_rate = round_rate_cpu,
- .get_rate = get_rate_cpu,
- .set_rate = set_rate_cpu,
-};
-
-static struct clk spll_clk = {
- .parent = &ckih_clk,
- .get_rate = get_rate_spll,
- .enable = clk_spll_enable,
- .disable = clk_spll_disable,
-};
-
-/*
- * the low frequency external clock reference
- * Default case is 32.768kHz.
- */
-static struct clk ckil_clk = {
- .get_rate = get_rate_low_reference,
-};
-
-/* Output of frequency pre multiplier */
-static struct clk fpm_clk = {
- .parent = &ckil_clk,
- .get_rate = get_rate_fpm,
-};
-
-#define PCCR0 CCM_PCCR0
-#define PCCR1 CCM_PCCR1
-
-#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .enable = clk_pccr_enable, \
- .disable = clk_pccr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = get_rate_##getsetround, \
- .set_rate = set_rate_##getsetround, \
- .round_rate = round_rate_##getsetround, \
- .enable = clk_pccr_enable, \
- .disable = clk_pccr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-/* Forward declaration to keep the following list in order */
-static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
- dma_clk1, lcdc_clk2, vpu_clk1;
-
-/* All clocks we can gate through PCCRx in the order of PCCRx bits */
-DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
-DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
-DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
-DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
-DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
-DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
-DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
-DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
-
-DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
-DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
-DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
-DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
-DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
-DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
-DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
-DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
-DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
-DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(pata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
-DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
-
-/* Clocks we cannot directly gate, but drivers need their rates */
-DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
-DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
-DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
-DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
-DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
-DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
-DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
-DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
-DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
-DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
-DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
-DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
-DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
-DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
-DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
-DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
-DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
-DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
-DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- /* i.mx27 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
- _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
- _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk)
- _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
- _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
- _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
- _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
- _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
- _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
- _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
- _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
- _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
- _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
- _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
- _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
- _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
- _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
- _REGISTER_CLOCK(NULL, "dma", dma_clk)
- _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
- _REGISTER_CLOCK(NULL, "brom", brom_clk)
- _REGISTER_CLOCK(NULL, "emma", emma_clk)
- _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk)
- _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
- _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
- _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
- _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
- _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK(NULL, "iim", iim_clk)
- _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
- _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
- _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
- _REGISTER_CLOCK(NULL, "scc", scc_clk)
-};
-
-/* Adjust the clock path for TO2 and later */
-static void __init to2_adjust_clocks(void)
-{
- unsigned long cscr = __raw_readl(CCM_CSCR);
-
- if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
- if (cscr & CCM_CSCR_ARM_SRC)
- cpu_clk.parent = &mpll_main1_clk;
-
- if (!(cscr & CCM_CSCR_SSI2))
- ssi1_clk.parent = &spll_clk;
-
- if (!(cscr & CCM_CSCR_SSI1))
- ssi1_clk.parent = &spll_clk;
-
- if (!(cscr & CCM_CSCR_VPU))
- vpu_clk.parent = &spll_clk;
- } else {
- cpu_clk.parent = &mpll_clk;
- cpu_clk.set_parent = NULL;
- cpu_clk.round_rate = NULL;
- cpu_clk.set_rate = NULL;
- ahb_clk.parent = &mpll_clk;
-
- per1_clk.parent = &mpll_clk;
- per2_clk.parent = &mpll_clk;
- per3_clk.parent = &mpll_clk;
- per4_clk.parent = &mpll_clk;
-
- ssi1_clk.parent = &mpll_clk;
- ssi2_clk.parent = &mpll_clk;
-
- vpu_clk.parent = &mpll_clk;
- }
-}
-
-/*
- * must be called very early to get information about the
- * available clock rate when the timer framework starts
- */
-int __init mx27_clocks_init(unsigned long fref)
-{
- u32 cscr = __raw_readl(CCM_CSCR);
-
- external_high_reference = fref;
-
- /* detect clock reference for both system PLLs */
- if (cscr & CCM_CSCR_MCU)
- mpll_clk.parent = &ckih_clk;
- else
- mpll_clk.parent = &fpm_clk;
-
- if (cscr & CCM_CSCR_SP)
- spll_clk.parent = &ckih_clk;
- else
- spll_clk.parent = &fpm_clk;
-
- to2_adjust_clocks();
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* Turn off all clocks we do not need */
- __raw_writel(0, CCM_PCCR0);
- __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
-
- spll_clk.disable(&spll_clk);
-
- /* enable basic clocks */
- clk_enable(&per1_clk);
- clk_enable(&gpio_clk);
- clk_enable(&emi_clk);
- clk_enable(&iim_clk);
- imx_print_silicon_rev("i.MX27", mx27_revision());
- clk_disable(&iim_clk);
-
-#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
- clk_enable(&uart1_clk);
-#endif
-
- mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
- MX27_INT_GPT1);
-
- return 0;
-}
-
-#ifdef CONFIG_OF
-int __init mx27_clocks_init_dt(void)
-{
- struct device_node *np;
- u32 fref = 26000000; /* default */
-
- for_each_compatible_node(np, NULL, "fixed-clock") {
- if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
- continue;
-
- if (!of_property_read_u32(np, "clock-frequency", &fref))
- break;
- }
-
- return mx27_clocks_init(fref);
-}
-#endif
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c
deleted file mode 100644
index 3a943cd4159f..000000000000
--- a/arch/arm/mach-imx/clock-imx31.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <asm/div64.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/mx31.h>
-#include <mach/common.h>
-
-#include "crmregs-imx3.h"
-
-#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
-
-static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
-{
- u32 min_pre, temp_pre, old_err, err;
-
- if (div >= 512) {
- *pre = 8;
- *post = 64;
- } else if (div >= 64) {
- min_pre = (div - 1) / 64 + 1;
- old_err = 8;
- for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
- err = div % temp_pre;
- if (err == 0) {
- *pre = temp_pre;
- break;
- }
- err = temp_pre - err;
- if (err < old_err) {
- old_err = err;
- *pre = temp_pre;
- }
- }
- *post = (div + *pre - 1) / *pre;
- } else if (div <= 8) {
- *pre = div;
- *post = 1;
- } else {
- *pre = 1;
- *post = div;
- }
-}
-
-static struct clk mcu_pll_clk;
-static struct clk serial_pll_clk;
-static struct clk ipg_clk;
-static struct clk ckih_clk;
-
-static int cgr_enable(struct clk *clk)
-{
- u32 reg;
-
- if (!clk->enable_reg)
- return 0;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 3 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void cgr_disable(struct clk *clk)
-{
- u32 reg;
-
- if (!clk->enable_reg)
- return;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(3 << clk->enable_shift);
-
- /* special case for EMI clock */
- if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
- reg |= (1 << clk->enable_shift);
-
- __raw_writel(reg, clk->enable_reg);
-}
-
-static unsigned long pll_ref_get_rate(void)
-{
- unsigned long ccmr;
- unsigned int prcs;
-
- ccmr = __raw_readl(MXC_CCM_CCMR);
- prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
- if (prcs == 0x1)
- return CKIL_CLK_FREQ * 1024;
- else
- return clk_get_rate(&ckih_clk);
-}
-
-static unsigned long usb_pll_get_rate(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(MXC_CCM_UPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long serial_pll_get_rate(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(MXC_CCM_SRPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static unsigned long mcu_pll_get_rate(struct clk *clk)
-{
- unsigned long reg, ccmr;
-
- ccmr = __raw_readl(MXC_CCM_CCMR);
-
- if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
- return clk_get_rate(&ckih_clk);
-
- reg = __raw_readl(MXC_CCM_MPCTL);
-
- return mxc_decode_pll(reg, pll_ref_get_rate());
-}
-
-static int usb_pll_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg |= MXC_CCM_CCMR_UPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-
- /* No lock bit on MX31, so using max time from spec */
- udelay(80);
-
- return 0;
-}
-
-static void usb_pll_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg &= ~MXC_CCM_CCMR_UPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-}
-
-static int serial_pll_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg |= MXC_CCM_CCMR_SPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-
- /* No lock bit on MX31, so using max time from spec */
- udelay(80);
-
- return 0;
-}
-
-static void serial_pll_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCMR);
- reg &= ~MXC_CCM_CCMR_SPE;
- __raw_writel(reg, MXC_CCM_CCMR);
-}
-
-#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
-#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
-#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
-
-static unsigned long mcu_main_get_rate(struct clk *clk)
-{
- u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
-
- if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
- return clk_get_rate(&serial_pll_clk);
- else
- return clk_get_rate(&mcu_pll_clk);
-}
-
-static unsigned long ahb_get_rate(struct clk *clk)
-{
- unsigned long max_pdf;
-
- max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
- MXC_CCM_PDR0_MAX_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (max_pdf + 1);
-}
-
-static unsigned long ipg_get_rate(struct clk *clk)
-{
- unsigned long ipg_pdf;
-
- ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
- MXC_CCM_PDR0_IPG_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ipg_pdf + 1);
-}
-
-static unsigned long nfc_get_rate(struct clk *clk)
-{
- unsigned long nfc_pdf;
-
- nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
- MXC_CCM_PDR0_NFC_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (nfc_pdf + 1);
-}
-
-static unsigned long hsp_get_rate(struct clk *clk)
-{
- unsigned long hsp_pdf;
-
- hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
- MXC_CCM_PDR0_HSP_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (hsp_pdf + 1);
-}
-
-static unsigned long usb_get_rate(struct clk *clk)
-{
- unsigned long usb_pdf, usb_prepdf;
-
- usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
- MXC_CCM_PDR1_USB_PODF_OFFSET);
- usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
- MXC_CCM_PDR1_USB_PRDF_OFFSET);
- return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
-}
-
-static unsigned long csi_get_rate(struct clk *clk)
-{
- u32 reg, pre, post;
-
- reg = __raw_readl(MXC_CCM_PDR0);
- pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
- MXC_CCM_PDR0_CSI_PRDF_OFFSET;
- pre++;
- post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
- MXC_CCM_PDR0_CSI_PODF_OFFSET;
- post++;
- return clk_get_rate(clk->parent) / (pre * post);
-}
-
-static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 pre, post, parent = clk_get_rate(clk->parent);
- u32 div = parent / rate;
-
- if (parent % rate)
- div++;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- return parent / (pre * post);
-}
-
-static int csi_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
-
- if ((parent / div) != rate)
- return -EINVAL;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- /* Set CSI clock divider */
- reg = __raw_readl(MXC_CCM_PDR0) &
- ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
- reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
- reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
- __raw_writel(reg, MXC_CCM_PDR0);
-
- return 0;
-}
-
-static unsigned long ssi1_get_rate(struct clk *clk)
-{
- unsigned long ssi1_pdf, ssi1_prepdf;
-
- ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
- MXC_CCM_PDR1_SSI1_PODF_OFFSET);
- ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
- MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
-}
-
-static unsigned long ssi2_get_rate(struct clk *clk)
-{
- unsigned long ssi2_pdf, ssi2_prepdf;
-
- ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
- MXC_CCM_PDR1_SSI2_PODF_OFFSET);
- ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
- MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
-}
-
-static unsigned long firi_get_rate(struct clk *clk)
-{
- unsigned long firi_pdf, firi_prepdf;
-
- firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
- MXC_CCM_PDR1_FIRI_PODF_OFFSET);
- firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
- MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
-}
-
-static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 pre, post;
- u32 parent = clk_get_rate(clk->parent);
- u32 div = parent / rate;
-
- if (parent % rate)
- div++;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- return parent / (pre * post);
-
-}
-
-static int firi_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
-
- if ((parent / div) != rate)
- return -EINVAL;
-
- __calc_pre_post_dividers(div, &pre, &post);
-
- /* Set FIRI clock divider */
- reg = __raw_readl(MXC_CCM_PDR1) &
- ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
- reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
- reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
- __raw_writel(reg, MXC_CCM_PDR1);
-
- return 0;
-}
-
-static unsigned long mbx_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 2;
-}
-
-static unsigned long mstick1_get_rate(struct clk *clk)
-{
- unsigned long msti_pdf;
-
- msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
- MXC_CCM_PDR2_MST1_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long mstick2_get_rate(struct clk *clk)
-{
- unsigned long msti_pdf;
-
- msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
- MXC_CCM_PDR2_MST2_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long ckih_rate;
-
-static unsigned long clk_ckih_get_rate(struct clk *clk)
-{
- return ckih_rate;
-}
-
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
- return CKIL_CLK_FREQ;
-}
-
-static struct clk ckih_clk = {
- .get_rate = clk_ckih_get_rate,
-};
-
-static struct clk mcu_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = mcu_pll_get_rate,
-};
-
-static struct clk mcu_main_clk = {
- .parent = &mcu_pll_clk,
- .get_rate = mcu_main_get_rate,
-};
-
-static struct clk serial_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = serial_pll_get_rate,
- .enable = serial_pll_enable,
- .disable = serial_pll_disable,
-};
-
-static struct clk usb_pll_clk = {
- .parent = &ckih_clk,
- .get_rate = usb_pll_get_rate,
- .enable = usb_pll_enable,
- .disable = usb_pll_disable,
-};
-
-static struct clk ahb_clk = {
- .parent = &mcu_main_clk,
- .get_rate = ahb_get_rate,
-};
-
-#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .enable = cgr_enable, \
- .disable = cgr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = getsetround##_get_rate, \
- .set_rate = getsetround##_set_rate, \
- .round_rate = getsetround##_round_rate, \
- .enable = cgr_enable, \
- .disable = cgr_disable, \
- .secondary = s, \
- .parent = p, \
- }
-
-DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
-
-DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
-DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
-
-DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
-DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
-DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
-DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
-
-DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
-DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
-DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
-
-DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
-DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
-DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- _REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
- _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
- _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
- _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
- _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
- _REGISTER_CLOCK(NULL, "epit", epit1_clk)
- _REGISTER_CLOCK(NULL, "epit", epit2_clk)
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
- _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
- _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
- _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
- _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
- _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
- /* i.mx31 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
- _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
- _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
- _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
- _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK(NULL, "firi", firi_clk)
- _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
- _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
- _REGISTER_CLOCK(NULL, "rng", rng_clk)
- _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1)
- _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
- _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
- _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
- _REGISTER_CLOCK(NULL, "scc", scc_clk)
- _REGISTER_CLOCK(NULL, "iim", iim_clk)
- _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
- _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
-};
-
-int __init mx31_clocks_init(unsigned long fref)
-{
- u32 reg;
-
- ckih_rate = fref;
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* change the csi_clk parent if necessary */
- reg = __raw_readl(MXC_CCM_CCMR);
- if (!(reg & MXC_CCM_CCMR_CSCS))
- if (clk_set_parent(&csi_clk, &usb_pll_clk))
- pr_err("%s: error changing csi_clk parent\n", __func__);
-
-
- /* Turn off all possible clocks */
- __raw_writel((3 << 4), MXC_CCM_CGR0);
- __raw_writel(0, MXC_CCM_CGR1);
- __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
- 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
- MX32, but still required to be set */
- MXC_CCM_CGR2);
-
- /*
- * Before turning off usb_pll make sure ipg_per_clk is generated
- * by ipg_clk and not usb_pll.
- */
- __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
-
- usb_pll_disable(&usb_pll_clk);
-
- pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
-
- clk_enable(&gpt_clk);
- clk_enable(&emi_clk);
- clk_enable(&iim_clk);
- mx31_revision();
- clk_disable(&iim_clk);
-
- clk_enable(&serial_pll_clk);
-
- if (mx31_revision() >= IMX_CHIP_REVISION_2_0) {
- reg = __raw_readl(MXC_CCM_PMCR1);
- /* No PLL restart on DVFS switch; enable auto EMI handshake */
- reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
- __raw_writel(reg, MXC_CCM_PMCR1);
- }
-
- mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
- MX31_INT_GPT);
-
- return 0;
-}
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
deleted file mode 100644
index e56c1a83eee3..000000000000
--- a/arch/arm/mach-imx/clock-imx35.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (C) 2009 by Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
-#include "crmregs-imx3.h"
-
-#ifdef HAVE_SET_RATE_SUPPORT
-static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
-{
- u32 min_pre, temp_pre, old_err, err;
-
- min_pre = (div - 1) / maxpost + 1;
- old_err = 8;
-
- for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
- if (div > (temp_pre * maxpost))
- break;
-
- if (div < (temp_pre * temp_pre))
- continue;
-
- err = div % temp_pre;
-
- if (err == 0) {
- *pre = temp_pre;
- break;
- }
-
- err = temp_pre - err;
-
- if (err < old_err) {
- old_err = err;
- *pre = temp_pre;
- }
- }
-
- *post = (div + *pre - 1) / *pre;
-}
-
-/* get the best values for a 3-bit divider combined with a 6-bit divider */
-static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
-{
- if (div >= 512) {
- *pre = 8;
- *post = 64;
- } else if (div >= 64) {
- calc_dividers(div, pre, post, 64);
- } else if (div <= 8) {
- *pre = div;
- *post = 1;
- } else {
- *pre = 1;
- *post = div;
- }
-}
-
-/* get the best values for two cascaded 3-bit dividers */
-static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
-{
- if (div >= 64) {
- *pre = *post = 8;
- } else if (div > 8) {
- calc_dividers(div, pre, post, 8);
- } else {
- *pre = 1;
- *post = div;
- }
-}
-#endif
-
-static unsigned long get_rate_mpll(void)
-{
- ulong mpctl = __raw_readl(MX35_CCM_MPCTL);
-
- return mxc_decode_pll(mpctl, 24000000);
-}
-
-static unsigned long get_rate_ppll(void)
-{
- ulong ppctl = __raw_readl(MX35_CCM_PPCTL);
-
- return mxc_decode_pll(ppctl, 24000000);
-}
-
-struct arm_ahb_div {
- unsigned char arm, ahb, sel;
-};
-
-static struct arm_ahb_div clk_consumer[] = {
- { .arm = 1, .ahb = 4, .sel = 0},
- { .arm = 1, .ahb = 3, .sel = 1},
- { .arm = 2, .ahb = 2, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 4, .ahb = 1, .sel = 0},
- { .arm = 1, .ahb = 5, .sel = 0},
- { .arm = 1, .ahb = 8, .sel = 0},
- { .arm = 1, .ahb = 6, .sel = 1},
- { .arm = 2, .ahb = 4, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
- { .arm = 4, .ahb = 2, .sel = 0},
- { .arm = 0, .ahb = 0, .sel = 0},
-};
-
-static unsigned long get_rate_arm(void)
-{
- unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
- struct arm_ahb_div *aad;
- unsigned long fref = get_rate_mpll();
-
- aad = &clk_consumer[(pdr0 >> 16) & 0xf];
- if (aad->sel)
- fref = fref * 3 / 4;
-
- return fref / aad->arm;
-}
-
-static unsigned long get_rate_ahb(struct clk *clk)
-{
- unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
- struct arm_ahb_div *aad;
- unsigned long fref = get_rate_arm();
-
- aad = &clk_consumer[(pdr0 >> 16) & 0xf];
-
- return fref / aad->ahb;
-}
-
-static unsigned long get_rate_ipg(struct clk *clk)
-{
- return get_rate_ahb(NULL) >> 1;
-}
-
-static unsigned long get_rate_uart(struct clk *clk)
-{
- unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
- unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
- unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
-
- if (pdr3 & (1 << 14))
- return get_rate_arm() / div;
- else
- return get_rate_ppll() / div;
-}
-
-static unsigned long get_rate_sdhc(struct clk *clk)
-{
- unsigned long pdr3 = __raw_readl(MX35_CCM_PDR3);
- unsigned long div, rate;
-
- if (pdr3 & (1 << 6))
- rate = get_rate_arm();
- else
- rate = get_rate_ppll();
-
- switch (clk->id) {
- default:
- case 0:
- div = pdr3 & 0x3f;
- break;
- case 1:
- div = (pdr3 >> 8) & 0x3f;
- break;
- case 2:
- div = (pdr3 >> 16) & 0x3f;
- break;
- }
-
- return rate / (div + 1);
-}
-
-static unsigned long get_rate_mshc(struct clk *clk)
-{
- unsigned long pdr1 = __raw_readl(MXC_CCM_PDR1);
- unsigned long div1, div2, rate;
-
- if (pdr1 & (1 << 7))
- rate = get_rate_arm();
- else
- rate = get_rate_ppll();
-
- div1 = (pdr1 >> 29) & 0x7;
- div2 = (pdr1 >> 22) & 0x3f;
-
- return rate / ((div1 + 1) * (div2 + 1));
-}
-
-static unsigned long get_rate_ssi(struct clk *clk)
-{
- unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
- unsigned long div1, div2, rate;
-
- if (pdr2 & (1 << 6))
- rate = get_rate_arm();
- else
- rate = get_rate_ppll();
-
- switch (clk->id) {
- default:
- case 0:
- div1 = pdr2 & 0x3f;
- div2 = (pdr2 >> 24) & 0x7;
- break;
- case 1:
- div1 = (pdr2 >> 8) & 0x3f;
- div2 = (pdr2 >> 27) & 0x7;
- break;
- }
-
- return rate / ((div1 + 1) * (div2 + 1));
-}
-
-static unsigned long get_rate_csi(struct clk *clk)
-{
- unsigned long pdr2 = __raw_readl(MX35_CCM_PDR2);
- unsigned long rate;
-
- if (pdr2 & (1 << 7))
- rate = get_rate_arm();
- else
- rate = get_rate_ppll();
-
- return rate / (((pdr2 >> 16) & 0x3f) + 1);
-}
-
-static unsigned long get_rate_otg(struct clk *clk)
-{
- unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
- unsigned long rate;
-
- if (pdr4 & (1 << 9))
- rate = get_rate_arm();
- else
- rate = get_rate_ppll();
-
- return rate / (((pdr4 >> 22) & 0x3f) + 1);
-}
-
-static unsigned long get_rate_ipg_per(struct clk *clk)
-{
- unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
- unsigned long pdr4 = __raw_readl(MX35_CCM_PDR4);
- unsigned long div;
-
- if (pdr0 & (1 << 26)) {
- div = (pdr4 >> 16) & 0x3f;
- return get_rate_arm() / (div + 1);
- } else {
- div = (pdr0 >> 12) & 0x7;
- return get_rate_ahb(NULL) / (div + 1);
- }
-}
-
-static unsigned long get_rate_hsp(struct clk *clk)
-{
- unsigned long hsp_podf = (__raw_readl(MXC_CCM_PDR0) >> 20) & 0x03;
- unsigned long fref = get_rate_mpll();
-
- if (fref > 400 * 1000 * 1000) {
- switch (hsp_podf) {
- case 0:
- return fref >> 2;
- case 1:
- return fref >> 3;
- case 2:
- return fref / 3;
- }
- } else {
- switch (hsp_podf) {
- case 0:
- case 2:
- return fref / 3;
- case 1:
- return fref / 6;
- }
- }
-
- return 0;
-}
-
-static int clk_cgr_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg |= 3 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void clk_cgr_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(3 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
-}
-
-#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .set_rate = sr, \
- .enable = clk_cgr_enable, \
- .disable = clk_cgr_disable, \
- }
-
-DEFINE_CLOCK(asrc_clk, 0, MX35_CCM_CGR0, 0, NULL, NULL);
-DEFINE_CLOCK(pata_clk, 0, MX35_CCM_CGR0, 2, get_rate_ipg, NULL);
-/* DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR0, 4, NULL, NULL); */
-DEFINE_CLOCK(can1_clk, 0, MX35_CCM_CGR0, 6, get_rate_ipg, NULL);
-DEFINE_CLOCK(can2_clk, 1, MX35_CCM_CGR0, 8, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi1_clk, 0, MX35_CCM_CGR0, 10, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi2_clk, 1, MX35_CCM_CGR0, 12, get_rate_ipg, NULL);
-DEFINE_CLOCK(ect_clk, 0, MX35_CCM_CGR0, 14, get_rate_ipg, NULL);
-DEFINE_CLOCK(edio_clk, 0, MX35_CCM_CGR0, 16, NULL, NULL);
-DEFINE_CLOCK(emi_clk, 0, MX35_CCM_CGR0, 18, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit1_clk, 0, MX35_CCM_CGR0, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit2_clk, 1, MX35_CCM_CGR0, 22, get_rate_ipg, NULL);
-DEFINE_CLOCK(esai_clk, 0, MX35_CCM_CGR0, 24, NULL, NULL);
-DEFINE_CLOCK(esdhc1_clk, 0, MX35_CCM_CGR0, 26, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc2_clk, 1, MX35_CCM_CGR0, 28, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc3_clk, 2, MX35_CCM_CGR0, 30, get_rate_sdhc, NULL);
-
-DEFINE_CLOCK(fec_clk, 0, MX35_CCM_CGR1, 0, get_rate_ipg, NULL);
-DEFINE_CLOCK(gpio1_clk, 0, MX35_CCM_CGR1, 2, NULL, NULL);
-DEFINE_CLOCK(gpio2_clk, 1, MX35_CCM_CGR1, 4, NULL, NULL);
-DEFINE_CLOCK(gpio3_clk, 2, MX35_CCM_CGR1, 6, NULL, NULL);
-DEFINE_CLOCK(gpt_clk, 0, MX35_CCM_CGR1, 8, get_rate_ipg, NULL);
-DEFINE_CLOCK(i2c1_clk, 0, MX35_CCM_CGR1, 10, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c2_clk, 1, MX35_CCM_CGR1, 12, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c3_clk, 2, MX35_CCM_CGR1, 14, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(iomuxc_clk, 0, MX35_CCM_CGR1, 16, NULL, NULL);
-DEFINE_CLOCK(ipu_clk, 0, MX35_CCM_CGR1, 18, get_rate_hsp, NULL);
-DEFINE_CLOCK(kpp_clk, 0, MX35_CCM_CGR1, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(mlb_clk, 0, MX35_CCM_CGR1, 22, get_rate_ahb, NULL);
-DEFINE_CLOCK(mshc_clk, 0, MX35_CCM_CGR1, 24, get_rate_mshc, NULL);
-DEFINE_CLOCK(owire_clk, 0, MX35_CCM_CGR1, 26, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(pwm_clk, 0, MX35_CCM_CGR1, 28, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(rngc_clk, 0, MX35_CCM_CGR1, 30, get_rate_ipg, NULL);
-
-DEFINE_CLOCK(rtc_clk, 0, MX35_CCM_CGR2, 0, get_rate_ipg, NULL);
-DEFINE_CLOCK(rtic_clk, 0, MX35_CCM_CGR2, 2, get_rate_ahb, NULL);
-DEFINE_CLOCK(scc_clk, 0, MX35_CCM_CGR2, 4, get_rate_ipg, NULL);
-DEFINE_CLOCK(sdma_clk, 0, MX35_CCM_CGR2, 6, NULL, NULL);
-DEFINE_CLOCK(spba_clk, 0, MX35_CCM_CGR2, 8, get_rate_ipg, NULL);
-DEFINE_CLOCK(spdif_clk, 0, MX35_CCM_CGR2, 10, NULL, NULL);
-DEFINE_CLOCK(ssi1_clk, 0, MX35_CCM_CGR2, 12, get_rate_ssi, NULL);
-DEFINE_CLOCK(ssi2_clk, 1, MX35_CCM_CGR2, 14, get_rate_ssi, NULL);
-DEFINE_CLOCK(uart1_clk, 0, MX35_CCM_CGR2, 16, get_rate_uart, NULL);
-DEFINE_CLOCK(uart2_clk, 1, MX35_CCM_CGR2, 18, get_rate_uart, NULL);
-DEFINE_CLOCK(uart3_clk, 2, MX35_CCM_CGR2, 20, get_rate_uart, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, MX35_CCM_CGR2, 22, get_rate_otg, NULL);
-DEFINE_CLOCK(wdog_clk, 0, MX35_CCM_CGR2, 24, NULL, NULL);
-DEFINE_CLOCK(max_clk, 0, MX35_CCM_CGR2, 26, NULL, NULL);
-DEFINE_CLOCK(audmux_clk, 0, MX35_CCM_CGR2, 30, NULL, NULL);
-
-DEFINE_CLOCK(csi_clk, 0, MX35_CCM_CGR3, 0, get_rate_csi, NULL);
-DEFINE_CLOCK(iim_clk, 0, MX35_CCM_CGR3, 2, NULL, NULL);
-DEFINE_CLOCK(gpu2d_clk, 0, MX35_CCM_CGR3, 4, NULL, NULL);
-
-DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL);
-
-static int clk_dummy_enable(struct clk *clk)
-{
- return 0;
-}
-
-static void clk_dummy_disable(struct clk *clk)
-{
-}
-
-static unsigned long get_rate_nfc(struct clk *clk)
-{
- unsigned long div1;
-
- div1 = (__raw_readl(MX35_CCM_PDR4) >> 28) + 1;
-
- return get_rate_ahb(NULL) / div1;
-}
-
-/* NAND Controller: It seems it can't be disabled */
-static struct clk nfc_clk = {
- .id = 0,
- .enable_reg = 0,
- .enable_shift = 0,
- .get_rate = get_rate_nfc,
- .set_rate = NULL, /* set_rate_nfc, */
- .enable = clk_dummy_enable,
- .disable = clk_dummy_disable
-};
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
- _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
- _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
- _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
- _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
- _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
- _REGISTER_CLOCK(NULL, "ect", ect_clk)
- _REGISTER_CLOCK(NULL, "edio", edio_clk)
- _REGISTER_CLOCK(NULL, "emi", emi_clk)
- _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
- _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
- _REGISTER_CLOCK(NULL, "esai", esai_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk)
- /* i.mx35 has the i.mx27 type fec */
- _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
- _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
- _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
- _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
- _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
- _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
- _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
- _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
- _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
- _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
- _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
- _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
- _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
- _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
- _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
- _REGISTER_CLOCK(NULL, "scc", scc_clk)
- _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
- _REGISTER_CLOCK(NULL, "spba", spba_clk)
- _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- /* i.mx35 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
- _REGISTER_CLOCK(NULL, "max", max_clk)
- _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
- _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
- _REGISTER_CLOCK(NULL, "iim", iim_clk)
- _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
- _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
-};
-
-int __init mx35_clocks_init()
-{
- unsigned int cgr2 = 3 << 26;
-
-#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
- cgr2 |= 3 << 16;
-#endif
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- /* Turn off all clocks except the ones we need to survive, namely:
- * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
- */
- __raw_writel((3 << 18), MX35_CCM_CGR0);
- __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
- MX35_CCM_CGR1);
- __raw_writel(cgr2, MX35_CCM_CGR2);
- __raw_writel(0, MX35_CCM_CGR3);
-
- clk_enable(&iim_clk);
- imx_print_silicon_rev("i.MX35", mx35_revision());
- clk_disable(&iim_clk);
-
- /*
- * Check if we came up in internal boot mode. If yes, we need some
- * extra clocks turned on, otherwise the MX35 boot ROM code will
- * hang after a watchdog reset.
- */
- if (!(__raw_readl(MX35_CCM_RCSR) & (3 << 10))) {
- /* Additionally turn on UART1, SCC, and IIM clocks */
- clk_enable(&iim_clk);
- clk_enable(&uart1_clk);
- clk_enable(&scc_clk);
- }
-
-#ifdef CONFIG_MXC_USE_EPIT
- epit_timer_init(&epit1_clk,
- MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
-#else
- mxc_timer_init(&gpt_clk,
- MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
-#endif
-
- return 0;
-}
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
deleted file mode 100644
index 111c328f5420..000000000000
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ /dev/null
@@ -1,2111 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2011 Linaro Ltd.
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <asm/div64.h>
-#include <asm/mach/map.h>
-#include <mach/clock.h>
-#include <mach/common.h>
-#include <mach/hardware.h>
-
-#define PLL_BASE IMX_IO_ADDRESS(MX6Q_ANATOP_BASE_ADDR)
-#define PLL1_SYS (PLL_BASE + 0x000)
-#define PLL2_BUS (PLL_BASE + 0x030)
-#define PLL3_USB_OTG (PLL_BASE + 0x010)
-#define PLL4_AUDIO (PLL_BASE + 0x070)
-#define PLL5_VIDEO (PLL_BASE + 0x0a0)
-#define PLL6_MLB (PLL_BASE + 0x0d0)
-#define PLL7_USB_HOST (PLL_BASE + 0x020)
-#define PLL8_ENET (PLL_BASE + 0x0e0)
-#define PFD_480 (PLL_BASE + 0x0f0)
-#define PFD_528 (PLL_BASE + 0x100)
-#define PLL_NUM_OFFSET 0x010
-#define PLL_DENOM_OFFSET 0x020
-
-#define PFD0 7
-#define PFD1 15
-#define PFD2 23
-#define PFD3 31
-#define PFD_FRAC_MASK 0x3f
-
-#define BM_PLL_BYPASS (0x1 << 16)
-#define BM_PLL_ENABLE (0x1 << 13)
-#define BM_PLL_POWER_DOWN (0x1 << 12)
-#define BM_PLL_LOCK (0x1 << 31)
-#define BP_PLL_SYS_DIV_SELECT 0
-#define BM_PLL_SYS_DIV_SELECT (0x7f << 0)
-#define BP_PLL_BUS_DIV_SELECT 0
-#define BM_PLL_BUS_DIV_SELECT (0x1 << 0)
-#define BP_PLL_USB_DIV_SELECT 0
-#define BM_PLL_USB_DIV_SELECT (0x3 << 0)
-#define BP_PLL_AV_DIV_SELECT 0
-#define BM_PLL_AV_DIV_SELECT (0x7f << 0)
-#define BP_PLL_ENET_DIV_SELECT 0
-#define BM_PLL_ENET_DIV_SELECT (0x3 << 0)
-#define BM_PLL_ENET_EN_PCIE (0x1 << 19)
-#define BM_PLL_ENET_EN_SATA (0x1 << 20)
-
-#define CCM_BASE IMX_IO_ADDRESS(MX6Q_CCM_BASE_ADDR)
-#define CCR (CCM_BASE + 0x00)
-#define CCDR (CCM_BASE + 0x04)
-#define CSR (CCM_BASE + 0x08)
-#define CCSR (CCM_BASE + 0x0c)
-#define CACRR (CCM_BASE + 0x10)
-#define CBCDR (CCM_BASE + 0x14)
-#define CBCMR (CCM_BASE + 0x18)
-#define CSCMR1 (CCM_BASE + 0x1c)
-#define CSCMR2 (CCM_BASE + 0x20)
-#define CSCDR1 (CCM_BASE + 0x24)
-#define CS1CDR (CCM_BASE + 0x28)
-#define CS2CDR (CCM_BASE + 0x2c)
-#define CDCDR (CCM_BASE + 0x30)
-#define CHSCCDR (CCM_BASE + 0x34)
-#define CSCDR2 (CCM_BASE + 0x38)
-#define CSCDR3 (CCM_BASE + 0x3c)
-#define CSCDR4 (CCM_BASE + 0x40)
-#define CWDR (CCM_BASE + 0x44)
-#define CDHIPR (CCM_BASE + 0x48)
-#define CDCR (CCM_BASE + 0x4c)
-#define CTOR (CCM_BASE + 0x50)
-#define CLPCR (CCM_BASE + 0x54)
-#define CISR (CCM_BASE + 0x58)
-#define CIMR (CCM_BASE + 0x5c)
-#define CCOSR (CCM_BASE + 0x60)
-#define CGPR (CCM_BASE + 0x64)
-#define CCGR0 (CCM_BASE + 0x68)
-#define CCGR1 (CCM_BASE + 0x6c)
-#define CCGR2 (CCM_BASE + 0x70)
-#define CCGR3 (CCM_BASE + 0x74)
-#define CCGR4 (CCM_BASE + 0x78)
-#define CCGR5 (CCM_BASE + 0x7c)
-#define CCGR6 (CCM_BASE + 0x80)
-#define CCGR7 (CCM_BASE + 0x84)
-#define CMEOR (CCM_BASE + 0x88)
-
-#define CG0 0
-#define CG1 2
-#define CG2 4
-#define CG3 6
-#define CG4 8
-#define CG5 10
-#define CG6 12
-#define CG7 14
-#define CG8 16
-#define CG9 18
-#define CG10 20
-#define CG11 22
-#define CG12 24
-#define CG13 26
-#define CG14 28
-#define CG15 30
-
-#define BM_CCSR_PLL1_SW_SEL (0x1 << 2)
-#define BM_CCSR_STEP_SEL (0x1 << 8)
-
-#define BP_CACRR_ARM_PODF 0
-#define BM_CACRR_ARM_PODF (0x7 << 0)
-
-#define BP_CBCDR_PERIPH2_CLK2_PODF 0
-#define BM_CBCDR_PERIPH2_CLK2_PODF (0x7 << 0)
-#define BP_CBCDR_MMDC_CH1_AXI_PODF 3
-#define BM_CBCDR_MMDC_CH1_AXI_PODF (0x7 << 3)
-#define BP_CBCDR_AXI_SEL 6
-#define BM_CBCDR_AXI_SEL (0x3 << 6)
-#define BP_CBCDR_IPG_PODF 8
-#define BM_CBCDR_IPG_PODF (0x3 << 8)
-#define BP_CBCDR_AHB_PODF 10
-#define BM_CBCDR_AHB_PODF (0x7 << 10)
-#define BP_CBCDR_AXI_PODF 16
-#define BM_CBCDR_AXI_PODF (0x7 << 16)
-#define BP_CBCDR_MMDC_CH0_AXI_PODF 19
-#define BM_CBCDR_MMDC_CH0_AXI_PODF (0x7 << 19)
-#define BP_CBCDR_PERIPH_CLK_SEL 25
-#define BM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
-#define BP_CBCDR_PERIPH2_CLK_SEL 26
-#define BM_CBCDR_PERIPH2_CLK_SEL (0x1 << 26)
-#define BP_CBCDR_PERIPH_CLK2_PODF 27
-#define BM_CBCDR_PERIPH_CLK2_PODF (0x7 << 27)
-
-#define BP_CBCMR_GPU2D_AXI_SEL 0
-#define BM_CBCMR_GPU2D_AXI_SEL (0x1 << 0)
-#define BP_CBCMR_GPU3D_AXI_SEL 1
-#define BM_CBCMR_GPU3D_AXI_SEL (0x1 << 1)
-#define BP_CBCMR_GPU3D_CORE_SEL 4
-#define BM_CBCMR_GPU3D_CORE_SEL (0x3 << 4)
-#define BP_CBCMR_GPU3D_SHADER_SEL 8
-#define BM_CBCMR_GPU3D_SHADER_SEL (0x3 << 8)
-#define BP_CBCMR_PCIE_AXI_SEL 10
-#define BM_CBCMR_PCIE_AXI_SEL (0x1 << 10)
-#define BP_CBCMR_VDO_AXI_SEL 11
-#define BM_CBCMR_VDO_AXI_SEL (0x1 << 11)
-#define BP_CBCMR_PERIPH_CLK2_SEL 12
-#define BM_CBCMR_PERIPH_CLK2_SEL (0x3 << 12)
-#define BP_CBCMR_VPU_AXI_SEL 14
-#define BM_CBCMR_VPU_AXI_SEL (0x3 << 14)
-#define BP_CBCMR_GPU2D_CORE_SEL 16
-#define BM_CBCMR_GPU2D_CORE_SEL (0x3 << 16)
-#define BP_CBCMR_PRE_PERIPH_CLK_SEL 18
-#define BM_CBCMR_PRE_PERIPH_CLK_SEL (0x3 << 18)
-#define BP_CBCMR_PERIPH2_CLK2_SEL 20
-#define BM_CBCMR_PERIPH2_CLK2_SEL (0x1 << 20)
-#define BP_CBCMR_PRE_PERIPH2_CLK_SEL 21
-#define BM_CBCMR_PRE_PERIPH2_CLK_SEL (0x3 << 21)
-#define BP_CBCMR_GPU2D_CORE_PODF 23
-#define BM_CBCMR_GPU2D_CORE_PODF (0x7 << 23)
-#define BP_CBCMR_GPU3D_CORE_PODF 26
-#define BM_CBCMR_GPU3D_CORE_PODF (0x7 << 26)
-#define BP_CBCMR_GPU3D_SHADER_PODF 29
-#define BM_CBCMR_GPU3D_SHADER_PODF (0x7 << 29)
-
-#define BP_CSCMR1_PERCLK_PODF 0
-#define BM_CSCMR1_PERCLK_PODF (0x3f << 0)
-#define BP_CSCMR1_SSI1_SEL 10
-#define BM_CSCMR1_SSI1_SEL (0x3 << 10)
-#define BP_CSCMR1_SSI2_SEL 12
-#define BM_CSCMR1_SSI2_SEL (0x3 << 12)
-#define BP_CSCMR1_SSI3_SEL 14
-#define BM_CSCMR1_SSI3_SEL (0x3 << 14)
-#define BP_CSCMR1_USDHC1_SEL 16
-#define BM_CSCMR1_USDHC1_SEL (0x1 << 16)
-#define BP_CSCMR1_USDHC2_SEL 17
-#define BM_CSCMR1_USDHC2_SEL (0x1 << 17)
-#define BP_CSCMR1_USDHC3_SEL 18
-#define BM_CSCMR1_USDHC3_SEL (0x1 << 18)
-#define BP_CSCMR1_USDHC4_SEL 19
-#define BM_CSCMR1_USDHC4_SEL (0x1 << 19)
-#define BP_CSCMR1_EMI_PODF 20
-#define BM_CSCMR1_EMI_PODF (0x7 << 20)
-#define BP_CSCMR1_EMI_SLOW_PODF 23
-#define BM_CSCMR1_EMI_SLOW_PODF (0x7 << 23)
-#define BP_CSCMR1_EMI_SEL 27
-#define BM_CSCMR1_EMI_SEL (0x3 << 27)
-#define BP_CSCMR1_EMI_SLOW_SEL 29
-#define BM_CSCMR1_EMI_SLOW_SEL (0x3 << 29)
-
-#define BP_CSCMR2_CAN_PODF 2
-#define BM_CSCMR2_CAN_PODF (0x3f << 2)
-#define BM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10)
-#define BM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11)
-#define BP_CSCMR2_ESAI_SEL 19
-#define BM_CSCMR2_ESAI_SEL (0x3 << 19)
-
-#define BP_CSCDR1_UART_PODF 0
-#define BM_CSCDR1_UART_PODF (0x3f << 0)
-#define BP_CSCDR1_USDHC1_PODF 11
-#define BM_CSCDR1_USDHC1_PODF (0x7 << 11)
-#define BP_CSCDR1_USDHC2_PODF 16
-#define BM_CSCDR1_USDHC2_PODF (0x7 << 16)
-#define BP_CSCDR1_USDHC3_PODF 19
-#define BM_CSCDR1_USDHC3_PODF (0x7 << 19)
-#define BP_CSCDR1_USDHC4_PODF 22
-#define BM_CSCDR1_USDHC4_PODF (0x7 << 22)
-#define BP_CSCDR1_VPU_AXI_PODF 25
-#define BM_CSCDR1_VPU_AXI_PODF (0x7 << 25)
-
-#define BP_CS1CDR_SSI1_PODF 0
-#define BM_CS1CDR_SSI1_PODF (0x3f << 0)
-#define BP_CS1CDR_SSI1_PRED 6
-#define BM_CS1CDR_SSI1_PRED (0x7 << 6)
-#define BP_CS1CDR_ESAI_PRED 9
-#define BM_CS1CDR_ESAI_PRED (0x7 << 9)
-#define BP_CS1CDR_SSI3_PODF 16
-#define BM_CS1CDR_SSI3_PODF (0x3f << 16)
-#define BP_CS1CDR_SSI3_PRED 22
-#define BM_CS1CDR_SSI3_PRED (0x7 << 22)
-#define BP_CS1CDR_ESAI_PODF 25
-#define BM_CS1CDR_ESAI_PODF (0x7 << 25)
-
-#define BP_CS2CDR_SSI2_PODF 0
-#define BM_CS2CDR_SSI2_PODF (0x3f << 0)
-#define BP_CS2CDR_SSI2_PRED 6
-#define BM_CS2CDR_SSI2_PRED (0x7 << 6)
-#define BP_CS2CDR_LDB_DI0_SEL 9
-#define BM_CS2CDR_LDB_DI0_SEL (0x7 << 9)
-#define BP_CS2CDR_LDB_DI1_SEL 12
-#define BM_CS2CDR_LDB_DI1_SEL (0x7 << 12)
-#define BP_CS2CDR_ENFC_SEL 16
-#define BM_CS2CDR_ENFC_SEL (0x3 << 16)
-#define BP_CS2CDR_ENFC_PRED 18
-#define BM_CS2CDR_ENFC_PRED (0x7 << 18)
-#define BP_CS2CDR_ENFC_PODF 21
-#define BM_CS2CDR_ENFC_PODF (0x3f << 21)
-
-#define BP_CDCDR_ASRC_SERIAL_SEL 7
-#define BM_CDCDR_ASRC_SERIAL_SEL (0x3 << 7)
-#define BP_CDCDR_ASRC_SERIAL_PODF 9
-#define BM_CDCDR_ASRC_SERIAL_PODF (0x7 << 9)
-#define BP_CDCDR_ASRC_SERIAL_PRED 12
-#define BM_CDCDR_ASRC_SERIAL_PRED (0x7 << 12)
-#define BP_CDCDR_SPDIF_SEL 20
-#define BM_CDCDR_SPDIF_SEL (0x3 << 20)
-#define BP_CDCDR_SPDIF_PODF 22
-#define BM_CDCDR_SPDIF_PODF (0x7 << 22)
-#define BP_CDCDR_SPDIF_PRED 25
-#define BM_CDCDR_SPDIF_PRED (0x7 << 25)
-#define BP_CDCDR_HSI_TX_PODF 29
-#define BM_CDCDR_HSI_TX_PODF (0x7 << 29)
-#define BP_CDCDR_HSI_TX_SEL 28
-#define BM_CDCDR_HSI_TX_SEL (0x1 << 28)
-
-#define BP_CHSCCDR_IPU1_DI0_SEL 0
-#define BM_CHSCCDR_IPU1_DI0_SEL (0x7 << 0)
-#define BP_CHSCCDR_IPU1_DI0_PRE_PODF 3
-#define BM_CHSCCDR_IPU1_DI0_PRE_PODF (0x7 << 3)
-#define BP_CHSCCDR_IPU1_DI0_PRE_SEL 6
-#define BM_CHSCCDR_IPU1_DI0_PRE_SEL (0x7 << 6)
-#define BP_CHSCCDR_IPU1_DI1_SEL 9
-#define BM_CHSCCDR_IPU1_DI1_SEL (0x7 << 9)
-#define BP_CHSCCDR_IPU1_DI1_PRE_PODF 12
-#define BM_CHSCCDR_IPU1_DI1_PRE_PODF (0x7 << 12)
-#define BP_CHSCCDR_IPU1_DI1_PRE_SEL 15
-#define BM_CHSCCDR_IPU1_DI1_PRE_SEL (0x7 << 15)
-
-#define BP_CSCDR2_IPU2_DI0_SEL 0
-#define BM_CSCDR2_IPU2_DI0_SEL (0x7)
-#define BP_CSCDR2_IPU2_DI0_PRE_PODF 3
-#define BM_CSCDR2_IPU2_DI0_PRE_PODF (0x7 << 3)
-#define BP_CSCDR2_IPU2_DI0_PRE_SEL 6
-#define BM_CSCDR2_IPU2_DI0_PRE_SEL (0x7 << 6)
-#define BP_CSCDR2_IPU2_DI1_SEL 9
-#define BM_CSCDR2_IPU2_DI1_SEL (0x7 << 9)
-#define BP_CSCDR2_IPU2_DI1_PRE_PODF 12
-#define BM_CSCDR2_IPU2_DI1_PRE_PODF (0x7 << 12)
-#define BP_CSCDR2_IPU2_DI1_PRE_SEL 15
-#define BM_CSCDR2_IPU2_DI1_PRE_SEL (0x7 << 15)
-#define BP_CSCDR2_ECSPI_CLK_PODF 19
-#define BM_CSCDR2_ECSPI_CLK_PODF (0x3f << 19)
-
-#define BP_CSCDR3_IPU1_HSP_SEL 9
-#define BM_CSCDR3_IPU1_HSP_SEL (0x3 << 9)
-#define BP_CSCDR3_IPU1_HSP_PODF 11
-#define BM_CSCDR3_IPU1_HSP_PODF (0x7 << 11)
-#define BP_CSCDR3_IPU2_HSP_SEL 14
-#define BM_CSCDR3_IPU2_HSP_SEL (0x3 << 14)
-#define BP_CSCDR3_IPU2_HSP_PODF 16
-#define BM_CSCDR3_IPU2_HSP_PODF (0x7 << 16)
-
-#define BM_CDHIPR_AXI_PODF_BUSY (0x1 << 0)
-#define BM_CDHIPR_AHB_PODF_BUSY (0x1 << 1)
-#define BM_CDHIPR_MMDC_CH1_PODF_BUSY (0x1 << 2)
-#define BM_CDHIPR_PERIPH2_SEL_BUSY (0x1 << 3)
-#define BM_CDHIPR_MMDC_CH0_PODF_BUSY (0x1 << 4)
-#define BM_CDHIPR_PERIPH_SEL_BUSY (0x1 << 5)
-#define BM_CDHIPR_ARM_PODF_BUSY (0x1 << 16)
-
-#define BP_CLPCR_LPM 0
-#define BM_CLPCR_LPM (0x3 << 0)
-#define BM_CLPCR_BYPASS_PMIC_READY (0x1 << 2)
-#define BM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
-#define BM_CLPCR_SBYOS (0x1 << 6)
-#define BM_CLPCR_DIS_REF_OSC (0x1 << 7)
-#define BM_CLPCR_VSTBY (0x1 << 8)
-#define BP_CLPCR_STBY_COUNT 9
-#define BM_CLPCR_STBY_COUNT (0x3 << 9)
-#define BM_CLPCR_COSC_PWRDOWN (0x1 << 11)
-#define BM_CLPCR_WB_PER_AT_LPM (0x1 << 16)
-#define BM_CLPCR_WB_CORE_AT_LPM (0x1 << 17)
-#define BM_CLPCR_BYP_MMDC_CH0_LPM_HS (0x1 << 19)
-#define BM_CLPCR_BYP_MMDC_CH1_LPM_HS (0x1 << 21)
-#define BM_CLPCR_MASK_CORE0_WFI (0x1 << 22)
-#define BM_CLPCR_MASK_CORE1_WFI (0x1 << 23)
-#define BM_CLPCR_MASK_CORE2_WFI (0x1 << 24)
-#define BM_CLPCR_MASK_CORE3_WFI (0x1 << 25)
-#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
-#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
-
-#define BP_CCOSR_CKO1_EN 7
-#define BP_CCOSR_CKO1_PODF 4
-#define BM_CCOSR_CKO1_PODF (0x7 << 4)
-#define BP_CCOSR_CKO1_SEL 0
-#define BM_CCOSR_CKO1_SEL (0xf << 0)
-
-#define FREQ_480M 480000000
-#define FREQ_528M 528000000
-#define FREQ_594M 594000000
-#define FREQ_650M 650000000
-#define FREQ_1300M 1300000000
-
-static struct clk pll1_sys;
-static struct clk pll2_bus;
-static struct clk pll3_usb_otg;
-static struct clk pll4_audio;
-static struct clk pll5_video;
-static struct clk pll6_mlb;
-static struct clk pll7_usb_host;
-static struct clk pll8_enet;
-static struct clk apbh_dma_clk;
-static struct clk arm_clk;
-static struct clk ipg_clk;
-static struct clk ahb_clk;
-static struct clk axi_clk;
-static struct clk mmdc_ch0_axi_clk;
-static struct clk mmdc_ch1_axi_clk;
-static struct clk periph_clk;
-static struct clk periph_pre_clk;
-static struct clk periph_clk2_clk;
-static struct clk periph2_clk;
-static struct clk periph2_pre_clk;
-static struct clk periph2_clk2_clk;
-static struct clk gpu2d_core_clk;
-static struct clk gpu3d_core_clk;
-static struct clk gpu3d_shader_clk;
-static struct clk ipg_perclk;
-static struct clk emi_clk;
-static struct clk emi_slow_clk;
-static struct clk can1_clk;
-static struct clk uart_clk;
-static struct clk usdhc1_clk;
-static struct clk usdhc2_clk;
-static struct clk usdhc3_clk;
-static struct clk usdhc4_clk;
-static struct clk vpu_clk;
-static struct clk hsi_tx_clk;
-static struct clk ipu1_di0_pre_clk;
-static struct clk ipu1_di1_pre_clk;
-static struct clk ipu2_di0_pre_clk;
-static struct clk ipu2_di1_pre_clk;
-static struct clk ipu1_clk;
-static struct clk ipu2_clk;
-static struct clk ssi1_clk;
-static struct clk ssi3_clk;
-static struct clk esai_clk;
-static struct clk ssi2_clk;
-static struct clk spdif_clk;
-static struct clk asrc_serial_clk;
-static struct clk gpu2d_axi_clk;
-static struct clk gpu3d_axi_clk;
-static struct clk pcie_clk;
-static struct clk vdo_axi_clk;
-static struct clk ldb_di0_clk;
-static struct clk ldb_di1_clk;
-static struct clk ipu1_di0_clk;
-static struct clk ipu1_di1_clk;
-static struct clk ipu2_di0_clk;
-static struct clk ipu2_di1_clk;
-static struct clk enfc_clk;
-static struct clk cko1_clk;
-static struct clk dummy_clk = {};
-
-static unsigned long external_high_reference;
-static unsigned long external_low_reference;
-static unsigned long oscillator_reference;
-
-static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
-{
- return oscillator_reference;
-}
-
-static unsigned long get_high_reference_clock_rate(struct clk *clk)
-{
- return external_high_reference;
-}
-
-static unsigned long get_low_reference_clock_rate(struct clk *clk)
-{
- return external_low_reference;
-}
-
-static struct clk ckil_clk = {
- .get_rate = get_low_reference_clock_rate,
-};
-
-static struct clk ckih_clk = {
- .get_rate = get_high_reference_clock_rate,
-};
-
-static struct clk osc_clk = {
- .get_rate = get_oscillator_reference_clock_rate,
-};
-
-static inline void __iomem *pll_get_reg_addr(struct clk *pll)
-{
- if (pll == &pll1_sys)
- return PLL1_SYS;
- else if (pll == &pll2_bus)
- return PLL2_BUS;
- else if (pll == &pll3_usb_otg)
- return PLL3_USB_OTG;
- else if (pll == &pll4_audio)
- return PLL4_AUDIO;
- else if (pll == &pll5_video)
- return PLL5_VIDEO;
- else if (pll == &pll6_mlb)
- return PLL6_MLB;
- else if (pll == &pll7_usb_host)
- return PLL7_USB_HOST;
- else if (pll == &pll8_enet)
- return PLL8_ENET;
- else
- BUG();
-
- return NULL;
-}
-
-static int pll_enable(struct clk *clk)
-{
- int timeout = 0x100000;
- void __iomem *reg;
- u32 val;
-
- reg = pll_get_reg_addr(clk);
- val = readl_relaxed(reg);
- val &= ~BM_PLL_BYPASS;
- val &= ~BM_PLL_POWER_DOWN;
- /* 480MHz PLLs have the opposite definition for power bit */
- if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
- val |= BM_PLL_POWER_DOWN;
- writel_relaxed(val, reg);
-
- /* Wait for PLL to lock */
- while (!(readl_relaxed(reg) & BM_PLL_LOCK) && --timeout)
- cpu_relax();
-
- if (unlikely(!timeout))
- return -EBUSY;
-
- /* Enable the PLL output now */
- val = readl_relaxed(reg);
- val |= BM_PLL_ENABLE;
- writel_relaxed(val, reg);
-
- return 0;
-}
-
-static void pll_disable(struct clk *clk)
-{
- void __iomem *reg;
- u32 val;
-
- reg = pll_get_reg_addr(clk);
- val = readl_relaxed(reg);
- val &= ~BM_PLL_ENABLE;
- val |= BM_PLL_BYPASS;
- val |= BM_PLL_POWER_DOWN;
- if (clk == &pll3_usb_otg || clk == &pll7_usb_host)
- val &= ~BM_PLL_POWER_DOWN;
- writel_relaxed(val, reg);
-}
-
-static unsigned long pll1_sys_get_rate(struct clk *clk)
-{
- u32 div = (readl_relaxed(PLL1_SYS) & BM_PLL_SYS_DIV_SELECT) >>
- BP_PLL_SYS_DIV_SELECT;
-
- return clk_get_rate(clk->parent) * div / 2;
-}
-
-static int pll1_sys_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 val, div;
-
- if (rate < FREQ_650M || rate > FREQ_1300M)
- return -EINVAL;
-
- div = rate * 2 / clk_get_rate(clk->parent);
- val = readl_relaxed(PLL1_SYS);
- val &= ~BM_PLL_SYS_DIV_SELECT;
- val |= div << BP_PLL_SYS_DIV_SELECT;
- writel_relaxed(val, PLL1_SYS);
-
- return 0;
-}
-
-static unsigned long pll8_enet_get_rate(struct clk *clk)
-{
- u32 div = (readl_relaxed(PLL8_ENET) & BM_PLL_ENET_DIV_SELECT) >>
- BP_PLL_ENET_DIV_SELECT;
-
- switch (div) {
- case 0:
- return 25000000;
- case 1:
- return 50000000;
- case 2:
- return 100000000;
- case 3:
- return 125000000;
- }
-
- return 0;
-}
-
-static int pll8_enet_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 val, div;
-
- switch (rate) {
- case 25000000:
- div = 0;
- break;
- case 50000000:
- div = 1;
- break;
- case 100000000:
- div = 2;
- break;
- case 125000000:
- div = 3;
- break;
- default:
- return -EINVAL;
- }
-
- val = readl_relaxed(PLL8_ENET);
- val &= ~BM_PLL_ENET_DIV_SELECT;
- val |= div << BP_PLL_ENET_DIV_SELECT;
- writel_relaxed(val, PLL8_ENET);
-
- return 0;
-}
-
-static unsigned long pll_av_get_rate(struct clk *clk)
-{
- void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
- unsigned long parent_rate = clk_get_rate(clk->parent);
- u32 mfn = readl_relaxed(reg + PLL_NUM_OFFSET);
- u32 mfd = readl_relaxed(reg + PLL_DENOM_OFFSET);
- u32 div = (readl_relaxed(reg) & BM_PLL_AV_DIV_SELECT) >>
- BP_PLL_AV_DIV_SELECT;
-
- return (parent_rate * div) + ((parent_rate / mfd) * mfn);
-}
-
-static int pll_av_set_rate(struct clk *clk, unsigned long rate)
-{
- void __iomem *reg = (clk == &pll4_audio) ? PLL4_AUDIO : PLL5_VIDEO;
- unsigned int parent_rate = clk_get_rate(clk->parent);
- u32 val, div;
- u32 mfn, mfd = 1000000;
- s64 temp64;
-
- if (rate < FREQ_650M || rate > FREQ_1300M)
- return -EINVAL;
-
- div = rate / parent_rate;
- temp64 = (u64) (rate - div * parent_rate);
- temp64 *= mfd;
- do_div(temp64, parent_rate);
- mfn = temp64;
-
- val = readl_relaxed(reg);
- val &= ~BM_PLL_AV_DIV_SELECT;
- val |= div << BP_PLL_AV_DIV_SELECT;
- writel_relaxed(val, reg);
- writel_relaxed(mfn, reg + PLL_NUM_OFFSET);
- writel_relaxed(mfd, reg + PLL_DENOM_OFFSET);
-
- return 0;
-}
-
-static void __iomem *pll_get_div_reg_bit(struct clk *clk, u32 *bp, u32 *bm)
-{
- void __iomem *reg;
-
- if (clk == &pll2_bus) {
- reg = PLL2_BUS;
- *bp = BP_PLL_BUS_DIV_SELECT;
- *bm = BM_PLL_BUS_DIV_SELECT;
- } else if (clk == &pll3_usb_otg) {
- reg = PLL3_USB_OTG;
- *bp = BP_PLL_USB_DIV_SELECT;
- *bm = BM_PLL_USB_DIV_SELECT;
- } else if (clk == &pll7_usb_host) {
- reg = PLL7_USB_HOST;
- *bp = BP_PLL_USB_DIV_SELECT;
- *bm = BM_PLL_USB_DIV_SELECT;
- } else {
- BUG();
- }
-
- return reg;
-}
-
-static unsigned long pll_get_rate(struct clk *clk)
-{
- void __iomem *reg;
- u32 div, bp, bm;
-
- reg = pll_get_div_reg_bit(clk, &bp, &bm);
- div = (readl_relaxed(reg) & bm) >> bp;
-
- return (div == 1) ? clk_get_rate(clk->parent) * 22 :
- clk_get_rate(clk->parent) * 20;
-}
-
-static int pll_set_rate(struct clk *clk, unsigned long rate)
-{
- void __iomem *reg;
- u32 val, div, bp, bm;
-
- if (rate == FREQ_528M)
- div = 1;
- else if (rate == FREQ_480M)
- div = 0;
- else
- return -EINVAL;
-
- reg = pll_get_div_reg_bit(clk, &bp, &bm);
- val = readl_relaxed(reg);
- val &= ~bm;
- val |= div << bp;
- writel_relaxed(val, reg);
-
- return 0;
-}
-
-#define pll2_bus_get_rate pll_get_rate
-#define pll2_bus_set_rate pll_set_rate
-#define pll3_usb_otg_get_rate pll_get_rate
-#define pll3_usb_otg_set_rate pll_set_rate
-#define pll7_usb_host_get_rate pll_get_rate
-#define pll7_usb_host_set_rate pll_set_rate
-#define pll4_audio_get_rate pll_av_get_rate
-#define pll4_audio_set_rate pll_av_set_rate
-#define pll5_video_get_rate pll_av_get_rate
-#define pll5_video_set_rate pll_av_set_rate
-#define pll6_mlb_get_rate NULL
-#define pll6_mlb_set_rate NULL
-
-#define DEF_PLL(name) \
- static struct clk name = { \
- .enable = pll_enable, \
- .disable = pll_disable, \
- .get_rate = name##_get_rate, \
- .set_rate = name##_set_rate, \
- .parent = &osc_clk, \
- }
-
-DEF_PLL(pll1_sys);
-DEF_PLL(pll2_bus);
-DEF_PLL(pll3_usb_otg);
-DEF_PLL(pll4_audio);
-DEF_PLL(pll5_video);
-DEF_PLL(pll6_mlb);
-DEF_PLL(pll7_usb_host);
-DEF_PLL(pll8_enet);
-
-static unsigned long pfd_get_rate(struct clk *clk)
-{
- u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
- u32 frac, bp_frac;
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.enable(&apbh_dma_clk);
-
- bp_frac = clk->enable_shift - 7;
- frac = readl_relaxed(clk->enable_reg) >> bp_frac & PFD_FRAC_MASK;
- do_div(tmp, frac);
-
- return tmp;
-}
-
-static int pfd_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 val, frac, bp_frac;
- u64 tmp = (u64) clk_get_rate(clk->parent) * 18;
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.enable(&apbh_dma_clk);
-
- /*
- * Round up the divider so that we don't set a rate
- * higher than what is requested
- */
- tmp += rate / 2;
- do_div(tmp, rate);
- frac = tmp;
- frac = (frac < 12) ? 12 : frac;
- frac = (frac > 35) ? 35 : frac;
-
- /*
- * The frac field always starts from 7 bits lower
- * position of enable bit
- */
- bp_frac = clk->enable_shift - 7;
- val = readl_relaxed(clk->enable_reg);
- val &= ~(PFD_FRAC_MASK << bp_frac);
- val |= frac << bp_frac;
- writel_relaxed(val, clk->enable_reg);
-
- tmp = (u64) clk_get_rate(clk->parent) * 18;
- do_div(tmp, frac);
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.disable(&apbh_dma_clk);
-
- return 0;
-}
-
-static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 frac;
- u64 tmp;
-
- tmp = (u64) clk_get_rate(clk->parent) * 18;
- tmp += rate / 2;
- do_div(tmp, rate);
- frac = tmp;
- frac = (frac < 12) ? 12 : frac;
- frac = (frac > 35) ? 35 : frac;
- tmp = (u64) clk_get_rate(clk->parent) * 18;
- do_div(tmp, frac);
-
- return tmp;
-}
-
-static int pfd_enable(struct clk *clk)
-{
- u32 val;
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.enable(&apbh_dma_clk);
-
- val = readl_relaxed(clk->enable_reg);
- val &= ~(1 << clk->enable_shift);
- writel_relaxed(val, clk->enable_reg);
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.disable(&apbh_dma_clk);
-
- return 0;
-}
-
-static void pfd_disable(struct clk *clk)
-{
- u32 val;
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.enable(&apbh_dma_clk);
-
- val = readl_relaxed(clk->enable_reg);
- val |= 1 << clk->enable_shift;
- writel_relaxed(val, clk->enable_reg);
-
- if (apbh_dma_clk.usecount == 0)
- apbh_dma_clk.disable(&apbh_dma_clk);
-}
-
-#define DEF_PFD(name, er, es, p) \
- static struct clk name = { \
- .enable_reg = er, \
- .enable_shift = es, \
- .enable = pfd_enable, \
- .disable = pfd_disable, \
- .get_rate = pfd_get_rate, \
- .set_rate = pfd_set_rate, \
- .round_rate = pfd_round_rate, \
- .parent = p, \
- }
-
-DEF_PFD(pll2_pfd_352m, PFD_528, PFD0, &pll2_bus);
-DEF_PFD(pll2_pfd_594m, PFD_528, PFD1, &pll2_bus);
-DEF_PFD(pll2_pfd_400m, PFD_528, PFD2, &pll2_bus);
-DEF_PFD(pll3_pfd_720m, PFD_480, PFD0, &pll3_usb_otg);
-DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg);
-DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg);
-DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg);
-
-static unsigned long twd_clk_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 2;
-}
-
-static struct clk twd_clk = {
- .parent = &arm_clk,
- .get_rate = twd_clk_get_rate,
-};
-
-static unsigned long pll2_200m_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 2;
-}
-
-static struct clk pll2_200m = {
- .parent = &pll2_pfd_400m,
- .get_rate = pll2_200m_get_rate,
-};
-
-static unsigned long pll3_120m_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 4;
-}
-
-static struct clk pll3_120m = {
- .parent = &pll3_usb_otg,
- .get_rate = pll3_120m_get_rate,
-};
-
-static unsigned long pll3_80m_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 6;
-}
-
-static struct clk pll3_80m = {
- .parent = &pll3_usb_otg,
- .get_rate = pll3_80m_get_rate,
-};
-
-static unsigned long pll3_60m_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 8;
-}
-
-static struct clk pll3_60m = {
- .parent = &pll3_usb_otg,
- .get_rate = pll3_60m_get_rate,
-};
-
-static int pll1_sw_clk_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 val = readl_relaxed(CCSR);
-
- if (parent == &pll1_sys) {
- val &= ~BM_CCSR_PLL1_SW_SEL;
- val &= ~BM_CCSR_STEP_SEL;
- } else if (parent == &osc_clk) {
- val |= BM_CCSR_PLL1_SW_SEL;
- val &= ~BM_CCSR_STEP_SEL;
- } else if (parent == &pll2_pfd_400m) {
- val |= BM_CCSR_PLL1_SW_SEL;
- val |= BM_CCSR_STEP_SEL;
- } else {
- return -EINVAL;
- }
-
- writel_relaxed(val, CCSR);
-
- return 0;
-}
-
-static struct clk pll1_sw_clk = {
- .parent = &pll1_sys,
- .set_parent = pll1_sw_clk_set_parent,
-};
-
-static void calc_pred_podf_dividers(u32 div, u32 *pred, u32 *podf)
-{
- u32 min_pred, temp_pred, old_err, err;
-
- if (div >= 512) {
- *pred = 8;
- *podf = 64;
- } else if (div >= 8) {
- min_pred = (div - 1) / 64 + 1;
- old_err = 8;
- for (temp_pred = 8; temp_pred >= min_pred; temp_pred--) {
- err = div % temp_pred;
- if (err == 0) {
- *pred = temp_pred;
- break;
- }
- err = temp_pred - err;
- if (err < old_err) {
- old_err = err;
- *pred = temp_pred;
- }
- }
- *podf = (div + *pred - 1) / *pred;
- } else if (div < 8) {
- *pred = div;
- *podf = 1;
- }
-}
-
-static int _clk_enable(struct clk *clk)
-{
- u32 reg;
- reg = readl_relaxed(clk->enable_reg);
- reg |= 0x3 << clk->enable_shift;
- writel_relaxed(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void _clk_disable(struct clk *clk)
-{
- u32 reg;
- reg = readl_relaxed(clk->enable_reg);
- reg &= ~(0x3 << clk->enable_shift);
- writel_relaxed(reg, clk->enable_reg);
-}
-
-static int _clk_enable_1b(struct clk *clk)
-{
- u32 reg;
- reg = readl_relaxed(clk->enable_reg);
- reg |= 0x1 << clk->enable_shift;
- writel_relaxed(reg, clk->enable_reg);
-
- return 0;
-}
-
-static void _clk_disable_1b(struct clk *clk)
-{
- u32 reg;
- reg = readl_relaxed(clk->enable_reg);
- reg &= ~(0x1 << clk->enable_shift);
- writel_relaxed(reg, clk->enable_reg);
-}
-
-struct divider {
- struct clk *clk;
- void __iomem *reg;
- u32 bp_pred;
- u32 bm_pred;
- u32 bp_podf;
- u32 bm_podf;
-};
-
-#define DEF_CLK_DIV1(d, c, r, b) \
- static struct divider d = { \
- .clk = c, \
- .reg = r, \
- .bp_podf = BP_##r##_##b##_PODF, \
- .bm_podf = BM_##r##_##b##_PODF, \
- }
-
-DEF_CLK_DIV1(arm_div, &arm_clk, CACRR, ARM);
-DEF_CLK_DIV1(ipg_div, &ipg_clk, CBCDR, IPG);
-DEF_CLK_DIV1(ahb_div, &ahb_clk, CBCDR, AHB);
-DEF_CLK_DIV1(axi_div, &axi_clk, CBCDR, AXI);
-DEF_CLK_DIV1(mmdc_ch0_axi_div, &mmdc_ch0_axi_clk, CBCDR, MMDC_CH0_AXI);
-DEF_CLK_DIV1(mmdc_ch1_axi_div, &mmdc_ch1_axi_clk, CBCDR, MMDC_CH1_AXI);
-DEF_CLK_DIV1(periph_clk2_div, &periph_clk2_clk, CBCDR, PERIPH_CLK2);
-DEF_CLK_DIV1(periph2_clk2_div, &periph2_clk2_clk, CBCDR, PERIPH2_CLK2);
-DEF_CLK_DIV1(gpu2d_core_div, &gpu2d_core_clk, CBCMR, GPU2D_CORE);
-DEF_CLK_DIV1(gpu3d_core_div, &gpu3d_core_clk, CBCMR, GPU3D_CORE);
-DEF_CLK_DIV1(gpu3d_shader_div, &gpu3d_shader_clk, CBCMR, GPU3D_SHADER);
-DEF_CLK_DIV1(ipg_perclk_div, &ipg_perclk, CSCMR1, PERCLK);
-DEF_CLK_DIV1(emi_div, &emi_clk, CSCMR1, EMI);
-DEF_CLK_DIV1(emi_slow_div, &emi_slow_clk, CSCMR1, EMI_SLOW);
-DEF_CLK_DIV1(can_div, &can1_clk, CSCMR2, CAN);
-DEF_CLK_DIV1(uart_div, &uart_clk, CSCDR1, UART);
-DEF_CLK_DIV1(usdhc1_div, &usdhc1_clk, CSCDR1, USDHC1);
-DEF_CLK_DIV1(usdhc2_div, &usdhc2_clk, CSCDR1, USDHC2);
-DEF_CLK_DIV1(usdhc3_div, &usdhc3_clk, CSCDR1, USDHC3);
-DEF_CLK_DIV1(usdhc4_div, &usdhc4_clk, CSCDR1, USDHC4);
-DEF_CLK_DIV1(vpu_div, &vpu_clk, CSCDR1, VPU_AXI);
-DEF_CLK_DIV1(hsi_tx_div, &hsi_tx_clk, CDCDR, HSI_TX);
-DEF_CLK_DIV1(ipu1_di0_pre_div, &ipu1_di0_pre_clk, CHSCCDR, IPU1_DI0_PRE);
-DEF_CLK_DIV1(ipu1_di1_pre_div, &ipu1_di1_pre_clk, CHSCCDR, IPU1_DI1_PRE);
-DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE);
-DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE);
-DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP);
-DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP);
-DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1);
-
-#define DEF_CLK_DIV2(d, c, r, b) \
- static struct divider d = { \
- .clk = c, \
- .reg = r, \
- .bp_pred = BP_##r##_##b##_PRED, \
- .bm_pred = BM_##r##_##b##_PRED, \
- .bp_podf = BP_##r##_##b##_PODF, \
- .bm_podf = BM_##r##_##b##_PODF, \
- }
-
-DEF_CLK_DIV2(ssi1_div, &ssi1_clk, CS1CDR, SSI1);
-DEF_CLK_DIV2(ssi3_div, &ssi3_clk, CS1CDR, SSI3);
-DEF_CLK_DIV2(esai_div, &esai_clk, CS1CDR, ESAI);
-DEF_CLK_DIV2(ssi2_div, &ssi2_clk, CS2CDR, SSI2);
-DEF_CLK_DIV2(enfc_div, &enfc_clk, CS2CDR, ENFC);
-DEF_CLK_DIV2(spdif_div, &spdif_clk, CDCDR, SPDIF);
-DEF_CLK_DIV2(asrc_serial_div, &asrc_serial_clk, CDCDR, ASRC_SERIAL);
-
-static struct divider *dividers[] = {
- &arm_div,
- &ipg_div,
- &ahb_div,
- &axi_div,
- &mmdc_ch0_axi_div,
- &mmdc_ch1_axi_div,
- &periph_clk2_div,
- &periph2_clk2_div,
- &gpu2d_core_div,
- &gpu3d_core_div,
- &gpu3d_shader_div,
- &ipg_perclk_div,
- &emi_div,
- &emi_slow_div,
- &can_div,
- &uart_div,
- &usdhc1_div,
- &usdhc2_div,
- &usdhc3_div,
- &usdhc4_div,
- &vpu_div,
- &hsi_tx_div,
- &ipu1_di0_pre_div,
- &ipu1_di1_pre_div,
- &ipu2_di0_pre_div,
- &ipu2_di1_pre_div,
- &ipu1_div,
- &ipu2_div,
- &ssi1_div,
- &ssi3_div,
- &esai_div,
- &ssi2_div,
- &enfc_div,
- &spdif_div,
- &asrc_serial_div,
- &cko1_div,
-};
-
-static unsigned long ldb_di_clk_get_rate(struct clk *clk)
-{
- u32 val = readl_relaxed(CSCMR2);
-
- val &= (clk == &ldb_di0_clk) ? BM_CSCMR2_LDB_DI0_IPU_DIV :
- BM_CSCMR2_LDB_DI1_IPU_DIV;
- if (val)
- return clk_get_rate(clk->parent) / 7;
- else
- return clk_get_rate(clk->parent) * 2 / 7;
-}
-
-static int ldb_di_clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- u32 val = readl_relaxed(CSCMR2);
-
- if (rate * 7 <= parent_rate + parent_rate / 20)
- val |= BM_CSCMR2_LDB_DI0_IPU_DIV;
- else
- val &= ~BM_CSCMR2_LDB_DI0_IPU_DIV;
-
- writel_relaxed(val, CSCMR2);
-
- return 0;
-}
-
-static unsigned long ldb_di_clk_round_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
-
- if (rate * 7 <= parent_rate + parent_rate / 20)
- return parent_rate / 7;
- else
- return 2 * parent_rate / 7;
-}
-
-static unsigned long _clk_get_rate(struct clk *clk)
-{
- struct divider *d;
- u32 val, pred, podf;
- int i, num;
-
- if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
- return ldb_di_clk_get_rate(clk);
-
- num = ARRAY_SIZE(dividers);
- for (i = 0; i < num; i++)
- if (dividers[i]->clk == clk) {
- d = dividers[i];
- break;
- }
- if (i == num)
- return clk_get_rate(clk->parent);
-
- val = readl_relaxed(d->reg);
- pred = ((val & d->bm_pred) >> d->bp_pred) + 1;
- podf = ((val & d->bm_podf) >> d->bp_podf) + 1;
-
- return clk_get_rate(clk->parent) / (pred * podf);
-}
-
-static int clk_busy_wait(struct clk *clk)
-{
- int timeout = 0x100000;
- u32 bm;
-
- if (clk == &axi_clk)
- bm = BM_CDHIPR_AXI_PODF_BUSY;
- else if (clk == &ahb_clk)
- bm = BM_CDHIPR_AHB_PODF_BUSY;
- else if (clk == &mmdc_ch0_axi_clk)
- bm = BM_CDHIPR_MMDC_CH0_PODF_BUSY;
- else if (clk == &periph_clk)
- bm = BM_CDHIPR_PERIPH_SEL_BUSY;
- else if (clk == &arm_clk)
- bm = BM_CDHIPR_ARM_PODF_BUSY;
- else
- return -EINVAL;
-
- while ((readl_relaxed(CDHIPR) & bm) && --timeout)
- cpu_relax();
-
- if (unlikely(!timeout))
- return -EBUSY;
-
- return 0;
-}
-
-static int _clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- struct divider *d;
- u32 val, div, max_div, pred = 0, podf;
- int i, num;
-
- if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
- return ldb_di_clk_set_rate(clk, rate);
-
- num = ARRAY_SIZE(dividers);
- for (i = 0; i < num; i++)
- if (dividers[i]->clk == clk) {
- d = dividers[i];
- break;
- }
- if (i == num)
- return -EINVAL;
-
- max_div = ((d->bm_pred >> d->bp_pred) + 1) *
- ((d->bm_podf >> d->bp_podf) + 1);
-
- div = parent_rate / rate;
- if (div == 0)
- div++;
-
- if ((parent_rate / div != rate) || div > max_div)
- return -EINVAL;
-
- if (d->bm_pred) {
- calc_pred_podf_dividers(div, &pred, &podf);
- } else {
- pred = 1;
- podf = div;
- }
-
- val = readl_relaxed(d->reg);
- val &= ~(d->bm_pred | d->bm_podf);
- val |= (pred - 1) << d->bp_pred | (podf - 1) << d->bp_podf;
- writel_relaxed(val, d->reg);
-
- if (clk == &axi_clk || clk == &ahb_clk ||
- clk == &mmdc_ch0_axi_clk || clk == &arm_clk)
- return clk_busy_wait(clk);
-
- return 0;
-}
-
-static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long parent_rate = clk_get_rate(clk->parent);
- u32 div = parent_rate / rate;
- u32 div_max, pred = 0, podf;
- struct divider *d;
- int i, num;
-
- if (clk == &ldb_di0_clk || clk == &ldb_di1_clk)
- return ldb_di_clk_round_rate(clk, rate);
-
- num = ARRAY_SIZE(dividers);
- for (i = 0; i < num; i++)
- if (dividers[i]->clk == clk) {
- d = dividers[i];
- break;
- }
- if (i == num)
- return -EINVAL;
-
- if (div == 0 || parent_rate % rate)
- div++;
-
- if (d->bm_pred) {
- calc_pred_podf_dividers(div, &pred, &podf);
- div = pred * podf;
- } else {
- div_max = (d->bm_podf >> d->bp_podf) + 1;
- if (div > div_max)
- div = div_max;
- }
-
- return parent_rate / div;
-}
-
-struct multiplexer {
- struct clk *clk;
- void __iomem *reg;
- u32 bp;
- u32 bm;
- int pnum;
- struct clk *parents[];
-};
-
-static struct multiplexer axi_mux = {
- .clk = &axi_clk,
- .reg = CBCDR,
- .bp = BP_CBCDR_AXI_SEL,
- .bm = BM_CBCDR_AXI_SEL,
- .parents = {
- &periph_clk,
- &pll2_pfd_400m,
- &pll3_pfd_540m,
- NULL
- },
-};
-
-static struct multiplexer periph_mux = {
- .clk = &periph_clk,
- .reg = CBCDR,
- .bp = BP_CBCDR_PERIPH_CLK_SEL,
- .bm = BM_CBCDR_PERIPH_CLK_SEL,
- .parents = {
- &periph_pre_clk,
- &periph_clk2_clk,
- NULL
- },
-};
-
-static struct multiplexer periph_pre_mux = {
- .clk = &periph_pre_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_PRE_PERIPH_CLK_SEL,
- .bm = BM_CBCMR_PRE_PERIPH_CLK_SEL,
- .parents = {
- &pll2_bus,
- &pll2_pfd_400m,
- &pll2_pfd_352m,
- &pll2_200m,
- NULL
- },
-};
-
-static struct multiplexer periph_clk2_mux = {
- .clk = &periph_clk2_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_PERIPH_CLK2_SEL,
- .bm = BM_CBCMR_PERIPH_CLK2_SEL,
- .parents = {
- &pll3_usb_otg,
- &osc_clk,
- NULL
- },
-};
-
-static struct multiplexer periph2_mux = {
- .clk = &periph2_clk,
- .reg = CBCDR,
- .bp = BP_CBCDR_PERIPH2_CLK_SEL,
- .bm = BM_CBCDR_PERIPH2_CLK_SEL,
- .parents = {
- &periph2_pre_clk,
- &periph2_clk2_clk,
- NULL
- },
-};
-
-static struct multiplexer periph2_pre_mux = {
- .clk = &periph2_pre_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_PRE_PERIPH2_CLK_SEL,
- .bm = BM_CBCMR_PRE_PERIPH2_CLK_SEL,
- .parents = {
- &pll2_bus,
- &pll2_pfd_400m,
- &pll2_pfd_352m,
- &pll2_200m,
- NULL
- },
-};
-
-static struct multiplexer periph2_clk2_mux = {
- .clk = &periph2_clk2_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_PERIPH2_CLK2_SEL,
- .bm = BM_CBCMR_PERIPH2_CLK2_SEL,
- .parents = {
- &pll3_usb_otg,
- &osc_clk,
- NULL
- },
-};
-
-static struct multiplexer gpu2d_axi_mux = {
- .clk = &gpu2d_axi_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_GPU2D_AXI_SEL,
- .bm = BM_CBCMR_GPU2D_AXI_SEL,
- .parents = {
- &axi_clk,
- &ahb_clk,
- NULL
- },
-};
-
-static struct multiplexer gpu3d_axi_mux = {
- .clk = &gpu3d_axi_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_GPU3D_AXI_SEL,
- .bm = BM_CBCMR_GPU3D_AXI_SEL,
- .parents = {
- &axi_clk,
- &ahb_clk,
- NULL
- },
-};
-
-static struct multiplexer gpu3d_core_mux = {
- .clk = &gpu3d_core_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_GPU3D_CORE_SEL,
- .bm = BM_CBCMR_GPU3D_CORE_SEL,
- .parents = {
- &mmdc_ch0_axi_clk,
- &pll3_usb_otg,
- &pll2_pfd_594m,
- &pll2_pfd_400m,
- NULL
- },
-};
-
-static struct multiplexer gpu3d_shader_mux = {
- .clk = &gpu3d_shader_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_GPU3D_SHADER_SEL,
- .bm = BM_CBCMR_GPU3D_SHADER_SEL,
- .parents = {
- &mmdc_ch0_axi_clk,
- &pll3_usb_otg,
- &pll2_pfd_594m,
- &pll3_pfd_720m,
- NULL
- },
-};
-
-static struct multiplexer pcie_axi_mux = {
- .clk = &pcie_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_PCIE_AXI_SEL,
- .bm = BM_CBCMR_PCIE_AXI_SEL,
- .parents = {
- &axi_clk,
- &ahb_clk,
- NULL
- },
-};
-
-static struct multiplexer vdo_axi_mux = {
- .clk = &vdo_axi_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_VDO_AXI_SEL,
- .bm = BM_CBCMR_VDO_AXI_SEL,
- .parents = {
- &axi_clk,
- &ahb_clk,
- NULL
- },
-};
-
-static struct multiplexer vpu_axi_mux = {
- .clk = &vpu_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_VPU_AXI_SEL,
- .bm = BM_CBCMR_VPU_AXI_SEL,
- .parents = {
- &axi_clk,
- &pll2_pfd_400m,
- &pll2_pfd_352m,
- NULL
- },
-};
-
-static struct multiplexer gpu2d_core_mux = {
- .clk = &gpu2d_core_clk,
- .reg = CBCMR,
- .bp = BP_CBCMR_GPU2D_CORE_SEL,
- .bm = BM_CBCMR_GPU2D_CORE_SEL,
- .parents = {
- &axi_clk,
- &pll3_usb_otg,
- &pll2_pfd_352m,
- &pll2_pfd_400m,
- NULL
- },
-};
-
-#define DEF_SSI_MUX(id) \
- static struct multiplexer ssi##id##_mux = { \
- .clk = &ssi##id##_clk, \
- .reg = CSCMR1, \
- .bp = BP_CSCMR1_SSI##id##_SEL, \
- .bm = BM_CSCMR1_SSI##id##_SEL, \
- .parents = { \
- &pll3_pfd_508m, \
- &pll3_pfd_454m, \
- &pll4_audio, \
- NULL \
- }, \
- }
-
-DEF_SSI_MUX(1);
-DEF_SSI_MUX(2);
-DEF_SSI_MUX(3);
-
-#define DEF_USDHC_MUX(id) \
- static struct multiplexer usdhc##id##_mux = { \
- .clk = &usdhc##id##_clk, \
- .reg = CSCMR1, \
- .bp = BP_CSCMR1_USDHC##id##_SEL, \
- .bm = BM_CSCMR1_USDHC##id##_SEL, \
- .parents = { \
- &pll2_pfd_400m, \
- &pll2_pfd_352m, \
- NULL \
- }, \
- }
-
-DEF_USDHC_MUX(1);
-DEF_USDHC_MUX(2);
-DEF_USDHC_MUX(3);
-DEF_USDHC_MUX(4);
-
-static struct multiplexer emi_mux = {
- .clk = &emi_clk,
- .reg = CSCMR1,
- .bp = BP_CSCMR1_EMI_SEL,
- .bm = BM_CSCMR1_EMI_SEL,
- .parents = {
- &axi_clk,
- &pll3_usb_otg,
- &pll2_pfd_400m,
- &pll2_pfd_352m,
- NULL
- },
-};
-
-static struct multiplexer emi_slow_mux = {
- .clk = &emi_slow_clk,
- .reg = CSCMR1,
- .bp = BP_CSCMR1_EMI_SLOW_SEL,
- .bm = BM_CSCMR1_EMI_SLOW_SEL,
- .parents = {
- &axi_clk,
- &pll3_usb_otg,
- &pll2_pfd_400m,
- &pll2_pfd_352m,
- NULL
- },
-};
-
-static struct multiplexer esai_mux = {
- .clk = &esai_clk,
- .reg = CSCMR2,
- .bp = BP_CSCMR2_ESAI_SEL,
- .bm = BM_CSCMR2_ESAI_SEL,
- .parents = {
- &pll4_audio,
- &pll3_pfd_508m,
- &pll3_pfd_454m,
- &pll3_usb_otg,
- NULL
- },
-};
-
-#define DEF_LDB_DI_MUX(id) \
- static struct multiplexer ldb_di##id##_mux = { \
- .clk = &ldb_di##id##_clk, \
- .reg = CS2CDR, \
- .bp = BP_CS2CDR_LDB_DI##id##_SEL, \
- .bm = BM_CS2CDR_LDB_DI##id##_SEL, \
- .parents = { \
- &pll5_video, \
- &pll2_pfd_352m, \
- &pll2_pfd_400m, \
- &pll3_pfd_540m, \
- &pll3_usb_otg, \
- NULL \
- }, \
- }
-
-DEF_LDB_DI_MUX(0);
-DEF_LDB_DI_MUX(1);
-
-static struct multiplexer enfc_mux = {
- .clk = &enfc_clk,
- .reg = CS2CDR,
- .bp = BP_CS2CDR_ENFC_SEL,
- .bm = BM_CS2CDR_ENFC_SEL,
- .parents = {
- &pll2_pfd_352m,
- &pll2_bus,
- &pll3_usb_otg,
- &pll2_pfd_400m,
- NULL
- },
-};
-
-static struct multiplexer spdif_mux = {
- .clk = &spdif_clk,
- .reg = CDCDR,
- .bp = BP_CDCDR_SPDIF_SEL,
- .bm = BM_CDCDR_SPDIF_SEL,
- .parents = {
- &pll4_audio,
- &pll3_pfd_508m,
- &pll3_pfd_454m,
- &pll3_usb_otg,
- NULL
- },
-};
-
-static struct multiplexer asrc_serial_mux = {
- .clk = &asrc_serial_clk,
- .reg = CDCDR,
- .bp = BP_CDCDR_ASRC_SERIAL_SEL,
- .bm = BM_CDCDR_ASRC_SERIAL_SEL,
- .parents = {
- &pll4_audio,
- &pll3_pfd_508m,
- &pll3_pfd_454m,
- &pll3_usb_otg,
- NULL
- },
-};
-
-static struct multiplexer hsi_tx_mux = {
- .clk = &hsi_tx_clk,
- .reg = CDCDR,
- .bp = BP_CDCDR_HSI_TX_SEL,
- .bm = BM_CDCDR_HSI_TX_SEL,
- .parents = {
- &pll3_120m,
- &pll2_pfd_400m,
- NULL
- },
-};
-
-#define DEF_IPU_DI_PRE_MUX(r, i, d) \
- static struct multiplexer ipu##i##_di##d##_pre_mux = { \
- .clk = &ipu##i##_di##d##_pre_clk, \
- .reg = r, \
- .bp = BP_##r##_IPU##i##_DI##d##_PRE_SEL, \
- .bm = BM_##r##_IPU##i##_DI##d##_PRE_SEL, \
- .parents = { \
- &mmdc_ch0_axi_clk, \
- &pll3_usb_otg, \
- &pll5_video, \
- &pll2_pfd_352m, \
- &pll2_pfd_400m, \
- &pll3_pfd_540m, \
- NULL \
- }, \
- }
-
-DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 0);
-DEF_IPU_DI_PRE_MUX(CHSCCDR, 1, 1);
-DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 0);
-DEF_IPU_DI_PRE_MUX(CSCDR2, 2, 1);
-
-#define DEF_IPU_DI_MUX(r, i, d) \
- static struct multiplexer ipu##i##_di##d##_mux = { \
- .clk = &ipu##i##_di##d##_clk, \
- .reg = r, \
- .bp = BP_##r##_IPU##i##_DI##d##_SEL, \
- .bm = BM_##r##_IPU##i##_DI##d##_SEL, \
- .parents = { \
- &ipu##i##_di##d##_pre_clk, \
- &dummy_clk, \
- &dummy_clk, \
- &ldb_di0_clk, \
- &ldb_di1_clk, \
- NULL \
- }, \
- }
-
-DEF_IPU_DI_MUX(CHSCCDR, 1, 0);
-DEF_IPU_DI_MUX(CHSCCDR, 1, 1);
-DEF_IPU_DI_MUX(CSCDR2, 2, 0);
-DEF_IPU_DI_MUX(CSCDR2, 2, 1);
-
-#define DEF_IPU_MUX(id) \
- static struct multiplexer ipu##id##_mux = { \
- .clk = &ipu##id##_clk, \
- .reg = CSCDR3, \
- .bp = BP_CSCDR3_IPU##id##_HSP_SEL, \
- .bm = BM_CSCDR3_IPU##id##_HSP_SEL, \
- .parents = { \
- &mmdc_ch0_axi_clk, \
- &pll2_pfd_400m, \
- &pll3_120m, \
- &pll3_pfd_540m, \
- NULL \
- }, \
- }
-
-DEF_IPU_MUX(1);
-DEF_IPU_MUX(2);
-
-static struct multiplexer cko1_mux = {
- .clk = &cko1_clk,
- .reg = CCOSR,
- .bp = BP_CCOSR_CKO1_SEL,
- .bm = BM_CCOSR_CKO1_SEL,
- .parents = {
- &pll3_usb_otg,
- &pll2_bus,
- &pll1_sys,
- &pll5_video,
- &dummy_clk,
- &axi_clk,
- &enfc_clk,
- &ipu1_di0_clk,
- &ipu1_di1_clk,
- &ipu2_di0_clk,
- &ipu2_di1_clk,
- &ahb_clk,
- &ipg_clk,
- &ipg_perclk,
- &ckil_clk,
- &pll4_audio,
- NULL
- },
-};
-
-static struct multiplexer *multiplexers[] = {
- &axi_mux,
- &periph_mux,
- &periph_pre_mux,
- &periph_clk2_mux,
- &periph2_mux,
- &periph2_pre_mux,
- &periph2_clk2_mux,
- &gpu2d_axi_mux,
- &gpu3d_axi_mux,
- &gpu3d_core_mux,
- &gpu3d_shader_mux,
- &pcie_axi_mux,
- &vdo_axi_mux,
- &vpu_axi_mux,
- &gpu2d_core_mux,
- &ssi1_mux,
- &ssi2_mux,
- &ssi3_mux,
- &usdhc1_mux,
- &usdhc2_mux,
- &usdhc3_mux,
- &usdhc4_mux,
- &emi_mux,
- &emi_slow_mux,
- &esai_mux,
- &ldb_di0_mux,
- &ldb_di1_mux,
- &enfc_mux,
- &spdif_mux,
- &asrc_serial_mux,
- &hsi_tx_mux,
- &ipu1_di0_pre_mux,
- &ipu1_di0_mux,
- &ipu1_di1_pre_mux,
- &ipu1_di1_mux,
- &ipu2_di0_pre_mux,
- &ipu2_di0_mux,
- &ipu2_di1_pre_mux,
- &ipu2_di1_mux,
- &ipu1_mux,
- &ipu2_mux,
- &cko1_mux,
-};
-
-static int _clk_set_parent(struct clk *clk, struct clk *parent)
-{
- struct multiplexer *m;
- int i, num;
- u32 val;
-
- num = ARRAY_SIZE(multiplexers);
- for (i = 0; i < num; i++)
- if (multiplexers[i]->clk == clk) {
- m = multiplexers[i];
- break;
- }
- if (i == num)
- return -EINVAL;
-
- i = 0;
- while (m->parents[i]) {
- if (parent == m->parents[i])
- break;
- i++;
- }
- if (!m->parents[i] || m->parents[i] == &dummy_clk)
- return -EINVAL;
-
- val = readl_relaxed(m->reg);
- val &= ~m->bm;
- val |= i << m->bp;
- writel_relaxed(val, m->reg);
-
- if (clk == &periph_clk)
- return clk_busy_wait(clk);
-
- return 0;
-}
-
-#define DEF_NG_CLK(name, p) \
- static struct clk name = { \
- .get_rate = _clk_get_rate, \
- .set_rate = _clk_set_rate, \
- .round_rate = _clk_round_rate, \
- .set_parent = _clk_set_parent, \
- .parent = p, \
- }
-
-DEF_NG_CLK(periph_clk2_clk, &osc_clk);
-DEF_NG_CLK(periph_pre_clk, &pll2_bus);
-DEF_NG_CLK(periph_clk, &periph_pre_clk);
-DEF_NG_CLK(periph2_clk2_clk, &osc_clk);
-DEF_NG_CLK(periph2_pre_clk, &pll2_bus);
-DEF_NG_CLK(periph2_clk, &periph2_pre_clk);
-DEF_NG_CLK(axi_clk, &periph_clk);
-DEF_NG_CLK(emi_clk, &axi_clk);
-DEF_NG_CLK(arm_clk, &pll1_sw_clk);
-DEF_NG_CLK(ahb_clk, &periph_clk);
-DEF_NG_CLK(ipg_clk, &ahb_clk);
-DEF_NG_CLK(ipg_perclk, &ipg_clk);
-DEF_NG_CLK(ipu1_di0_pre_clk, &pll3_pfd_540m);
-DEF_NG_CLK(ipu1_di1_pre_clk, &pll3_pfd_540m);
-DEF_NG_CLK(ipu2_di0_pre_clk, &pll3_pfd_540m);
-DEF_NG_CLK(ipu2_di1_pre_clk, &pll3_pfd_540m);
-DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg);
-
-#define DEF_CLK(name, er, es, p, s) \
- static struct clk name = { \
- .enable_reg = er, \
- .enable_shift = es, \
- .enable = _clk_enable, \
- .disable = _clk_disable, \
- .get_rate = _clk_get_rate, \
- .set_rate = _clk_set_rate, \
- .round_rate = _clk_round_rate, \
- .set_parent = _clk_set_parent, \
- .parent = p, \
- .secondary = s, \
- }
-
-#define DEF_CLK_1B(name, er, es, p, s) \
- static struct clk name = { \
- .enable_reg = er, \
- .enable_shift = es, \
- .enable = _clk_enable_1b, \
- .disable = _clk_disable_1b, \
- .get_rate = _clk_get_rate, \
- .set_rate = _clk_set_rate, \
- .round_rate = _clk_round_rate, \
- .set_parent = _clk_set_parent, \
- .parent = p, \
- .secondary = s, \
- }
-
-DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL);
-DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL);
-DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL);
-DEF_CLK(asrc_clk, CCGR0, CG3, &pll4_audio, NULL);
-DEF_CLK(can1_serial_clk, CCGR0, CG8, &pll3_usb_otg, NULL);
-DEF_CLK(can1_clk, CCGR0, CG7, &pll3_usb_otg, &can1_serial_clk);
-DEF_CLK(can2_serial_clk, CCGR0, CG10, &pll3_usb_otg, NULL);
-DEF_CLK(can2_clk, CCGR0, CG9, &pll3_usb_otg, &can2_serial_clk);
-DEF_CLK(ecspi1_clk, CCGR1, CG0, &pll3_60m, NULL);
-DEF_CLK(ecspi2_clk, CCGR1, CG1, &pll3_60m, NULL);
-DEF_CLK(ecspi3_clk, CCGR1, CG2, &pll3_60m, NULL);
-DEF_CLK(ecspi4_clk, CCGR1, CG3, &pll3_60m, NULL);
-DEF_CLK(ecspi5_clk, CCGR1, CG4, &pll3_60m, NULL);
-DEF_CLK(enet_clk, CCGR1, CG5, &ipg_clk, NULL);
-DEF_CLK(esai_clk, CCGR1, CG8, &pll3_usb_otg, NULL);
-DEF_CLK(gpt_serial_clk, CCGR1, CG11, &ipg_perclk, NULL);
-DEF_CLK(gpt_clk, CCGR1, CG10, &ipg_perclk, &gpt_serial_clk);
-DEF_CLK(gpu2d_core_clk, CCGR1, CG12, &pll2_pfd_352m, &gpu2d_axi_clk);
-DEF_CLK(gpu3d_core_clk, CCGR1, CG13, &pll2_pfd_594m, &gpu3d_axi_clk);
-DEF_CLK(gpu3d_shader_clk, CCGR1, CG13, &pll3_pfd_720m, &gpu3d_axi_clk);
-DEF_CLK(hdmi_iahb_clk, CCGR2, CG0, &ahb_clk, NULL);
-DEF_CLK(hdmi_isfr_clk, CCGR2, CG2, &pll3_pfd_540m, &hdmi_iahb_clk);
-DEF_CLK(i2c1_clk, CCGR2, CG3, &ipg_perclk, NULL);
-DEF_CLK(i2c2_clk, CCGR2, CG4, &ipg_perclk, NULL);
-DEF_CLK(i2c3_clk, CCGR2, CG5, &ipg_perclk, NULL);
-DEF_CLK(iim_clk, CCGR2, CG6, &ipg_clk, NULL);
-DEF_CLK(enfc_clk, CCGR2, CG7, &pll2_pfd_352m, NULL);
-DEF_CLK(ipu1_clk, CCGR3, CG0, &mmdc_ch0_axi_clk, NULL);
-DEF_CLK(ipu1_di0_clk, CCGR3, CG1, &ipu1_di0_pre_clk, NULL);
-DEF_CLK(ipu1_di1_clk, CCGR3, CG2, &ipu1_di1_pre_clk, NULL);
-DEF_CLK(ipu2_clk, CCGR3, CG3, &mmdc_ch0_axi_clk, NULL);
-DEF_CLK(ipu2_di0_clk, CCGR3, CG4, &ipu2_di0_pre_clk, NULL);
-DEF_CLK(ipu2_di1_clk, CCGR3, CG5, &ipu2_di1_pre_clk, NULL);
-DEF_CLK(ldb_di0_clk, CCGR3, CG6, &pll3_pfd_540m, NULL);
-DEF_CLK(ldb_di1_clk, CCGR3, CG7, &pll3_pfd_540m, NULL);
-DEF_CLK(hsi_tx_clk, CCGR3, CG8, &pll2_pfd_400m, NULL);
-DEF_CLK(mlb_clk, CCGR3, CG9, &pll6_mlb, NULL);
-DEF_CLK(mmdc_ch0_ipg_clk, CCGR3, CG12, &ipg_clk, NULL);
-DEF_CLK(mmdc_ch0_axi_clk, CCGR3, CG10, &periph_clk, &mmdc_ch0_ipg_clk);
-DEF_CLK(mmdc_ch1_ipg_clk, CCGR3, CG13, &ipg_clk, NULL);
-DEF_CLK(mmdc_ch1_axi_clk, CCGR3, CG11, &periph2_clk, &mmdc_ch1_ipg_clk);
-DEF_CLK(openvg_axi_clk, CCGR3, CG13, &axi_clk, NULL);
-DEF_CLK(pwm1_clk, CCGR4, CG8, &ipg_perclk, NULL);
-DEF_CLK(pwm2_clk, CCGR4, CG9, &ipg_perclk, NULL);
-DEF_CLK(pwm3_clk, CCGR4, CG10, &ipg_perclk, NULL);
-DEF_CLK(pwm4_clk, CCGR4, CG11, &ipg_perclk, NULL);
-DEF_CLK(gpmi_bch_apb_clk, CCGR4, CG12, &usdhc3_clk, NULL);
-DEF_CLK(gpmi_bch_clk, CCGR4, CG13, &usdhc4_clk, &gpmi_bch_apb_clk);
-DEF_CLK(gpmi_apb_clk, CCGR4, CG15, &usdhc3_clk, &gpmi_bch_clk);
-DEF_CLK(gpmi_io_clk, CCGR4, CG14, &enfc_clk, &gpmi_apb_clk);
-DEF_CLK(sdma_clk, CCGR5, CG3, &ahb_clk, NULL);
-DEF_CLK(spba_clk, CCGR5, CG6, &ipg_clk, NULL);
-DEF_CLK(spdif_clk, CCGR5, CG7, &pll3_usb_otg, &spba_clk);
-DEF_CLK(ssi1_clk, CCGR5, CG9, &pll3_pfd_508m, NULL);
-DEF_CLK(ssi2_clk, CCGR5, CG10, &pll3_pfd_508m, NULL);
-DEF_CLK(ssi3_clk, CCGR5, CG11, &pll3_pfd_508m, NULL);
-DEF_CLK(uart_serial_clk, CCGR5, CG13, &pll3_usb_otg, NULL);
-DEF_CLK(uart_clk, CCGR5, CG12, &pll3_80m, &uart_serial_clk);
-DEF_CLK(usboh3_clk, CCGR6, CG0, &ipg_clk, NULL);
-DEF_CLK(usdhc1_clk, CCGR6, CG1, &pll2_pfd_400m, NULL);
-DEF_CLK(usdhc2_clk, CCGR6, CG2, &pll2_pfd_400m, NULL);
-DEF_CLK(usdhc3_clk, CCGR6, CG3, &pll2_pfd_400m, NULL);
-DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL);
-DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL);
-DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL);
-DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL);
-DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL);
-
-static int pcie_clk_enable(struct clk *clk)
-{
- u32 val;
-
- val = readl_relaxed(PLL8_ENET);
- val |= BM_PLL_ENET_EN_PCIE;
- writel_relaxed(val, PLL8_ENET);
-
- return _clk_enable(clk);
-}
-
-static void pcie_clk_disable(struct clk *clk)
-{
- u32 val;
-
- _clk_disable(clk);
-
- val = readl_relaxed(PLL8_ENET);
- val &= BM_PLL_ENET_EN_PCIE;
- writel_relaxed(val, PLL8_ENET);
-}
-
-static struct clk pcie_clk = {
- .enable_reg = CCGR4,
- .enable_shift = CG0,
- .enable = pcie_clk_enable,
- .disable = pcie_clk_disable,
- .set_parent = _clk_set_parent,
- .parent = &axi_clk,
- .secondary = &pll8_enet,
-};
-
-static int sata_clk_enable(struct clk *clk)
-{
- u32 val;
-
- val = readl_relaxed(PLL8_ENET);
- val |= BM_PLL_ENET_EN_SATA;
- writel_relaxed(val, PLL8_ENET);
-
- return _clk_enable(clk);
-}
-
-static void sata_clk_disable(struct clk *clk)
-{
- u32 val;
-
- _clk_disable(clk);
-
- val = readl_relaxed(PLL8_ENET);
- val &= BM_PLL_ENET_EN_SATA;
- writel_relaxed(val, PLL8_ENET);
-}
-
-static struct clk sata_clk = {
- .enable_reg = CCGR5,
- .enable_shift = CG2,
- .enable = sata_clk_enable,
- .disable = sata_clk_disable,
- .parent = &ipg_clk,
- .secondary = &pll8_enet,
-};
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- }
-
-static struct clk_lookup lookups[] = {
- _REGISTER_CLOCK("2020000.uart", NULL, uart_clk),
- _REGISTER_CLOCK("21e8000.uart", NULL, uart_clk),
- _REGISTER_CLOCK("21ec000.uart", NULL, uart_clk),
- _REGISTER_CLOCK("21f0000.uart", NULL, uart_clk),
- _REGISTER_CLOCK("21f4000.uart", NULL, uart_clk),
- _REGISTER_CLOCK("2188000.enet", NULL, enet_clk),
- _REGISTER_CLOCK("2190000.usdhc", NULL, usdhc1_clk),
- _REGISTER_CLOCK("2194000.usdhc", NULL, usdhc2_clk),
- _REGISTER_CLOCK("2198000.usdhc", NULL, usdhc3_clk),
- _REGISTER_CLOCK("219c000.usdhc", NULL, usdhc4_clk),
- _REGISTER_CLOCK("21a0000.i2c", NULL, i2c1_clk),
- _REGISTER_CLOCK("21a4000.i2c", NULL, i2c2_clk),
- _REGISTER_CLOCK("21a8000.i2c", NULL, i2c3_clk),
- _REGISTER_CLOCK("2008000.ecspi", NULL, ecspi1_clk),
- _REGISTER_CLOCK("200c000.ecspi", NULL, ecspi2_clk),
- _REGISTER_CLOCK("2010000.ecspi", NULL, ecspi3_clk),
- _REGISTER_CLOCK("2014000.ecspi", NULL, ecspi4_clk),
- _REGISTER_CLOCK("2018000.ecspi", NULL, ecspi5_clk),
- _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk),
- _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk),
- _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk),
- _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
- _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
- _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk),
- _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk),
- _REGISTER_CLOCK(NULL, "aips_tz2_clk", aips_tz2_clk),
- _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk),
- _REGISTER_CLOCK(NULL, "can2_clk", can2_clk),
- _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_isfr_clk),
- _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
- _REGISTER_CLOCK(NULL, "mlb_clk", mlb_clk),
- _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
- _REGISTER_CLOCK(NULL, "pwm1_clk", pwm1_clk),
- _REGISTER_CLOCK(NULL, "pwm2_clk", pwm2_clk),
- _REGISTER_CLOCK(NULL, "pwm3_clk", pwm3_clk),
- _REGISTER_CLOCK(NULL, "pwm4_clk", pwm4_clk),
- _REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
- _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
- _REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
- _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk),
-};
-
-int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
-{
- u32 val = readl_relaxed(CLPCR);
-
- val &= ~BM_CLPCR_LPM;
- switch (mode) {
- case WAIT_CLOCKED:
- break;
- case WAIT_UNCLOCKED:
- val |= 0x1 << BP_CLPCR_LPM;
- break;
- case STOP_POWER_ON:
- val |= 0x2 << BP_CLPCR_LPM;
- break;
- case WAIT_UNCLOCKED_POWER_OFF:
- val |= 0x1 << BP_CLPCR_LPM;
- val &= ~BM_CLPCR_VSTBY;
- val &= ~BM_CLPCR_SBYOS;
- break;
- case STOP_POWER_OFF:
- val |= 0x2 << BP_CLPCR_LPM;
- val |= 0x3 << BP_CLPCR_STBY_COUNT;
- val |= BM_CLPCR_VSTBY;
- val |= BM_CLPCR_SBYOS;
- break;
- default:
- return -EINVAL;
- }
- writel_relaxed(val, CLPCR);
-
- return 0;
-}
-
-static struct map_desc imx6q_clock_desc[] = {
- imx_map_entry(MX6Q, CCM, MT_DEVICE),
- imx_map_entry(MX6Q, ANATOP, MT_DEVICE),
-};
-
-void __init imx6q_clock_map_io(void)
-{
- iotable_init(imx6q_clock_desc, ARRAY_SIZE(imx6q_clock_desc));
-}
-
-int __init mx6q_clocks_init(void)
-{
- struct device_node *np;
- void __iomem *base;
- int i, irq;
-
- /* retrieve the freqency of fixed clocks from device tree */
- for_each_compatible_node(np, NULL, "fixed-clock") {
- u32 rate;
- if (of_property_read_u32(np, "clock-frequency", &rate))
- continue;
-
- if (of_device_is_compatible(np, "fsl,imx-ckil"))
- external_low_reference = rate;
- else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
- external_high_reference = rate;
- else if (of_device_is_compatible(np, "fsl,imx-osc"))
- oscillator_reference = rate;
- }
-
- for (i = 0; i < ARRAY_SIZE(lookups); i++)
- clkdev_add(&lookups[i]);
-
- /* only keep necessary clocks on */
- writel_relaxed(0x3 << CG0 | 0x3 << CG1 | 0x3 << CG2, CCGR0);
- writel_relaxed(0x3 << CG8 | 0x3 << CG9 | 0x3 << CG10, CCGR2);
- writel_relaxed(0x3 << CG10 | 0x3 << CG12, CCGR3);
- writel_relaxed(0x3 << CG4 | 0x3 << CG6 | 0x3 << CG7, CCGR4);
- writel_relaxed(0x3 << CG0, CCGR5);
- writel_relaxed(0, CCGR6);
- writel_relaxed(0, CCGR7);
-
- clk_enable(&uart_clk);
- clk_enable(&mmdc_ch0_axi_clk);
-
- clk_set_rate(&pll4_audio, FREQ_650M);
- clk_set_rate(&pll5_video, FREQ_650M);
- clk_set_parent(&ipu1_di0_clk, &ipu1_di0_pre_clk);
- clk_set_parent(&ipu1_di0_pre_clk, &pll5_video);
- clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594m);
- clk_set_rate(&gpu3d_shader_clk, FREQ_594M);
- clk_set_parent(&gpu3d_core_clk, &mmdc_ch0_axi_clk);
- clk_set_rate(&gpu3d_core_clk, FREQ_528M);
- clk_set_parent(&asrc_serial_clk, &pll3_usb_otg);
- clk_set_rate(&asrc_serial_clk, 1500000);
- clk_set_rate(&enfc_clk, 11000000);
-
- /*
- * Before pinctrl API is available, we have to rely on the pad
- * configuration set up by bootloader. For usdhc example here,
- * u-boot sets up the pads for 49.5 MHz case, and we have to lower
- * the usdhc clock from 198 to 49.5 MHz to match the pad configuration.
- *
- * FIXME: This is should be removed after pinctrl API is available.
- * At that time, usdhc driver can call pinctrl API to change pad
- * configuration dynamically per different usdhc clock settings.
- */
- clk_set_rate(&usdhc1_clk, 49500000);
- clk_set_rate(&usdhc2_clk, 49500000);
- clk_set_rate(&usdhc3_clk, 49500000);
- clk_set_rate(&usdhc4_clk, 49500000);
-
- clk_set_parent(&cko1_clk, &ahb_clk);
-
- np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
- base = of_iomap(np, 0);
- WARN_ON(!base);
- irq = irq_of_parse_and_map(np, 0);
- mxc_timer_init(&gpt_clk, base, irq);
-
- return 0;
-}
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 08470504a088..000000000000
--- a/arch/arm/mach-imx/clock-mx51-mx53.c
+++ /dev/null
@@ -1,1675 +0,0 @@
-/*
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
- *
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-#include <linux/of.h>
-
-#include <asm/div64.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/clock.h>
-
-#include "crm-regs-imx5.h"
-
-/* External clock values passed-in by the board code */
-static unsigned long external_high_reference, external_low_reference;
-static unsigned long oscillator_reference, ckih2_reference;
-
-static struct clk osc_clk;
-static struct clk pll1_main_clk;
-static struct clk pll1_sw_clk;
-static struct clk pll2_sw_clk;
-static struct clk pll3_sw_clk;
-static struct clk mx53_pll4_sw_clk;
-static struct clk lp_apm_clk;
-static struct clk periph_apm_clk;
-static struct clk ahb_clk;
-static struct clk ipg_clk;
-static struct clk usboh3_clk;
-static struct clk emi_fast_clk;
-static struct clk ipu_clk;
-static struct clk mipi_hsc1_clk;
-static struct clk esdhc1_clk;
-static struct clk esdhc2_clk;
-static struct clk esdhc3_mx53_clk;
-
-#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
-
-/* calculate best pre and post dividers to get the required divider */
-static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
- u32 max_pre, u32 max_post)
-{
- if (div >= max_pre * max_post) {
- *pre = max_pre;
- *post = max_post;
- } else if (div >= max_pre) {
- u32 min_pre, temp_pre, old_err, err;
- min_pre = DIV_ROUND_UP(div, max_post);
- old_err = max_pre;
- for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
- err = div % temp_pre;
- if (err == 0) {
- *pre = temp_pre;
- break;
- }
- err = temp_pre - err;
- if (err < old_err) {
- old_err = err;
- *pre = temp_pre;
- }
- }
- *post = DIV_ROUND_UP(div, *pre);
- } else {
- *pre = div;
- *post = 1;
- }
-}
-
-static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
-{
- u32 reg = __raw_readl(clk->enable_reg);
-
- reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
- reg |= mode << clk->enable_shift;
-
- __raw_writel(reg, clk->enable_reg);
-}
-
-static int _clk_ccgr_enable(struct clk *clk)
-{
- _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
- return 0;
-}
-
-static void _clk_ccgr_disable(struct clk *clk)
-{
- _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
-}
-
-static int _clk_ccgr_enable_inrun(struct clk *clk)
-{
- _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
- return 0;
-}
-
-static void _clk_ccgr_disable_inwait(struct clk *clk)
-{
- _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
-}
-
-/*
- * For the 4-to-1 muxed input clock
- */
-static inline u32 _get_mux(struct clk *parent, struct clk *m0,
- struct clk *m1, struct clk *m2, struct clk *m3)
-{
- if (parent == m0)
- return 0;
- else if (parent == m1)
- return 1;
- else if (parent == m2)
- return 2;
- else if (parent == m3)
- return 3;
- else
- BUG();
-
- return -EINVAL;
-}
-
-static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
-{
- if (pll == &pll1_main_clk)
- return MX51_DPLL1_BASE;
- else if (pll == &pll2_sw_clk)
- return MX51_DPLL2_BASE;
- else if (pll == &pll3_sw_clk)
- return MX51_DPLL3_BASE;
- else
- BUG();
-
- return NULL;
-}
-
-static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
-{
- if (pll == &pll1_main_clk)
- return MX53_DPLL1_BASE;
- else if (pll == &pll2_sw_clk)
- return MX53_DPLL2_BASE;
- else if (pll == &pll3_sw_clk)
- return MX53_DPLL3_BASE;
- else if (pll == &mx53_pll4_sw_clk)
- return MX53_DPLL4_BASE;
- else
- BUG();
-
- return NULL;
-}
-
-static inline void __iomem *_get_pll_base(struct clk *pll)
-{
- if (cpu_is_mx51())
- return _mx51_get_pll_base(pll);
- else
- return _mx53_get_pll_base(pll);
-}
-
-static unsigned long clk_pll_get_rate(struct clk *clk)
-{
- long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
- unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
- void __iomem *pllbase;
- s64 temp;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- pllbase = _get_pll_base(clk);
-
- dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
- dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
-
- if (pll_hfsm == 0) {
- dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
- dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
- dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
- } else {
- dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
- dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
- dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
- }
- pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
- mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
- mfi = (mfi <= 5) ? 5 : mfi;
- mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
- mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
- /* Sign extend to 32-bits */
- if (mfn >= 0x04000000) {
- mfn |= 0xFC000000;
- mfn_abs = -mfn;
- }
-
- ref_clk = 2 * parent_rate;
- if (dbl != 0)
- ref_clk *= 2;
-
- ref_clk /= (pdf + 1);
- temp = (u64) ref_clk * mfn_abs;
- do_div(temp, mfd + 1);
- if (mfn < 0)
- temp = -temp;
- temp = (ref_clk * mfi) + temp;
-
- return temp;
-}
-
-static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- void __iomem *pllbase;
-
- long mfi, pdf, mfn, mfd = 999999;
- s64 temp64;
- unsigned long quad_parent_rate;
- unsigned long pll_hfsm, dp_ctl;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- pllbase = _get_pll_base(clk);
-
- quad_parent_rate = 4 * parent_rate;
- pdf = mfi = -1;
- while (++pdf < 16 && mfi < 5)
- mfi = rate * (pdf+1) / quad_parent_rate;
- if (mfi > 15)
- return -EINVAL;
- pdf--;
-
- temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
- do_div(temp64, quad_parent_rate/1000000);
- mfn = (long)temp64;
-
- dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- /* use dpdck0_2 */
- __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
- pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
- if (pll_hfsm == 0) {
- reg = mfi << 4 | pdf;
- __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
- __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
- __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
- } else {
- reg = mfi << 4 | pdf;
- __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
- __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
- __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
- }
-
- return 0;
-}
-
-static int _clk_pll_enable(struct clk *clk)
-{
- u32 reg;
- void __iomem *pllbase;
- int i = 0;
-
- pllbase = _get_pll_base(clk);
- reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- if (reg & MXC_PLL_DP_CTL_UPEN)
- return 0;
-
- reg |= MXC_PLL_DP_CTL_UPEN;
- __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
-
- /* Wait for lock */
- do {
- reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
- if (reg & MXC_PLL_DP_CTL_LRF)
- break;
-
- udelay(1);
- } while (++i < MAX_DPLL_WAIT_TRIES);
-
- if (i == MAX_DPLL_WAIT_TRIES) {
- pr_err("MX5: pll locking failed\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void _clk_pll_disable(struct clk *clk)
-{
- u32 reg;
- void __iomem *pllbase;
-
- pllbase = _get_pll_base(clk);
- reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
- __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
-}
-
-static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg, step;
-
- reg = __raw_readl(MXC_CCM_CCSR);
-
- /* When switching from pll_main_clk to a bypass clock, first select a
- * multiplexed clock in 'step_sel', then shift the glitchless mux
- * 'pll1_sw_clk_sel'.
- *
- * When switching back, do it in reverse order
- */
- if (parent == &pll1_main_clk) {
- /* Switch to pll1_main_clk */
- reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
- __raw_writel(reg, MXC_CCM_CCSR);
- /* step_clk mux switched to lp_apm, to save power. */
- reg = __raw_readl(MXC_CCM_CCSR);
- reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
- reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
- MXC_CCM_CCSR_STEP_SEL_OFFSET);
- } else {
- if (parent == &lp_apm_clk) {
- step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
- } else if (parent == &pll2_sw_clk) {
- step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
- } else if (parent == &pll3_sw_clk) {
- step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
- } else
- return -EINVAL;
-
- reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
- reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
-
- __raw_writel(reg, MXC_CCM_CCSR);
- /* Switch to step_clk */
- reg = __raw_readl(MXC_CCM_CCSR);
- reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
- }
- __raw_writel(reg, MXC_CCM_CCSR);
- return 0;
-}
-
-static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
-{
- u32 reg, div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- reg = __raw_readl(MXC_CCM_CCSR);
-
- if (clk->parent == &pll2_sw_clk) {
- div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
- MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
- } else if (clk->parent == &pll3_sw_clk) {
- div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
- MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
- } else
- div = 1;
- return parent_rate / div;
-}
-
-static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CCSR);
-
- if (parent == &pll2_sw_clk)
- reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
- else
- reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
-
- __raw_writel(reg, MXC_CCM_CCSR);
- return 0;
-}
-
-static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- if (parent == &osc_clk)
- reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
- else
- return -EINVAL;
-
- __raw_writel(reg, MXC_CCM_CCSR);
-
- return 0;
-}
-
-static unsigned long clk_cpu_get_rate(struct clk *clk)
-{
- u32 cacrr, div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
- cacrr = __raw_readl(MXC_CCM_CACRR);
- div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
-
- return parent_rate / div;
-}
-
-static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, cpu_podf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
- cpu_podf = parent_rate / rate - 1;
- /* use post divider to change freq */
- reg = __raw_readl(MXC_CCM_CACRR);
- reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
- reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
- __raw_writel(reg, MXC_CCM_CACRR);
-
- return 0;
-}
-
-static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg, mux;
- int i = 0;
-
- mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
-
- reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
- reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
- __raw_writel(reg, MXC_CCM_CBCMR);
-
- /* Wait for lock */
- do {
- reg = __raw_readl(MXC_CCM_CDHIPR);
- if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
- break;
-
- udelay(1);
- } while (++i < MAX_DPLL_WAIT_TRIES);
-
- if (i == MAX_DPLL_WAIT_TRIES) {
- pr_err("MX5: Set parent for periph_apm clock failed\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
-
- if (parent == &pll2_sw_clk)
- reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
- else if (parent == &periph_apm_clk)
- reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
- else
- return -EINVAL;
-
- __raw_writel(reg, MXC_CCM_CBCDR);
-
- return 0;
-}
-
-static struct clk main_bus_clk = {
- .parent = &pll2_sw_clk,
- .set_parent = _clk_main_bus_set_parent,
-};
-
-static unsigned long clk_ahb_get_rate(struct clk *clk)
-{
- u32 reg, div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
- MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
- return parent_rate / div;
-}
-
-
-static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div;
- unsigned long parent_rate;
- int i = 0;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (div > 8 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
- reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
- __raw_writel(reg, MXC_CCM_CBCDR);
-
- /* Wait for lock */
- do {
- reg = __raw_readl(MXC_CCM_CDHIPR);
- if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
- break;
-
- udelay(1);
- } while (++i < MAX_DPLL_WAIT_TRIES);
-
- if (i == MAX_DPLL_WAIT_TRIES) {
- pr_err("MX5: clk_ahb_set_rate failed\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static unsigned long _clk_ahb_round_rate(struct clk *clk,
- unsigned long rate)
-{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
- if (div > 8)
- div = 8;
- else if (div == 0)
- div++;
- return parent_rate / div;
-}
-
-
-static int _clk_max_enable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_enable(clk);
-
- /* Handshake with MAX when LPM is entered. */
- reg = __raw_readl(MXC_CCM_CLPCR);
- if (cpu_is_mx51())
- reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
- else if (cpu_is_mx53())
- reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-
- return 0;
-}
-
-static void _clk_max_disable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_disable_inwait(clk);
-
- /* No Handshake with MAX when LPM is entered as its disabled. */
- reg = __raw_readl(MXC_CCM_CLPCR);
- if (cpu_is_mx51())
- reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
- else if (cpu_is_mx53())
- reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-}
-
-static unsigned long clk_ipg_get_rate(struct clk *clk)
-{
- u32 reg, div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
- MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
-
- return parent_rate / div;
-}
-
-static unsigned long clk_ipg_per_get_rate(struct clk *clk)
-{
- u32 reg, prediv1, prediv2, podf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
- /* the main_bus_clk is the one before the DVFS engine */
- reg = __raw_readl(MXC_CCM_CBCDR);
- prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
- MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
- prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
- MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
- podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
- MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
- return parent_rate / (prediv1 * prediv2 * podf);
- } else if (clk->parent == &ipg_clk)
- return parent_rate;
- else
- BUG();
-}
-
-static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CBCMR);
-
- reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
- reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
-
- if (parent == &ipg_clk)
- reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
- else if (parent == &lp_apm_clk)
- reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
- else if (parent != &main_bus_clk)
- return -EINVAL;
-
- __raw_writel(reg, MXC_CCM_CBCMR);
-
- return 0;
-}
-
-#define clk_nfc_set_parent NULL
-
-static unsigned long clk_nfc_get_rate(struct clk *clk)
-{
- unsigned long rate;
- u32 reg, div;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
- MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
- rate = clk_get_rate(clk->parent) / div;
- WARN_ON(rate == 0);
- return rate;
-}
-
-static unsigned long clk_nfc_round_rate(struct clk *clk,
- unsigned long rate)
-{
- u32 div;
- unsigned long parent_rate = clk_get_rate(clk->parent);
-
- if (!rate)
- return -EINVAL;
-
- div = parent_rate / rate;
-
- if (parent_rate % rate)
- div++;
-
- if (div > 8)
- return -EINVAL;
-
- return parent_rate / div;
-
-}
-
-static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div;
-
- div = clk_get_rate(clk->parent) / rate;
- if (div == 0)
- div++;
- if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
- return -EINVAL;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
- reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
- __raw_writel(reg, MXC_CCM_CBCDR);
-
- while (__raw_readl(MXC_CCM_CDHIPR) &
- MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
- }
-
- return 0;
-}
-
-static unsigned long get_high_reference_clock_rate(struct clk *clk)
-{
- return external_high_reference;
-}
-
-static unsigned long get_low_reference_clock_rate(struct clk *clk)
-{
- return external_low_reference;
-}
-
-static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
-{
- return oscillator_reference;
-}
-
-static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
-{
- return ckih2_reference;
-}
-
-static unsigned long clk_emi_slow_get_rate(struct clk *clk)
-{
- u32 reg, div;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
- MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
-
- return clk_get_rate(clk->parent) / div;
-}
-
-static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
-{
- unsigned long rate;
- u32 reg, div;
-
- reg = __raw_readl(MXC_CCM_CBCDR);
- div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
- MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
- rate = clk_get_rate(clk->parent) / div;
-
- return rate;
-}
-
-/* External high frequency clock */
-static struct clk ckih_clk = {
- .get_rate = get_high_reference_clock_rate,
-};
-
-static struct clk ckih2_clk = {
- .get_rate = get_ckih2_reference_clock_rate,
-};
-
-static struct clk osc_clk = {
- .get_rate = get_oscillator_reference_clock_rate,
-};
-
-/* External low frequency (32kHz) clock */
-static struct clk ckil_clk = {
- .get_rate = get_low_reference_clock_rate,
-};
-
-static struct clk pll1_main_clk = {
- .parent = &osc_clk,
- .get_rate = clk_pll_get_rate,
- .enable = _clk_pll_enable,
- .disable = _clk_pll_disable,
-};
-
-/* Clock tree block diagram (WIP):
- * CCM: Clock Controller Module
- *
- * PLL output -> |
- * | CCM Switcher -> CCM_CLK_ROOT_GEN ->
- * PLL bypass -> |
- *
- */
-
-/* PLL1 SW supplies to ARM core */
-static struct clk pll1_sw_clk = {
- .parent = &pll1_main_clk,
- .set_parent = _clk_pll1_sw_set_parent,
- .get_rate = clk_pll1_sw_get_rate,
-};
-
-/* PLL2 SW supplies to AXI/AHB/IP buses */
-static struct clk pll2_sw_clk = {
- .parent = &osc_clk,
- .get_rate = clk_pll_get_rate,
- .set_rate = _clk_pll_set_rate,
- .set_parent = _clk_pll2_sw_set_parent,
- .enable = _clk_pll_enable,
- .disable = _clk_pll_disable,
-};
-
-/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
-static struct clk pll3_sw_clk = {
- .parent = &osc_clk,
- .set_rate = _clk_pll_set_rate,
- .get_rate = clk_pll_get_rate,
- .enable = _clk_pll_enable,
- .disable = _clk_pll_disable,
-};
-
-/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
-static struct clk mx53_pll4_sw_clk = {
- .parent = &osc_clk,
- .set_rate = _clk_pll_set_rate,
- .enable = _clk_pll_enable,
- .disable = _clk_pll_disable,
-};
-
-/* Low-power Audio Playback Mode clock */
-static struct clk lp_apm_clk = {
- .parent = &osc_clk,
- .set_parent = _clk_lp_apm_set_parent,
-};
-
-static struct clk periph_apm_clk = {
- .parent = &pll1_sw_clk,
- .set_parent = _clk_periph_apm_set_parent,
-};
-
-static struct clk cpu_clk = {
- .parent = &pll1_sw_clk,
- .get_rate = clk_cpu_get_rate,
- .set_rate = clk_cpu_set_rate,
-};
-
-static struct clk ahb_clk = {
- .parent = &main_bus_clk,
- .get_rate = clk_ahb_get_rate,
- .set_rate = _clk_ahb_set_rate,
- .round_rate = _clk_ahb_round_rate,
-};
-
-static struct clk iim_clk = {
- .parent = &ipg_clk,
- .enable_reg = MXC_CCM_CCGR0,
- .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
-};
-
-/* Main IP interface clock for access to registers */
-static struct clk ipg_clk = {
- .parent = &ahb_clk,
- .get_rate = clk_ipg_get_rate,
-};
-
-static struct clk ipg_perclk = {
- .parent = &lp_apm_clk,
- .get_rate = clk_ipg_per_get_rate,
- .set_parent = _clk_ipg_per_set_parent,
-};
-
-static struct clk ahb_max_clk = {
- .parent = &ahb_clk,
- .enable_reg = MXC_CCM_CCGR0,
- .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
- .enable = _clk_max_enable,
- .disable = _clk_max_disable,
-};
-
-static struct clk aips_tz1_clk = {
- .parent = &ahb_clk,
- .secondary = &ahb_max_clk,
- .enable_reg = MXC_CCM_CCGR0,
- .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable_inwait,
-};
-
-static struct clk aips_tz2_clk = {
- .parent = &ahb_clk,
- .secondary = &ahb_max_clk,
- .enable_reg = MXC_CCM_CCGR0,
- .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable_inwait,
-};
-
-static struct clk gpc_dvfs_clk = {
- .enable_reg = MXC_CCM_CCGR5,
- .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable,
-};
-
-static struct clk gpt_32k_clk = {
- .id = 0,
- .parent = &ckil_clk,
-};
-
-static struct clk dummy_clk = {
- .id = 0,
-};
-
-static struct clk emi_slow_clk = {
- .parent = &pll2_sw_clk,
- .enable_reg = MXC_CCM_CCGR5,
- .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable_inwait,
- .get_rate = clk_emi_slow_get_rate,
-};
-
-static int clk_ipu_enable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_enable(clk);
-
- /* Enable handshake with IPU when certain clock rates are changed */
- reg = __raw_readl(MXC_CCM_CCDR);
- reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
- __raw_writel(reg, MXC_CCM_CCDR);
-
- /* Enable handshake with IPU when LPM is entered */
- reg = __raw_readl(MXC_CCM_CLPCR);
- reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-
- return 0;
-}
-
-static void clk_ipu_disable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_disable(clk);
-
- /* Disable handshake with IPU whe dividers are changed */
- reg = __raw_readl(MXC_CCM_CCDR);
- reg |= MXC_CCM_CCDR_IPU_HS_MASK;
- __raw_writel(reg, MXC_CCM_CCDR);
-
- /* Disable handshake with IPU when LPM is entered */
- reg = __raw_readl(MXC_CCM_CLPCR);
- reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-}
-
-static struct clk ahbmux1_clk = {
- .parent = &ahb_clk,
- .secondary = &ahb_max_clk,
- .enable_reg = MXC_CCM_CCGR0,
- .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable_inwait,
-};
-
-static struct clk ipu_sec_clk = {
- .parent = &emi_fast_clk,
- .secondary = &ahbmux1_clk,
-};
-
-static struct clk ddr_hf_clk = {
- .parent = &pll1_sw_clk,
- .get_rate = _clk_ddr_hf_get_rate,
-};
-
-static struct clk ddr_clk = {
- .parent = &ddr_hf_clk,
-};
-
-/* clock definitions for MIPI HSC unit which has been removed
- * from documentation, but not from hardware
- */
-static int _clk_hsc_enable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_enable(clk);
- /* Handshake with IPU when certain clock rates are changed. */
- reg = __raw_readl(MXC_CCM_CCDR);
- reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
- __raw_writel(reg, MXC_CCM_CCDR);
-
- reg = __raw_readl(MXC_CCM_CLPCR);
- reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-
- return 0;
-}
-
-static void _clk_hsc_disable(struct clk *clk)
-{
- u32 reg;
-
- _clk_ccgr_disable(clk);
- /* No handshake with HSC as its not enabled. */
- reg = __raw_readl(MXC_CCM_CCDR);
- reg |= MXC_CCM_CCDR_HSC_HS_MASK;
- __raw_writel(reg, MXC_CCM_CCDR);
-
- reg = __raw_readl(MXC_CCM_CLPCR);
- reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
- __raw_writel(reg, MXC_CCM_CLPCR);
-}
-
-static struct clk mipi_hsp_clk = {
- .parent = &ipu_clk,
- .enable_reg = MXC_CCM_CCGR4,
- .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
- .enable = _clk_hsc_enable,
- .disable = _clk_hsc_disable,
- .secondary = &mipi_hsc1_clk,
-};
-
-#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = pfx##_get_rate, \
- .set_rate = pfx##_set_rate, \
- .round_rate = pfx##_round_rate, \
- .set_parent = pfx##_set_parent, \
- .enable = _clk_ccgr_enable, \
- .disable = _clk_ccgr_disable, \
- .parent = p, \
- .secondary = s, \
- }
-
-#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = pfx##_get_rate, \
- .set_rate = pfx##_set_rate, \
- .set_parent = pfx##_set_parent, \
- .enable = _clk_max_enable, \
- .disable = _clk_max_disable, \
- .parent = p, \
- .secondary = s, \
- }
-
-#define CLK_GET_RATE(name, nr, bitsname) \
-static unsigned long clk_##name##_get_rate(struct clk *clk) \
-{ \
- u32 reg, pred, podf; \
- \
- reg = __raw_readl(MXC_CCM_CSCDR##nr); \
- pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \
- >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
- podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \
- >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
- \
- return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \
- (pred + 1) * (podf + 1)); \
-}
-
-#define CLK_SET_PARENT(name, nr, bitsname) \
-static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
-{ \
- u32 reg, mux; \
- \
- mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \
- &pll3_sw_clk, &lp_apm_clk); \
- reg = __raw_readl(MXC_CCM_CSCMR##nr) & \
- ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \
- reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \
- __raw_writel(reg, MXC_CCM_CSCMR##nr); \
- \
- return 0; \
-}
-
-#define CLK_SET_RATE(name, nr, bitsname) \
-static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- u32 reg, div, parent_rate; \
- u32 pre = 0, post = 0; \
- \
- parent_rate = clk_get_rate(clk->parent); \
- div = parent_rate / rate; \
- \
- if ((parent_rate / div) != rate) \
- return -EINVAL; \
- \
- __calc_pre_post_dividers(div, &pre, &post, \
- (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \
- MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \
- (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \
- MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
- \
- /* Set sdhc1 clock divider */ \
- reg = __raw_readl(MXC_CCM_CSCDR##nr) & \
- ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \
- | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \
- reg |= (post - 1) << \
- MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
- reg |= (pre - 1) << \
- MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
- __raw_writel(reg, MXC_CCM_CSCDR##nr); \
- \
- return 0; \
-}
-
-/* UART */
-CLK_GET_RATE(uart, 1, UART)
-CLK_SET_PARENT(uart, 1, UART)
-
-static struct clk uart_root_clk = {
- .parent = &pll2_sw_clk,
- .get_rate = clk_uart_get_rate,
- .set_parent = clk_uart_set_parent,
-};
-
-/* USBOH3 */
-CLK_GET_RATE(usboh3, 1, USBOH3)
-CLK_SET_PARENT(usboh3, 1, USBOH3)
-
-static struct clk usboh3_clk = {
- .parent = &pll2_sw_clk,
- .get_rate = clk_usboh3_get_rate,
- .set_parent = clk_usboh3_set_parent,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable,
- .enable_reg = MXC_CCM_CCGR2,
- .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
-};
-
-static struct clk usb_ahb_clk = {
- .parent = &ipg_clk,
- .enable = _clk_ccgr_enable,
- .disable = _clk_ccgr_disable,
- .enable_reg = MXC_CCM_CCGR2,
- .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
-};
-
-static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
-
- if (parent == &pll3_sw_clk)
- reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
-
- __raw_writel(reg, MXC_CCM_CSCMR1);
-
- return 0;
-}
-
-static struct clk usb_phy1_clk = {
- .parent = &pll3_sw_clk,
- .set_parent = clk_usb_phy1_set_parent,
- .enable = _clk_ccgr_enable,
- .enable_reg = MXC_CCM_CCGR2,
- .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
- .disable = _clk_ccgr_disable,
-};
-
-/* eCSPI */
-CLK_GET_RATE(ecspi, 2, CSPI)
-CLK_SET_PARENT(ecspi, 1, CSPI)
-
-static struct clk ecspi_main_clk = {
- .parent = &pll3_sw_clk,
- .get_rate = clk_ecspi_get_rate,
- .set_parent = clk_ecspi_set_parent,
-};
-
-/* eSDHC */
-CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
-CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
-CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
-
-/* mx51 specific */
-CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
-CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
-CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
-
-static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CSCMR1);
- if (parent == &esdhc1_clk)
- reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
- else if (parent == &esdhc2_clk)
- reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
- else
- return -EINVAL;
- __raw_writel(reg, MXC_CCM_CSCMR1);
-
- return 0;
-}
-
-static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CSCMR1);
- if (parent == &esdhc1_clk)
- reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
- else if (parent == &esdhc2_clk)
- reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
- else
- return -EINVAL;
- __raw_writel(reg, MXC_CCM_CSCMR1);
-
- return 0;
-}
-
-/* mx53 specific */
-static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CSCMR1);
- if (parent == &esdhc1_clk)
- reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
- else if (parent == &esdhc3_mx53_clk)
- reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
- else
- return -EINVAL;
- __raw_writel(reg, MXC_CCM_CSCMR1);
-
- return 0;
-}
-
-CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
-CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
-CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
-
-static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_CSCMR1);
- if (parent == &esdhc1_clk)
- reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
- else if (parent == &esdhc3_mx53_clk)
- reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
- else
- return -EINVAL;
- __raw_writel(reg, MXC_CCM_CSCMR1);
-
- return 0;
-}
-
-#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
- static struct clk name = { \
- .id = i, \
- .enable_reg = er, \
- .enable_shift = es, \
- .get_rate = gr, \
- .set_rate = sr, \
- .enable = e, \
- .disable = d, \
- .parent = p, \
- .secondary = s, \
- }
-
-#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
- DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
-
-/* Shared peripheral bus arbiter */
-DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-
-/* UART */
-DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
- NULL, NULL, &ipg_clk, &aips_tz1_clk);
-DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
- NULL, NULL, &ipg_clk, &aips_tz1_clk);
-DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
- NULL, NULL, &ipg_clk, &spba_clk);
-DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET,
- NULL, NULL, &ipg_clk, &spba_clk);
-DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &ipg_clk, &spba_clk);
-DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
- NULL, NULL, &uart_root_clk, &uart1_ipg_clk);
-DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &uart_root_clk, &uart2_ipg_clk);
-DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &uart_root_clk, &uart3_ipg_clk);
-DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET,
- NULL, NULL, &uart_root_clk, &uart4_ipg_clk);
-DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET,
- NULL, NULL, &uart_root_clk, &uart5_ipg_clk);
-
-/* GPT */
-DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &ipg_clk, &gpt_ipg_clk);
-
-DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &ipg_perclk, NULL);
-DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &ipg_perclk, NULL);
-
-/* I2C */
-DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &ipg_perclk, NULL);
-DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
- NULL, NULL, &ipg_perclk, NULL);
-DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
- NULL, NULL, &ipg_perclk, NULL);
-
-/* FEC */
-DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-
-/* NFC */
-DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
- clk_nfc, &emi_slow_clk, NULL);
-
-/* SSI */
-DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
-DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
- NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
-DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
- NULL, NULL, &ipg_clk, NULL);
-DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
- NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
-
-/* eCSPI */
-DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
- &ipg_clk, &spba_clk);
-DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
- NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
-DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
- NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
- &ipg_clk, &aips_tz2_clk);
-DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
- NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
-
-/* CSPI */
-DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
- NULL, NULL, &ipg_clk, &aips_tz2_clk);
-DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
- NULL, NULL, &ipg_clk, &cspi_ipg_clk);
-
-/* SDMA */
-DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
- NULL, NULL, &ahb_clk, NULL);
-
-/* eSDHC */
-DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
- NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
-DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
- clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
-DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
- NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
-DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
- NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
-DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
-
-/* mx51 specific */
-DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
- clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
-
-static struct clk esdhc3_clk = {
- .id = 2,
- .parent = &esdhc1_clk,
- .set_parent = clk_esdhc3_set_parent,
- .enable_reg = MXC_CCM_CCGR3,
- .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
- .enable = _clk_max_enable,
- .disable = _clk_max_disable,
- .secondary = &esdhc3_ipg_clk,
-};
-static struct clk esdhc4_clk = {
- .id = 3,
- .parent = &esdhc1_clk,
- .set_parent = clk_esdhc4_set_parent,
- .enable_reg = MXC_CCM_CCGR3,
- .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
- .enable = _clk_max_enable,
- .disable = _clk_max_disable,
- .secondary = &esdhc4_ipg_clk,
-};
-
-/* mx53 specific */
-static struct clk esdhc2_mx53_clk = {
- .id = 2,
- .parent = &esdhc1_clk,
- .set_parent = clk_esdhc2_mx53_set_parent,
- .enable_reg = MXC_CCM_CCGR3,
- .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
- .enable = _clk_max_enable,
- .disable = _clk_max_disable,
- .secondary = &esdhc3_ipg_clk,
-};
-
-DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET,
- clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk);
-
-static struct clk esdhc4_mx53_clk = {
- .id = 3,
- .parent = &esdhc1_clk,
- .set_parent = clk_esdhc4_mx53_set_parent,
- .enable_reg = MXC_CCM_CCGR3,
- .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
- .enable = _clk_max_enable,
- .disable = _clk_max_disable,
- .secondary = &esdhc4_ipg_clk,
-};
-
-static struct clk sata_clk = {
- .parent = &ipg_clk,
- .enable = _clk_max_enable,
- .enable_reg = MXC_CCM_CCGR4,
- .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
- .disable = _clk_max_disable,
-};
-
-static struct clk ahci_phy_clk = {
- .parent = &usb_phy1_clk,
-};
-
-static struct clk ahci_dma_clk = {
- .parent = &ahb_clk,
-};
-
-DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
-DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
-DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
-
-/* IPU */
-DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
- NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
-
-DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
- NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
- &ddr_clk, NULL);
-
-DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
- NULL, NULL, &pll3_sw_clk, NULL);
-DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
- NULL, NULL, &pll3_sw_clk, NULL);
-
-/* PATA */
-DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG0_OFFSET,
- NULL, NULL, &ipg_clk, &spba_clk);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup mx51_lookups[] = {
- /* i.mx51 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
- /* i.mx51 has the i.mx27 type fec */
- _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
- _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
- _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
- _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
- _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
- _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
- _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
- _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
- _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
- /* i.mx51 has the i.mx35 type sdma */
- _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
- _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
- _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
- _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
- _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
- _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
- /* i.mx51 has the i.mx35 type cspi */
- _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk)
- _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
- _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
- _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
- _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
- _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
- _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
- _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
- _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
- _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
-};
-
-static struct clk_lookup mx53_lookups[] = {
- /* i.mx53 has the i.mx21 type uart */
- _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
- _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
- _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
- _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
- _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
- _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
- /* i.mx53 has the i.mx25 type fec */
- _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
- _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
- _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
- _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk)
- /* i.mx53 has the i.mx51 type ecspi */
- _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
- _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
- /* i.mx53 has the i.mx25 type cspi */
- _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk)
- _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk)
- _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
- _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
- /* i.mx53 has the i.mx35 type sdma */
- _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
- _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
- _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
- _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
- _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
- _REGISTER_CLOCK("pata_imx", NULL, pata_clk)
- _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk)
- _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk)
- _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk)
-};
-
-static void clk_tree_init(void)
-{
- u32 reg;
-
- ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
-
- /*
- * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
- * 8MHz, its derived from lp_apm.
- *
- * FIXME: Verify if true for all boards
- */
- reg = __raw_readl(MXC_CCM_CBCDR);
- reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
- reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
- reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
- reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
- __raw_writel(reg, MXC_CCM_CBCDR);
-}
-
-int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
- unsigned long ckih1, unsigned long ckih2)
-{
- int i;
-
- external_low_reference = ckil;
- external_high_reference = ckih1;
- ckih2_reference = ckih2;
- oscillator_reference = osc;
-
- for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
- clkdev_add(&mx51_lookups[i]);
-
- clk_tree_init();
-
- clk_enable(&cpu_clk);
- clk_enable(&main_bus_clk);
-
- clk_enable(&iim_clk);
- imx_print_silicon_rev("i.MX51", mx51_revision());
- clk_disable(&iim_clk);
-
- /* move usb_phy_clk to 24MHz */
- clk_set_parent(&usb_phy1_clk, &osc_clk);
-
- /* set the usboh3_clk parent to pll2_sw_clk */
- clk_set_parent(&usboh3_clk, &pll2_sw_clk);
-
- /* Set SDHC parents to be PLL2 */
- clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
- clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
-
- /* set SDHC root clock as 166.25MHZ*/
- clk_set_rate(&esdhc1_clk, 166250000);
- clk_set_rate(&esdhc2_clk, 166250000);
-
- /* System timer */
- mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
- MX51_INT_GPT);
- return 0;
-}
-
-int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
- unsigned long ckih1, unsigned long ckih2)
-{
- int i;
-
- external_low_reference = ckil;
- external_high_reference = ckih1;
- ckih2_reference = ckih2;
- oscillator_reference = osc;
-
- for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
- clkdev_add(&mx53_lookups[i]);
-
- clk_tree_init();
-
- clk_set_parent(&uart_root_clk, &pll3_sw_clk);
- clk_enable(&cpu_clk);
- clk_enable(&main_bus_clk);
-
- clk_enable(&iim_clk);
- imx_print_silicon_rev("i.MX53", mx53_revision());
- clk_disable(&iim_clk);
-
- /* Set SDHC parents to be PLL2 */
- clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
- clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk);
-
- /* set SDHC root clock as 200MHZ*/
- clk_set_rate(&esdhc1_clk, 200000000);
- clk_set_rate(&esdhc3_mx53_clk, 200000000);
-
- /* System timer */
- mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
- MX53_INT_GPT);
- return 0;
-}
-
-#ifdef CONFIG_OF
-static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
- unsigned long *ckih1, unsigned long *ckih2)
-{
- struct device_node *np;
-
- /* retrieve the freqency of fixed clocks from device tree */
- for_each_compatible_node(np, NULL, "fixed-clock") {
- u32 rate;
- if (of_property_read_u32(np, "clock-frequency", &rate))
- continue;
-
- if (of_device_is_compatible(np, "fsl,imx-ckil"))
- *ckil = rate;
- else if (of_device_is_compatible(np, "fsl,imx-osc"))
- *osc = rate;
- else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
- *ckih1 = rate;
- else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
- *ckih2 = rate;
- }
-}
-
-int __init mx51_clocks_init_dt(void)
-{
- unsigned long ckil, osc, ckih1, ckih2;
-
- clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
- return mx51_clocks_init(ckil, osc, ckih1, ckih2);
-}
-
-int __init mx53_clocks_init_dt(void)
-{
- unsigned long ckil, osc, ckih1, ckih2;
-
- clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
- return mx53_clocks_init(ckil, osc, ckih1, ckih2);
-}
-#endif
diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c
index aa15c517d06e..8eb15a2fcaf9 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);
* Dependent on link order - so the assumption is that vfp_init is called
* before us.
*/
-static int __init mx51_neon_fixup(void)
+int __init mx51_neon_fixup(void)
{
- if (!cpu_is_mx51())
- return 0;
-
if (mx51_revision() < IMX_CHIP_REVISION_3_0 &&
(elf_hwcap & HWCAP_NEON)) {
elf_hwcap &= ~HWCAP_NEON;
@@ -75,7 +72,6 @@ static int __init mx51_neon_fixup(void)
return 0;
}
-late_initcall(mx51_neon_fixup);
#endif
static int get_mx53_srev(void)
diff --git a/arch/arm/mach-imx/crmregs-imx3.h b/arch/arm/mach-imx/crmregs-imx3.h
index 53141273df45..a1dfde53e335 100644
--- a/arch/arm/mach-imx/crmregs-imx3.h
+++ b/arch/arm/mach-imx/crmregs-imx3.h
@@ -24,48 +24,47 @@
#define CKIH_CLK_FREQ_27MHZ 27000000
#define CKIL_CLK_FREQ 32768
-#define MXC_CCM_BASE (cpu_is_mx31() ? \
-MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR) : MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR))
+extern void __iomem *mx3_ccm_base;
/* Register addresses */
-#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
-#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04)
-#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08)
-#define MX35_CCM_PDR2 (MXC_CCM_BASE + 0x0C)
-#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C)
-#define MX35_CCM_PDR3 (MXC_CCM_BASE + 0x10)
-#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10)
-#define MX35_CCM_PDR4 (MXC_CCM_BASE + 0x14)
-#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14)
-#define MX35_CCM_RCSR (MXC_CCM_BASE + 0x18)
-#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18)
-#define MX35_CCM_MPCTL (MXC_CCM_BASE + 0x1C)
-#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C)
-#define MX35_CCM_PPCTL (MXC_CCM_BASE + 0x20)
-#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20)
-#define MX35_CCM_ACMR (MXC_CCM_BASE + 0x24)
-#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24)
-#define MX35_CCM_COSR (MXC_CCM_BASE + 0x28)
-#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28)
-#define MX35_CCM_CGR0 (MXC_CCM_BASE + 0x2C)
-#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C)
-#define MX35_CCM_CGR1 (MXC_CCM_BASE + 0x30)
-#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30)
-#define MX35_CCM_CGR2 (MXC_CCM_BASE + 0x34)
-#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34)
-#define MX35_CCM_CGR3 (MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C)
-#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40)
-#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44)
-#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48)
-#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C)
-#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50)
-#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54)
-#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58)
-#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C)
-#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60)
-#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CCMR 0x00
+#define MXC_CCM_PDR0 0x04
+#define MXC_CCM_PDR1 0x08
+#define MX35_CCM_PDR2 0x0C
+#define MXC_CCM_RCSR 0x0C
+#define MX35_CCM_PDR3 0x10
+#define MXC_CCM_MPCTL 0x10
+#define MX35_CCM_PDR4 0x14
+#define MXC_CCM_UPCTL 0x14
+#define MX35_CCM_RCSR 0x18
+#define MXC_CCM_SRPCTL 0x18
+#define MX35_CCM_MPCTL 0x1C
+#define MXC_CCM_COSR 0x1C
+#define MX35_CCM_PPCTL 0x20
+#define MXC_CCM_CGR0 0x20
+#define MX35_CCM_ACMR 0x24
+#define MXC_CCM_CGR1 0x24
+#define MX35_CCM_COSR 0x28
+#define MXC_CCM_CGR2 0x28
+#define MX35_CCM_CGR0 0x2C
+#define MXC_CCM_WIMR 0x2C
+#define MX35_CCM_CGR1 0x30
+#define MXC_CCM_LDC 0x30
+#define MX35_CCM_CGR2 0x34
+#define MXC_CCM_DCVR0 0x34
+#define MX35_CCM_CGR3 0x38
+#define MXC_CCM_DCVR1 0x38
+#define MXC_CCM_DCVR2 0x3C
+#define MXC_CCM_DCVR3 0x40
+#define MXC_CCM_LTR0 0x44
+#define MXC_CCM_LTR1 0x48
+#define MXC_CCM_LTR2 0x4C
+#define MXC_CCM_LTR3 0x50
+#define MXC_CCM_LTBR0 0x54
+#define MXC_CCM_LTBR1 0x58
+#define MXC_CCM_PMCR0 0x5C
+#define MXC_CCM_PMCR1 0x60
+#define MXC_CCM_PDR2 0x64
/* Register bit definitions */
#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 5f577fbda2c8..18e78dba4298 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)")
.handle_irq = imx51_handle_irq,
.timer = &imx51_timer,
.init_machine = imx51_dt_init,
+ .init_late = imx51_init_late,
.dt_compat = imx51_dt_board_compat,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 574eca4b89a5..eb04b6248e48 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -10,6 +10,9 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
@@ -81,6 +84,19 @@ static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
{ /* sentinel */ }
};
+static void __init imx53_qsb_init(void)
+{
+ struct clk *clk;
+
+ clk = clk_get_sys(NULL, "ssi_ext1");
+ if (IS_ERR(clk)) {
+ pr_err("failed to get clk ssi_ext1\n");
+ return;
+ }
+
+ clk_register_clkdev(clk, NULL, "0-000a");
+}
+
static void __init imx53_dt_init(void)
{
struct device_node *node;
@@ -99,6 +115,9 @@ static void __init imx53_dt_init(void)
of_node_put(node);
}
+ if (of_machine_is_compatible("fsl,imx53-qsb"))
+ imx53_qsb_init();
+
of_platform_populate(NULL, of_default_bus_match_table,
imx53_auxdata_lookup, NULL);
}
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
index 0213f8dcee81..c40a34c00489 100644
--- a/arch/arm/mach-imx/lluart.c
+++ b/arch/arm/mach-imx/lluart.c
@@ -17,6 +17,12 @@
#include <mach/hardware.h>
static struct map_desc imx_lluart_desc = {
+#ifdef CONFIG_DEBUG_IMX6Q_UART2
+ .virtual = MX6Q_IO_P2V(MX6Q_UART2_BASE_ADDR),
+ .pfn = __phys_to_pfn(MX6Q_UART2_BASE_ADDR),
+ .length = MX6Q_UART2_SIZE,
+ .type = MT_DEVICE,
+#endif
#ifdef CONFIG_DEBUG_IMX6Q_UART4
.virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
.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 ce341a6874fc..ac50f1671e38 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")
.handle_irq = imx51_handle_irq,
.timer = &mxc_timer,
.init_machine = eukrea_cpuimx51sd_init,
+ .init_late = imx51_init_late,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 3df360a52c17..b47e98b7d539 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -10,6 +10,8 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
@@ -64,18 +66,53 @@ soft:
/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
static int ksz9021rn_phy_fixup(struct phy_device *phydev)
{
- /* min rx data delay */
- phy_write(phydev, 0x0b, 0x8105);
- phy_write(phydev, 0x0c, 0x0000);
+ if (IS_ENABLED(CONFIG_PHYLIB)) {
+ /* min rx data delay */
+ phy_write(phydev, 0x0b, 0x8105);
+ phy_write(phydev, 0x0c, 0x0000);
- /* max rx/tx clock delay, min rx/tx control delay */
- phy_write(phydev, 0x0b, 0x8104);
- phy_write(phydev, 0x0c, 0xf0f0);
- phy_write(phydev, 0x0b, 0x104);
+ /* max rx/tx clock delay, min rx/tx control delay */
+ phy_write(phydev, 0x0b, 0x8104);
+ phy_write(phydev, 0x0c, 0xf0f0);
+ phy_write(phydev, 0x0b, 0x104);
+ }
return 0;
}
+static void __init imx6q_sabrelite_cko1_setup(void)
+{
+ struct clk *cko1_sel, *ahb, *cko1;
+ unsigned long rate;
+
+ cko1_sel = clk_get_sys(NULL, "cko1_sel");
+ ahb = clk_get_sys(NULL, "ahb");
+ cko1 = clk_get_sys(NULL, "cko1");
+ if (IS_ERR(cko1_sel) || IS_ERR(ahb) || IS_ERR(cko1)) {
+ pr_err("cko1 setup failed!\n");
+ goto put_clk;
+ }
+ clk_set_parent(cko1_sel, ahb);
+ rate = clk_round_rate(cko1, 16000000);
+ clk_set_rate(cko1, rate);
+ clk_register_clkdev(cko1, NULL, "0-000a");
+put_clk:
+ if (!IS_ERR(cko1_sel))
+ clk_put(cko1_sel);
+ if (!IS_ERR(ahb))
+ clk_put(ahb);
+ if (!IS_ERR(cko1))
+ clk_put(cko1);
+}
+
+static void __init imx6q_sabrelite_init(void)
+{
+ if (IS_ENABLED(CONFIG_PHYLIB))
+ phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
+ ksz9021rn_phy_fixup);
+ imx6q_sabrelite_cko1_setup();
+}
+
static void __init imx6q_init_machine(void)
{
/*
@@ -85,8 +122,7 @@ static void __init imx6q_init_machine(void)
pinctrl_provide_dummies();
if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
- phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
- ksz9021rn_phy_fixup);
+ imx6q_sabrelite_init();
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
@@ -139,6 +175,7 @@ static struct sys_timer imx6q_timer = {
static const char *imx6q_dt_compat[] __initdata = {
"fsl,imx6q-arm2",
"fsl,imx6q-sabrelite",
+ "fsl,imx6q-sabresd",
"fsl,imx6q",
NULL,
};
diff --git a/arch/arm/mach-imx/mach-mx51_3ds.c b/arch/arm/mach-imx/mach-mx51_3ds.c
index 83eab4176ca4..3c5b163923f6 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")
.handle_irq = imx51_handle_irq,
.timer = &mx51_3ds_timer,
.init_machine = mx51_3ds_init,
+ .init_late = imx51_init_late,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c
index e4b822e9f719..dde397014d4b 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[] = {
MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
MX51_PAD_CSPI1_SS0__GPIO4_24,
MX51_PAD_CSPI1_SS1__GPIO4_25,
+
+ /* Audio */
+ MX51_PAD_AUD3_BB_TXD__AUD3_TXD,
+ MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
+ MX51_PAD_AUD3_BB_CK__AUD3_TXC,
+ MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
};
/* Serial ports */
@@ -426,5 +432,6 @@ MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
.handle_irq = imx51_handle_irq,
.timer = &mx51_babbage_timer,
.init_machine = mx51_babbage_init,
+ .init_late = imx51_init_late,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_efikamx.c b/arch/arm/mach-imx/mach-mx51_efikamx.c
index 86e96ef11f9d..8d09c0126cab 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)
static int __init mx51_efikamx_power_init(void)
{
- if (machine_is_mx51_efikamx()) {
- pwgt1 = regulator_get(NULL, "pwgt1");
- pwgt2 = regulator_get(NULL, "pwgt2");
- if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
- regulator_enable(pwgt1);
- regulator_enable(pwgt2);
- }
- gpio_request(EFIKAMX_POWEROFF, "poweroff");
- pm_power_off = mx51_efikamx_power_off;
-
- /* enable coincell charger. maybe need a small power driver ? */
- coincell = regulator_get(NULL, "coincell");
- if (!IS_ERR(coincell)) {
- regulator_set_voltage(coincell, 3000000, 3000000);
- regulator_enable(coincell);
- }
-
- regulator_has_full_constraints();
+ pwgt1 = regulator_get(NULL, "pwgt1");
+ pwgt2 = regulator_get(NULL, "pwgt2");
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_enable(pwgt1);
+ regulator_enable(pwgt2);
+ }
+ gpio_request(EFIKAMX_POWEROFF, "poweroff");
+ pm_power_off = mx51_efikamx_power_off;
+
+ /* enable coincell charger. maybe need a small power driver ? */
+ coincell = regulator_get(NULL, "coincell");
+ if (!IS_ERR(coincell)) {
+ regulator_set_voltage(coincell, 3000000, 3000000);
+ regulator_enable(coincell);
}
+ regulator_has_full_constraints();
+
return 0;
}
-late_initcall(mx51_efikamx_power_init);
+
+static void __init mx51_efikamx_init_late(void)
+{
+ imx51_init_late();
+ mx51_efikamx_power_init();
+}
static void __init mx51_efikamx_init(void)
{
@@ -292,5 +295,6 @@ MACHINE_START(MX51_EFIKAMX, "Genesi Efika MX (Smarttop)")
.handle_irq = imx51_handle_irq,
.timer = &mx51_efikamx_timer,
.init_machine = mx51_efikamx_init,
+ .init_late = mx51_efikamx_init_late,
.restart = mx51_efikamx_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx51_efikasb.c b/arch/arm/mach-imx/mach-mx51_efikasb.c
index 88f837a6cc76..fdbd181b97ef 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)
static int __init mx51_efikasb_power_init(void)
{
- if (machine_is_mx51_efikasb()) {
- pwgt1 = regulator_get(NULL, "pwgt1");
- pwgt2 = regulator_get(NULL, "pwgt2");
- if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
- regulator_enable(pwgt1);
- regulator_enable(pwgt2);
- }
- gpio_request(EFIKASB_POWEROFF, "poweroff");
- pm_power_off = mx51_efikasb_power_off;
-
- regulator_has_full_constraints();
+ pwgt1 = regulator_get(NULL, "pwgt1");
+ pwgt2 = regulator_get(NULL, "pwgt2");
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_enable(pwgt1);
+ regulator_enable(pwgt2);
}
+ gpio_request(EFIKASB_POWEROFF, "poweroff");
+ pm_power_off = mx51_efikasb_power_off;
+
+ regulator_has_full_constraints();
return 0;
}
-late_initcall(mx51_efikasb_power_init);
+
+static void __init mx51_efikasb_init_late(void)
+{
+ imx51_init_late();
+ mx51_efikasb_power_init();
+}
/* 01 R1.3 board
10 R2.0 board */
@@ -287,6 +290,7 @@ MACHINE_START(MX51_EFIKASB, "Genesi Efika MX (Smartbook)")
.init_irq = mx51_init_irq,
.handle_irq = imx51_handle_irq,
.init_machine = efikasb_board_init,
+ .init_late = mx51_efikasb_init_late,
.timer = &mx51_efikasb_timer,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index 10c9795934a3..0a40004154f2 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)
MX3_CAMERA_BUF_SIZE);
}
+static void __init pcm037_init_late(void)
+{
+ pcm037_eet_init_devices();
+}
+
MACHINE_START(PCM037, "Phytec Phycore pcm037")
/* Maintainer: Pengutronix */
.atag_offset = 0x100,
@@ -704,5 +709,6 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
.handle_irq = imx31_handle_irq,
.timer = &pcm037_timer,
.init_machine = pcm037_init,
+ .init_late = pcm037_init_late,
.restart = mxc_restart,
MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c
index 1b7606bef8f4..11ffa81ad17d 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
.rep = 0, /* No auto-repeat */
};
-static int __init eet_init_devices(void)
+int __init pcm037_eet_init_devices(void)
{
- if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET)
+ if (pcm037_variant() != PCM037_EET)
return 0;
mxc_iomux_setup_multiple_pins(pcm037_eet_pins,
@@ -176,4 +176,3 @@ static int __init eet_init_devices(void)
return 0;
}
-late_initcall(eet_init_devices);
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 9128d15b1eb7..967ed5b35a45 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -32,6 +32,10 @@
#include <mach/iomux-v3.h>
#include <mach/irqs.h>
+#include "crmregs-imx3.h"
+
+void __iomem *mx3_ccm_base;
+
static void imx3_idle(void)
{
unsigned long reg = 0;
@@ -138,6 +142,7 @@ void __init imx31_init_early(void)
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
arch_ioremap_caller = imx3_ioremap_caller;
arm_pm_idle = imx3_idle;
+ mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
}
void __init mx31_init_irq(void)
@@ -211,6 +216,7 @@ void __init imx35_init_early(void)
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
arm_pm_idle = imx3_idle;
arch_ioremap_caller = imx3_ioremap_caller;
+ mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
}
void __init mx35_init_irq(void)
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index ba91e6b31cf4..feeee17da96b 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)
gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
if (IS_ERR(gpc_dvfs_clk))
return;
+ clk_prepare(gpc_dvfs_clk);
}
clk_enable(gpc_dvfs_clk);
mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
@@ -236,3 +237,8 @@ void __init imx53_soc_init(void)
platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
ARRAY_SIZE(imx53_audmux_res));
}
+
+void __init imx51_init_late(void)
+{
+ mx51_neon_fixup();
+}
diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h
index d6929721a5fd..7d167690e17d 100644
--- a/arch/arm/mach-imx/pcm037.h
+++ b/arch/arm/mach-imx/pcm037.h
@@ -8,4 +8,10 @@ enum pcm037_board_variant {
extern enum pcm037_board_variant pcm037_variant(void);
+#ifdef CONFIG_MACH_PCM037_EET
+int pcm037_eet_init_devices(void);
+#else
+static inline int pcm037_eet_init_devices(void) { return 0; }
+#endif
+
#endif
diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c
index b3752439632e..822103bdb709 100644
--- a/arch/arm/mach-imx/pm-imx3.c
+++ b/arch/arm/mach-imx/pm-imx3.c
@@ -21,14 +21,14 @@
*/
void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode)
{
- int reg = __raw_readl(MXC_CCM_CCMR);
+ int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR);
reg &= ~MXC_CCM_CCMR_LPM_MASK;
switch (mode) {
case MX3_WAIT:
if (cpu_is_mx35())
reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
- __raw_writel(reg, MXC_CCM_CCMR);
+ __raw_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
break;
default:
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 985453994dd3..55e357ab2923 100644
--- a/arch/arm/mach-kirkwood/board-dreamplug.c
+++ b/arch/arm/mach-kirkwood/board-dreamplug.c
@@ -27,7 +27,6 @@
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 10d1969b9e3a..edc3f8a9d45e 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)
kirkwood_l2_init();
#endif
+ /* Setup root of clk tree */
+ kirkwood_clk_init();
+
/* internal devices that every board has */
kirkwood_wdt_init();
kirkwood_xor0_init();
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 3ad037385a5e..25fb3fd418ef 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -15,7 +15,8 @@
#include <linux/ata_platform.h>
#include <linux/mtd/nand.h>
#include <linux/dma-mapping.h>
-#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/timex.h>
@@ -32,6 +33,7 @@
#include <plat/common.h>
#include <plat/time.h>
#include <plat/addr-map.h>
+#include <plat/mv_xor.h>
#include "common.h"
/*****************************************************************************
@@ -61,20 +63,188 @@ void __init kirkwood_map_io(void)
iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
}
-/*
- * Default clock control bits. Any bit _not_ set in this variable
- * will be cleared from the hardware after platform devices have been
- * registered. Some reserved bits must be set to 1.
- */
-unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
+/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+
+static void disable_sata0(void)
+{
+ /* Disable PLL and IVREF */
+ writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
+}
+
+static void disable_sata1(void)
+{
+ /* Disable PLL and IVREF */
+ writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
+}
+
+static void disable_pcie0(void)
+{
+ writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
+ while (1)
+ if (readl(PCIE_STATUS) & 0x1)
+ break;
+ writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
+}
+
+static void disable_pcie1(void)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+
+ if (dev == MV88F6282_DEV_ID) {
+ writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
+ while (1)
+ if (readl(PCIE1_STATUS) & 0x1)
+ break;
+ writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
+ }
+}
+
+/* An extended version of the gated clk. This calls fn() before
+ * disabling the clock. We use this to turn off PHYs etc. */
+struct clk_gate_fn {
+ struct clk_gate gate;
+ void (*fn)(void);
+};
+
+#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate)
+#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+
+static void clk_gate_fn_disable(struct clk_hw *hw)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
+
+ if (gate_fn->fn)
+ gate_fn->fn();
+
+ clk_gate_ops.disable(hw);
+}
+
+static struct clk_ops clk_gate_fn_ops;
+
+static struct clk __init *clk_register_gate_fn(struct device *dev,
+ const char *name,
+ const char *parent_name, unsigned long flags,
+ void __iomem *reg, u8 bit_idx,
+ u8 clk_gate_flags, spinlock_t *lock,
+ void (*fn)(void))
+{
+ struct clk_gate_fn *gate_fn;
+ struct clk *clk;
+ struct clk_init_data init;
+
+ gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL);
+ if (!gate_fn) {
+ pr_err("%s: could not allocate gated clk\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = name;
+ init.ops = &clk_gate_fn_ops;
+ init.flags = flags;
+ init.parent_names = (parent_name ? &parent_name : NULL);
+ init.num_parents = (parent_name ? 1 : 0);
+
+ /* struct clk_gate assignments */
+ gate_fn->gate.reg = reg;
+ gate_fn->gate.bit_idx = bit_idx;
+ gate_fn->gate.flags = clk_gate_flags;
+ gate_fn->gate.lock = lock;
+ gate_fn->gate.hw.init = &init;
+
+ /* ops is the gate ops, but with our disable function */
+ if (clk_gate_fn_ops.disable != clk_gate_fn_disable) {
+ clk_gate_fn_ops = clk_gate_ops;
+ clk_gate_fn_ops.disable = clk_gate_fn_disable;
+ }
+ clk = clk_register(dev, &gate_fn->gate.hw);
+
+ if (IS_ERR(clk))
+ kfree(gate_fn);
+
+ return clk;
+}
+
+static DEFINE_SPINLOCK(gating_lock);
+static struct clk *tclk;
+
+static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx)
+{
+ return clk_register_gate(NULL, name, "tclk", 0,
+ (void __iomem *)CLOCK_GATING_CTRL,
+ bit_idx, 0, &gating_lock);
+}
+
+static struct clk __init *kirkwood_register_gate_fn(const char *name,
+ u8 bit_idx,
+ void (*fn)(void))
+{
+ return clk_register_gate_fn(NULL, name, "tclk", 0,
+ (void __iomem *)CLOCK_GATING_CTRL,
+ bit_idx, 0, &gating_lock, fn);
+}
+
+void __init kirkwood_clk_init(void)
+{
+ struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio;
+ struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio;
+
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL,
+ CLK_IS_ROOT, kirkwood_tclk);
+
+ runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT);
+ ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
+ ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
+ sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0,
+ disable_sata0);
+ sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1,
+ disable_sata1);
+ usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0);
+ sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO);
+ crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
+ xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0);
+ xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1);
+ pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0,
+ disable_pcie0);
+ pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1,
+ disable_pcie1);
+ audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO);
+ kirkwood_register_gate("tdm", CGC_BIT_TDM);
+ kirkwood_register_gate("tsu", CGC_BIT_TSU);
+
+ /* clkdev entries, mapping clks to devices */
+ orion_clkdev_add(NULL, "orion_spi.0", runit);
+ orion_clkdev_add(NULL, "orion_spi.1", runit);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1);
+ orion_clkdev_add(NULL, "orion_wdt", tclk);
+ orion_clkdev_add("0", "sata_mv.0", sata0);
+ orion_clkdev_add("1", "sata_mv.0", sata1);
+ orion_clkdev_add(NULL, "orion-ehci.0", usb0);
+ orion_clkdev_add(NULL, "orion_nand", runit);
+ orion_clkdev_add(NULL, "mvsdio", sdio);
+ orion_clkdev_add(NULL, "mv_crypto", crypto);
+ orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0);
+ orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1);
+ orion_clkdev_add("0", "pcie", pex0);
+ orion_clkdev_add("1", "pcie", pex1);
+ orion_clkdev_add(NULL, "kirkwood-i2s", audio);
+}
/*****************************************************************************
* EHCI0
****************************************************************************/
void __init kirkwood_ehci_init(void)
{
- kirkwood_clk_ctrl |= CGC_USB0;
orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
}
@@ -84,11 +254,9 @@ void __init kirkwood_ehci_init(void)
****************************************************************************/
void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
- kirkwood_clk_ctrl |= CGC_GE0;
-
orion_ge00_init(eth_data,
GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
- IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
+ IRQ_KIRKWOOD_GE00_ERR);
}
@@ -97,12 +265,9 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
****************************************************************************/
void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
{
-
- kirkwood_clk_ctrl |= CGC_GE1;
-
orion_ge01_init(eth_data,
GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
- IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
+ IRQ_KIRKWOOD_GE01_ERR);
}
@@ -144,7 +309,6 @@ static struct platform_device kirkwood_nand_flash = {
void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
int chip_delay)
{
- kirkwood_clk_ctrl |= CGC_RUNIT;
kirkwood_nand_data.parts = parts;
kirkwood_nand_data.nr_parts = nr_parts;
kirkwood_nand_data.chip_delay = chip_delay;
@@ -154,7 +318,6 @@ void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
int (*dev_ready)(struct mtd_info *))
{
- kirkwood_clk_ctrl |= CGC_RUNIT;
kirkwood_nand_data.parts = parts;
kirkwood_nand_data.nr_parts = nr_parts;
kirkwood_nand_data.dev_ready = dev_ready;
@@ -175,10 +338,6 @@ static void __init kirkwood_rtc_init(void)
****************************************************************************/
void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
{
- kirkwood_clk_ctrl |= CGC_SATA0;
- if (sata_data->n_ports > 1)
- kirkwood_clk_ctrl |= CGC_SATA1;
-
orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
}
@@ -221,7 +380,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
mvsdio_data->clock = 100000000;
else
mvsdio_data->clock = 200000000;
- kirkwood_clk_ctrl |= CGC_SDIO;
kirkwood_sdio.dev.platform_data = mvsdio_data;
platform_device_register(&kirkwood_sdio);
}
@@ -232,8 +390,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
****************************************************************************/
void __init kirkwood_spi_init()
{
- kirkwood_clk_ctrl |= CGC_RUNIT;
- orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
+ orion_spi_init(SPI_PHYS_BASE);
}
@@ -253,7 +410,7 @@ void __init kirkwood_i2c_init(void)
void __init kirkwood_uart0_init(void)
{
orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
- IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
+ IRQ_KIRKWOOD_UART_0, tclk);
}
@@ -263,7 +420,7 @@ void __init kirkwood_uart0_init(void)
void __init kirkwood_uart1_init(void)
{
orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
- IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
+ IRQ_KIRKWOOD_UART_1, tclk);
}
/*****************************************************************************
@@ -271,7 +428,6 @@ void __init kirkwood_uart1_init(void)
****************************************************************************/
void __init kirkwood_crypto_init(void)
{
- kirkwood_clk_ctrl |= CGC_CRYPTO;
orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
}
@@ -282,8 +438,6 @@ void __init kirkwood_crypto_init(void)
****************************************************************************/
void __init kirkwood_xor0_init(void)
{
- kirkwood_clk_ctrl |= CGC_XOR0;
-
orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
}
@@ -294,8 +448,6 @@ void __init kirkwood_xor0_init(void)
****************************************************************************/
void __init kirkwood_xor1_init(void)
{
- kirkwood_clk_ctrl |= CGC_XOR1;
-
orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
}
@@ -306,7 +458,7 @@ void __init kirkwood_xor1_init(void)
****************************************************************************/
void __init kirkwood_wdt_init(void)
{
- orion_wdt_init(kirkwood_tclk);
+ orion_wdt_init();
}
@@ -382,7 +534,6 @@ static struct platform_device kirkwood_pcm_device = {
void __init kirkwood_audio_init(void)
{
- kirkwood_clk_ctrl |= CGC_AUDIO;
platform_device_register(&kirkwood_i2s_device);
platform_device_register(&kirkwood_pcm_device);
}
@@ -466,6 +617,9 @@ void __init kirkwood_init(void)
kirkwood_l2_init();
#endif
+ /* Setup root of clk tree */
+ kirkwood_clk_init();
+
/* internal devices that every board has */
kirkwood_rtc_init();
kirkwood_wdt_init();
@@ -478,72 +632,6 @@ void __init kirkwood_init(void)
#endif
}
-static int __init kirkwood_clock_gate(void)
-{
- unsigned int curr = readl(CLOCK_GATING_CTRL);
- u32 dev, rev;
-
-#ifdef CONFIG_OF
- struct device_node *np;
-#endif
- kirkwood_pcie_id(&dev, &rev);
- printk(KERN_DEBUG "Gating clock of unused units\n");
- printk(KERN_DEBUG "before: 0x%08x\n", curr);
-
- /* Make sure those units are accessible */
- writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
-
-#ifdef CONFIG_OF
- np = of_find_compatible_node(NULL, NULL, "mrvl,orion-nand");
- if (np && of_device_is_available(np)) {
- kirkwood_clk_ctrl |= CGC_RUNIT;
- of_node_put(np);
- }
-#endif
-
- /* For SATA: first shutdown the phy */
- if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
- /* Disable PLL and IVREF */
- writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
- /* Disable PHY */
- writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
- }
- if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
- /* Disable PLL and IVREF */
- writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
- /* Disable PHY */
- writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
- }
-
- /* For PCIe: first shutdown the phy */
- if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
- writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
- while (1)
- if (readl(PCIE_STATUS) & 0x1)
- break;
- writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
- }
-
- /* For PCIe 1: first shutdown the phy */
- if (dev == MV88F6282_DEV_ID) {
- if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
- writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
- while (1)
- if (readl(PCIE1_STATUS) & 0x1)
- break;
- writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
- }
- } else /* keep this bit set for devices that don't have PCIe1 */
- kirkwood_clk_ctrl |= CGC_PEX1;
-
- /* Now gate clock the required units */
- writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
- printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
-
- return 0;
-}
-late_initcall(kirkwood_clock_gate);
-
void kirkwood_restart(char mode, const char *cmd)
{
/*
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index a34c41a5172e..9248fa2c165b 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);
void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *));
void kirkwood_audio_init(void);
void kirkwood_restart(char, const char *);
+void kirkwood_clk_init(void);
/* board init functions for boards not fully converted to fdt */
#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 957bd7997d7e..3eee37a3b501 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 @@
#define L2_WRITETHROUGH 0x00000010
#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c)
+#define CGC_BIT_GE0 (0)
+#define CGC_BIT_PEX0 (2)
+#define CGC_BIT_USB0 (3)
+#define CGC_BIT_SDIO (4)
+#define CGC_BIT_TSU (5)
+#define CGC_BIT_DUNIT (6)
+#define CGC_BIT_RUNIT (7)
+#define CGC_BIT_XOR0 (8)
+#define CGC_BIT_AUDIO (9)
+#define CGC_BIT_SATA0 (14)
+#define CGC_BIT_SATA1 (15)
+#define CGC_BIT_XOR1 (16)
+#define CGC_BIT_CRYPTO (17)
+#define CGC_BIT_PEX1 (18)
+#define CGC_BIT_GE1 (19)
+#define CGC_BIT_TDM (20)
#define CGC_GE0 (1 << 0)
#define CGC_PEX0 (1 << 2)
#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 85f6169c2484..6d8364a97810 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -23,7 +23,6 @@
#include <linux/gpio_keys.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index de373176ee67..6e8b2efa3c35 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/clk.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
@@ -19,6 +20,23 @@
#include <plat/addr-map.h>
#include "common.h"
+static void kirkwood_enable_pcie_clk(const char *port)
+{
+ struct clk *clk;
+
+ clk = clk_get_sys("pcie", port);
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "PCIE clock %s missing\n", port);
+ return;
+ }
+ clk_prepare_enable(clk);
+ clk_put(clk);
+}
+
+/* This function is called very early in the boot when probing the
+ hardware to determine what we actually are, and what rate tclk is
+ ticking at. Hence calling kirkwood_enable_pcie_clk() is not
+ possible since the clk tree has not been created yet. */
void kirkwood_enable_pcie(void)
{
u32 curr = readl(CLOCK_GATING_CTRL);
@@ -26,7 +44,7 @@ void kirkwood_enable_pcie(void)
writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
}
-void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+void kirkwood_pcie_id(u32 *dev, u32 *rev)
{
kirkwood_enable_pcie();
*dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
@@ -159,7 +177,6 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp)
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
{
- extern unsigned int kirkwood_clk_ctrl;
struct pcie_port *pp;
int index;
@@ -178,11 +195,11 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
switch (index) {
case 0:
- kirkwood_clk_ctrl |= CGC_PEX0;
+ kirkwood_enable_pcie_clk("0");
pcie0_ioresources_init(pp);
break;
case 1:
- kirkwood_clk_ctrl |= CGC_PEX1;
+ kirkwood_enable_pcie_clk("1");
pcie1_ioresources_init(pp);
break;
default:
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index fd2c9c8b6831..f742a66a7045 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -16,7 +16,6 @@
#include <linux/gpio.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/kirkwood.h>
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index f9d2a11b7f96..bad738e44044 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -16,7 +16,6 @@
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <linux/i2c.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c
index 24294b2bc469..8943ede29b44 100644
--- a/arch/arm/mach-kirkwood/tsx1x-common.c
+++ b/arch/arm/mach-kirkwood/tsx1x-common.c
@@ -4,7 +4,6 @@
#include <linux/mtd/physmap.h>
#include <linux/spi/flash.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <linux/serial_reg.h>
#include <mach/kirkwood.h>
#include "common.h"
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
index 26aac363a064..4fa3e99d9a62 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)
msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
}
+static void __init halibut_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
.atag_offset = 0x100,
.fixup = halibut_fixup,
@@ -101,5 +106,6 @@ MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
.init_early = halibut_init_early,
.init_irq = halibut_init_irq,
.init_machine = halibut_init,
+ .init_late = halibut_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
index 5a4882fc6f7a..cf1f89a5dc62 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)
msm_clock_init();
}
+static void __init mahimahi_init_late(void)
+{
+ smd_debugfs_init();
+}
+
extern struct sys_timer msm_timer;
MACHINE_START(MAHIMAHI, "mahimahi")
@@ -79,5 +84,6 @@ MACHINE_START(MAHIMAHI, "mahimahi")
.map_io = mahimahi_map_io,
.init_irq = msm_init_irq,
.init_machine = mahimahi_init,
+ .init_late = mahimahi_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 6d84ee740df4..451ab1d43c92 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)
#endif
}
+static void __init msm7x2x_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
.atag_offset = 0x100,
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
+ .init_late = msm7x2x_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -141,6 +147,7 @@ MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
+ .init_late = msm7x2x_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -149,6 +156,7 @@ MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
+ .init_late = msm7x2x_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -157,5 +165,6 @@ MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
+ .init_late = msm7x2x_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 75b3cfcada6d..a5001378135d 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)
msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
}
+static void __init msm7x30_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
.atag_offset = 0x100,
.fixup = msm7x30_fixup,
@@ -126,6 +131,7 @@ MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
+ .init_late = msm7x30_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -136,6 +142,7 @@ MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
+ .init_late = msm7x30_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -146,5 +153,6 @@ MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
+ .init_late = msm7x30_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index ed3598128530..65f4a1daa2e5 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)
platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
}
+static void __init msm8960_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
.fixup = msm8960_fixup,
.reserve = msm8960_reserve,
@@ -101,6 +106,7 @@ MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
.timer = &msm_timer,
.handle_irq = gic_handle_irq,
.init_machine = msm8960_sim_init,
+ .init_late = msm8960_init_late,
MACHINE_END
MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
@@ -111,5 +117,6 @@ MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
.timer = &msm_timer,
.handle_irq = gic_handle_irq,
.init_machine = msm8960_rumi3_init,
+ .init_late = msm8960_init_late,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index fb3496a52ef4..e37a724cd1eb 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)
{
}
+static void __init msm8x60_init_late(void)
+{
+ smd_debugfs_init();
+}
+
#ifdef CONFIG_OF
static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = {
{}
@@ -111,6 +116,7 @@ MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
.init_irq = msm8x60_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = msm8x60_init,
+ .init_late = msm8x60_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -121,6 +127,7 @@ MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
.init_irq = msm8x60_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = msm8x60_init,
+ .init_late = msm8x60_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -131,6 +138,7 @@ MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
.init_irq = msm8x60_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = msm8x60_init,
+ .init_late = msm8x60_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -141,6 +149,7 @@ MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
.init_irq = msm8x60_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = msm8x60_init,
+ .init_late = msm8x60_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -150,6 +159,7 @@ DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
.map_io = msm8x60_map_io,
.init_irq = msm8x60_init_irq,
.init_machine = msm8x60_dt_init,
+ .init_late = msm8x60_init_late,
.timer = &msm_timer,
.dt_compat = msm8x60_fluid_match,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index fbaa4ed95a3c..c8fe0edb9761 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)
qsd8x50_init_mmc();
}
+static void __init qsd8x50_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
.atag_offset = 0x100,
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
+ .init_late = qsd8x50_init_late,
.timer = &msm_timer,
MACHINE_END
@@ -203,5 +209,6 @@ MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
+ .init_late = qsd8x50_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
index 4a8ea0d40b6f..2e569ab10eef 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)
msm_clock_init();
}
+static void __init sapphire_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(SAPPHIRE, "sapphire")
/* Maintainer: Brian Swetland <swetland@google.com> */
.atag_offset = 0x100,
@@ -108,5 +113,6 @@ MACHINE_START(SAPPHIRE, "sapphire")
.map_io = sapphire_map_io,
.init_irq = sapphire_init_irq,
.init_machine = sapphire_init,
+ .init_late = sapphire_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index d4060a37e23d..bbe13f12fa01 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)
msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
}
+static void __init trout_init_late(void)
+{
+ smd_debugfs_init();
+}
+
MACHINE_START(TROUT, "HTC Dream")
.atag_offset = 0x100,
.fixup = trout_fixup,
@@ -105,5 +110,6 @@ MACHINE_START(TROUT, "HTC Dream")
.init_early = trout_init_early,
.init_irq = trout_init_irq,
.init_machine = trout_init,
+ .init_late = trout_init_late,
.timer = &msm_timer,
MACHINE_END
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 2ce8f1f2fc4d..435f8edfafd1 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,
struct msm_mmc_platform_data *plat,
unsigned int stat_irq, unsigned long stat_irq_flags);
+#if defined(CONFIG_MSM_SMD) && defined(CONFIG_DEBUG_FS)
+int smd_debugfs_init(void);
+#else
+static inline int smd_debugfs_init(void) { return 0; }
+#endif
+
#endif
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
index c56df9e932ae..8056b3e5590f 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,
debugfs_create_file(name, mode, dent, fill, &debug_ops);
}
-static int smd_debugfs_init(void)
+int __init smd_debugfs_init(void)
{
struct dentry *dent;
@@ -234,7 +234,6 @@ static int smd_debugfs_init(void)
return 0;
}
-late_initcall(smd_debugfs_init);
#endif
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index a5dcf766a3f9..b4c53b846c9c 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
+#include <linux/clk-provider.h>
#include <linux/ethtool.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
@@ -103,24 +104,24 @@ static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
static int get_tclk(void)
{
- int tclk;
+ int tclk_freq;
/*
* TCLK tick rate is configured by DEV_A[2:0] strap pins.
*/
switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
case 1:
- tclk = 166666667;
+ tclk_freq = 166666667;
break;
case 3:
- tclk = 200000000;
+ tclk_freq = 200000000;
break;
default:
panic("unknown TCLK PLL setting: %.8x\n",
readl(SAMPLE_AT_RESET_HIGH));
}
- return tclk;
+ return tclk_freq;
}
@@ -166,6 +167,19 @@ void __init mv78xx0_map_io(void)
/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static struct clk *tclk;
+
+static void __init clk_init(void)
+{
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ get_tclk());
+
+ orion_clkdev_init(tclk);
+}
+
+/*****************************************************************************
* EHCI
****************************************************************************/
void __init mv78xx0_ehci0_init(void)
@@ -199,7 +213,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge00_init(eth_data,
GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
- IRQ_MV78XX0_GE_ERR, get_tclk());
+ IRQ_MV78XX0_GE_ERR);
}
@@ -210,7 +224,7 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge01_init(eth_data,
GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
- NO_IRQ, get_tclk());
+ NO_IRQ);
}
@@ -234,7 +248,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
orion_ge10_init(eth_data,
GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
- NO_IRQ, get_tclk());
+ NO_IRQ);
}
@@ -258,7 +272,7 @@ void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
orion_ge11_init(eth_data,
GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
- NO_IRQ, get_tclk());
+ NO_IRQ);
}
/*****************************************************************************
@@ -285,7 +299,7 @@ void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
void __init mv78xx0_uart0_init(void)
{
orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
- IRQ_MV78XX0_UART_0, get_tclk());
+ IRQ_MV78XX0_UART_0, tclk);
}
@@ -295,7 +309,7 @@ void __init mv78xx0_uart0_init(void)
void __init mv78xx0_uart1_init(void)
{
orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
- IRQ_MV78XX0_UART_1, get_tclk());
+ IRQ_MV78XX0_UART_1, tclk);
}
@@ -305,7 +319,7 @@ void __init mv78xx0_uart1_init(void)
void __init mv78xx0_uart2_init(void)
{
orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
- IRQ_MV78XX0_UART_2, get_tclk());
+ IRQ_MV78XX0_UART_2, tclk);
}
/*****************************************************************************
@@ -314,7 +328,7 @@ void __init mv78xx0_uart2_init(void)
void __init mv78xx0_uart3_init(void)
{
orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
- IRQ_MV78XX0_UART_3, get_tclk());
+ IRQ_MV78XX0_UART_3, tclk);
}
/*****************************************************************************
@@ -378,25 +392,26 @@ void __init mv78xx0_init(void)
int hclk;
int pclk;
int l2clk;
- int tclk;
core_index = mv78xx0_core_index();
hclk = get_hclk();
get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
- tclk = get_tclk();
printk(KERN_INFO "%s ", mv78xx0_id());
printk("core #%d, ", core_index);
printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
- printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+ printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000);
mv78xx0_setup_cpu_mbus();
#ifdef CONFIG_CACHE_FEROCEON_L2
feroceon_l2_init(is_l2_writethrough());
#endif
+
+ /* Setup root of clk tree */
+ clk_init();
}
void mv78xx0_restart(char mode, const char *cmd)
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 07d5383d68ee..91cf0625819c 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -7,18 +7,28 @@ config MXS_OCOTP
config SOC_IMX23
bool
+ select ARM_AMBA
select CPU_ARM926T
select HAVE_PWM
select PINCTRL_IMX23
config SOC_IMX28
bool
+ select ARM_AMBA
select CPU_ARM926T
select HAVE_PWM
select PINCTRL_IMX28
comment "MXS platforms:"
+config MACH_MXS_DT
+ bool "Support MXS platforms from device tree"
+ select SOC_IMX23
+ select SOC_IMX28
+ help
+ Include support for Freescale MXS platforms(i.MX23 and i.MX28)
+ using the device tree for discovery
+
config MACH_STMP378X_DEVB
bool "Support STMP378x_devb Platform"
select SOC_IMX23
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 908bf9a567f1..e41590ccb437 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,12 +1,10 @@
# Common support
-obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o mm.o
+obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o
obj-$(CONFIG_MXS_OCOTP) += ocotp.o
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_SOC_IMX23) += clock-mx23.o
-obj-$(CONFIG_SOC_IMX28) += clock-mx28.o
-
+obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
obj-$(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 e3ac52c34019..000000000000
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/clkdev.h>
-
-#include <asm/clkdev.h>
-#include <asm/div64.h>
-
-#include <mach/mx23.h>
-#include <mach/common.h>
-#include <mach/clock.h>
-
-#include "regs-clkctrl-mx23.h"
-
-#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
-#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
-
-#define PARENT_RATE_SHIFT 8
-
-static int _raw_clk_enable(struct clk *clk)
-{
- u32 reg;
-
- if (clk->enable_reg) {
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
- }
-
- return 0;
-}
-
-static void _raw_clk_disable(struct clk *clk)
-{
- u32 reg;
-
- if (clk->enable_reg) {
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
- }
-}
-
-/*
- * ref_xtal_clk
- */
-static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
-{
- return 24000000;
-}
-
-static struct clk ref_xtal_clk = {
- .get_rate = ref_xtal_clk_get_rate,
-};
-
-/*
- * pll_clk
- */
-static unsigned long pll_clk_get_rate(struct clk *clk)
-{
- return 480000000;
-}
-
-static int pll_clk_enable(struct clk *clk)
-{
- __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
- BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
-
- /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
- * and is incorrect (excessive). Per definition of the PLLCTRL0
- * POWER field, waiting at least 10us.
- */
- udelay(10);
-
- return 0;
-}
-
-static void pll_clk_disable(struct clk *clk)
-{
- __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
- BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
-}
-
-static struct clk pll_clk = {
- .get_rate = pll_clk_get_rate,
- .enable = pll_clk_enable,
- .disable = pll_clk_disable,
- .parent = &ref_xtal_clk,
-};
-
-/*
- * ref_clk
- */
-#define _CLK_GET_RATE_REF(name, sr, ss) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- unsigned long parent_rate; \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
- div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
- parent_rate = clk_get_rate(clk->parent); \
- \
- return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
- div, PARENT_RATE_SHIFT); \
-}
-
-_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
-_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
-_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
-_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
-
-#define _DEFINE_CLOCK_REF(name, er, es) \
- static struct clk name = { \
- .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
- .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
- .get_rate = name##_get_rate, \
- .enable = _raw_clk_enable, \
- .disable = _raw_clk_disable, \
- .parent = &pll_clk, \
- }
-
-_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
-_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
-_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
-_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
-
-/*
- * General clocks
- *
- * clk_get_rate
- */
-static unsigned long rtc_clk_get_rate(struct clk *clk)
-{
- /* ref_xtal_clk is implemented as the only parent */
- return clk_get_rate(clk->parent) / 768;
-}
-
-static unsigned long clk32k_clk_get_rate(struct clk *clk)
-{
- return clk->parent->get_rate(clk->parent) / 750;
-}
-
-#define _CLK_GET_RATE(name, rs) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- \
- if (clk->parent == &ref_xtal_clk) \
- div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
- BP_CLKCTRL_##rs##_DIV_XTAL; \
- else \
- div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
- BP_CLKCTRL_##rs##_DIV_##rs; \
- \
- if (!div) \
- return -EINVAL; \
- \
- return clk_get_rate(clk->parent) / div; \
-}
-
-_CLK_GET_RATE(cpu_clk, CPU)
-_CLK_GET_RATE(emi_clk, EMI)
-
-#define _CLK_GET_RATE1(name, rs) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
- \
- if (!div) \
- return -EINVAL; \
- \
- return clk_get_rate(clk->parent) / div; \
-}
-
-_CLK_GET_RATE1(hbus_clk, HBUS)
-_CLK_GET_RATE1(xbus_clk, XBUS)
-_CLK_GET_RATE1(ssp_clk, SSP)
-_CLK_GET_RATE1(gpmi_clk, GPMI)
-_CLK_GET_RATE1(lcdif_clk, PIX)
-
-#define _CLK_GET_RATE_STUB(name) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- return clk_get_rate(clk->parent); \
-}
-
-_CLK_GET_RATE_STUB(uart_clk)
-_CLK_GET_RATE_STUB(audio_clk)
-_CLK_GET_RATE_STUB(pwm_clk)
-
-/*
- * clk_set_rate
- */
-static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, bm_busy, div_max, d, f, div, frac;
- unsigned long diff, parent_rate, calc_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- if (clk->parent == &ref_xtal_clk) {
- div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
- bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
- div = DIV_ROUND_UP(parent_rate, rate);
- if (div == 0 || div > div_max)
- return -EINVAL;
- } else {
- div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
- bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
- rate >>= PARENT_RATE_SHIFT;
- parent_rate >>= PARENT_RATE_SHIFT;
- diff = parent_rate;
- div = frac = 1;
- for (d = 1; d <= div_max; d++) {
- f = parent_rate * 18 / d / rate;
- if ((parent_rate * 18 / d) % rate)
- f++;
- if (f < 18 || f > 35)
- continue;
-
- calc_rate = parent_rate * 18 / f / d;
- if (calc_rate > rate)
- continue;
-
- if (rate - calc_rate < diff) {
- frac = f;
- div = d;
- diff = rate - calc_rate;
- }
-
- if (diff == 0)
- break;
- }
-
- if (diff == parent_rate)
- return -EINVAL;
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
- reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
- reg |= frac;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
- }
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
- reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
- reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
-
- mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
-
- return 0;
-}
-
-#define _CLK_SET_RATE(name, dr) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- u32 reg, div_max, div; \
- unsigned long parent_rate; \
- \
- parent_rate = clk_get_rate(clk->parent); \
- div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
- \
- div = DIV_ROUND_UP(parent_rate, rate); \
- if (div == 0 || div > div_max) \
- return -EINVAL; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- reg &= ~BM_CLKCTRL_##dr##_DIV; \
- reg |= div << BP_CLKCTRL_##dr##_DIV; \
- if (reg & (1 << clk->enable_shift)) { \
- pr_err("%s: clock is gated\n", __func__); \
- return -EINVAL; \
- } \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- \
- mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
- return 0; \
-}
-
-_CLK_SET_RATE(xbus_clk, XBUS)
-_CLK_SET_RATE(ssp_clk, SSP)
-_CLK_SET_RATE(gpmi_clk, GPMI)
-_CLK_SET_RATE(lcdif_clk, PIX)
-
-#define _CLK_SET_RATE_STUB(name) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- return -EINVAL; \
-}
-
-_CLK_SET_RATE_STUB(emi_clk)
-_CLK_SET_RATE_STUB(uart_clk)
-_CLK_SET_RATE_STUB(audio_clk)
-_CLK_SET_RATE_STUB(pwm_clk)
-_CLK_SET_RATE_STUB(clk32k_clk)
-
-/*
- * clk_set_parent
- */
-#define _CLK_SET_PARENT(name, bit) \
-static int name##_set_parent(struct clk *clk, struct clk *parent) \
-{ \
- if (parent != clk->parent) { \
- __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
- clk->parent = parent; \
- } \
- \
- return 0; \
-}
-
-_CLK_SET_PARENT(cpu_clk, CPU)
-_CLK_SET_PARENT(emi_clk, EMI)
-_CLK_SET_PARENT(ssp_clk, SSP)
-_CLK_SET_PARENT(gpmi_clk, GPMI)
-_CLK_SET_PARENT(lcdif_clk, PIX)
-
-#define _CLK_SET_PARENT_STUB(name) \
-static int name##_set_parent(struct clk *clk, struct clk *parent) \
-{ \
- if (parent != clk->parent) \
- return -EINVAL; \
- else \
- return 0; \
-}
-
-_CLK_SET_PARENT_STUB(uart_clk)
-_CLK_SET_PARENT_STUB(audio_clk)
-_CLK_SET_PARENT_STUB(pwm_clk)
-_CLK_SET_PARENT_STUB(clk32k_clk)
-
-/*
- * clk definition
- */
-static struct clk cpu_clk = {
- .get_rate = cpu_clk_get_rate,
- .set_rate = cpu_clk_set_rate,
- .set_parent = cpu_clk_set_parent,
- .parent = &ref_cpu_clk,
-};
-
-static struct clk hbus_clk = {
- .get_rate = hbus_clk_get_rate,
- .parent = &cpu_clk,
-};
-
-static struct clk xbus_clk = {
- .get_rate = xbus_clk_get_rate,
- .set_rate = xbus_clk_set_rate,
- .parent = &ref_xtal_clk,
-};
-
-static struct clk rtc_clk = {
- .get_rate = rtc_clk_get_rate,
- .parent = &ref_xtal_clk,
-};
-
-/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
-static struct clk usb_clk = {
- .enable_reg = DIGCTRL_BASE_ADDR,
- .enable_shift = 2,
- .enable = _raw_clk_enable,
- .disable = _raw_clk_disable,
- .parent = &pll_clk,
-};
-
-#define _DEFINE_CLOCK(name, er, es, p) \
- static struct clk name = { \
- .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
- .enable_shift = BP_CLKCTRL_##er##_##es, \
- .get_rate = name##_get_rate, \
- .set_rate = name##_set_rate, \
- .set_parent = name##_set_parent, \
- .enable = _raw_clk_enable, \
- .disable = _raw_clk_disable, \
- .parent = p, \
- }
-
-_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- /* for amba bus driver */
- _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
- /* for amba-pl011 driver */
- _REGISTER_CLOCK("duart", NULL, uart_clk)
- _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
- _REGISTER_CLOCK("rtc", NULL, rtc_clk)
- _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
- _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
- _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
- _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
- _REGISTER_CLOCK(NULL, "usb", usb_clk)
- _REGISTER_CLOCK(NULL, "audio", audio_clk)
- _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
- _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
- _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
-};
-
-static int clk_misc_init(void)
-{
- u32 reg;
- int ret;
-
- /* Fix up parent per register setting */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
- cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
- &ref_xtal_clk : &ref_cpu_clk;
- emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
- &ref_xtal_clk : &ref_emi_clk;
- ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
- &ref_xtal_clk : &ref_io_clk;
- gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
- &ref_xtal_clk : &ref_io_clk;
- lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
- &ref_xtal_clk : &ref_pix_clk;
-
- /* Use int div over frac when both are available */
- __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
- __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
- __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
- reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
- reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
- reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
- reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
-
- /*
- * Set safe hbus clock divider. A divider of 3 ensure that
- * the Vddd voltage required for the cpu clock is sufficiently
- * high for the hbus clock.
- */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
- reg &= BM_CLKCTRL_HBUS_DIV;
- reg |= 3 << BP_CLKCTRL_HBUS_DIV;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
-
- ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
-
- /* Gate off cpu clock in WFI for power saving */
- __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
-
- /*
- * 480 MHz seems too high to be ssp clock source directly,
- * so set frac to get a 288 MHz ref_io.
- */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
- reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
- reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
-
- return ret;
-}
-
-int __init mx23_clocks_init(void)
-{
- clk_misc_init();
-
- /*
- * source ssp clock from ref_io than ref_xtal,
- * as ref_xtal only provides 24 MHz as maximum.
- */
- clk_set_parent(&ssp_clk, &ref_io_clk);
-
- clk_prepare_enable(&cpu_clk);
- clk_prepare_enable(&hbus_clk);
- clk_prepare_enable(&xbus_clk);
- clk_prepare_enable(&emi_clk);
- clk_prepare_enable(&uart_clk);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
-
- return 0;
-}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
deleted file mode 100644
index cea29c99e214..000000000000
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ /dev/null
@@ -1,803 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/jiffies.h>
-#include <linux/clkdev.h>
-#include <linux/spinlock.h>
-
-#include <asm/clkdev.h>
-#include <asm/div64.h>
-
-#include <mach/mx28.h>
-#include <mach/common.h>
-#include <mach/clock.h>
-#include <mach/digctl.h>
-
-#include "regs-clkctrl-mx28.h"
-
-#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
-#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
-
-#define PARENT_RATE_SHIFT 8
-
-static struct clk pll2_clk;
-static struct clk cpu_clk;
-static struct clk emi_clk;
-static struct clk saif0_clk;
-static struct clk saif1_clk;
-static struct clk clk32k_clk;
-static DEFINE_SPINLOCK(clkmux_lock);
-
-/*
- * HW_SAIF_CLKMUX_SEL:
- * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
- * clock pins selected for SAIF1 input clocks.
- * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
- * SAIF0 clock inputs selected for SAIF1 input clocks.
- * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
- * clocks.
- * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
- * clocks.
- */
-int mxs_saif_clkmux_select(unsigned int clkmux)
-{
- if (clkmux > 0x3)
- return -EINVAL;
-
- spin_lock(&clkmux_lock);
- __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
- DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
- __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
- DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
- spin_unlock(&clkmux_lock);
-
- return 0;
-}
-
-static int _raw_clk_enable(struct clk *clk)
-{
- u32 reg;
-
- if (clk->enable_reg) {
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
- }
-
- return 0;
-}
-
-static void _raw_clk_disable(struct clk *clk)
-{
- u32 reg;
-
- if (clk->enable_reg) {
- reg = __raw_readl(clk->enable_reg);
- reg |= 1 << clk->enable_shift;
- __raw_writel(reg, clk->enable_reg);
- }
-}
-
-/*
- * ref_xtal_clk
- */
-static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
-{
- return 24000000;
-}
-
-static struct clk ref_xtal_clk = {
- .get_rate = ref_xtal_clk_get_rate,
-};
-
-/*
- * pll_clk
- */
-static unsigned long pll0_clk_get_rate(struct clk *clk)
-{
- return 480000000;
-}
-
-static unsigned long pll1_clk_get_rate(struct clk *clk)
-{
- return 480000000;
-}
-
-static unsigned long pll2_clk_get_rate(struct clk *clk)
-{
- return 50000000;
-}
-
-#define _CLK_ENABLE_PLL(name, r, g) \
-static int name##_enable(struct clk *clk) \
-{ \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
- udelay(10); \
- \
- if (clk == &pll2_clk) \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
- else \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
- \
- return 0; \
-}
-
-_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
-_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
-_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
-
-#define _CLK_DISABLE_PLL(name, r, g) \
-static void name##_disable(struct clk *clk) \
-{ \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
- \
- if (clk == &pll2_clk) \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
- else \
- __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
- \
-}
-
-_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
-_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
-_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
-
-#define _DEFINE_CLOCK_PLL(name) \
- static struct clk name = { \
- .get_rate = name##_get_rate, \
- .enable = name##_enable, \
- .disable = name##_disable, \
- .parent = &ref_xtal_clk, \
- }
-
-_DEFINE_CLOCK_PLL(pll0_clk);
-_DEFINE_CLOCK_PLL(pll1_clk);
-_DEFINE_CLOCK_PLL(pll2_clk);
-
-/*
- * ref_clk
- */
-#define _CLK_GET_RATE_REF(name, sr, ss) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- unsigned long parent_rate; \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
- div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
- parent_rate = clk_get_rate(clk->parent); \
- \
- return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
- div, PARENT_RATE_SHIFT); \
-}
-
-_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
-_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
-_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
-_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
-_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
-_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
-
-#define _DEFINE_CLOCK_REF(name, er, es) \
- static struct clk name = { \
- .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
- .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
- .get_rate = name##_get_rate, \
- .enable = _raw_clk_enable, \
- .disable = _raw_clk_disable, \
- .parent = &pll0_clk, \
- }
-
-_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
-_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
-_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
-_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
-_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
-_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
-
-/*
- * General clocks
- *
- * clk_get_rate
- */
-static unsigned long lradc_clk_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 16;
-}
-
-static unsigned long rtc_clk_get_rate(struct clk *clk)
-{
- /* ref_xtal_clk is implemented as the only parent */
- return clk_get_rate(clk->parent) / 768;
-}
-
-static unsigned long clk32k_clk_get_rate(struct clk *clk)
-{
- return clk->parent->get_rate(clk->parent) / 750;
-}
-
-static unsigned long spdif_clk_get_rate(struct clk *clk)
-{
- return clk_get_rate(clk->parent) / 4;
-}
-
-#define _CLK_GET_RATE(name, rs) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- \
- if (clk->parent == &ref_xtal_clk) \
- div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
- BP_CLKCTRL_##rs##_DIV_XTAL; \
- else \
- div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
- BP_CLKCTRL_##rs##_DIV_##rs; \
- \
- if (!div) \
- return -EINVAL; \
- \
- return clk_get_rate(clk->parent) / div; \
-}
-
-_CLK_GET_RATE(cpu_clk, CPU)
-_CLK_GET_RATE(emi_clk, EMI)
-
-#define _CLK_GET_RATE1(name, rs) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- u32 reg, div; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
- \
- if (!div) \
- return -EINVAL; \
- \
- if (clk == &saif0_clk || clk == &saif1_clk) \
- return clk_get_rate(clk->parent) >> 16 * div; \
- else \
- return clk_get_rate(clk->parent) / div; \
-}
-
-_CLK_GET_RATE1(hbus_clk, HBUS)
-_CLK_GET_RATE1(xbus_clk, XBUS)
-_CLK_GET_RATE1(ssp0_clk, SSP0)
-_CLK_GET_RATE1(ssp1_clk, SSP1)
-_CLK_GET_RATE1(ssp2_clk, SSP2)
-_CLK_GET_RATE1(ssp3_clk, SSP3)
-_CLK_GET_RATE1(gpmi_clk, GPMI)
-_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
-_CLK_GET_RATE1(saif0_clk, SAIF0)
-_CLK_GET_RATE1(saif1_clk, SAIF1)
-
-#define _CLK_GET_RATE_STUB(name) \
-static unsigned long name##_get_rate(struct clk *clk) \
-{ \
- return clk_get_rate(clk->parent); \
-}
-
-_CLK_GET_RATE_STUB(uart_clk)
-_CLK_GET_RATE_STUB(pwm_clk)
-_CLK_GET_RATE_STUB(can0_clk)
-_CLK_GET_RATE_STUB(can1_clk)
-_CLK_GET_RATE_STUB(fec_clk)
-
-/*
- * clk_set_rate
- */
-/* fool compiler */
-#define BM_CLKCTRL_CPU_DIV 0
-#define BP_CLKCTRL_CPU_DIV 0
-#define BM_CLKCTRL_CPU_BUSY 0
-
-#define _CLK_SET_RATE(name, dr, fr, fs) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- u32 reg, bm_busy, div_max, d, f, div, frac; \
- unsigned long diff, parent_rate, calc_rate; \
- \
- div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
- bm_busy = BM_CLKCTRL_##dr##_BUSY; \
- \
- if (clk->parent == &ref_xtal_clk) { \
- parent_rate = clk_get_rate(clk->parent); \
- div = DIV_ROUND_UP(parent_rate, rate); \
- if (clk == &cpu_clk) { \
- div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
- BP_CLKCTRL_CPU_DIV_XTAL; \
- bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
- } \
- if (div == 0 || div > div_max) \
- return -EINVAL; \
- } else { \
- /* \
- * hack alert: this block modifies clk->parent, too, \
- * so the base to use it the grand parent. \
- */ \
- parent_rate = clk_get_rate(clk->parent->parent); \
- rate >>= PARENT_RATE_SHIFT; \
- parent_rate >>= PARENT_RATE_SHIFT; \
- diff = parent_rate; \
- div = frac = 1; \
- if (clk == &cpu_clk) { \
- div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
- BP_CLKCTRL_CPU_DIV_CPU; \
- bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
- } \
- for (d = 1; d <= div_max; d++) { \
- f = parent_rate * 18 / d / rate; \
- if ((parent_rate * 18 / d) % rate) \
- f++; \
- if (f < 18 || f > 35) \
- continue; \
- \
- calc_rate = parent_rate * 18 / f / d; \
- if (calc_rate > rate) \
- continue; \
- \
- if (rate - calc_rate < diff) { \
- frac = f; \
- div = d; \
- diff = rate - calc_rate; \
- } \
- \
- if (diff == 0) \
- break; \
- } \
- \
- if (diff == parent_rate) \
- return -EINVAL; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
- reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
- reg |= frac << BP_CLKCTRL_##fr##_##fs##FRAC; \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
- } \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- if (clk == &cpu_clk) { \
- reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
- reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
- } else { \
- reg &= ~BM_CLKCTRL_##dr##_DIV; \
- reg |= div << BP_CLKCTRL_##dr##_DIV; \
- if (reg & (1 << clk->enable_shift)) { \
- pr_err("%s: clock is gated\n", __func__); \
- return -EINVAL; \
- } \
- } \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- \
- return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
-}
-
-_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
-_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
-_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
-_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
-_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
-_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
-_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
-
-#define _CLK_SET_RATE1(name, dr) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- u32 reg, div_max, div; \
- unsigned long parent_rate; \
- \
- parent_rate = clk_get_rate(clk->parent); \
- div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
- \
- div = DIV_ROUND_UP(parent_rate, rate); \
- if (div == 0 || div > div_max) \
- return -EINVAL; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- reg &= ~BM_CLKCTRL_##dr##_DIV; \
- reg |= div << BP_CLKCTRL_##dr##_DIV; \
- if (reg & (1 << clk->enable_shift)) { \
- pr_err("%s: clock is gated\n", __func__); \
- return -EINVAL; \
- } \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
- \
- return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
-}
-
-_CLK_SET_RATE1(xbus_clk, XBUS)
-
-/* saif clock uses 16 bits frac div */
-#define _CLK_SET_RATE_SAIF(name, rs) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- u16 div; \
- u32 reg; \
- u64 lrate; \
- unsigned long parent_rate; \
- \
- parent_rate = clk_get_rate(clk->parent); \
- if (rate > parent_rate) \
- return -EINVAL; \
- \
- lrate = (u64)rate << 16; \
- do_div(lrate, parent_rate); \
- div = (u16)lrate; \
- \
- if (!div) \
- return -EINVAL; \
- \
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- reg &= ~BM_CLKCTRL_##rs##_DIV; \
- reg |= div << BP_CLKCTRL_##rs##_DIV; \
- if (reg & (1 << clk->enable_shift)) { \
- pr_err("%s: clock is gated\n", __func__); \
- return -EINVAL; \
- } \
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
- \
- return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
-}
-
-_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
-_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
-
-#define _CLK_SET_RATE_STUB(name) \
-static int name##_set_rate(struct clk *clk, unsigned long rate) \
-{ \
- return -EINVAL; \
-}
-
-_CLK_SET_RATE_STUB(emi_clk)
-_CLK_SET_RATE_STUB(uart_clk)
-_CLK_SET_RATE_STUB(pwm_clk)
-_CLK_SET_RATE_STUB(spdif_clk)
-_CLK_SET_RATE_STUB(clk32k_clk)
-_CLK_SET_RATE_STUB(can0_clk)
-_CLK_SET_RATE_STUB(can1_clk)
-_CLK_SET_RATE_STUB(fec_clk)
-
-/*
- * clk_set_parent
- */
-#define _CLK_SET_PARENT(name, bit) \
-static int name##_set_parent(struct clk *clk, struct clk *parent) \
-{ \
- if (parent != clk->parent) { \
- __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
- clk->parent = parent; \
- } \
- \
- return 0; \
-}
-
-_CLK_SET_PARENT(cpu_clk, CPU)
-_CLK_SET_PARENT(emi_clk, EMI)
-_CLK_SET_PARENT(ssp0_clk, SSP0)
-_CLK_SET_PARENT(ssp1_clk, SSP1)
-_CLK_SET_PARENT(ssp2_clk, SSP2)
-_CLK_SET_PARENT(ssp3_clk, SSP3)
-_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
-_CLK_SET_PARENT(gpmi_clk, GPMI)
-_CLK_SET_PARENT(saif0_clk, SAIF0)
-_CLK_SET_PARENT(saif1_clk, SAIF1)
-
-#define _CLK_SET_PARENT_STUB(name) \
-static int name##_set_parent(struct clk *clk, struct clk *parent) \
-{ \
- if (parent != clk->parent) \
- return -EINVAL; \
- else \
- return 0; \
-}
-
-_CLK_SET_PARENT_STUB(pwm_clk)
-_CLK_SET_PARENT_STUB(uart_clk)
-_CLK_SET_PARENT_STUB(clk32k_clk)
-_CLK_SET_PARENT_STUB(spdif_clk)
-_CLK_SET_PARENT_STUB(fec_clk)
-_CLK_SET_PARENT_STUB(can0_clk)
-_CLK_SET_PARENT_STUB(can1_clk)
-
-/*
- * clk definition
- */
-static struct clk cpu_clk = {
- .get_rate = cpu_clk_get_rate,
- .set_rate = cpu_clk_set_rate,
- .set_parent = cpu_clk_set_parent,
- .parent = &ref_cpu_clk,
-};
-
-static struct clk hbus_clk = {
- .get_rate = hbus_clk_get_rate,
- .parent = &cpu_clk,
-};
-
-static struct clk xbus_clk = {
- .get_rate = xbus_clk_get_rate,
- .set_rate = xbus_clk_set_rate,
- .parent = &ref_xtal_clk,
-};
-
-static struct clk lradc_clk = {
- .get_rate = lradc_clk_get_rate,
- .parent = &clk32k_clk,
-};
-
-static struct clk rtc_clk = {
- .get_rate = rtc_clk_get_rate,
- .parent = &ref_xtal_clk,
-};
-
-/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
-static struct clk usb0_clk = {
- .enable_reg = DIGCTRL_BASE_ADDR,
- .enable_shift = 2,
- .enable = _raw_clk_enable,
- .disable = _raw_clk_disable,
- .parent = &pll0_clk,
-};
-
-static struct clk usb1_clk = {
- .enable_reg = DIGCTRL_BASE_ADDR,
- .enable_shift = 16,
- .enable = _raw_clk_enable,
- .disable = _raw_clk_disable,
- .parent = &pll1_clk,
-};
-
-#define _DEFINE_CLOCK(name, er, es, p) \
- static struct clk name = { \
- .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
- .enable_shift = BP_CLKCTRL_##er##_##es, \
- .get_rate = name##_get_rate, \
- .set_rate = name##_set_rate, \
- .set_parent = name##_set_parent, \
- .enable = _raw_clk_enable, \
- .disable = _raw_clk_disable, \
- .parent = p, \
- }
-
-_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
-_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
-_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
-_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
-_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
-_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
-
-#define _REGISTER_CLOCK(d, n, c) \
- { \
- .dev_id = d, \
- .con_id = n, \
- .clk = &c, \
- },
-
-static struct clk_lookup lookups[] = {
- /* for amba bus driver */
- _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
- /* for amba-pl011 driver */
- _REGISTER_CLOCK("duart", NULL, uart_clk)
- _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
- _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
- _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
- _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
- _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
- _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
- _REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
- _REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
- _REGISTER_CLOCK("rtc", NULL, rtc_clk)
- _REGISTER_CLOCK("pll2", NULL, pll2_clk)
- _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
- _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
- _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
- _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
- _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
- _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
- _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
- _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
- _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
- _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
- _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.5", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.6", NULL, pwm_clk)
- _REGISTER_CLOCK("mxs-pwm.7", NULL, pwm_clk)
- _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
- _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
- _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
- _REGISTER_CLOCK("mxs-saif.0", NULL, saif0_clk)
- _REGISTER_CLOCK("mxs-saif.1", NULL, saif1_clk)
-};
-
-static int clk_misc_init(void)
-{
- u32 reg;
- int ret;
-
- /* Fix up parent per register setting */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
- cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
- &ref_xtal_clk : &ref_cpu_clk;
- emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
- &ref_xtal_clk : &ref_emi_clk;
- ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
- &ref_xtal_clk : &ref_io0_clk;
- ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
- &ref_xtal_clk : &ref_io0_clk;
- ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
- &ref_xtal_clk : &ref_io1_clk;
- ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
- &ref_xtal_clk : &ref_io1_clk;
- lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
- &ref_xtal_clk : &ref_pix_clk;
- gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
- &ref_xtal_clk : &ref_gpmi_clk;
- saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
- &ref_xtal_clk : &pll0_clk;
- saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
- &ref_xtal_clk : &pll0_clk;
-
- /* Use int div over frac when both are available */
- __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
- __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
- __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
- reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
- reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
- reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
- reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
- reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
- reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
- reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
-
- /* SAIF has to use frac div for functional operation */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
- reg |= BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
-
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
- reg |= BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
-
- /*
- * Set safe hbus clock divider. A divider of 3 ensure that
- * the Vddd voltage required for the cpu clock is sufficiently
- * high for the hbus clock.
- */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
- reg &= BM_CLKCTRL_HBUS_DIV;
- reg |= 3 << BP_CLKCTRL_HBUS_DIV;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
-
- ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
-
- /* Gate off cpu clock in WFI for power saving */
- __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
- CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
-
- /*
- * Extra fec clock setting
- * The DENX M28 uses an external clock source
- * and the clock output must not be enabled
- */
- if (!machine_is_m28evk()) {
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
- reg &= ~BM_CLKCTRL_ENET_SLEEP;
- reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
- }
-
- /*
- * 480 MHz seems too high to be ssp clock source directly,
- * so set frac0 to get a 288 MHz ref_io0.
- */
- reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
- reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
- reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
- __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
-
- return ret;
-}
-
-int __init mx28_clocks_init(void)
-{
- clk_misc_init();
-
- /*
- * source ssp clock from ref_io0 than ref_xtal,
- * as ref_xtal only provides 24 MHz as maximum.
- */
- clk_set_parent(&ssp0_clk, &ref_io0_clk);
- clk_set_parent(&ssp1_clk, &ref_io0_clk);
- clk_set_parent(&ssp2_clk, &ref_io1_clk);
- clk_set_parent(&ssp3_clk, &ref_io1_clk);
-
- clk_prepare_enable(&cpu_clk);
- clk_prepare_enable(&hbus_clk);
- clk_prepare_enable(&xbus_clk);
- clk_prepare_enable(&emi_clk);
- clk_prepare_enable(&uart_clk);
-
- clk_set_parent(&lcdif_clk, &ref_pix_clk);
- clk_set_parent(&saif0_clk, &pll0_clk);
- clk_set_parent(&saif1_clk, &pll0_clk);
-
- /*
- * Set an initial clock rate for the saif internal logic to work
- * properly. This is important when working in EXTMASTER mode that
- * uses the other saif's BITCLK&LRCLK but it still needs a basic
- * clock which should be fast enough for the internal logic.
- */
- clk_set_rate(&saif0_clk, 24000000);
- clk_set_rate(&saif1_clk, 24000000);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
-
- return 0;
-}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
deleted file mode 100644
index 97a6f4acc6cc..000000000000
--- a/arch/arm/mach-mxs/clock.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Based on arch/arm/plat-omap/clock.c
- *
- * Copyright (C) 2004 - 2005 Nokia corporation
- * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
- * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-/* #define DEBUG */
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/proc_fs.h>
-#include <linux/semaphore.h>
-#include <linux/string.h>
-
-#include <mach/clock.h>
-
-static LIST_HEAD(clocks);
-static DEFINE_MUTEX(clocks_mutex);
-
-/*-------------------------------------------------------------------------
- * Standard clock functions defined in include/linux/clk.h
- *-------------------------------------------------------------------------*/
-
-static void __clk_disable(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return;
- WARN_ON(!clk->usecount);
-
- if (!(--clk->usecount)) {
- if (clk->disable)
- clk->disable(clk);
- __clk_disable(clk->parent);
- }
-}
-
-static int __clk_enable(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- if (clk->usecount++ == 0) {
- __clk_enable(clk->parent);
-
- if (clk->enable)
- clk->enable(clk);
- }
- return 0;
-}
-
-/*
- * The clk_enable/clk_disable could be called by drivers in atomic context,
- * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
- * can hold a mutex, as the pair will only be called in non-atomic context.
- * Before migrating to common clk framework, we can have __clk_enable and
- * __clk_disable called in clk_prepare/clk_unprepare with mutex held and
- * leave clk_enable/clk_disable as the dummy functions.
- */
-int clk_prepare(struct clk *clk)
-{
- int ret = 0;
-
- if (clk == NULL || IS_ERR(clk))
- return -EINVAL;
-
- mutex_lock(&clocks_mutex);
- ret = __clk_enable(clk);
- mutex_unlock(&clocks_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_prepare);
-
-void clk_unprepare(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return;
-
- mutex_lock(&clocks_mutex);
- __clk_disable(clk);
- mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unprepare);
-
-int clk_enable(struct clk *clk)
-{
- return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
- /* nothing to do */
-}
-EXPORT_SYMBOL(clk_disable);
-
-/* Retrieve the *current* clock rate. If the clock itself
- * does not provide a special calculation routine, ask
- * its parent and so on, until one is able to return
- * a valid clock rate
- */
-unsigned long clk_get_rate(struct clk *clk)
-{
- if (clk == NULL || IS_ERR(clk))
- return 0UL;
-
- if (clk->get_rate)
- return clk->get_rate(clk);
-
- return clk_get_rate(clk->parent);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/* Round the requested clock rate to the nearest supported
- * rate that is less than or equal to the requested rate.
- * This is dependent on the clock's current parent.
- */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
- if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
- return 0;
-
- return clk->round_rate(clk, rate);
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/* Set the clock to the requested clock rate. The rate must
- * match a supported rate exactly based on what clk_round_rate returns
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- int ret = -EINVAL;
-
- if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
- return ret;
-
- mutex_lock(&clocks_mutex);
- ret = clk->set_rate(clk, rate);
- mutex_unlock(&clocks_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/* Set the clock's parent to another clock source */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- int ret = -EINVAL;
- struct clk *old;
-
- if (clk == NULL || IS_ERR(clk) || parent == NULL ||
- IS_ERR(parent) || clk->set_parent == NULL)
- return ret;
-
- if (clk->usecount)
- clk_prepare_enable(parent);
-
- mutex_lock(&clocks_mutex);
- ret = clk->set_parent(clk, parent);
- if (ret == 0) {
- old = clk->parent;
- clk->parent = parent;
- } else {
- old = parent;
- }
- mutex_unlock(&clocks_mutex);
-
- if (clk->usecount)
- clk_disable(old);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-/* Retrieve the clock's parent clock source */
-struct clk *clk_get_parent(struct clk *clk)
-{
- struct clk *ret = NULL;
-
- if (clk == NULL || IS_ERR(clk))
- return ret;
-
- return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index b8913df4cfa2..19659de1c4e8 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -1,6 +1,5 @@
config MXS_HAVE_AMBA_DUART
bool
- select ARM_AMBA
config MXS_HAVE_PLATFORM_AUART
bool
diff --git a/arch/arm/mach-mxs/devices/platform-dma.c b/arch/arm/mach-mxs/devices/platform-dma.c
index 6a0202b1016c..46824501de00 100644
--- a/arch/arm/mach-mxs/devices/platform-dma.c
+++ b/arch/arm/mach-mxs/devices/platform-dma.c
@@ -14,7 +14,7 @@
#include <mach/mx28.h>
#include <mach/devices-common.h>
-static struct platform_device *__init mxs_add_dma(const char *devid,
+struct platform_device *__init mxs_add_dma(const char *devid,
resource_size_t base)
{
struct resource res[] = {
@@ -29,22 +29,3 @@ static struct platform_device *__init mxs_add_dma(const char *devid,
res, ARRAY_SIZE(res), NULL, 0,
DMA_BIT_MASK(32));
}
-
-static int __init mxs_add_mxs_dma(void)
-{
- char *apbh = "mxs-dma-apbh";
- char *apbx = "mxs-dma-apbx";
-
- if (cpu_is_mx23()) {
- mxs_add_dma(apbh, MX23_APBH_DMA_BASE_ADDR);
- mxs_add_dma(apbx, MX23_APBX_DMA_BASE_ADDR);
- }
-
- if (cpu_is_mx28()) {
- mxs_add_dma(apbh, MX28_APBH_DMA_BASE_ADDR);
- mxs_add_dma(apbx, MX28_APBX_DMA_BASE_ADDR);
- }
-
- return 0;
-}
-arch_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 ed0885e414e0..cd99f19ec637 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 @@
#include <mach/devices-common.h>
struct platform_device *__init mxs_add_gpio(
- int id, resource_size_t iobase, int irq)
+ char *name, int id, resource_size_t iobase, int irq)
{
struct resource res[] = {
{
@@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio(
};
return platform_device_register_resndata(&mxs_apbh_bus,
- "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0);
+ name, id, res, ARRAY_SIZE(res), NULL, 0);
}
-
-static int __init mxs_add_mxs_gpio(void)
-{
- if (cpu_is_mx23()) {
- mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
- mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
- mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
- }
-
- if (cpu_is_mx28()) {
- mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
- mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
- mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
- mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
- mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
- }
-
- return 0;
-}
-postcore_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 bef9d923f54e..b33c9d05c552 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 @@
#include <mach/mx28.h>
#include <mach/devices-common.h>
-#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \
+#define mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid) \
{ \
+ .devid = _devid, \
.id = _id, \
.iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
.dma = soc ## _DMA_SSP ## hwid, \
@@ -26,23 +27,23 @@
.irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
}
-#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \
- [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
+#define mxs_mxs_mmc_data_entry(soc, _devid, _id, hwid) \
+ [_id] = mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid)
#ifdef CONFIG_SOC_IMX23
const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
- mxs_mxs_mmc_data_entry(MX23, 0, 1),
- mxs_mxs_mmc_data_entry(MX23, 1, 2),
+ mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 0, 1),
+ mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 1, 2),
};
#endif
#ifdef CONFIG_SOC_IMX28
const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
- mxs_mxs_mmc_data_entry(MX28, 0, 0),
- mxs_mxs_mmc_data_entry(MX28, 1, 1),
- mxs_mxs_mmc_data_entry(MX28, 2, 2),
- mxs_mxs_mmc_data_entry(MX28, 3, 3),
+ mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 0, 0),
+ mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 1, 1),
+ mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 2, 2),
+ mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 3, 3),
};
#endif
@@ -70,6 +71,6 @@ struct platform_device *__init mxs_add_mxs_mmc(
},
};
- return mxs_add_platform_device("mxs-mmc", data->id,
+ return mxs_add_platform_device(data->devid, data->id,
res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
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 592c9ab5d760..000000000000
--- a/arch/arm/mach-mxs/include/mach/clock.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MACH_MXS_CLOCK_H__
-#define __MACH_MXS_CLOCK_H__
-
-#ifndef __ASSEMBLY__
-#include <linux/list.h>
-
-struct module;
-
-struct clk {
- int id;
- /* Source clock this clk depends on */
- struct clk *parent;
- /* Reference count of clock enable/disable */
- __s8 usecount;
- /* Register bit position for clock's enable/disable control. */
- u8 enable_shift;
- /* Register address for clock's enable/disable control. */
- void __iomem *enable_reg;
- u32 flags;
- /* get the current clock rate (always a fresh value) */
- unsigned long (*get_rate) (struct clk *);
- /* Function ptr to set the clock to a new rate. The rate must match a
- supported rate returned from round_rate. Leave blank if clock is not
- programmable */
- int (*set_rate) (struct clk *, unsigned long);
- /* Function ptr to round the requested clock rate to the nearest
- supported rate that is less than or equal to the requested rate. */
- unsigned long (*round_rate) (struct clk *, unsigned long);
- /* Function ptr to enable the clock. Leave blank if clock can not
- be gated. */
- int (*enable) (struct clk *);
- /* Function ptr to disable the clock. Leave blank if clock can not
- be gated. */
- void (*disable) (struct clk *);
- /* Function ptr to set the parent clock of the clock. */
- int (*set_parent) (struct clk *, struct clk *);
-};
-
-int clk_register(struct clk *clk);
-void clk_unregister(struct clk *clk);
-
-#endif /* __ASSEMBLY__ */
-#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 8d88399b73ef..de6c7ba42544 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -11,28 +11,27 @@
#ifndef __MACH_MXS_COMMON_H__
#define __MACH_MXS_COMMON_H__
-struct clk;
-
extern const u32 *mxs_get_ocotp(void);
extern int mxs_reset_block(void __iomem *);
-extern void mxs_timer_init(struct clk *, int);
+extern void mxs_timer_init(int);
extern void mxs_restart(char, const char *);
extern int mxs_saif_clkmux_select(unsigned int clkmux);
extern void mx23_soc_init(void);
-extern int mx23_register_gpios(void);
extern int mx23_clocks_init(void);
extern void mx23_map_io(void);
extern void mx23_init_irq(void);
extern void mx28_soc_init(void);
-extern int mx28_register_gpios(void);
extern int mx28_clocks_init(void);
extern void mx28_map_io(void);
extern void mx28_init_irq(void);
extern void icoll_init_irq(void);
-extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
+extern struct platform_device *mxs_add_dma(const char *devid,
+ resource_size_t base);
+extern struct platform_device *mxs_add_gpio(char *name, int id,
+ resource_size_t iobase, int irq);
#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 21e45a70d344..e8b1d958240b 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(
const struct mxs_mxs_i2c_data *data);
/* mmc */
-#include <mach/mmc.h>
+#include <linux/mmc/mxs-mmc.h>
struct mxs_mxs_mmc_data {
+ const char *devid;
int id;
resource_size_t iobase;
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 211547a05564..000000000000
--- a/arch/arm/mach-mxs/include/mach/mmc.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MACH_MXS_MMC_H__
-#define __MACH_MXS_MMC_H__
-
-struct mxs_mmc_platform_data {
- int wp_gpio; /* write protect pin */
- unsigned int flags;
-#define SLOTF_4_BIT_CAPABLE (1 << 0)
-#define SLOTF_8_BIT_CAPABLE (1 << 1)
-};
-#endif /* __MACH_MXS_MMC_H__ */
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index da4610ebe9e6..dafd48e86c8c 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)
struct clk *clk;
/* Enable fec phy clock */
- clk = clk_get_sys("pll2", NULL);
+ clk = clk_get_sys("enet_out", NULL);
if (!IS_ERR(clk))
clk_prepare_enable(clk);
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
new file mode 100644
index 000000000000..8cac94b33020
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/init.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+static int __init mxs_icoll_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
+
+ return 0;
+}
+
+static int __init mxs_gpio_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ static int gpio_irq_base = MXS_GPIO_IRQ_START;
+
+ irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
+ gpio_irq_base += 32;
+
+ return 0;
+}
+
+static const struct of_device_id mxs_irq_match[] __initconst = {
+ { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
+ { .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
+ { /* sentinel */ }
+};
+
+static void __init mxs_dt_init_irq(void)
+{
+ icoll_init_irq();
+ of_irq_init(mxs_irq_match);
+}
+
+static void __init imx23_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer imx23_timer = {
+ .init = imx23_timer_init,
+};
+
+static void __init imx28_timer_init(void)
+{
+ mx28_clocks_init();
+}
+
+static struct sys_timer imx28_timer = {
+ .init = imx28_timer_init,
+};
+
+static void __init imx28_evk_init(void)
+{
+ struct clk *clk;
+
+ /* Enable fec phy clock */
+ clk = clk_get_sys("enet_out", NULL);
+ if (!IS_ERR(clk))
+ clk_prepare_enable(clk);
+}
+
+static void __init mxs_machine_init(void)
+{
+ if (of_machine_is_compatible("fsl,imx28-evk"))
+ imx28_evk_init();
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ NULL, NULL);
+}
+
+static const char *imx23_dt_compat[] __initdata = {
+ "fsl,imx23-evk",
+ "fsl,imx23",
+ NULL,
+};
+
+static const char *imx28_dt_compat[] __initdata = {
+ "fsl,imx28-evk",
+ "fsl,imx28",
+ NULL,
+};
+
+DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
+ .map_io = mx23_map_io,
+ .init_irq = mxs_dt_init_irq,
+ .timer = &imx23_timer,
+ .init_machine = mxs_machine_init,
+ .dt_compat = imx23_dt_compat,
+ .restart = mxs_restart,
+MACHINE_END
+
+DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
+ .map_io = mx28_map_io,
+ .init_irq = mxs_dt_init_irq,
+ .timer = &imx28_timer,
+ .init_machine = mxs_machine_init,
+ .dt_compat = imx28_dt_compat,
+ .restart = mxs_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c
index 67a384edcf5b..dccb67a9e7c4 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)
void __init mx23_soc_init(void)
{
pinctrl_provide_dummies();
+
+ mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
+ mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
+
+ mxs_add_gpio("imx23-gpio", 0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
+ mxs_add_gpio("imx23-gpio", 1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
+ mxs_add_gpio("imx23-gpio", 2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
}
void __init mx28_soc_init(void)
{
pinctrl_provide_dummies();
+
+ mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
+ mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
+
+ mxs_add_gpio("imx28-gpio", 0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
+ mxs_add_gpio("imx28-gpio", 1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
+ mxs_add_gpio("imx28-gpio", 2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
+ mxs_add_gpio("imx28-gpio", 3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
+ mxs_add_gpio("imx28-gpio", 4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
}
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 0ea5c9d0e2b2..000000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx23.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Freescale CLKCTRL Register Definitions
- *
- * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
- * Copyright 2008-2010 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This file is created by xml file. Don't Edit it.
- *
- * Xml Revision: 1.48
- * Template revision: 26195
- */
-
-#ifndef __REGS_CLKCTRL_MX23_H__
-#define __REGS_CLKCTRL_MX23_H__
-
-
-#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
-#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
-#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
-#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
-
-#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
-#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
-#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
- (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
-#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
-#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
-#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
- (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
-#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
-#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
-#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
- (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
-#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
-#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
-#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
-#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
-#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
-
-#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
-
-#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
-#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
-#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
-#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
-#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
- (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
-
-#define HW_CLKCTRL_CPU (0x00000020)
-#define HW_CLKCTRL_CPU_SET (0x00000024)
-#define HW_CLKCTRL_CPU_CLR (0x00000028)
-#define HW_CLKCTRL_CPU_TOG (0x0000002c)
-
-#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
-#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
-#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
-#define BP_CLKCTRL_CPU_DIV_XTAL 16
-#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
-#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
- (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
-#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
-#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
-#define BP_CLKCTRL_CPU_DIV_CPU 0
-#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
-#define BF_CLKCTRL_CPU_DIV_CPU(v) \
- (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
-
-#define HW_CLKCTRL_HBUS (0x00000030)
-#define HW_CLKCTRL_HBUS_SET (0x00000034)
-#define HW_CLKCTRL_HBUS_CLR (0x00000038)
-#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
-
-#define BM_CLKCTRL_HBUS_BUSY 0x20000000
-#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
-#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
-#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
-#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
-#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
-#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
-#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
-#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
-#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
-#define BP_CLKCTRL_HBUS_SLOW_DIV 16
-#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
-#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
- (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
-#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
-#define BP_CLKCTRL_HBUS_DIV 0
-#define BM_CLKCTRL_HBUS_DIV 0x0000001F
-#define BF_CLKCTRL_HBUS_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
-
-#define HW_CLKCTRL_XBUS (0x00000040)
-
-#define BM_CLKCTRL_XBUS_BUSY 0x80000000
-#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
-#define BP_CLKCTRL_XBUS_DIV 0
-#define BM_CLKCTRL_XBUS_DIV 0x000003FF
-#define BF_CLKCTRL_XBUS_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
-
-#define HW_CLKCTRL_XTAL (0x00000050)
-#define HW_CLKCTRL_XTAL_SET (0x00000054)
-#define HW_CLKCTRL_XTAL_CLR (0x00000058)
-#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
-
-#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
-#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
-#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
-#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
-#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
-#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
-#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
-#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
-#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
-#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
-#define BP_CLKCTRL_XTAL_DIV_UART 0
-#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
-#define BF_CLKCTRL_XTAL_DIV_UART(v) \
- (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
-
-#define HW_CLKCTRL_PIX (0x00000060)
-
-#define BP_CLKCTRL_PIX_CLKGATE 31
-#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
-#define BM_CLKCTRL_PIX_BUSY 0x20000000
-#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
-#define BP_CLKCTRL_PIX_DIV 0
-#define BM_CLKCTRL_PIX_DIV 0x00000FFF
-#define BF_CLKCTRL_PIX_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_PIX_DIV)
-
-#define HW_CLKCTRL_SSP (0x00000070)
-
-#define BP_CLKCTRL_SSP_CLKGATE 31
-#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
-#define BM_CLKCTRL_SSP_BUSY 0x20000000
-#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
-#define BP_CLKCTRL_SSP_DIV 0
-#define BM_CLKCTRL_SSP_DIV 0x000001FF
-#define BF_CLKCTRL_SSP_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SSP_DIV)
-
-#define HW_CLKCTRL_GPMI (0x00000080)
-
-#define BP_CLKCTRL_GPMI_CLKGATE 31
-#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
-#define BM_CLKCTRL_GPMI_BUSY 0x20000000
-#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
-#define BP_CLKCTRL_GPMI_DIV 0
-#define BM_CLKCTRL_GPMI_DIV 0x000003FF
-#define BF_CLKCTRL_GPMI_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
-
-#define HW_CLKCTRL_SPDIF (0x00000090)
-
-#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
-
-#define HW_CLKCTRL_EMI (0x000000a0)
-
-#define BP_CLKCTRL_EMI_CLKGATE 31
-#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
-#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
-#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
-#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
-#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
-#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
-#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
-#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
-#define BP_CLKCTRL_EMI_DIV_XTAL 8
-#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
-#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
- (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
-#define BP_CLKCTRL_EMI_DIV_EMI 0
-#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
-#define BF_CLKCTRL_EMI_DIV_EMI(v) \
- (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
-
-#define HW_CLKCTRL_IR (0x000000b0)
-
-#define BM_CLKCTRL_IR_CLKGATE 0x80000000
-#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
-#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
-#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
-#define BP_CLKCTRL_IR_IROV_DIV 16
-#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
-#define BF_CLKCTRL_IR_IROV_DIV(v) \
- (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
-#define BP_CLKCTRL_IR_IR_DIV 0
-#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
-#define BF_CLKCTRL_IR_IR_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
-
-#define HW_CLKCTRL_SAIF (0x000000c0)
-
-#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
-#define BM_CLKCTRL_SAIF_BUSY 0x20000000
-#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
-#define BP_CLKCTRL_SAIF_DIV 0
-#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
-#define BF_CLKCTRL_SAIF_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
-
-#define HW_CLKCTRL_TV (0x000000d0)
-
-#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
-#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
-
-#define HW_CLKCTRL_ETM (0x000000e0)
-
-#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
-#define BM_CLKCTRL_ETM_BUSY 0x20000000
-#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
-#define BP_CLKCTRL_ETM_DIV 0
-#define BM_CLKCTRL_ETM_DIV 0x0000003F
-#define BF_CLKCTRL_ETM_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_ETM_DIV)
-
-#define HW_CLKCTRL_FRAC (0x000000f0)
-#define HW_CLKCTRL_FRAC_SET (0x000000f4)
-#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
-#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
-
-#define BP_CLKCTRL_FRAC_CLKGATEIO 31
-#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
-#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
-#define BP_CLKCTRL_FRAC_IOFRAC 24
-#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
-#define BF_CLKCTRL_FRAC_IOFRAC(v) \
- (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
-#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
-#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
-#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
-#define BP_CLKCTRL_FRAC_PIXFRAC 16
-#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
-#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
- (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
-#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
-#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
-#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
-#define BP_CLKCTRL_FRAC_EMIFRAC 8
-#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
-#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
- (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
-#define BP_CLKCTRL_FRAC_CLKGATECPU 7
-#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
-#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
-#define BP_CLKCTRL_FRAC_CPUFRAC 0
-#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
-#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
- (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
-
-#define HW_CLKCTRL_FRAC1 (0x00000100)
-#define HW_CLKCTRL_FRAC1_SET (0x00000104)
-#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
-#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
-
-#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
-#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
-
-#define HW_CLKCTRL_CLKSEQ (0x00000110)
-#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
-#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
-#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
-
-#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
-#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
-#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
-#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
-#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
-#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
-
-#define HW_CLKCTRL_RESET (0x00000120)
-
-#define BM_CLKCTRL_RESET_CHIP 0x00000002
-#define BM_CLKCTRL_RESET_DIG 0x00000001
-
-#define HW_CLKCTRL_STATUS (0x00000130)
-
-#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
-#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
-#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
- (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
-
-#define HW_CLKCTRL_VERSION (0x00000140)
-
-#define BP_CLKCTRL_VERSION_MAJOR 24
-#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
-#define BF_CLKCTRL_VERSION_MAJOR(v) \
- (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
-#define BP_CLKCTRL_VERSION_MINOR 16
-#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
-#define BF_CLKCTRL_VERSION_MINOR(v) \
- (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
-#define BP_CLKCTRL_VERSION_STEP 0
-#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
-#define BF_CLKCTRL_VERSION_STEP(v) \
- (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
-
-#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 7d1b061d7943..000000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx28.h
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Freescale CLKCTRL Register Definitions
- *
- * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * This file is created by xml file. Don't Edit it.
- *
- * Xml Revision: 1.48
- * Template revision: 26195
- */
-
-#ifndef __REGS_CLKCTRL_MX28_H__
-#define __REGS_CLKCTRL_MX28_H__
-
-#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
-#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
-#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
-#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
-
-#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
-#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
-#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
- (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
-#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
-#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
-#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
- (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
-#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
-#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
-#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
- (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
-#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
-#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
-#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
-#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
-#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
-
-#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
-
-#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
-#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
-#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
-#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
-#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
- (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
-
-#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
-#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
-#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
-#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
-
-#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
-#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
-#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
-#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
- (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
-#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
-#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
-#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
- (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
-#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
-#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
-#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
-#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
-#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
-#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
- (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
-#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
-#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
-#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
-#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
-#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
-#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
-
-#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
-
-#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
-#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
-#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
-#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
-#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
- (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
-
-#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
-#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
-#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
-#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
-
-#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
-#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
-#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
-#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
- (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
-#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
-#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
-#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
-#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
- (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
-#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
-
-#define HW_CLKCTRL_CPU (0x00000050)
-#define HW_CLKCTRL_CPU_SET (0x00000054)
-#define HW_CLKCTRL_CPU_CLR (0x00000058)
-#define HW_CLKCTRL_CPU_TOG (0x0000005c)
-
-#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
-#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
-#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
-#define BP_CLKCTRL_CPU_DIV_XTAL 16
-#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
-#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
- (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
-#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
-#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
-#define BP_CLKCTRL_CPU_DIV_CPU 0
-#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
-#define BF_CLKCTRL_CPU_DIV_CPU(v) \
- (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
-
-#define HW_CLKCTRL_HBUS (0x00000060)
-#define HW_CLKCTRL_HBUS_SET (0x00000064)
-#define HW_CLKCTRL_HBUS_CLR (0x00000068)
-#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
-
-#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
-#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
-#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
-#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
-#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
-#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
-#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
-#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
-#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
-#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
-#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
-#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
-#define BP_CLKCTRL_HBUS_SLOW_DIV 16
-#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
-#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
- (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
-#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
-#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
-#define BP_CLKCTRL_HBUS_DIV 0
-#define BM_CLKCTRL_HBUS_DIV 0x0000001F
-#define BF_CLKCTRL_HBUS_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
-
-#define HW_CLKCTRL_XBUS (0x00000070)
-
-#define BM_CLKCTRL_XBUS_BUSY 0x80000000
-#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
-#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
-#define BP_CLKCTRL_XBUS_DIV 0
-#define BM_CLKCTRL_XBUS_DIV 0x000003FF
-#define BF_CLKCTRL_XBUS_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
-
-#define HW_CLKCTRL_XTAL (0x00000080)
-#define HW_CLKCTRL_XTAL_SET (0x00000084)
-#define HW_CLKCTRL_XTAL_CLR (0x00000088)
-#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
-
-#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
-#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
-#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
-#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
-#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
-#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
-#define BP_CLKCTRL_XTAL_DIV_UART 0
-#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
-#define BF_CLKCTRL_XTAL_DIV_UART(v) \
- (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
-
-#define HW_CLKCTRL_SSP0 (0x00000090)
-
-#define BP_CLKCTRL_SSP0_CLKGATE 31
-#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
-#define BM_CLKCTRL_SSP0_BUSY 0x20000000
-#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
-#define BP_CLKCTRL_SSP0_DIV 0
-#define BM_CLKCTRL_SSP0_DIV 0x000001FF
-#define BF_CLKCTRL_SSP0_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
-
-#define HW_CLKCTRL_SSP1 (0x000000a0)
-
-#define BP_CLKCTRL_SSP1_CLKGATE 31
-#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
-#define BM_CLKCTRL_SSP1_BUSY 0x20000000
-#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
-#define BP_CLKCTRL_SSP1_DIV 0
-#define BM_CLKCTRL_SSP1_DIV 0x000001FF
-#define BF_CLKCTRL_SSP1_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
-
-#define HW_CLKCTRL_SSP2 (0x000000b0)
-
-#define BP_CLKCTRL_SSP2_CLKGATE 31
-#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
-#define BM_CLKCTRL_SSP2_BUSY 0x20000000
-#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
-#define BP_CLKCTRL_SSP2_DIV 0
-#define BM_CLKCTRL_SSP2_DIV 0x000001FF
-#define BF_CLKCTRL_SSP2_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
-
-#define HW_CLKCTRL_SSP3 (0x000000c0)
-
-#define BP_CLKCTRL_SSP3_CLKGATE 31
-#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
-#define BM_CLKCTRL_SSP3_BUSY 0x20000000
-#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
-#define BP_CLKCTRL_SSP3_DIV 0
-#define BM_CLKCTRL_SSP3_DIV 0x000001FF
-#define BF_CLKCTRL_SSP3_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
-
-#define HW_CLKCTRL_GPMI (0x000000d0)
-
-#define BP_CLKCTRL_GPMI_CLKGATE 31
-#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
-#define BM_CLKCTRL_GPMI_BUSY 0x20000000
-#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
-#define BP_CLKCTRL_GPMI_DIV 0
-#define BM_CLKCTRL_GPMI_DIV 0x000003FF
-#define BF_CLKCTRL_GPMI_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
-
-#define HW_CLKCTRL_SPDIF (0x000000e0)
-
-#define BP_CLKCTRL_SPDIF_CLKGATE 31
-#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
-
-#define HW_CLKCTRL_EMI (0x000000f0)
-
-#define BP_CLKCTRL_EMI_CLKGATE 31
-#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
-#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
-#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
-#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
-#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
-#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
-#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
-#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
-#define BP_CLKCTRL_EMI_DIV_XTAL 8
-#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
-#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
- (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
-#define BP_CLKCTRL_EMI_DIV_EMI 0
-#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
-#define BF_CLKCTRL_EMI_DIV_EMI(v) \
- (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
-
-#define HW_CLKCTRL_SAIF0 (0x00000100)
-
-#define BP_CLKCTRL_SAIF0_CLKGATE 31
-#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
-#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
-#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
-#define BP_CLKCTRL_SAIF0_DIV 0
-#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
-#define BF_CLKCTRL_SAIF0_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
-
-#define HW_CLKCTRL_SAIF1 (0x00000110)
-
-#define BP_CLKCTRL_SAIF1_CLKGATE 31
-#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
-#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
-#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
-#define BP_CLKCTRL_SAIF1_DIV 0
-#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
-#define BF_CLKCTRL_SAIF1_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
-
-#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
-
-#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
-#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
-#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
-#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
-#define BP_CLKCTRL_DIS_LCDIF_DIV 0
-#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
-#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
-
-#define HW_CLKCTRL_ETM (0x00000130)
-
-#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
-#define BM_CLKCTRL_ETM_BUSY 0x20000000
-#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
-#define BP_CLKCTRL_ETM_DIV 0
-#define BM_CLKCTRL_ETM_DIV 0x0000007F
-#define BF_CLKCTRL_ETM_DIV(v) \
- (((v) << 0) & BM_CLKCTRL_ETM_DIV)
-
-#define HW_CLKCTRL_ENET (0x00000140)
-
-#define BM_CLKCTRL_ENET_SLEEP 0x80000000
-#define BP_CLKCTRL_ENET_DISABLE 30
-#define BM_CLKCTRL_ENET_DISABLE 0x40000000
-#define BM_CLKCTRL_ENET_STATUS 0x20000000
-#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
-#define BP_CLKCTRL_ENET_DIV_TIME 21
-#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
-#define BF_CLKCTRL_ENET_DIV_TIME(v) \
- (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
-#define BM_CLKCTRL_ENET_BUSY 0x08000000
-#define BP_CLKCTRL_ENET_DIV 21
-#define BM_CLKCTRL_ENET_DIV 0x07E00000
-#define BF_CLKCTRL_ENET_DIV(v) \
- (((v) << 21) & BM_CLKCTRL_ENET_DIV)
-#define BP_CLKCTRL_ENET_TIME_SEL 19
-#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
-#define BF_CLKCTRL_ENET_TIME_SEL(v) \
- (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
-#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
-#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
-#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
-#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
-#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
-#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
-#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
-
-#define HW_CLKCTRL_HSADC (0x00000150)
-
-#define BM_CLKCTRL_HSADC_RESETB 0x40000000
-#define BP_CLKCTRL_HSADC_FREQDIV 28
-#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
-#define BF_CLKCTRL_HSADC_FREQDIV(v) \
- (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
-
-#define HW_CLKCTRL_FLEXCAN (0x00000160)
-
-#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
-#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
-#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
-#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
-#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
-#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
-
-#define HW_CLKCTRL_FRAC0 (0x000001b0)
-#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
-#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
-#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
-
-#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
-#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
-#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
-#define BP_CLKCTRL_FRAC0_IO0FRAC 24
-#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
-#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
- (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
-#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
-#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
-#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
-#define BP_CLKCTRL_FRAC0_IO1FRAC 16
-#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
-#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
- (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
-#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
-#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
-#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
-#define BP_CLKCTRL_FRAC0_EMIFRAC 8
-#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
-#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
- (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
-#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
-#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
-#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
-#define BP_CLKCTRL_FRAC0_CPUFRAC 0
-#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
-#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
- (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
-
-#define HW_CLKCTRL_FRAC1 (0x000001c0)
-#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
-#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
-#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
-
-#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
-#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
-#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
-#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
-#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
-#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
- (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
-#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
-#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
-#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
-#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
-#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
-#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
- (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
-#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
-#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
-#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
-#define BP_CLKCTRL_FRAC1_PIXFRAC 0
-#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
-#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
- (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
-
-#define HW_CLKCTRL_CLKSEQ (0x000001d0)
-#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
-#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
-#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
-
-#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
-#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
-#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
-#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
-#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
-#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
-#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
-#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
-
-#define HW_CLKCTRL_RESET (0x000001e0)
-
-#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
-#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
-#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
-#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
-#define BM_CLKCTRL_RESET_CHIP 0x00000002
-#define BM_CLKCTRL_RESET_DIG 0x00000001
-
-#define HW_CLKCTRL_STATUS (0x000001f0)
-
-#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
-#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
-#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
- (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
-
-#define HW_CLKCTRL_VERSION (0x00000200)
-
-#define BP_CLKCTRL_VERSION_MAJOR 24
-#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
-#define BF_CLKCTRL_VERSION_MAJOR(v) \
- (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
-#define BP_CLKCTRL_VERSION_MINOR 16
-#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
-#define BF_CLKCTRL_VERSION_MINOR(v) \
- (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
-#define BP_CLKCTRL_VERSION_STEP 0
-#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
-#define BF_CLKCTRL_VERSION_STEP(v) \
- (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
-
-#endif /* __REGS_CLKCTRL_MX28_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 80ac1fca8a00..30042e23bfa7 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,8 +37,6 @@
#define MXS_MODULE_CLKGATE (1 << 30)
#define MXS_MODULE_SFTRST (1 << 31)
-#define CLKCTRL_TIMEOUT 10 /* 10 ms */
-
static void __iomem *mxs_clkctrl_reset_addr;
/*
@@ -139,17 +137,3 @@ error:
return -ETIMEDOUT;
}
EXPORT_SYMBOL(mxs_reset_block);
-
-int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
-{
- unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
- while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
- + reg_offset) & mask) {
- if (time_after(jiffies, timeout)) {
- pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
- return -ETIMEDOUT;
- }
- }
-
- return 0;
-}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index 564a63279f18..02d36de9c4e8 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -20,6 +20,7 @@
* MA 02110-1301, USA.
*/
+#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/clockchips.h>
@@ -243,8 +244,16 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
return 0;
}
-void __init mxs_timer_init(struct clk *timer_clk, int irq)
+void __init mxs_timer_init(int irq)
{
+ struct clk *timer_clk;
+
+ timer_clk = clk_get_sys("timrot", NULL);
+ if (IS_ERR(timer_clk)) {
+ pr_err("%s: failed to get clk\n", __func__);
+ return;
+ }
+
clk_prepare_enable(timer_clk);
/*
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index c1b681ef4cba..f2f8a5847018 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:
gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
return err;
}
-late_initcall(late_init);
+
+static void __init ams_delta_init_late(void)
+{
+ omap1_init_late();
+ late_init();
+}
static void __init ams_delta_map_io(void)
{
@@ -611,6 +616,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = ams_delta_init,
+ .init_late = ams_delta_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 4a4afb371022..c7364fdbda05 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_fsample_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 9a5fe581bc1c..e75e2d55a2d7 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_generic_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 057ec13f0649..7e503686f7af 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = h2_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index f6ddf8759657..9fb03f189d93 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = h3_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 60c06ee23855..118a9d4a4c54 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = htcherald_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 67d7fd57a692..7970223a559d 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = innovator_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index d21dcc2fbc5a..7212ae97f44a 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_nokia770_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index a5f85dda3f69..da8d872d3d1c 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = osk_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index a60e6c22f816..949b62a73693 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_palmte_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 8d854878547b..7f1e1cf2bf46 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_palmtt_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 61ed4f0247ce..3c71c6bace2c 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_palmz71_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index a2c88890e767..f2cb24387c22 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_perseus2_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index f34cb74a9f41..3b7b82b13684 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = omap_sx1_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = omap1_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 37232d04233f..afd67f0ec495 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")
.reserve = omap_reserve,
.init_irq = omap1_init_irq,
.init_machine = voiceblue_init,
+ .init_late = omap1_init_late,
.timer = &omap1_timer,
.restart = voiceblue_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h
index bb7779b57795..c2552b24f9f2 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)
}
#endif
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+int omap_serial_wakeup_init(void);
+#else
+static inline int omap_serial_wakeup_init(void)
+{
+ return 0;
+}
+#endif
+
void omap1_init_early(void);
void omap1_init_irq(void);
+void omap1_init_late(void);
void omap1_restart(char, const char *);
extern void __init omap_check_revision(void);
@@ -63,7 +73,14 @@ extern void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
unsigned int ctrl);
extern struct sys_timer omap1_timer;
-extern bool omap_32k_timer_init(void);
+#ifdef CONFIG_OMAP_32K_TIMER
+extern int omap_32k_timer_init(void);
+#else
+static inline int __init omap_32k_timer_init(void)
+{
+ return -ENODEV;
+}
+#endif
extern u32 omap_irq_flags;
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index dcd8ddbec2bb..fa1fa4deb6aa 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -22,6 +22,7 @@
#include <plat/tc.h>
#include <plat/board.h>
#include <plat/mux.h>
+#include <plat/dma.h>
#include <plat/mmc.h>
#include <plat/omap7xx.h>
@@ -31,6 +32,22 @@
#include "common.h"
#include "clock.h"
+#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
+
+static struct platform_device omap_pcm = {
+ .name = "omap-pcm-audio",
+ .id = -1,
+};
+
+static void omap_init_audio(void)
+{
+ platform_device_register(&omap_pcm);
+}
+
+#else
+static inline void omap_init_audio(void) {}
+#endif
+
/*-------------------------------------------------------------------------*/
#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,
}
}
+#define OMAP_MMC_NR_RES 4
+
+/*
+ * Register MMC devices.
+ */
+static int __init omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ unsigned rx_req, unsigned tx_req,
+ struct omap_mmc_platform_data *data)
+{
+ struct platform_device *pdev;
+ struct resource res[OMAP_MMC_NR_RES];
+ int ret;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+ res[2].start = rx_req;
+ res[2].name = "rx";
+ res[2].flags = IORESOURCE_DMA;
+ res[3].start = tx_req;
+ res[3].name = "tx";
+ res[3].flags = IORESOURCE_DMA;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret == 0)
+ ret = platform_device_add_data(pdev, data, sizeof(*data));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+
+ /* return device handle to board setup code */
+ data->dev = &pdev->dev;
+ return 0;
+
+fail:
+ platform_device_put(pdev);
+ return ret;
+}
+
void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers)
{
@@ -135,6 +202,7 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
for (i = 0; i < nr_controllers; i++) {
unsigned long base, size;
+ unsigned rx_req, tx_req;
unsigned int irq = 0;
if (!mmc_data[i])
@@ -146,19 +214,24 @@ void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
case 0:
base = OMAP1_MMC1_BASE;
irq = INT_MMC;
+ rx_req = OMAP_DMA_MMC_RX;
+ tx_req = OMAP_DMA_MMC_TX;
break;
case 1:
if (!cpu_is_omap16xx())
return;
base = OMAP1_MMC2_BASE;
irq = INT_1610_MMC2;
+ rx_req = OMAP_DMA_MMC2_RX;
+ tx_req = OMAP_DMA_MMC2_TX;
break;
default:
continue;
}
size = OMAP1_MMC_SIZE;
- omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]);
+ omap_mmc_add("mmci-omap", i, base, size, irq,
+ rx_req, tx_req, mmc_data[i]);
};
}
@@ -242,23 +315,48 @@ void __init omap1_camera_init(void *info)
static inline void omap_init_sti(void) {}
-#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
+/* Numbering for the SPI-capable controllers when used for SPI:
+ * spi = 1
+ * uwire = 2
+ * mmc1..2 = 3..4
+ * mcbsp1..3 = 5..7
+ */
-static struct platform_device omap_pcm = {
- .name = "omap-pcm-audio",
- .id = -1,
+#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
+
+#define OMAP_UWIRE_BASE 0xfffb3000
+
+static struct resource uwire_resources[] = {
+ {
+ .start = OMAP_UWIRE_BASE,
+ .end = OMAP_UWIRE_BASE + 0x20,
+ .flags = IORESOURCE_MEM,
+ },
};
-static void omap_init_audio(void)
+static struct platform_device omap_uwire_device = {
+ .name = "omap_uwire",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(uwire_resources),
+ .resource = uwire_resources,
+};
+
+static void omap_init_uwire(void)
{
- platform_device_register(&omap_pcm);
-}
+ /* FIXME define and use a boot tag; not all boards will be hooking
+ * up devices to the microwire controller, and multi-board configs
+ * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
+ */
+ /* board-specific code must configure chipselects (only a few
+ * are normally used) and SCLK/SDI/SDO (each has two choices).
+ */
+ (void) platform_device_register(&omap_uwire_device);
+}
#else
-static inline void omap_init_audio(void) {}
+static inline void omap_init_uwire(void) {}
#endif
-/*-------------------------------------------------------------------------*/
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
@@ -292,11 +390,12 @@ static int __init omap1_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
+ omap_init_audio();
omap_init_mbox();
omap_init_rtc();
omap_init_spi100k();
omap_init_sti();
- omap_init_audio();
+ omap_init_uwire();
return 0;
}
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 71ce017bf5d8..6c95a59f0f16 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)
omap_init_consistent_dma_size();
}
+void __init omap1_init_late(void)
+{
+ omap_serial_wakeup_init();
+}
+
/*
* NOTE: Please use ioremap + __raw_read/write where possible instead of these
*/
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 93ae8f29727e..6809c9e56c93 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)
enable_irq_wake(gpio_to_irq(gpio_nr));
}
-static int __init omap_serial_wakeup_init(void)
+int __init omap_serial_wakeup_init(void)
{
if (!cpu_is_omap16xx())
return 0;
@@ -251,7 +251,6 @@ static int __init omap_serial_wakeup_init(void)
return 0;
}
-late_initcall(omap_serial_wakeup_init);
#endif /* CONFIG_OMAP_SERIAL_WAKE */
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 4d8dd9a1b04c..4062480bfec7 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)
}
#endif /* CONFIG_OMAP_MPU_TIMER */
-static inline int omap_32k_timer_usable(void)
-{
- int res = false;
-
- if (cpu_is_omap730() || cpu_is_omap15xx())
- return res;
-
-#ifdef CONFIG_OMAP_32K_TIMER
- res = omap_32k_timer_init();
-#endif
-
- return res;
-}
-
/*
* ---------------------------------------------------------------------------
* Timer initialization
@@ -253,7 +239,7 @@ static inline int omap_32k_timer_usable(void)
*/
static void __init omap1_timer_init(void)
{
- if (!omap_32k_timer_usable())
+ if (omap_32k_timer_init() != 0)
omap_mpu_timer_init();
}
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 325b9a0aa4a0..eae49c3980c9 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -71,6 +71,7 @@
/* 16xx specific defines */
#define OMAP1_32K_TIMER_BASE 0xfffb9000
+#define OMAP1_32KSYNC_TIMER_BASE 0xfffbc400
#define OMAP1_32K_TIMER_CR 0x08
#define OMAP1_32K_TIMER_TVR 0x00
#define OMAP1_32K_TIMER_TCR 0x04
@@ -182,10 +183,29 @@ static __init void omap_init_32k_timer(void)
* Timer initialization
* ---------------------------------------------------------------------------
*/
-bool __init omap_32k_timer_init(void)
+int __init omap_32k_timer_init(void)
{
- omap_init_clocksource_32k();
- omap_init_32k_timer();
+ int ret = -ENODEV;
- return true;
+ if (cpu_is_omap16xx()) {
+ void __iomem *base;
+ struct clk *sync32k_ick;
+
+ base = ioremap(OMAP1_32KSYNC_TIMER_BASE, SZ_1K);
+ if (!base) {
+ pr_err("32k_counter: failed to map base addr\n");
+ return -ENODEV;
+ }
+
+ sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
+ if (!IS_ERR(sync32k_ick))
+ clk_enable(sync32k_ick);
+
+ ret = omap_init_clocksource_32k(base);
+ }
+
+ if (!ret)
+ omap_init_32k_timer();
+
+ return ret;
}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 964ee67a3b77..4cf5142f22cc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -78,12 +78,12 @@ config SOC_OMAP3430
default y
select ARCH_OMAP_OTG
-config SOC_OMAPTI81XX
+config SOC_TI81XX
bool "TI81XX support"
depends on ARCH_OMAP3
default y
-config SOC_OMAPAM33XX
+config SOC_AM33XX
bool "AM33XX support"
depends on ARCH_OMAP3
default y
@@ -320,12 +320,12 @@ config MACH_OMAP_3630SDP
config MACH_TI8168EVM
bool "TI8168 Evaluation Module"
- depends on SOC_OMAPTI81XX
+ depends on SOC_TI81XX
default y
config MACH_TI8148EVM
bool "TI8148 Evaluation Module"
- depends on SOC_OMAPTI81XX
+ depends on SOC_TI81XX
default y
config MACH_OMAP_4430SDP
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 385c083d24b2..fa742f3c2629 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -24,10 +24,11 @@ endif
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
# SMP support ONLY available for OMAP4
+
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
-obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
- sleep44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o
+obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o
plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
@@ -64,10 +65,10 @@ endif
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
- cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \
- cpuidle44xx.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
+obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@ -84,90 +85,86 @@ endif
# PRCM
obj-y += prm_common.o
obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
-obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
- vc3xxx_data.o vp3xxx_data.o
-# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
-# will be removed once the OMAP4 part of the codebase is converted to
-# use OMAP4-specific PRCM functions.
-obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
- cm44xx.o prcm_mpu44xx.o \
- prminst44xx.o vc44xx_data.o \
- vp44xx_data.o prm44xx.o
+obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += prcm.o cminst44xx.o cm44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += prcm_mpu44xx.o prminst44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += vc44xx_data.o vp44xx_data.o prm44xx.o
# OMAP voltage domains
voltagedomain-common := voltage.o vc.o vp.o
-obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) \
- voltagedomains2xxx_data.o
-obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
- voltagedomains3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
- voltagedomains44xx_data.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
# OMAP powerdomain framework
powerdomain-common += powerdomain.o powerdomain-common.o
-obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \
- powerdomain2xxx_3xxx.o \
- powerdomains2xxx_data.o \
- powerdomains2xxx_3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \
- powerdomain2xxx_3xxx.o \
- powerdomains3xxx_data.o \
- powerdomains2xxx_3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
- powerdomain44xx.o \
- powerdomains44xx_data.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
+obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
# PRCM clockdomain control
-clockdomain-common += clockdomain.o \
- clockdomains_common_data.o
-obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) \
- clockdomain2xxx_3xxx.o \
- clockdomains2xxx_3xxx_data.o
+clockdomain-common += clockdomain.o
+clockdomain-common += clockdomains_common_data.o
+obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
-obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) \
- clockdomain2xxx_3xxx.o \
- clockdomains2xxx_3xxx_data.o \
- clockdomains3xxx_data.o
-obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) \
- clockdomain44xx.o \
- clockdomains44xx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
+obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o
+obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
# Clock framework
-obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
- clkt2xxx_sys.o \
- clkt2xxx_dpllcore.o \
- clkt2xxx_virt_prcm_set.o \
- clkt2xxx_apll.o clkt2xxx_osc.o \
- clkt2xxx_dpll.o clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
+obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
-obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \
- clock34xx.o clkt34xx_dpll3m2.o \
- clock3517.o clock36xx.o \
- dpll3xxx.o clock3xxx_data.o \
- clkt_iclk.o
-obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \
- dpll3xxx.o dpll44xx.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
+obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
+obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
# OMAP2 clock rate set data (old "OPP" data)
obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
# hwmod data
-obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o \
- omap_hwmod_2xxx_3xxx_ipblock_data.o \
- omap_hwmod_2xxx_interconnect_data.o \
- omap_hwmod_2xxx_3xxx_interconnect_data.o \
- omap_hwmod_2420_data.o
-obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o \
- omap_hwmod_2xxx_3xxx_ipblock_data.o \
- omap_hwmod_2xxx_interconnect_data.o \
- omap_hwmod_2xxx_3xxx_interconnect_data.o \
- omap_hwmod_2430_data.o
-obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o \
- omap_hwmod_2xxx_3xxx_interconnect_data.o \
- omap_hwmod_3xxx_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_ipblock_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_2xxx_3xxx_interconnect_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
# EMU peripherals
@@ -208,23 +205,19 @@ obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
-obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
- sdram-nokia.o
-obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
- sdram-nokia.o \
- board-rx51-peripherals.o \
- board-rx51-video.o
-obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
- board-zoom-peripherals.o \
- board-zoom-display.o \
- board-zoom-debugboard.o
-obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
- board-zoom-peripherals.o \
- board-zoom-display.o \
- board-zoom-debugboard.o
-obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
- board-zoom-peripherals.o \
- board-zoom-display.o
+obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o sdram-nokia.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o board-zoom-peripherals.o
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-display.o
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o board-zoom-peripherals.o
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-display.o
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o
+obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-peripherals.o
+obj-$(CONFIG_MACH_OMAP_3630SDP) += board-zoom-display.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
obj-$(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 e658f835d0de..99ca6bad5c30 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")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = omap_2430sdp_init,
+ .init_late = omap2430_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 37abb0d49b51..a98c688058a9 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_3430sdp_init,
+ .init_late = omap3430_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 6ef350d1ae4f..2dc9ba523c7a 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_sdp_init,
+ .init_late = omap3630_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 94af6cde2e36..8e17284a803f 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")
.init_irq = gic_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = omap_4430sdp_init,
+ .init_late = omap4430_init_late,
.timer = &omap4_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index 3b8a53c1f2a8..92432c28673d 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = am3517_crane_init,
+ .init_late = am35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 99790eb646e8..18f601096ce1 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = am3517_evm_init,
+ .init_late = am35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 768ece2e9c3b..502c31e123be 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")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = omap_apollon_init,
+ .init_late = omap2420_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index c03df142ea67..ded100c80a91 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = cm_t35_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -681,6 +682,7 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = cm_t3730_init,
+ .init_late = omap3630_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index 9e66e167e4f3..a33ad4641d9a 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = cm_t3517_init,
+ .init_late = am35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index b063f0d2faa6..6567c1cd5572 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = devkit8000_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_secure_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 7302ba7ff1b9..202934657867 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)")
.init_irq = omap_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = omap_generic_init,
+ .init_late = omap4430_init_late,
.timer = &omap4_timer,
.dt_compat = omap4_boards_compat,
.restart = omap_prcm_restart,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0bbbabe28fcc..876becf8205a 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")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = omap_h4_init,
+ .init_late = omap2420_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 7a274098f67b..74915295482e 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = igep_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -662,6 +663,7 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = igep_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 1b6049567ab4..ef9e82977499 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_ldp_init,
+ .init_late = omap3430_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 518091c5f77c..8ca14e88a31a 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")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = n8x0_init_machine,
+ .init_late = omap2420_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -706,6 +707,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = n8x0_init_machine,
+ .init_late = omap2420_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -718,6 +720,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
.init_irq = omap2_init_irq,
.handle_irq = omap2_intc_handle_irq,
.init_machine = n8x0_init_machine,
+ .init_late = omap2420_init_late,
.timer = &omap2_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 2a7b9a9da1db..79c6909eeb78 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3_beagle_init,
+ .init_late = omap3_init_late,
.timer = &omap3_secure_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index ace3c675e9c2..639bd07ea38a 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3_evm_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index c008bf8e1c36..932e1778aff9 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3logic_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -254,6 +255,7 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3logic_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 33d995d0f075..57aebee44fd0 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3pandora_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 4396bae91677..b318f5602e36 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3_stalker_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_secure_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index ae2251fa4a69..485d14d6a8cd 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap3_touchbook_init,
+ .init_late = omap3430_init_late,
.timer = &omap3_secure_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 68b8fc9ff010..982fb2622ab8 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")
.init_irq = gic_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = omap4_panda_init,
+ .init_late = omap4430_init_late,
.timer = &omap4_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 5527c1979a16..8fa2fc3a4c3c 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = overo_init,
+ .init_late = omap35xx_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index ae53d71f0ce0..0ad1bb3bdb98 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = rm680_init,
+ .init_late = omap3630_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -163,6 +164,7 @@ MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = rm680_init,
+ .init_late = omap3630_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 2da92a6ba40a..345dd931f76f 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = rx51_init,
+ .init_late = omap3430_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index ab9a7a9e9d64..d4c8392cadb6 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")
.init_irq = ti81xx_init_irq,
.timer = &omap3_timer,
.init_machine = ti81xx_evm_init,
+ .init_late = ti81xx_init_late,
.restart = omap_prcm_restart,
MACHINE_END
@@ -63,5 +64,6 @@ MACHINE_START(TI8148EVM, "ti8148evm")
.init_irq = ti81xx_init_irq,
.timer = &omap3_timer,
.init_machine = ti81xx_evm_init,
+ .init_late = ti81xx_init_late,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 5c20bcc57f2b..4e7e56142e6f 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")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_zoom_init,
+ .init_late = omap3430_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
@@ -149,6 +150,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
.init_irq = omap3_init_irq,
.handle_irq = omap3_intc_handle_irq,
.init_machine = omap_zoom_init,
+ .init_late = omap3630_init_late,
.timer = &omap3_timer,
.restart = omap_prcm_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index d6c9e6180318..be9dfd1abe60 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)
}
#endif
-#ifdef CONFIG_SOC_OMAPTI81XX
+#ifdef CONFIG_SOC_TI81XX
extern void omapti81xx_map_common_io(void);
#else
static inline void omapti81xx_map_common_io(void)
@@ -63,7 +63,7 @@ static inline void omapti81xx_map_common_io(void)
}
#endif
-#ifdef CONFIG_SOC_OMAPAM33XX
+#ifdef CONFIG_SOC_AM33XX
extern void omapam33xx_map_common_io(void);
#else
static inline void omapam33xx_map_common_io(void)
@@ -79,6 +79,42 @@ static inline void omap44xx_map_common_io(void)
}
#endif
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
+int omap2_pm_init(void);
+#else
+static inline int omap2_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+int omap3_pm_init(void);
+#else
+static inline int omap3_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+int omap4_pm_init(void);
+#else
+static inline int omap4_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_OMAP_MUX
+int omap_mux_late_init(void);
+#else
+static inline int omap_mux_late_init(void)
+{
+ return 0;
+}
+#endif
+
extern void omap2_init_common_infrastructure(void);
extern struct sys_timer omap2_timer;
@@ -95,6 +131,17 @@ void omap3_init_early(void); /* Do not use this one */
void am35xx_init_early(void);
void ti81xx_init_early(void);
void omap4430_init_early(void);
+void omap3_init_late(void); /* Do not use this one */
+void omap4430_init_late(void);
+void omap2420_init_late(void);
+void omap2430_init_late(void);
+void omap3430_init_late(void);
+void omap35xx_init_late(void);
+void omap3630_init_late(void);
+void am35xx_init_late(void);
+void ti81xx_init_late(void);
+void omap4430_init_late(void);
+int omap2_common_pm_late_init(void);
void omap_prcm_restart(char, const char *);
/*
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index ae62ece04ef9..7b4b9327e543 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
void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
{
- char *name = "mmci-omap";
+ struct platform_device *pdev;
+ struct omap_hwmod *oh;
+ int id = 0;
+ char *oh_name = "msdi1";
+ char *dev_name = "mmci-omap";
if (!mmc_data[0]) {
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)
}
omap242x_mmc_mux(mmc_data[0]);
- omap_mmc_add(name, 0, OMAP2_MMC1_BASE, OMAP2420_MMC_SIZE,
- INT_24XX_MMC_IRQ, mmc_data[0]);
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return;
+ }
+ pdev = omap_device_build(dev_name, id, oh, mmc_data[0],
+ sizeof(struct omap_mmc_platform_data), NULL, 0, 0);
+ if (IS_ERR(pdev))
+ WARN(1, "Can'd build omap_device for %s:%s.\n",
+ dev_name, oh->name);
}
#endif
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index b19d8496c16e..ff75abe60af2 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)
dma_stride = OMAP2_DMA_STRIDE;
dma_common_ch_start = CSDP;
- if (cpu_is_omap3630() || cpu_is_omap44xx())
- dma_common_ch_end = CCDN;
- else
- dma_common_ch_end = CCFN;
p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
if (!p) {
@@ -277,6 +273,13 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
return -ENOMEM;
}
+
+ /* Check the capabilities register for descriptor loading feature */
+ if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS)
+ dma_common_ch_end = CCDN;
+ else
+ dma_common_ch_end = CCFN;
+
return 0;
}
diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c
index 3376388b317a..845309f146fe 100644
--- a/arch/arm/mach-omap2/dsp.c
+++ b/arch/arm/mach-omap2/dsp.c
@@ -28,8 +28,6 @@
#include <plat/dsp.h>
-extern phys_addr_t omap_dsp_get_mempool_base(void);
-
static struct platform_device *omap_dsp_pdev;
static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
@@ -47,6 +45,31 @@ static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
.dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits,
};
+static phys_addr_t omap_dsp_phys_mempool_base;
+
+void __init omap_dsp_reserve_sdram_memblock(void)
+{
+ phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
+ phys_addr_t paddr;
+
+ if (!size)
+ return;
+
+ paddr = arm_memblock_steal(size, SZ_1M);
+ if (!paddr) {
+ pr_err("%s: failed to reserve %llx bytes\n",
+ __func__, (unsigned long long)size);
+ return;
+ }
+
+ omap_dsp_phys_mempool_base = paddr;
+}
+
+static phys_addr_t omap_dsp_get_mempool_base(void)
+{
+ return omap_dsp_phys_mempool_base;
+}
+
static int __init omap_dsp_init(void)
{
struct platform_device *pdev;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 580e684e8825..46b09dae770e 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -50,6 +50,19 @@
#define GPMC_ECC_SIZE_CONFIG 0x1fc
#define GPMC_ECC1_RESULT 0x200
+/* GPMC ECC control settings */
+#define GPMC_ECC_CTRL_ECCCLEAR 0x100
+#define GPMC_ECC_CTRL_ECCDISABLE 0x000
+#define GPMC_ECC_CTRL_ECCREG1 0x001
+#define GPMC_ECC_CTRL_ECCREG2 0x002
+#define GPMC_ECC_CTRL_ECCREG3 0x003
+#define GPMC_ECC_CTRL_ECCREG4 0x004
+#define GPMC_ECC_CTRL_ECCREG5 0x005
+#define GPMC_ECC_CTRL_ECCREG6 0x006
+#define GPMC_ECC_CTRL_ECCREG7 0x007
+#define GPMC_ECC_CTRL_ECCREG8 0x008
+#define GPMC_ECC_CTRL_ECCREG9 0x009
+
#define GPMC_CS0_OFFSET 0x60
#define GPMC_CS_SIZE 0x30
@@ -860,8 +873,9 @@ int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
gpmc_ecc_used = cs;
/* clear ecc and enable bits */
- val = ((0x00000001<<8) | 0x00000001);
- gpmc_write_reg(GPMC_ECC_CONTROL, val);
+ gpmc_write_reg(GPMC_ECC_CONTROL,
+ GPMC_ECC_CTRL_ECCCLEAR |
+ GPMC_ECC_CTRL_ECCREG1);
/* program ecc and result sizes */
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)
switch (mode) {
case GPMC_ECC_READ:
- gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
+ case GPMC_ECC_WRITE:
+ gpmc_write_reg(GPMC_ECC_CONTROL,
+ GPMC_ECC_CTRL_ECCCLEAR |
+ GPMC_ECC_CTRL_ECCREG1);
break;
case GPMC_ECC_READSYN:
- gpmc_write_reg(GPMC_ECC_CONTROL, 0x100);
- break;
- case GPMC_ECC_WRITE:
- gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
+ gpmc_write_reg(GPMC_ECC_CONTROL,
+ GPMC_ECC_CTRL_ECCCLEAR |
+ GPMC_ECC_CTRL_ECCDISABLE);
break;
default:
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 b0268eaffe13..be697d4e0843 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,
*
* temporary HACK: ocr_mask instead of fixed supply
*/
- if (cpu_is_omap3505() || cpu_is_omap3517())
+ if (soc_is_am35xx())
mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
MMC_VDD_26_27 |
MMC_VDD_27_28 |
@@ -365,7 +365,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
else
mmc->slots[0].ocr_mask = c->ocr_mask;
- if (!cpu_is_omap3517() && !cpu_is_omap3505())
+ if (!soc_is_am35xx())
mmc->slots[0].features |= HSMMC_HAS_PBIAS;
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,
}
}
- if (cpu_is_omap3517() || cpu_is_omap3505())
+ if (soc_is_am35xx())
mmc->slots[0].set_power = nop_mmc_set_power;
/* OMAP3630 HSMMC1 supports only 4-bit */
@@ -400,7 +400,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
}
break;
case 2:
- if (cpu_is_omap3517() || cpu_is_omap3505())
+ if (soc_is_am35xx())
mmc->slots[0].set_power = am35x_hsmmc2_set_power;
if (c->ext_clock)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index f1398171d8a2..0389b3264abe 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)
*/
if (cpu_is_omap3630()) {
cpu_name = "OMAP3630";
- } else if (cpu_is_omap3517()) {
- /* AM35xx devices */
+ } else if (soc_is_am35xx()) {
cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
} else if (cpu_is_ti816x()) {
cpu_name = "TI816X";
@@ -352,13 +351,13 @@ void __init omap3xxx_check_revision(void)
*/
switch (rev) {
case 0:
- omap_revision = OMAP3517_REV_ES1_0;
+ omap_revision = AM35XX_REV_ES1_0;
cpu_rev = "1.0";
break;
case 1:
/* FALLTHROUGH */
default:
- omap_revision = OMAP3517_REV_ES1_1;
+ omap_revision = AM35XX_REV_ES1_1;
cpu_rev = "1.1";
}
break;
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
index d79321b0f2a2..548de90b58c2 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 @@
#define OMAP_WKG_ENB_B_0 0x14
#define OMAP_WKG_ENB_C_0 0x18
#define OMAP_WKG_ENB_D_0 0x1c
-#define OMAP_WKG_ENB_SECURE_A_0 0x20
-#define OMAP_WKG_ENB_SECURE_B_0 0x24
-#define OMAP_WKG_ENB_SECURE_C_0 0x28
-#define OMAP_WKG_ENB_SECURE_D_0 0x2c
#define OMAP_WKG_ENB_A_1 0x410
#define OMAP_WKG_ENB_B_1 0x414
#define OMAP_WKG_ENB_C_1 0x418
#define OMAP_WKG_ENB_D_1 0x41c
-#define OMAP_WKG_ENB_SECURE_A_1 0x420
-#define OMAP_WKG_ENB_SECURE_B_1 0x424
-#define OMAP_WKG_ENB_SECURE_C_1 0x428
-#define OMAP_WKG_ENB_SECURE_D_1 0x42c
#define OMAP_AUX_CORE_BOOT_0 0x800
#define OMAP_AUX_CORE_BOOT_1 0x804
#define OMAP_PTMSYNCREQ_MASK 0xc00
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 4b9491aa36fa..8d014ba04abc 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 = {
};
#endif
-#ifdef CONFIG_SOC_OMAPTI81XX
+#ifdef CONFIG_SOC_TI81XX
static struct map_desc omapti81xx_io_desc[] __initdata = {
{
.virtual = L4_34XX_VIRT,
@@ -184,7 +184,7 @@ static struct map_desc omapti81xx_io_desc[] __initdata = {
};
#endif
-#ifdef CONFIG_SOC_OMAPAM33XX
+#ifdef CONFIG_SOC_AM33XX
static struct map_desc omapam33xx_io_desc[] __initdata = {
{
.virtual = L4_34XX_VIRT,
@@ -216,41 +216,11 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
.type = MT_DEVICE,
},
{
- .virtual = OMAP44XX_GPMC_VIRT,
- .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
- .length = OMAP44XX_GPMC_SIZE,
- .type = MT_DEVICE,
- },
- {
- .virtual = OMAP44XX_EMIF1_VIRT,
- .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
- .length = OMAP44XX_EMIF1_SIZE,
- .type = MT_DEVICE,
- },
- {
- .virtual = OMAP44XX_EMIF2_VIRT,
- .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
- .length = OMAP44XX_EMIF2_SIZE,
- .type = MT_DEVICE,
- },
- {
- .virtual = OMAP44XX_DMM_VIRT,
- .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS),
- .length = OMAP44XX_DMM_SIZE,
- .type = MT_DEVICE,
- },
- {
.virtual = L4_PER_44XX_VIRT,
.pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
.length = L4_PER_44XX_SIZE,
.type = MT_DEVICE,
},
- {
- .virtual = L4_EMU_44XX_VIRT,
- .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS),
- .length = L4_EMU_44XX_SIZE,
- .type = MT_DEVICE,
- },
#ifdef CONFIG_OMAP4_ERRATA_I688
{
.virtual = OMAP4_SRAM_VA,
@@ -286,14 +256,14 @@ void __init omap34xx_map_common_io(void)
}
#endif
-#ifdef CONFIG_SOC_OMAPTI81XX
+#ifdef CONFIG_SOC_TI81XX
void __init omapti81xx_map_common_io(void)
{
iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
}
#endif
-#ifdef CONFIG_SOC_OMAPAM33XX
+#ifdef CONFIG_SOC_AM33XX
void __init omapam33xx_map_common_io(void)
{
iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
@@ -380,6 +350,13 @@ void __init omap2420_init_early(void)
omap_hwmod_init_postsetup();
omap2420_clk_init();
}
+
+void __init omap2420_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap2_pm_init();
+}
#endif
#ifdef CONFIG_SOC_OMAP2430
@@ -395,6 +372,13 @@ void __init omap2430_init_early(void)
omap_hwmod_init_postsetup();
omap2430_clk_init();
}
+
+void __init omap2430_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap2_pm_init();
+}
#endif
/*
@@ -449,6 +433,48 @@ void __init ti81xx_init_early(void)
omap_hwmod_init_postsetup();
omap3xxx_clk_init();
}
+
+void __init omap3_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
+
+void __init omap3430_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
+
+void __init omap35xx_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
+
+void __init omap3630_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
+
+void __init am35xx_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
+
+void __init ti81xx_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap3_pm_init();
+}
#endif
#ifdef CONFIG_ARCH_OMAP4
@@ -465,6 +491,13 @@ void __init omap4430_init_early(void)
omap_hwmod_init_postsetup();
omap4xxx_clk_init();
}
+
+void __init omap4430_init_late(void)
+{
+ omap_mux_late_init();
+ omap2_common_pm_late_init();
+ omap4_pm_init();
+}
#endif
void __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 0812b154f5b5..80b88921faba 100644
--- a/arch/arm/mach-omap2/iomap.h
+++ b/arch/arm/mach-omap2/iomap.h
@@ -37,9 +37,6 @@
#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
-#define OMAP4_GPMC_IO_OFFSET 0xa9000000
-#define OMAP4_GPMC_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
-
#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */
#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
@@ -170,28 +167,3 @@
#define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
#define L4_ABE_44XX_SIZE SZ_1M
-#define L4_EMU_44XX_PHYS L4_EMU_44XX_BASE
- /* 0x54000000 --> 0xfe800000 */
-#define L4_EMU_44XX_VIRT (L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
-#define L4_EMU_44XX_SIZE SZ_8M
-
-#define OMAP44XX_GPMC_PHYS OMAP44XX_GPMC_BASE
- /* 0x50000000 --> 0xf9000000 */
-#define OMAP44XX_GPMC_VIRT (OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
-#define OMAP44XX_GPMC_SIZE SZ_1M
-
-
-#define OMAP44XX_EMIF1_PHYS OMAP44XX_EMIF1_BASE
- /* 0x4c000000 --> 0xfd100000 */
-#define OMAP44XX_EMIF1_VIRT (OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
-#define OMAP44XX_EMIF1_SIZE SZ_1M
-
-#define OMAP44XX_EMIF2_PHYS OMAP44XX_EMIF2_BASE
- /* 0x4d000000 --> 0xfd200000 */
-#define OMAP44XX_EMIF2_SIZE SZ_1M
-#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE)
-
-#define OMAP44XX_DMM_PHYS OMAP44XX_DMM_BASE
- /* 0x4e000000 --> 0xfd300000 */
-#define OMAP44XX_DMM_SIZE SZ_1M
-#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 1ecf54565fe2..fdc4303be563 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
goto out;
irqnr = readl_relaxed(base_addr + 0xd8);
-#ifdef CONFIG_SOC_OMAPTI81XX
+#ifdef CONFIG_SOC_TI81XX
if (irqnr)
goto out;
irqnr = readl_relaxed(base_addr + 0xf8);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 3268ee24eada..80e55c5c9998 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)
}
/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
-static int __init omap_mux_late_init(void)
+int __init omap_mux_late_init(void)
{
struct omap_mux_partition *partition;
int ret;
@@ -823,7 +823,6 @@ static int __init omap_mux_late_init(void)
return 0;
}
-late_initcall(omap_mux_late_init);
static void __init omap_mux_package_fixup(struct omap_mux *p,
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 fd48797fa95a..b26d3c9bca16 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)
rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 ||
rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
h = omap34xx_hwmod_ocp_ifs;
- } else if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
+ } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
h = am35xx_hwmod_ocp_ifs;
} else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
rev == OMAP3630_REV_ES1_2) {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d0c1c9695996..9cb5cede0f50 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)
}
postcore_initcall(omap2_common_pm_init);
-static int __init omap2_common_pm_late_init(void)
+int __init omap2_common_pm_late_init(void)
{
/*
* 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)
return 0;
}
-late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index facfffca9eac..2edeffc923a6 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)
WKUP_MOD, PM_WKEN);
}
-static int __init omap2_pm_init(void)
+int __init omap2_pm_init(void)
{
u32 l;
- if (!cpu_is_omap24xx())
- return -ENODEV;
-
printk(KERN_INFO "Power Management for OMAP2 initializing\n");
l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
@@ -370,17 +367,13 @@ static int __init omap2_pm_init(void)
* These routines need to be in SRAM as that's the only
* memory the MPU can see when it wakes up.
*/
- if (cpu_is_omap24xx()) {
- omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
- omap24xx_idle_loop_suspend_sz);
+ omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
+ omap24xx_idle_loop_suspend_sz);
- omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
- omap24xx_cpu_suspend_sz);
- }
+ omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
+ omap24xx_cpu_suspend_sz);
arm_pm_idle = omap2_pm_idle;
return 0;
}
-
-late_initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 8b43aefba0ea..a34023d0ca7c 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)
}
}
-static int __init omap3_pm_init(void)
+int __init omap3_pm_init(void)
{
struct power_state *pwrst, *tmp;
struct clockdomain *neon_clkdm, *mpu_clkdm;
int ret;
- if (!cpu_is_omap34xx())
- return -ENODEV;
-
if (!omap3_has_io_chain_ctrl())
pr_warning("PM: no software I/O chain control; some wakeups may be lost\n");
@@ -804,5 +801,3 @@ err2:
err1:
return ret;
}
-
-late_initcall(omap3_pm_init);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 885625352429..ea24174f5707 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)
* Initializes all powerdomain and clockdomain target states
* and all PRCM settings.
*/
-static int __init omap4_pm_init(void)
+int __init omap4_pm_init(void)
{
int ret;
struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
- if (!cpu_is_omap44xx())
- return -ENODEV;
-
if (omap_rev() == OMAP4430_REV_ES1_0) {
WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
return -ENODEV;
@@ -217,4 +214,3 @@ static int __init omap4_pm_init(void)
err2:
return ret;
}
-late_initcall(omap4_pm_init);
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index b7ea468eea32..fb0a0a6869d1 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)
rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
- rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
+ rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1 ||
rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
else
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 1b7835865c83..840929bd9dae 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)
}
static struct irqaction omap2_gp_timer_irq = {
- .name = "gp timer",
+ .name = "gp_timer",
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler = omap2_gp_timer_interrupt,
};
@@ -132,7 +132,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
}
static struct clock_event_device clockevent_gpt = {
- .name = "gp timer",
+ .name = "gp_timer",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.set_next_event = omap2_gp_timer_set_next_event,
@@ -236,22 +236,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
}
/* Clocksource code */
-
-#ifdef CONFIG_OMAP_32K_TIMER
-/*
- * When 32k-timer is enabled, don't use GPTimer for clocksource
- * instead, just leave default clocksource which uses the 32k
- * sync counter. See clocksource setup in plat-omap/counter_32k.c
- */
-
-static void __init omap2_gp_clocksource_init(int unused, const char *dummy)
-{
- omap_init_clocksource_32k();
-}
-
-#else
-
static struct omap_dm_timer clksrc;
+static bool use_gptimer_clksrc;
/*
* clocksource
@@ -262,7 +248,7 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs)
}
static struct clocksource clocksource_gpt = {
- .name = "gp timer",
+ .name = "gp_timer",
.rating = 300,
.read = clocksource_read_cycles,
.mask = CLOCKSOURCE_MASK(32),
@@ -278,7 +264,46 @@ static u32 notrace dmtimer_read_sched_clock(void)
}
/* Setup free-running counter for clocksource */
-static void __init omap2_gp_clocksource_init(int gptimer_id,
+static int __init omap2_sync32k_clocksource_init(void)
+{
+ int ret;
+ struct omap_hwmod *oh;
+ void __iomem *vbase;
+ const char *oh_name = "counter_32k";
+
+ /*
+ * First check hwmod data is available for sync32k counter
+ */
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh || oh->slaves_cnt == 0)
+ return -ENODEV;
+
+ omap_hwmod_setup_one(oh_name);
+
+ vbase = omap_hwmod_get_mpu_rt_va(oh);
+ if (!vbase) {
+ pr_warn("%s: failed to get counter_32k resource\n", __func__);
+ return -ENXIO;
+ }
+
+ ret = omap_hwmod_enable(oh);
+ if (ret) {
+ pr_warn("%s: failed to enable counter_32k module (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = omap_init_clocksource_32k(vbase);
+ if (ret) {
+ pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n",
+ __func__, ret);
+ omap_hwmod_idle(oh);
+ }
+
+ return ret;
+}
+
+static void __init omap2_gptimer_clocksource_init(int gptimer_id,
const char *fck_source)
{
int res;
@@ -286,9 +311,6 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source);
BUG_ON(res);
- pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
- gptimer_id, clksrc.rate);
-
__omap_dm_timer_load_start(&clksrc,
OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
@@ -296,15 +318,36 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
pr_err("Could not register clocksource %s\n",
clocksource_gpt.name);
+ else
+ pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
+ gptimer_id, clksrc.rate);
+}
+
+static void __init omap2_clocksource_init(int gptimer_id,
+ const char *fck_source)
+{
+ /*
+ * First give preference to kernel parameter configuration
+ * by user (clocksource="gp_timer").
+ *
+ * In case of missing kernel parameter for clocksource,
+ * first check for availability for 32k-sync timer, in case
+ * of failure in finding 32k_counter module or registering
+ * it as clocksource, execution will fallback to gp-timer.
+ */
+ if (use_gptimer_clksrc == true)
+ omap2_gptimer_clocksource_init(gptimer_id, fck_source);
+ else if (omap2_sync32k_clocksource_init())
+ /* Fall back to gp-timer code */
+ omap2_gptimer_clocksource_init(gptimer_id, fck_source);
}
-#endif
#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, \
clksrc_nr, clksrc_src) \
static void __init omap##name##_timer_init(void) \
{ \
omap2_gp_clockevent_init((clkev_nr), clkev_src); \
- omap2_gp_clocksource_init((clksrc_nr), clksrc_src); \
+ omap2_clocksource_init((clksrc_nr), clksrc_src); \
}
#define OMAP_SYS_TIMER(name) \
@@ -335,7 +378,7 @@ static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
static void __init omap4_timer_init(void)
{
omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
- omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE);
+ omap2_clocksource_init(2, OMAP4_MPU_SOURCE);
#ifdef CONFIG_LOCAL_TIMERS
/* Local timers are not supprted on OMAP4430 ES1.0 */
if (omap_rev() != OMAP4430_REV_ES1_0) {
@@ -503,3 +546,28 @@ static int __init omap2_dm_timer_init(void)
return 0;
}
arch_initcall(omap2_dm_timer_init);
+
+/**
+ * omap2_override_clocksource - clocksource override with user configuration
+ *
+ * Allows user to override default clocksource, using kernel parameter
+ * clocksource="gp_timer" (For all OMAP2PLUS architectures)
+ *
+ * Note that, here we are using same standard kernel parameter "clocksource=",
+ * and not introducing any OMAP specific interface.
+ */
+static int __init omap2_override_clocksource(char *str)
+{
+ if (!str)
+ return 0;
+ /*
+ * For OMAP architecture, we only have two options
+ * - sync_32k (default)
+ * - gp_timer (sys_clk based)
+ */
+ if (!strcmp(str, "gp_timer"))
+ use_gptimer_clksrc = true;
+
+ return 0;
+}
+early_param("clocksource", omap2_override_clocksource);
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 8d5ed775dd56..b19d1b43c12e 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)
musb_plat.mode = board_data->mode;
musb_plat.extvbus = board_data->extvbus;
- if (cpu_is_omap3517() || cpu_is_omap3505()) {
+ if (soc_is_am35xx()) {
oh_name = "am35x_otg_hs";
name = "musb-am35x";
} else if (cpu_is_ti81xx()) {
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index 57db2038b23c..d0103c80d040 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)
}
#endif
- if (cpu_is_omap3517() || cpu_is_omap3505())
+ if (soc_is_am35xx())
voltdms = voltagedomains_am35xx;
else
voltdms = voltagedomains_omap3;
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index e2e9db492d0c..9148b229d0de 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -18,6 +18,7 @@
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
#include <linux/delay.h>
+#include <linux/clk-provider.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/setup.h>
@@ -70,6 +71,19 @@ void __init orion5x_map_io(void)
/*****************************************************************************
+ * CLK tree
+ ****************************************************************************/
+static struct clk *tclk;
+
+static void __init clk_init(void)
+{
+ tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT,
+ orion5x_tclk);
+
+ orion_clkdev_init(tclk);
+}
+
+/*****************************************************************************
* EHCI0
****************************************************************************/
void __init orion5x_ehci0_init(void)
@@ -95,7 +109,7 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge00_init(eth_data,
ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
- IRQ_ORION5X_ETH_ERR, orion5x_tclk);
+ IRQ_ORION5X_ETH_ERR);
}
@@ -132,7 +146,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
****************************************************************************/
void __init orion5x_spi_init()
{
- orion_spi_init(SPI_PHYS_BASE, orion5x_tclk);
+ orion_spi_init(SPI_PHYS_BASE);
}
@@ -142,7 +156,7 @@ void __init orion5x_spi_init()
void __init orion5x_uart0_init(void)
{
orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
- IRQ_ORION5X_UART0, orion5x_tclk);
+ IRQ_ORION5X_UART0, tclk);
}
/*****************************************************************************
@@ -151,7 +165,7 @@ void __init orion5x_uart0_init(void)
void __init orion5x_uart1_init(void)
{
orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
- IRQ_ORION5X_UART1, orion5x_tclk);
+ IRQ_ORION5X_UART1, tclk);
}
/*****************************************************************************
@@ -179,7 +193,7 @@ static void __init orion5x_crypto_init(void)
****************************************************************************/
void __init orion5x_wdt_init(void)
{
- orion_wdt_init(orion5x_tclk);
+ orion_wdt_init();
}
@@ -276,6 +290,9 @@ void __init orion5x_init(void)
*/
orion5x_setup_cpu_mbus_bridge();
+ /* Setup root of clk tree */
+ clk_init();
+
/*
* Don't issue "Wait for Interrupt" instruction if we are
* 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 e91bf0ba4e8e..92df49c1b62a 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -16,7 +16,6 @@
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
index be4c92858509..a00d2f1254ed 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)
soft_restart(0);
}
+#ifdef CONFIG_PM
+extern int pnx4008_pm_init(void);
+#else
+static inline int pnx4008_pm_init(void) { return 0; }
+#endif
+
+void __init pnx4008_init_late(void)
+{
+ pnx4008_pm_init();
+}
+
extern struct sys_timer pnx4008_timer;
MACHINE_START(PNX4008, "Philips PNX4008")
@@ -273,6 +284,7 @@ MACHINE_START(PNX4008, "Philips PNX4008")
.map_io = pnx4008_map_io,
.init_irq = pnx4008_init_irq,
.init_machine = pnx4008_init,
+ .init_late = pnx4008_init_late,
.timer = &pnx4008_timer,
.restart = pnx4008_restart,
MACHINE_END
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
index f3e60a049f98..26f8d06b142a 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 = {
.valid = pnx4008_pm_valid,
};
-static int __init pnx4008_pm_init(void)
+int __init pnx4008_pm_init(void)
{
u32 sram_size_to_allocate;
@@ -151,5 +151,3 @@ static int __init pnx4008_pm_init(void)
suspend_set_ops(&pnx4008_pm_ops);
return 0;
}
-
-late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index b28a930d4f8a..60d826fc2185 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) {}
extern void __init sirfsoc_map_lluart(void);
#endif
+#ifdef CONFIG_SUSPEND
+extern int sirfsoc_pm_init(void);
+#else
+static inline int sirfsoc_pm_init(void) { return 0; }
+#endif
+
#endif
diff --git a/arch/arm/mach-prima2/pm.c b/arch/arm/mach-prima2/pm.c
index 26ebb57719df..fb5a7910af35 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 = {
.valid = suspend_valid_only_mem,
};
-static int __init sirfsoc_pm_init(void)
+int __init sirfsoc_pm_init(void)
{
suspend_set_ops(&sirfsoc_pm_ops);
return 0;
}
-late_initcall(sirfsoc_pm_init);
static const struct of_device_id pwrc_ids[] = {
{ .compatible = "sirf,prima2-pwrc" },
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
index 02b9c05ff990..8f0429d4b79f 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)
of_platform_bus_probe(NULL, sirfsoc_of_bus_ids, NULL);
}
+void __init sirfsoc_init_late(void)
+{
+ sirfsoc_pm_init();
+}
+
static const char *prima2cb_dt_match[] __initdata = {
"sirf,prima2-cb",
NULL
@@ -39,6 +44,7 @@ MACHINE_START(PRIMA2_EVB, "prima2cb")
.timer = &sirfsoc_timer,
.dma_zone_size = SZ_256M,
.init_machine = sirfsoc_mach_init,
+ .init_late = sirfsoc_init_late,
.dt_compat = prima2cb_dt_match,
.restart = sirfsoc_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index b34287ab5afd..e24961109b70 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -518,6 +518,11 @@ config S3C2443_DMA
help
Internal config node for S3C2443 DMA support
+config S3C2443_SETUP_SPI
+ bool
+ help
+ Common setup code for SPI GPIO configurations
+
endif # CPU_S3C2443 || CPU_S3C2416
if CPU_S3C2443
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 3518fe812d5f..0ab6ab15da4c 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -14,6 +14,8 @@ obj- :=
# core
+obj-y += common.o
+
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
@@ -33,6 +35,10 @@ obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
obj-$(CONFIG_CPU_S3C2443) += s3c2443.o irq-s3c2443.o clock-s3c2443.o
+# PM
+
+obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
+
# common code
obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o
@@ -91,5 +97,6 @@ obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o
# device setup
obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_S3C2443_SETUP_SPI) += setup-spi.o
obj-$(CONFIG_ARCH_S3C24XX) += setup-i2c.o
obj-$(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 dbc9ab4aaca2..8702ecfaab30 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[] = {
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &hsspi_mux.clk),
};
void __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 efb3ac359566..a4c5a520d994 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 = {
&clk_hsmmc,
};
+static struct clk_lookup s3c2443_clk_lookup[] = {
+ CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_hsspi.clk),
+};
+
void __init s3c2443_init_clocks(int xtal)
{
unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
@@ -210,6 +215,7 @@ void __init s3c2443_init_clocks(int xtal)
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c
index 460431589f39..aeeb2be283fa 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[] = {
.enable = s3c2443_clkcon_enable_p,
.ctrlbit = S3C2443_PCLKCON_IIS,
}, {
- .name = "hsspi",
- .parent = &clk_p,
- .enable = s3c2443_clkcon_enable_p,
- .ctrlbit = S3C2443_PCLKCON_HSSPI,
- }, {
.name = "adc",
.parent = &clk_p,
.enable = s3c2443_clkcon_enable_p,
@@ -562,6 +557,14 @@ static struct clk hsmmc1_clk = {
.ctrlbit = S3C2443_HCLKCON_HSMMC,
};
+static struct clk hsspi_clk = {
+ .name = "spi",
+ .devname = "s3c64xx-spi.0",
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_HSSPI,
+};
+
/* EPLLCON compatible enough to get on/off information */
void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
@@ -612,6 +615,7 @@ static struct clk *clks[] __initdata = {
&clk_usb_bus,
&clk_armdiv,
&hsmmc1_clk,
+ &hsspi_clk,
};
static struct clksrc_clk *clksrcs[] __initdata = {
@@ -629,6 +633,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = {
CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
+ CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &hsspi_clk),
};
void __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 290942d9adda..56cdd34cce41 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -4,7 +4,7 @@
* http://www.simtec.co.uk/products/SWLINUX/
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C24XX CPU Support
+ * Common code for S3C24XX machines
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/regs-serial.h>
@@ -52,6 +53,8 @@
#include <plat/s3c2416.h>
#include <plat/s3c244x.h>
#include <plat/s3c2443.h>
+#include <plat/cpu-freq.h>
+#include <plat/pll.h>
/* table of supported CPUs */
@@ -234,3 +237,67 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
+
+/* Serial port registrations */
+
+static struct resource s3c2410_uart0_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \
+ IRQ_S3CUART_ERR0 - IRQ_S3CUART_RX0 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART1, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX1, \
+ IRQ_S3CUART_ERR1 - IRQ_S3CUART_RX1 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2410_PA_UART2, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX2, \
+ IRQ_S3CUART_ERR2 - IRQ_S3CUART_RX2 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+static struct resource s3c2410_uart3_resource[] = {
+ [0] = DEFINE_RES_MEM(S3C2443_PA_UART3, SZ_16K),
+ [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX3, \
+ IRQ_S3CUART_ERR3 - IRQ_S3CUART_RX3 + 1, \
+ NULL, IORESOURCE_IRQ)
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c2410_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c2410_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c2410_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c2410_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
+ },
+};
+
+/* initialise all the clocks */
+
+void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
+ unsigned long hclk,
+ unsigned long pclk)
+{
+ clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
+ clk_xtal.rate);
+
+ clk_mpll.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
+}
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c
index e227c472a40a..2d94228d2866 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[] = {
.name = "sdi",
.channels = MAP(S3C2443_DMAREQSEL_SDI),
},
- [DMACH_SPI0] = {
- .name = "spi0",
+ [DMACH_SPI0_RX] = {
+ .name = "spi0-rx",
+ .channels = MAP(S3C2443_DMAREQSEL_SPI0RX),
+ },
+ [DMACH_SPI0_TX] = {
+ .name = "spi0-tx",
.channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
},
- [DMACH_SPI1] = { /* only on S3C2443/S3C2450 */
- .name = "spi1",
+ [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */
+ .name = "spi1-rx",
+ .channels = MAP(S3C2443_DMAREQSEL_SPI1RX),
+ },
+ [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */
+ .name = "spi1-tx",
.channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
},
[DMACH_UART0] = {
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
index acbdfecd4186..454831b66037 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 {
DMACH_UART2_SRC2,
DMACH_UART3, /* s3c2443 has extra uart */
DMACH_UART3_SRC2,
+ DMACH_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */
+ DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */
+ DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */
DMACH_MAX, /* the end entry */
};
diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h
index 78ae807f1281..8ba381f2dbe1 100644
--- a/arch/arm/mach-s3c24xx/include/mach/map.h
+++ b/arch/arm/mach-s3c24xx/include/mach/map.h
@@ -98,6 +98,8 @@
/* SPI */
#define S3C2410_PA_SPI (0x59000000)
+#define S3C2443_PA_SPI0 (0x52000000)
+#define S3C2443_PA_SPI1 S3C2410_PA_SPI
/* SDI */
#define S3C2410_PA_SDI (0x5A000000)
@@ -162,4 +164,7 @@
#define S3C_PA_WDT S3C2410_PA_WATCHDOG
#define S3C_PA_NAND S3C24XX_PA_NAND
+#define S3C_PA_SPI0 S3C2443_PA_SPI0
+#define S3C_PA_SPI1 S3C2443_PA_SPI1
+
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/mach-s3c24xx/irq-pm.c
index 0efb2e2848c8..0efb2e2848c8 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 60627e63a254..60627e63a254 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 000000000000..5712c85f39b1
--- /dev/null
+++ b/arch/arm/mach-s3c24xx/setup-spi.c
@@ -0,0 +1,39 @@
+/*
+ * HS-SPI device setup for S3C2443/S3C2416
+ *
+ * Copyright (C) 2011 Samsung Electronics Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/s3c64xx-spi.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .tx_st_done = 21,
+ .high_speed = 1,
+};
+
+int s3c64xx_spi0_cfg_gpio(struct platform_device *pdev)
+{
+ /* enable hsspi bit in misccr */
+ s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1);
+
+ s3c_gpio_cfgall_range(S3C2410_GPE(11), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S
index c56612569b40..c56612569b40 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 b313380342a5..be746e33e86c 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)
/* if all else fails, or mode was for soft, jump to 0 */
soft_restart(0);
}
+
+void __init s3c64xx_init_late(void)
+{
+ s3c64xx_pm_late_initcall();
+}
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
index 7a10be629aba..6cfc99bdfb37 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);
void s3c64xx_setup_clocks(void);
void s3c64xx_restart(char mode, const char *cmd);
+void s3c64xx_init_late(void);
#ifdef CONFIG_CPU_S3C6400
@@ -51,4 +52,10 @@ extern void s3c6410_init_clocks(int xtal);
#define s3c6410_init NULL
#endif
+#ifdef CONFIG_PM
+int __init s3c64xx_pm_late_initcall(void);
+#else
+static inline int s3c64xx_pm_late_initcall(void) { return 0; }
+#endif
+
#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 f252691fb209..314df0518afd 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")
.handle_irq = vic_handle_irq,
.map_io = anw6410_map_io,
.init_machine = anw6410_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index aa1137fb47e6..eda5e027b109 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")
.handle_irq = vic_handle_irq,
.map_io = crag6410_map_io,
.init_machine = crag6410_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 521e07b8501b..1bf6b9da20fc 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")
.handle_irq = vic_handle_irq,
.map_io = hmt_map_io,
.init_machine = hmt_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index b2166d4a5538..f8ea61ea3b33 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")
.handle_irq = vic_handle_irq,
.map_io = mini6410_map_io,
.init_machine = mini6410_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 0efa2ba783b2..cad2e05eddf7 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")
.handle_irq = vic_handle_irq,
.map_io = ncp_map_io,
.init_machine = ncp_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 5c08266cea21..b92d8e17d502 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")
.handle_irq = vic_handle_irq,
.map_io = real6410_map_io,
.init_machine = real6410_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index 3f42431d4dda..c5021d0335c6 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")
.handle_irq = vic_handle_irq,
.map_io = smartq_map_io,
.init_machine = smartq5_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index e5c09b6db967..aa9072a4cbef 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")
.handle_irq = vic_handle_irq,
.map_io = smartq_map_io,
.init_machine = smartq7_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
index 5f096534f4c4..b0f4525c66bd 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")
.handle_irq = vic_handle_irq,
.map_io = smdk6400_map_io,
.init_machine = smdk6400_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 7da044f738ac..d44319b09412 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")
.handle_irq = vic_handle_irq,
.map_io = smdk6410_map_io,
.init_machine = smdk6410_machine_init,
+ .init_late = s3c64xx_init_late,
.timer = &s3c24xx_timer,
.restart = s3c64xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 7d3e81b9dd06..7feb426fc202 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)
}
arch_initcall(s3c64xx_pm_initcall);
-static __init int s3c64xx_pm_late_initcall(void)
+int __init s3c64xx_pm_late_initcall(void)
{
pm_genpd_poweroff_unused();
return 0;
}
-late_initcall(s3c64xx_pm_late_initcall);
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 375d3f779a88..d1dc7f1a239c 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -538,6 +538,7 @@ MACHINE_START(ASSABET, "Intel-Assabet")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = assabet_init,
+ .init_late = sa11x0_init_late,
#ifdef CONFIG_SA1111
.dma_zone_size = SZ_1M,
#endif
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index e0f0c030258c..b30fb99b587c 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")
.map_io = badge4_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq,
+ .init_late = sa11x0_init_late,
.timer = &sa1100_timer,
#ifdef CONFIG_SA1111
.dma_zone_size = SZ_1M,
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 4a61f60e0502..09d7f4b4b354 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")
.init_irq = cerf_init_irq,
.timer = &sa1100_timer,
.init_machine = cerf_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index c7f418b0cde9..ea5cff38745c 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -401,5 +401,6 @@ MACHINE_START(COLLIE, "Sharp-Collie")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = collie_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 16be4c56abe3..9db3e98e8b85 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)
arch_initcall(sa1100_init);
+void __init sa11x0_init_late(void)
+{
+ sa11x0_pm_init();
+}
/*
* Common I/O mapping:
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 9eb3b3cd5a63..a5b7c13da3e3 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);
extern void __init sa1100_init_irq(void);
extern void __init sa1100_init_gpio(void);
extern void sa11x0_restart(char, const char *);
+extern void sa11x0_init_late(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
@@ -41,3 +42,9 @@ void sa11x0_register_mcp(struct mcp_plat_data *data);
struct sa1100fb_mach_info;
void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
+
+#ifdef CONFIG_PM
+int sa11x0_pm_init(void);
+#else
+static inline int sa11x0_pm_init(void) { return 0; }
+#endif
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index b2e8d0f418e0..e1571eab08ae 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")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = h3100_mach_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index cb6659f294fe..ba7a2901ab88 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")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = h3600_mach_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index 5535475bf583..7f86bd911826 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")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = hackkit_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index ca7a7e834720..e3084f47027d 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")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = jornada720_mach_init,
+ .init_late = sa11x0_init_late,
#ifdef CONFIG_SA1111
.dma_zone_size = SZ_1M,
#endif
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index eb6534e0b0d0..b775a0abec0a 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -147,6 +147,7 @@ MACHINE_START(LART, "LART")
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq,
.init_machine = lart_init,
+ .init_late = sa11x0_init_late,
.timer = &sa1100_timer,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 8f6446b9f025..41f69d97066f 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -112,5 +112,6 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = nanoengine_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 1602575a0d5c..37fe0a0a5369 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -135,5 +135,6 @@ MACHINE_START(PLEB, "PLEB")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = pleb_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 2fa499ec6afe..690cf0ce5c0c 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 = {
.valid = suspend_valid_only_mem,
};
-static int __init sa11x0_pm_init(void)
+int __init sa11x0_pm_init(void)
{
suspend_set_ops(&sa11x0_pm_ops);
return 0;
}
-
-late_initcall(sa11x0_pm_init);
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index ca8bf59b9047..5d33fc3108ef 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)")
.init_irq = sa1100_init_irq,
.timer = &sa1100_timer,
.init_machine = shannon_init,
+ .init_late = sa11x0_init_late,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 3efae03cb3d7..fbd53593be54 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -395,6 +395,7 @@ MACHINE_START(SIMPAD, "Simpad")
.map_io = simpad_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq,
+ .init_late = sa11x0_init_late,
.timer = &sa1100_timer,
.restart = sa11x0_restart,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e6b177bc9410..8aa1962c22a2 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
#
# Common objects
-obj-y := timer.o console.o clock.o
+obj-y := timer.o console.o clock.o common.o
# CPU objects
obj-$(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 0891ec6e27f5..5a6f22f05e99 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")
.init_irq = sh73a0_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = ag5evm_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index b540b8eb20ca..ace60246a5df 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")
.init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = ap4evb_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index 63ab7062bee3..e9b32cfbf741 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")
.init_irq = r8a7740_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = bonito_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 39b6cf85ced6..796fa00ad3c4 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")
.init_irq = sh7367_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = g3evm_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 0e5a39c670bc..f1257321999a 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")
.init_irq = sh7377_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = g4evm_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 200dcd42a3a0..f60f1b281cc4 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")
.init_irq = sh73a0_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = kota2_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 50c67b22d087..b577f7c44678 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")
.init_irq = sh7372_init_irq,
.handle_irq = shmobile_handle_irq_intc,
.init_machine = mackerel_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index ef0e13bf0b3a..14de3787cafc 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")
.init_irq = r8a7779_init_irq,
.handle_irq = gic_handle_irq,
.init_machine = marzen_init,
+ .init_late = shmobile_init_late,
.timer = &shmobile_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c
new file mode 100644
index 000000000000..608aba9d60d7
--- /dev/null
+++ b/arch/arm/mach-shmobile/common.c
@@ -0,0 +1,24 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/common.h>
+
+void __init shmobile_init_late(void)
+{
+ shmobile_suspend_init();
+ shmobile_cpuidle_init();
+}
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
index 7e6559105d40..7b541e911ab4 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 = {
void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
-static int shmobile_cpuidle_init(void)
+int shmobile_cpuidle_init(void)
{
struct cpuidle_device *dev = &shmobile_cpuidle_dev;
struct cpuidle_driver *drv = &shmobile_cpuidle_driver;
@@ -65,4 +65,3 @@ static int shmobile_cpuidle_init(void)
return 0;
}
-late_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 ff5f12fd742f..01e2bc014f15 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);
extern void r8a7779_smp_prepare_cpus(void);
extern void r8a7779_register_twd(void);
+extern void shmobile_init_late(void);
+
+#ifdef CONFIG_SUSPEND
+int shmobile_suspend_init(void);
+#else
+static inline int shmobile_suspend_init(void) { return 0; }
+#endif
+
+#ifdef CONFIG_CPU_IDLE
+int shmobile_cpuidle_init(void);
+#else
+static inline int shmobile_cpuidle_init(void) { return 0; }
+#endif
+
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
index 4d1b86a49923..47d83f7a70b6 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 = {
.valid = suspend_valid_only_mem,
};
-static int __init shmobile_suspend_init(void)
+int __init shmobile_suspend_init(void)
{
suspend_set_ops(&shmobile_suspend_ops);
return 0;
}
-late_initcall(shmobile_suspend_init);
diff --git a/arch/arm/mach-spear13xx/Kconfig b/arch/arm/mach-spear13xx/Kconfig
new file mode 100644
index 000000000000..eaadc66d96b3
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Kconfig
@@ -0,0 +1,20 @@
+#
+# SPEAr13XX Machine configuration file
+#
+
+if ARCH_SPEAR13XX
+
+menu "SPEAr13xx Implementations"
+config MACH_SPEAR1310
+ bool "SPEAr1310 Machine support with Device Tree"
+ select PINCTRL_SPEAR1310
+ help
+ Supports ST SPEAr1310 machine configured via the device-tree
+
+config MACH_SPEAR1340
+ bool "SPEAr1340 Machine support with Device Tree"
+ select PINCTRL_SPEAR1340
+ help
+ Supports ST SPEAr1340 machine configured via the device-tree
+endmenu
+endif #ARCH_SPEAR13XX
diff --git a/arch/arm/mach-spear13xx/Makefile b/arch/arm/mach-spear13xx/Makefile
new file mode 100644
index 000000000000..3435ea78c15d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for SPEAr13XX machine series
+#
+
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+obj-$(CONFIG_ARCH_SPEAR13XX) += spear13xx.o
+obj-$(CONFIG_MACH_SPEAR1310) += spear1310.o
+obj-$(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 000000000000..403efd7e6d27
--- /dev/null
+++ b/arch/arm/mach-spear13xx/Makefile.boot
@@ -0,0 +1,6 @@
+zreladdr-y += 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
+dtb-$(CONFIG_MACH_SPEAR1310) += spear1310-evb.dtb
+dtb-$(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 000000000000..ed85473a047f
--- /dev/null
+++ b/arch/arm/mach-spear13xx/headsmp.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-spear13XX/headsmp.S
+ *
+ * Picked from realview
+ * Copyright (c) 2012 ST Microelectronics Limited
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * spear13xx specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(spear13xx_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /* re-enable coherency */
+ mrc p15, 0, r0, c1, c0, 1
+ orr r0, r0, #(1 << 6) | (1 << 0)
+ mcr p15, 0, r0, c1, c0, 1
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+ .align
+1: .long .
+ .long pen_release
+ENDPROC(spear13xx_secondary_startup)
diff --git a/arch/arm/mach-spear13xx/hotplug.c b/arch/arm/mach-spear13xx/hotplug.c
new file mode 100644
index 000000000000..5c6867b46d09
--- /dev/null
+++ b/arch/arm/mach-spear13xx/hotplug.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-spear13xx/hotplug.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Deepak Sikri <deepak.sikri@st.com>
+ *
+ * based upon linux/arch/arm/mach-realview/hotplug.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " dsb\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C)
+ : "cc", "memory");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile("mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
+{
+ for (;;) {
+ wfi();
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void __cpuinit platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
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 000000000000..ea1564609bd4
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header spear13xx machine family
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <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 000000000000..383ab04dc6c9
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/dma.h
@@ -0,0 +1,128 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/dma.h
+ *
+ * DMA information for SPEAr13xx machine family
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* request id of all the peripherals */
+enum dma_master_info {
+ /* Accessible from only one master */
+ DMA_MASTER_MCIF = 0,
+ DMA_MASTER_FSMC = 1,
+ /* Accessible from both 0 & 1 */
+ DMA_MASTER_MEMORY = 0,
+ DMA_MASTER_ADC = 0,
+ DMA_MASTER_UART0 = 0,
+ DMA_MASTER_SSP0 = 0,
+ DMA_MASTER_I2C0 = 0,
+
+#ifdef CONFIG_MACH_SPEAR1310
+ /* Accessible from only one master */
+ SPEAR1310_DMA_MASTER_JPEG = 1,
+
+ /* Accessible from both 0 & 1 */
+ SPEAR1310_DMA_MASTER_I2S = 0,
+ SPEAR1310_DMA_MASTER_UART1 = 0,
+ SPEAR1310_DMA_MASTER_UART2 = 0,
+ SPEAR1310_DMA_MASTER_UART3 = 0,
+ SPEAR1310_DMA_MASTER_UART4 = 0,
+ SPEAR1310_DMA_MASTER_UART5 = 0,
+ SPEAR1310_DMA_MASTER_I2C1 = 0,
+ SPEAR1310_DMA_MASTER_I2C2 = 0,
+ SPEAR1310_DMA_MASTER_I2C3 = 0,
+ SPEAR1310_DMA_MASTER_I2C4 = 0,
+ SPEAR1310_DMA_MASTER_I2C5 = 0,
+ SPEAR1310_DMA_MASTER_I2C6 = 0,
+ SPEAR1310_DMA_MASTER_I2C7 = 0,
+ SPEAR1310_DMA_MASTER_SSP1 = 0,
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+ /* Accessible from only one master */
+ SPEAR1340_DMA_MASTER_I2S_PLAY = 1,
+ SPEAR1340_DMA_MASTER_I2S_REC = 1,
+ SPEAR1340_DMA_MASTER_I2C1 = 1,
+ SPEAR1340_DMA_MASTER_UART1 = 1,
+
+ /* following are accessible from both master 0 & 1 */
+ SPEAR1340_DMA_MASTER_SPDIF = 0,
+ SPEAR1340_DMA_MASTER_CAM = 1,
+ SPEAR1340_DMA_MASTER_VIDEO_IN = 0,
+ SPEAR1340_DMA_MASTER_MALI = 0,
+#endif
+};
+
+enum request_id {
+ DMA_REQ_ADC = 0,
+ DMA_REQ_SSP0_TX = 4,
+ DMA_REQ_SSP0_RX = 5,
+ DMA_REQ_UART0_TX = 6,
+ DMA_REQ_UART0_RX = 7,
+ DMA_REQ_I2C0_TX = 8,
+ DMA_REQ_I2C0_RX = 9,
+
+#ifdef CONFIG_MACH_SPEAR1310
+ SPEAR1310_DMA_REQ_FROM_JPEG = 2,
+ SPEAR1310_DMA_REQ_TO_JPEG = 3,
+ SPEAR1310_DMA_REQ_I2S_TX = 10,
+ SPEAR1310_DMA_REQ_I2S_RX = 11,
+
+ SPEAR1310_DMA_REQ_I2C1_RX = 0,
+ SPEAR1310_DMA_REQ_I2C1_TX = 1,
+ SPEAR1310_DMA_REQ_I2C2_RX = 2,
+ SPEAR1310_DMA_REQ_I2C2_TX = 3,
+ SPEAR1310_DMA_REQ_I2C3_RX = 4,
+ SPEAR1310_DMA_REQ_I2C3_TX = 5,
+ SPEAR1310_DMA_REQ_I2C4_RX = 6,
+ SPEAR1310_DMA_REQ_I2C4_TX = 7,
+ SPEAR1310_DMA_REQ_I2C5_RX = 8,
+ SPEAR1310_DMA_REQ_I2C5_TX = 9,
+ SPEAR1310_DMA_REQ_I2C6_RX = 10,
+ SPEAR1310_DMA_REQ_I2C6_TX = 11,
+ SPEAR1310_DMA_REQ_UART1_RX = 12,
+ SPEAR1310_DMA_REQ_UART1_TX = 13,
+ SPEAR1310_DMA_REQ_UART2_RX = 14,
+ SPEAR1310_DMA_REQ_UART2_TX = 15,
+ SPEAR1310_DMA_REQ_UART5_RX = 16,
+ SPEAR1310_DMA_REQ_UART5_TX = 17,
+ SPEAR1310_DMA_REQ_SSP1_RX = 18,
+ SPEAR1310_DMA_REQ_SSP1_TX = 19,
+ SPEAR1310_DMA_REQ_I2C7_RX = 20,
+ SPEAR1310_DMA_REQ_I2C7_TX = 21,
+ SPEAR1310_DMA_REQ_UART3_RX = 28,
+ SPEAR1310_DMA_REQ_UART3_TX = 29,
+ SPEAR1310_DMA_REQ_UART4_RX = 30,
+ SPEAR1310_DMA_REQ_UART4_TX = 31,
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+ SPEAR1340_DMA_REQ_SPDIF_TX = 2,
+ SPEAR1340_DMA_REQ_SPDIF_RX = 3,
+ SPEAR1340_DMA_REQ_I2S_TX = 10,
+ SPEAR1340_DMA_REQ_I2S_RX = 11,
+ SPEAR1340_DMA_REQ_UART1_TX = 12,
+ SPEAR1340_DMA_REQ_UART1_RX = 13,
+ SPEAR1340_DMA_REQ_I2C1_TX = 14,
+ SPEAR1340_DMA_REQ_I2C1_RX = 15,
+ SPEAR1340_DMA_REQ_CAM0_EVEN = 0,
+ SPEAR1340_DMA_REQ_CAM0_ODD = 1,
+ SPEAR1340_DMA_REQ_CAM1_EVEN = 2,
+ SPEAR1340_DMA_REQ_CAM1_ODD = 3,
+ SPEAR1340_DMA_REQ_CAM2_EVEN = 4,
+ SPEAR1340_DMA_REQ_CAM2_ODD = 5,
+ SPEAR1340_DMA_REQ_CAM3_EVEN = 6,
+ SPEAR1340_DMA_REQ_CAM3_ODD = 7,
+#endif
+};
+
+#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 000000000000..6d8c45b9f298
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/generic.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/generic.h
+ *
+ * spear13xx machine family generic header file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/dmaengine.h>
+#include <asm/mach/time.h>
+
+/* Add spear13xx structure declarations here */
+extern struct sys_timer spear13xx_timer;
+extern struct pl022_ssp_controller pl022_plat_data;
+extern struct dw_dma_platform_data dmac_plat_data;
+extern struct dw_dma_slave cf_dma_priv;
+extern struct dw_dma_slave nand_read_dma_priv;
+extern struct dw_dma_slave nand_write_dma_priv;
+
+/* Add spear13xx family function declarations here */
+void __init spear_setup_of_timer(void);
+void __init spear13xx_map_io(void);
+void __init spear13xx_dt_init_irq(void);
+void __init spear13xx_l2x0_init(void);
+bool dw_dma_filter(struct dma_chan *chan, void *slave);
+void spear_restart(char, const char *);
+void spear13xx_secondary_startup(void);
+
+#ifdef CONFIG_MACH_SPEAR1310
+void __init spear1310_clk_init(void);
+#else
+static inline void spear1310_clk_init(void) {}
+#endif
+
+#ifdef CONFIG_MACH_SPEAR1340
+void __init spear1340_clk_init(void);
+#else
+static inline void spear1340_clk_init(void) {}
+#endif
+
+#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 000000000000..cd6f4f86a56b
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr13xx machine family
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#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 000000000000..40a8c178f10d
--- /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 000000000000..f542a24aa5f2
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/irqs.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for spear13xx machine family
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_GIC_END 160
+#define NR_IRQS IRQ_GIC_END
+
+#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 000000000000..30c57ef72686
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/spear.h
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/spear.h
+ *
+ * spear13xx Machine family specific definition
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR13XX_H
+#define __MACH_SPEAR13XX_H
+
+#include <asm/memory.h>
+
+#define PERIP_GRP2_BASE UL(0xB3000000)
+#define VA_PERIP_GRP2_BASE UL(0xFE000000)
+#define MCIF_SDHCI_BASE UL(0xB3000000)
+#define SYSRAM0_BASE UL(0xB3800000)
+#define VA_SYSRAM0_BASE UL(0xFE800000)
+#define SYS_LOCATION (VA_SYSRAM0_BASE + 0x600)
+
+#define PERIP_GRP1_BASE UL(0xE0000000)
+#define VA_PERIP_GRP1_BASE UL(0xFD000000)
+#define UART_BASE UL(0xE0000000)
+#define VA_UART_BASE UL(0xFD000000)
+#define SSP_BASE UL(0xE0100000)
+#define MISC_BASE UL(0xE0700000)
+#define VA_MISC_BASE IOMEM(UL(0xFD700000))
+
+#define A9SM_AND_MPMC_BASE UL(0xEC000000)
+#define VA_A9SM_AND_MPMC_BASE UL(0xFC000000)
+
+/* A9SM peripheral offsets */
+#define A9SM_PERIP_BASE UL(0xEC800000)
+#define VA_A9SM_PERIP_BASE UL(0xFC800000)
+#define VA_SCU_BASE (VA_A9SM_PERIP_BASE + 0x00)
+
+#define L2CC_BASE UL(0xED000000)
+#define VA_L2CC_BASE IOMEM(UL(0xFB000000))
+
+/* others */
+#define DMAC0_BASE UL(0xEA800000)
+#define DMAC1_BASE UL(0xEB000000)
+#define MCIF_CF_BASE UL(0xB2800000)
+
+/* Devices present in SPEAr1310 */
+#ifdef CONFIG_MACH_SPEAR1310
+#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000)
+#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000)
+#define SPEAR1310_RAS_BASE UL(0xD8400000)
+#define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000))
+#endif /* CONFIG_MACH_SPEAR1310 */
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE UART_BASE
+#define VA_SPEAR_DBG_UART_BASE VA_UART_BASE
+
+#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 000000000000..e69de29bb2d1
--- /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 000000000000..e69de29bb2d1
--- /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 000000000000..31af3e8d976e
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/timex.h
+ *
+ * SPEAr3XX machine family specific timex definitions
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#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 000000000000..c7840896ae6e
--- /dev/null
+++ b/arch/arm/mach-spear13xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear13xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#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 000000000000..f5d07f2663d7
--- /dev/null
+++ b/arch/arm/mach-spear13xx/platsmp.c
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-spear13xx/platsmp.c
+ *
+ * based upon linux/arch/arm/mach-realview/platsmp.c
+ *
+ * Copyright (C) 2012 ST Microelectronics Ltd.
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <mach/spear.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
+extern void spear13xx_secondary_startup(void);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_secondary_init(0);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ pen_release = -1;
+ smp_wmb();
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID.
+ */
+ pen_release = cpu;
+ flush_cache_all();
+ outer_flush_all();
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ smp_rmb();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+ unsigned int i, ncores = scu_get_core_count(scu_base);
+
+ if (ncores > nr_cpu_ids) {
+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
+ ncores, nr_cpu_ids);
+ ncores = nr_cpu_ids;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+
+ scu_enable(scu_base);
+
+ /*
+ * Write the address of secondary startup into the system-wide location
+ * (presently it is in SRAM). The BootMonitor waits until it receives a
+ * soft interrupt, and then the secondary CPU branches to this address.
+ */
+ __raw_writel(virt_to_phys(spear13xx_secondary_startup), SYS_LOCATION);
+}
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c
new file mode 100644
index 000000000000..fefd15b2f380
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1310.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-spear13xx/spear1310.c
+ *
+ * SPEAr1310 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr1310: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Base addresses */
+#define SPEAR1310_SSP1_BASE UL(0x5D400000)
+#define SPEAR1310_SATA0_BASE UL(0xB1000000)
+#define SPEAR1310_SATA1_BASE UL(0xB1800000)
+#define SPEAR1310_SATA2_BASE UL(0xB4000000)
+
+/* ssp device registration */
+static struct pl022_ssp_controller ssp1_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 3,
+};
+
+/* Add SPEAr1310 auxdata to pass platform data */
+static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
+ OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
+ OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
+ OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
+
+ OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
+ {}
+};
+
+static void __init spear1310_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear1310_auxdata_lookup, NULL);
+}
+
+static const char * const spear1310_dt_board_compat[] = {
+ "st,spear1310",
+ "st,spear1310-evb",
+ NULL,
+};
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xD8000000 0xFA000000
+ */
+struct map_desc spear1310_io_desc[] __initdata = {
+ {
+ .virtual = VA_SPEAR1310_RAS_GRP1_BASE,
+ .pfn = __phys_to_pfn(SPEAR1310_RAS_GRP1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
+};
+
+static void __init spear1310_map_io(void)
+{
+ iotable_init(spear1310_io_desc, ARRAY_SIZE(spear1310_io_desc));
+ spear13xx_map_io();
+}
+
+DT_MACHINE_START(SPEAR1310_DT, "ST SPEAr1310 SoC with Flattened Device Tree")
+ .map_io = spear1310_map_io,
+ .init_irq = spear13xx_dt_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &spear13xx_timer,
+ .init_machine = spear1310_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear1310_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear1340.c b/arch/arm/mach-spear13xx/spear1340.c
new file mode 100644
index 000000000000..ee38cbc56869
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear1340.c
@@ -0,0 +1,192 @@
+/*
+ * arch/arm/mach-spear13xx/spear1340.c
+ *
+ * SPEAr1340 machine source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr1340: " fmt
+
+#include <linux/ahci_platform.h>
+#include <linux/amba/serial.h>
+#include <linux/delay.h>
+#include <linux/dw_dmac.h>
+#include <linux/of_platform.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/arch.h>
+#include <mach/dma.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Base addresses */
+#define SPEAR1340_SATA_BASE UL(0xB1000000)
+#define SPEAR1340_UART1_BASE UL(0xB4100000)
+
+/* Power Management Registers */
+#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
+#define SPEAR1340_PCM_WKUP_CFG (VA_MISC_BASE + 0x104)
+#define SPEAR1340_SWITCH_CTR (VA_MISC_BASE + 0x108)
+
+#define SPEAR1340_PERIP1_SW_RST (VA_MISC_BASE + 0x318)
+#define SPEAR1340_PERIP2_SW_RST (VA_MISC_BASE + 0x31C)
+#define SPEAR1340_PERIP3_SW_RST (VA_MISC_BASE + 0x320)
+
+/* PCIE - SATA configuration registers */
+#define SPEAR1340_PCIE_SATA_CFG (VA_MISC_BASE + 0x424)
+ /* PCIE CFG MASks */
+ #define SPEAR1340_PCIE_CFG_DEVICE_PRESENT (1 << 11)
+ #define SPEAR1340_PCIE_CFG_POWERUP_RESET (1 << 10)
+ #define SPEAR1340_PCIE_CFG_CORE_CLK_EN (1 << 9)
+ #define SPEAR1340_PCIE_CFG_AUX_CLK_EN (1 << 8)
+ #define SPEAR1340_SATA_CFG_TX_CLK_EN (1 << 4)
+ #define SPEAR1340_SATA_CFG_RX_CLK_EN (1 << 3)
+ #define SPEAR1340_SATA_CFG_POWERUP_RESET (1 << 2)
+ #define SPEAR1340_SATA_CFG_PM_CLK_EN (1 << 1)
+ #define SPEAR1340_PCIE_SATA_SEL_PCIE (0)
+ #define SPEAR1340_PCIE_SATA_SEL_SATA (1)
+ #define SPEAR1340_SATA_PCIE_CFG_MASK 0xF1F
+ #define SPEAR1340_PCIE_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_PCIE | \
+ SPEAR1340_PCIE_CFG_AUX_CLK_EN | \
+ SPEAR1340_PCIE_CFG_CORE_CLK_EN | \
+ SPEAR1340_PCIE_CFG_POWERUP_RESET | \
+ SPEAR1340_PCIE_CFG_DEVICE_PRESENT)
+ #define SPEAR1340_SATA_CFG_VAL (SPEAR1340_PCIE_SATA_SEL_SATA | \
+ SPEAR1340_SATA_CFG_PM_CLK_EN | \
+ SPEAR1340_SATA_CFG_POWERUP_RESET | \
+ SPEAR1340_SATA_CFG_RX_CLK_EN | \
+ SPEAR1340_SATA_CFG_TX_CLK_EN)
+
+#define SPEAR1340_PCIE_MIPHY_CFG (VA_MISC_BASE + 0x428)
+ #define SPEAR1340_MIPHY_OSC_BYPASS_EXT (1 << 31)
+ #define SPEAR1340_MIPHY_CLK_REF_DIV2 (1 << 27)
+ #define SPEAR1340_MIPHY_CLK_REF_DIV4 (2 << 27)
+ #define SPEAR1340_MIPHY_CLK_REF_DIV8 (3 << 27)
+ #define SPEAR1340_MIPHY_PLL_RATIO_TOP(x) (x << 0)
+ #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA \
+ (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+ SPEAR1340_MIPHY_CLK_REF_DIV2 | \
+ SPEAR1340_MIPHY_PLL_RATIO_TOP(60))
+ #define SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK \
+ (SPEAR1340_MIPHY_PLL_RATIO_TOP(120))
+ #define SPEAR1340_PCIE_SATA_MIPHY_CFG_PCIE \
+ (SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
+ SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
+
+static struct dw_dma_slave uart1_dma_param[] = {
+ {
+ /* Tx */
+ .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
+ .cfg_lo = 0,
+ .src_master = DMA_MASTER_MEMORY,
+ .dst_master = SPEAR1340_DMA_MASTER_UART1,
+ }, {
+ /* Rx */
+ .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
+ .cfg_lo = 0,
+ .src_master = SPEAR1340_DMA_MASTER_UART1,
+ .dst_master = DMA_MASTER_MEMORY,
+ }
+};
+
+static struct amba_pl011_data uart1_data = {
+ .dma_filter = dw_dma_filter,
+ .dma_tx_param = &uart1_dma_param[0],
+ .dma_rx_param = &uart1_dma_param[1],
+};
+
+/* SATA device registration */
+static int sata_miphy_init(struct device *dev, void __iomem *addr)
+{
+ writel(SPEAR1340_SATA_CFG_VAL, SPEAR1340_PCIE_SATA_CFG);
+ writel(SPEAR1340_PCIE_SATA_MIPHY_CFG_SATA_25M_CRYSTAL_CLK,
+ SPEAR1340_PCIE_MIPHY_CFG);
+ /* Switch on sata power domain */
+ writel((readl(SPEAR1340_PCM_CFG) | (0x800)), SPEAR1340_PCM_CFG);
+ msleep(20);
+ /* Disable PCIE SATA Controller reset */
+ writel((readl(SPEAR1340_PERIP1_SW_RST) & (~0x1000)),
+ SPEAR1340_PERIP1_SW_RST);
+ msleep(20);
+
+ return 0;
+}
+
+void sata_miphy_exit(struct device *dev)
+{
+ writel(0, SPEAR1340_PCIE_SATA_CFG);
+ writel(0, SPEAR1340_PCIE_MIPHY_CFG);
+
+ /* Enable PCIE SATA Controller reset */
+ writel((readl(SPEAR1340_PERIP1_SW_RST) | (0x1000)),
+ SPEAR1340_PERIP1_SW_RST);
+ msleep(20);
+ /* Switch off sata power domain */
+ writel((readl(SPEAR1340_PCM_CFG) & (~0x800)), SPEAR1340_PCM_CFG);
+ msleep(20);
+}
+
+int sata_suspend(struct device *dev)
+{
+ if (dev->power.power_state.event == PM_EVENT_FREEZE)
+ return 0;
+
+ sata_miphy_exit(dev);
+
+ return 0;
+}
+
+int sata_resume(struct device *dev)
+{
+ if (dev->power.power_state.event == PM_EVENT_THAW)
+ return 0;
+
+ return sata_miphy_init(dev, NULL);
+}
+
+static struct ahci_platform_data sata_pdata = {
+ .init = sata_miphy_init,
+ .exit = sata_miphy_exit,
+ .suspend = sata_suspend,
+ .resume = sata_resume,
+};
+
+/* Add SPEAr1340 auxdata to pass platform data */
+static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
+ OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
+ OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
+ OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
+ OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
+
+ OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
+ &sata_pdata),
+ OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
+ {}
+};
+
+static void __init spear1340_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table,
+ spear1340_auxdata_lookup, NULL);
+}
+
+static const char * const spear1340_dt_board_compat[] = {
+ "st,spear1340",
+ "st,spear1340-evb",
+ NULL,
+};
+
+DT_MACHINE_START(SPEAR1340_DT, "ST SPEAr1340 SoC with Flattened Device Tree")
+ .map_io = spear13xx_map_io,
+ .init_irq = spear13xx_dt_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &spear13xx_timer,
+ .init_machine = spear1340_dt_init,
+ .restart = spear_restart,
+ .dt_compat = spear1340_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
new file mode 100644
index 000000000000..50b349ae863d
--- /dev/null
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -0,0 +1,197 @@
+/*
+ * arch/arm/mach-spear13xx/spear13xx.c
+ *
+ * SPEAr13XX machines common source file
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) "SPEAr13xx: " fmt
+
+#include <linux/amba/pl022.h>
+#include <linux/clk.h>
+#include <linux/dw_dmac.h>
+#include <linux/err.h>
+#include <linux/of_irq.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <asm/smp_twd.h>
+#include <mach/dma.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* common dw_dma filter routine to be used by peripherals */
+bool dw_dma_filter(struct dma_chan *chan, void *slave)
+{
+ struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
+
+ if (chan->device->dev == dws->dma_dev) {
+ chan->private = slave;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* ssp device registration */
+static struct dw_dma_slave ssp_dma_param[] = {
+ {
+ /* Tx */
+ .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
+ .cfg_lo = 0,
+ .src_master = DMA_MASTER_MEMORY,
+ .dst_master = DMA_MASTER_SSP0,
+ }, {
+ /* Rx */
+ .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
+ .cfg_lo = 0,
+ .src_master = DMA_MASTER_SSP0,
+ .dst_master = DMA_MASTER_MEMORY,
+ }
+};
+
+struct pl022_ssp_controller pl022_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 1,
+ .dma_filter = dw_dma_filter,
+ .dma_rx_param = &ssp_dma_param[1],
+ .dma_tx_param = &ssp_dma_param[0],
+ .num_chipselect = 3,
+};
+
+/* CF device registration */
+struct dw_dma_slave cf_dma_priv = {
+ .cfg_hi = 0,
+ .cfg_lo = 0,
+ .src_master = 0,
+ .dst_master = 0,
+};
+
+/* dmac device registeration */
+struct dw_dma_platform_data dmac_plat_data = {
+ .nr_channels = 8,
+ .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
+ .chan_priority = CHAN_PRIORITY_DESCENDING,
+};
+
+void __init spear13xx_l2x0_init(void)
+{
+ /*
+ * 512KB (64KB/way), 8-way associativity, parity supported
+ *
+ * FIXME: 9th bit, of Auxillary Controller register must be set
+ * for some spear13xx devices for stable L2 operation.
+ *
+ * Enable Early BRESP, L2 prefetch for Instruction and Data,
+ * write alloc and 'Full line of zero' options
+ *
+ */
+
+ writel_relaxed(0x06, VA_L2CC_BASE + L2X0_PREFETCH_CTRL);
+
+ /*
+ * Program following latencies in order to make
+ * SPEAr1340 work at 600 MHz
+ */
+ writel_relaxed(0x221, VA_L2CC_BASE + L2X0_TAG_LATENCY_CTRL);
+ writel_relaxed(0x441, VA_L2CC_BASE + L2X0_DATA_LATENCY_CTRL);
+ l2x0_init(VA_L2CC_BASE, 0x70A60001, 0xfe00ffff);
+}
+
+/*
+ * Following will create 16MB static virtual/physical mappings
+ * PHYSICAL VIRTUAL
+ * 0xB3000000 0xFE000000
+ * 0xE0000000 0xFD000000
+ * 0xEC000000 0xFC000000
+ * 0xED000000 0xFB000000
+ */
+struct map_desc spear13xx_io_desc[] __initdata = {
+ {
+ .virtual = VA_PERIP_GRP2_BASE,
+ .pfn = __phys_to_pfn(PERIP_GRP2_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_PERIP_GRP1_BASE,
+ .pfn = __phys_to_pfn(PERIP_GRP1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_A9SM_AND_MPMC_BASE,
+ .pfn = __phys_to_pfn(A9SM_AND_MPMC_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VA_L2CC_BASE,
+ .pfn = __phys_to_pfn(L2CC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear13xx_map_io(void)
+{
+ iotable_init(spear13xx_io_desc, ARRAY_SIZE(spear13xx_io_desc));
+}
+
+static void __init spear13xx_clk_init(void)
+{
+ if (of_machine_is_compatible("st,spear1310"))
+ spear1310_clk_init();
+ else if (of_machine_is_compatible("st,spear1340"))
+ spear1340_clk_init();
+ else
+ pr_err("%s: Unknown machine\n", __func__);
+}
+
+static void __init spear13xx_timer_init(void)
+{
+ char pclk_name[] = "osc_24m_clk";
+ struct clk *gpt_clk, *pclk;
+
+ spear13xx_clk_init();
+
+ /* get the system timer clock */
+ gpt_clk = clk_get_sys("gpt0", NULL);
+ if (IS_ERR(gpt_clk)) {
+ pr_err("%s:couldn't get clk for gpt\n", __func__);
+ BUG();
+ }
+
+ /* get the suitable parent clock for timer*/
+ pclk = clk_get(NULL, pclk_name);
+ if (IS_ERR(pclk)) {
+ pr_err("%s:couldn't get %s as parent for gpt\n", __func__,
+ pclk_name);
+ BUG();
+ }
+
+ clk_set_parent(gpt_clk, pclk);
+ clk_put(gpt_clk);
+ clk_put(pclk);
+
+ spear_setup_of_timer();
+ twd_local_timer_of_register();
+}
+
+struct sys_timer spear13xx_timer = {
+ .init = spear13xx_timer_init,
+};
+
+static const struct of_device_id gic_of_match[] __initconst = {
+ { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
+ { /* Sentinel */ }
+};
+
+void __init spear13xx_dt_init_irq(void)
+{
+ of_irq_init(gic_of_match);
+}
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
index 17b5d83cf2d5..8d12faa178fd 100644
--- a/arch/arm/mach-spear3xx/Makefile
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -3,7 +3,7 @@
#
# common files
-obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o clock.o
+obj-$(CONFIG_ARCH_SPEAR3XX) += spear3xx.o
# spear300 specific files
obj-$(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 cd6c11099083..000000000000
--- a/arch/arm/mach-spear3xx/clock.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/clock.c
- *
- * SPEAr3xx machines clock framework source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/clkdev.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <asm/mach-types.h>
-#include <plat/clock.h>
-#include <mach/misc_regs.h>
-#include <mach/spear.h>
-
-#define PLL1_CTR (MISC_BASE + 0x008)
-#define PLL1_FRQ (MISC_BASE + 0x00C)
-#define PLL1_MOD (MISC_BASE + 0x010)
-#define PLL2_CTR (MISC_BASE + 0x014)
-/* PLL_CTR register masks */
-#define PLL_ENABLE 2
-#define PLL_MODE_SHIFT 4
-#define PLL_MODE_MASK 0x3
-#define PLL_MODE_NORMAL 0
-#define PLL_MODE_FRACTION 1
-#define PLL_MODE_DITH_DSB 2
-#define PLL_MODE_DITH_SSB 3
-
-#define PLL2_FRQ (MISC_BASE + 0x018)
-/* PLL FRQ register masks */
-#define PLL_DIV_N_SHIFT 0
-#define PLL_DIV_N_MASK 0xFF
-#define PLL_DIV_P_SHIFT 8
-#define PLL_DIV_P_MASK 0x7
-#define PLL_NORM_FDBK_M_SHIFT 24
-#define PLL_NORM_FDBK_M_MASK 0xFF
-#define PLL_DITH_FDBK_M_SHIFT 16
-#define PLL_DITH_FDBK_M_MASK 0xFFFF
-
-#define PLL2_MOD (MISC_BASE + 0x01C)
-#define PLL_CLK_CFG (MISC_BASE + 0x020)
-#define CORE_CLK_CFG (MISC_BASE + 0x024)
-/* CORE CLK CFG register masks */
-#define PLL_HCLK_RATIO_SHIFT 10
-#define PLL_HCLK_RATIO_MASK 0x3
-#define HCLK_PCLK_RATIO_SHIFT 8
-#define HCLK_PCLK_RATIO_MASK 0x3
-
-#define PERIP_CLK_CFG (MISC_BASE + 0x028)
-/* PERIP_CLK_CFG register masks */
-#define UART_CLK_SHIFT 4
-#define UART_CLK_MASK 0x1
-#define FIRDA_CLK_SHIFT 5
-#define FIRDA_CLK_MASK 0x3
-#define GPT0_CLK_SHIFT 8
-#define GPT1_CLK_SHIFT 11
-#define GPT2_CLK_SHIFT 12
-#define GPT_CLK_MASK 0x1
-#define AUX_CLK_PLL3_VAL 0
-#define AUX_CLK_PLL1_VAL 1
-
-#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
-/* PERIP1_CLK_ENB register masks */
-#define UART_CLK_ENB 3
-#define SSP_CLK_ENB 5
-#define I2C_CLK_ENB 7
-#define JPEG_CLK_ENB 8
-#define FIRDA_CLK_ENB 10
-#define GPT1_CLK_ENB 11
-#define GPT2_CLK_ENB 12
-#define ADC_CLK_ENB 15
-#define RTC_CLK_ENB 17
-#define GPIO_CLK_ENB 18
-#define DMA_CLK_ENB 19
-#define SMI_CLK_ENB 21
-#define GMAC_CLK_ENB 23
-#define USBD_CLK_ENB 24
-#define USBH_CLK_ENB 25
-#define C3_CLK_ENB 31
-
-#define RAS_CLK_ENB (MISC_BASE + 0x034)
-
-#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
-#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
-#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
-/* gpt synthesizer register masks */
-#define GPT_MSCALE_SHIFT 0
-#define GPT_MSCALE_MASK 0xFFF
-#define GPT_NSCALE_SHIFT 12
-#define GPT_NSCALE_MASK 0xF
-
-#define AMEM_CLK_CFG (MISC_BASE + 0x050)
-#define EXPI_CLK_CFG (MISC_BASE + 0x054)
-#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
-#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
-#define UART_CLK_SYNT (MISC_BASE + 0x064)
-#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
-#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
-#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
-#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
-#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
-/* aux clk synthesiser register masks for irda to ras4 */
-#define AUX_SYNT_ENB 31
-#define AUX_EQ_SEL_SHIFT 30
-#define AUX_EQ_SEL_MASK 1
-#define AUX_EQ1_SEL 0
-#define AUX_EQ2_SEL 1
-#define AUX_XSCALE_SHIFT 16
-#define AUX_XSCALE_MASK 0xFFF
-#define AUX_YSCALE_SHIFT 0
-#define AUX_YSCALE_MASK 0xFFF
-
-/* root clks */
-/* 32 KHz oscillator clock */
-static struct clk osc_32k_clk = {
- .flags = ALWAYS_ENABLED,
- .rate = 32000,
-};
-
-/* 24 MHz oscillator clock */
-static struct clk osc_24m_clk = {
- .flags = ALWAYS_ENABLED,
- .rate = 24000000,
-};
-
-/* clock derived from 32 KHz osc clk */
-/* rtc clock */
-static struct clk rtc_clk = {
- .pclk = &osc_32k_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = RTC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from 24 MHz osc clk */
-/* pll masks structure */
-static struct pll_clk_masks pll1_masks = {
- .mode_mask = PLL_MODE_MASK,
- .mode_shift = PLL_MODE_SHIFT,
- .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
- .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
- .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
- .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
- .div_p_mask = PLL_DIV_P_MASK,
- .div_p_shift = PLL_DIV_P_SHIFT,
- .div_n_mask = PLL_DIV_N_MASK,
- .div_n_shift = PLL_DIV_N_SHIFT,
-};
-
-/* pll1 configuration structure */
-static struct pll_clk_config pll1_config = {
- .mode_reg = PLL1_CTR,
- .cfg_reg = PLL1_FRQ,
- .masks = &pll1_masks,
-};
-
-/* pll rate configuration table, in ascending order of rates */
-struct pll_rate_tbl pll_rtbl[] = {
- {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
- {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
-};
-
-/* PLL1 clock */
-static struct clk pll1_clk = {
- .flags = ENABLED_ON_INIT,
- .pclk = &osc_24m_clk,
- .en_reg = PLL1_CTR,
- .en_reg_bit = PLL_ENABLE,
- .calc_rate = &pll_calc_rate,
- .recalc = &pll_clk_recalc,
- .set_rate = &pll_clk_set_rate,
- .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
- .private_data = &pll1_config,
-};
-
-/* PLL3 48 MHz clock */
-static struct clk pll3_48m_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &osc_24m_clk,
- .rate = 48000000,
-};
-
-/* watch dog timer clock */
-static struct clk wdt_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &osc_24m_clk,
- .recalc = &follow_parent,
-};
-
-/* clock derived from pll1 clk */
-/* cpu clock */
-static struct clk cpu_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .recalc = &follow_parent,
-};
-
-/* ahb masks structure */
-static struct bus_clk_masks ahb_masks = {
- .mask = PLL_HCLK_RATIO_MASK,
- .shift = PLL_HCLK_RATIO_SHIFT,
-};
-
-/* ahb configuration structure */
-static struct bus_clk_config ahb_config = {
- .reg = CORE_CLK_CFG,
- .masks = &ahb_masks,
-};
-
-/* ahb rate configuration table, in ascending order of rates */
-struct bus_rate_tbl bus_rtbl[] = {
- {.div = 3}, /* == parent divided by 4 */
- {.div = 2}, /* == parent divided by 3 */
- {.div = 1}, /* == parent divided by 2 */
- {.div = 0}, /* == parent divided by 1 */
-};
-
-/* ahb clock */
-static struct clk ahb_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &bus_calc_rate,
- .recalc = &bus_clk_recalc,
- .set_rate = &bus_clk_set_rate,
- .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
- .private_data = &ahb_config,
-};
-
-/* auxiliary synthesizers masks */
-static struct aux_clk_masks aux_masks = {
- .eq_sel_mask = AUX_EQ_SEL_MASK,
- .eq_sel_shift = AUX_EQ_SEL_SHIFT,
- .eq1_mask = AUX_EQ1_SEL,
- .eq2_mask = AUX_EQ2_SEL,
- .xscale_sel_mask = AUX_XSCALE_MASK,
- .xscale_sel_shift = AUX_XSCALE_SHIFT,
- .yscale_sel_mask = AUX_YSCALE_MASK,
- .yscale_sel_shift = AUX_YSCALE_SHIFT,
-};
-
-/* uart synth configurations */
-static struct aux_clk_config uart_synth_config = {
- .synth_reg = UART_CLK_SYNT,
- .masks = &aux_masks,
-};
-
-/* aux rate configuration table, in ascending order of rates */
-struct aux_rate_tbl aux_rtbl[] = {
- /* For PLL1 = 332 MHz */
- {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
- {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
- {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
-};
-
-/* uart synth clock */
-static struct clk uart_synth_clk = {
- .en_reg = UART_CLK_SYNT,
- .en_reg_bit = AUX_SYNT_ENB,
- .pclk = &pll1_clk,
- .calc_rate = &aux_calc_rate,
- .recalc = &aux_clk_recalc,
- .set_rate = &aux_clk_set_rate,
- .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
- .private_data = &uart_synth_config,
-};
-
-/* uart parents */
-static struct pclk_info uart_pclk_info[] = {
- {
- .pclk = &uart_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* uart parent select structure */
-static struct pclk_sel uart_pclk_sel = {
- .pclk_info = uart_pclk_info,
- .pclk_count = ARRAY_SIZE(uart_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = UART_CLK_MASK,
-};
-
-/* uart clock */
-static struct clk uart_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = UART_CLK_ENB,
- .pclk_sel = &uart_pclk_sel,
- .pclk_sel_shift = UART_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* firda configurations */
-static struct aux_clk_config firda_synth_config = {
- .synth_reg = FIRDA_CLK_SYNT,
- .masks = &aux_masks,
-};
-
-/* firda synth clock */
-static struct clk firda_synth_clk = {
- .en_reg = FIRDA_CLK_SYNT,
- .en_reg_bit = AUX_SYNT_ENB,
- .pclk = &pll1_clk,
- .calc_rate = &aux_calc_rate,
- .recalc = &aux_clk_recalc,
- .set_rate = &aux_clk_set_rate,
- .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
- .private_data = &firda_synth_config,
-};
-
-/* firda parents */
-static struct pclk_info firda_pclk_info[] = {
- {
- .pclk = &firda_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* firda parent select structure */
-static struct pclk_sel firda_pclk_sel = {
- .pclk_info = firda_pclk_info,
- .pclk_count = ARRAY_SIZE(firda_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = FIRDA_CLK_MASK,
-};
-
-/* firda clock */
-static struct clk firda_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = FIRDA_CLK_ENB,
- .pclk_sel = &firda_pclk_sel,
- .pclk_sel_shift = FIRDA_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt synthesizer masks */
-static struct gpt_clk_masks gpt_masks = {
- .mscale_sel_mask = GPT_MSCALE_MASK,
- .mscale_sel_shift = GPT_MSCALE_SHIFT,
- .nscale_sel_mask = GPT_NSCALE_MASK,
- .nscale_sel_shift = GPT_NSCALE_SHIFT,
-};
-
-/* gpt rate configuration table, in ascending order of rates */
-struct gpt_rate_tbl gpt_rtbl[] = {
- /* For pll1 = 332 MHz */
- {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
- {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
- {.mscale = 1, .nscale = 0}, /* 83 MHz */
-};
-
-/* gpt0 synth clk config*/
-static struct gpt_clk_config gpt0_synth_config = {
- .synth_reg = PRSC1_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt synth clock */
-static struct clk gpt0_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt0_synth_config,
-};
-
-/* gpt parents */
-static struct pclk_info gpt0_pclk_info[] = {
- {
- .pclk = &gpt0_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt0_pclk_sel = {
- .pclk_info = gpt0_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt0 timer clock */
-static struct clk gpt0_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk_sel = &gpt0_pclk_sel,
- .pclk_sel_shift = GPT0_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt1 synth clk configurations */
-static struct gpt_clk_config gpt1_synth_config = {
- .synth_reg = PRSC2_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt1 synth clock */
-static struct clk gpt1_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt1_synth_config,
-};
-
-static struct pclk_info gpt1_pclk_info[] = {
- {
- .pclk = &gpt1_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt1_pclk_sel = {
- .pclk_info = gpt1_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt1_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt1 timer clock */
-static struct clk gpt1_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GPT1_CLK_ENB,
- .pclk_sel = &gpt1_pclk_sel,
- .pclk_sel_shift = GPT1_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt2 synth clk configurations */
-static struct gpt_clk_config gpt2_synth_config = {
- .synth_reg = PRSC3_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt1 synth clock */
-static struct clk gpt2_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt2_synth_config,
-};
-
-static struct pclk_info gpt2_pclk_info[] = {
- {
- .pclk = &gpt2_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt2_pclk_sel = {
- .pclk_info = gpt2_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt2 timer clock */
-static struct clk gpt2_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GPT2_CLK_ENB,
- .pclk_sel = &gpt2_pclk_sel,
- .pclk_sel_shift = GPT2_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* clock derived from pll3 clk */
-/* usbh clock */
-static struct clk usbh_clk = {
- .pclk = &pll3_48m_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = USBH_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* usbd clock */
-static struct clk usbd_clk = {
- .pclk = &pll3_48m_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = USBD_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from usbh clk */
-/* usbh0 clock */
-static struct clk usbh0_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &usbh_clk,
- .recalc = &follow_parent,
-};
-
-/* usbh1 clock */
-static struct clk usbh1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &usbh_clk,
- .recalc = &follow_parent,
-};
-
-/* clock derived from ahb clk */
-/* apb masks structure */
-static struct bus_clk_masks apb_masks = {
- .mask = HCLK_PCLK_RATIO_MASK,
- .shift = HCLK_PCLK_RATIO_SHIFT,
-};
-
-/* apb configuration structure */
-static struct bus_clk_config apb_config = {
- .reg = CORE_CLK_CFG,
- .masks = &apb_masks,
-};
-
-/* apb clock */
-static struct clk apb_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .calc_rate = &bus_calc_rate,
- .recalc = &bus_clk_recalc,
- .set_rate = &bus_clk_set_rate,
- .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
- .private_data = &apb_config,
-};
-
-/* i2c clock */
-static struct clk i2c_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = I2C_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* dma clock */
-static struct clk dma_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = DMA_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* jpeg clock */
-static struct clk jpeg_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = JPEG_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* gmac clock */
-static struct clk gmac_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GMAC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* smi clock */
-static struct clk smi_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SMI_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* c3 clock */
-static struct clk c3_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = C3_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from apb clk */
-/* adc clock */
-static struct clk adc_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = ADC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* emi clock */
-static struct clk emi_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .recalc = &follow_parent,
-};
-#endif
-
-/* ssp clock */
-static struct clk ssp0_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SSP_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* gpio clock */
-static struct clk gpio_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GPIO_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-static struct clk dummy_apb_pclk;
-
-#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
- defined(CONFIG_MACH_SPEAR320)
-/* fsmc clock */
-static struct clk fsmc_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .recalc = &follow_parent,
-};
-#endif
-
-/* common clocks to spear310 and spear320 */
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-/* uart1 clock */
-static struct clk uart1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* uart2 clock */
-static struct clk uart2_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
-
-/* common clocks to spear300 and spear320 */
-#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
-/* clcd clock */
-static struct clk clcd_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll3_48m_clk,
- .recalc = &follow_parent,
-};
-
-/* sdhci clock */
-static struct clk sdhci_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .recalc = &follow_parent,
-};
-#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
-
-/* spear300 machine specific clock structures */
-#ifdef CONFIG_MACH_SPEAR300
-/* gpio1 clock */
-static struct clk gpio1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* keyboard clock */
-static struct clk kbd_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-#endif
-
-/* spear310 machine specific clock structures */
-#ifdef CONFIG_MACH_SPEAR310
-/* uart3 clock */
-static struct clk uart3_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* uart4 clock */
-static struct clk uart4_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* uart5 clock */
-static struct clk uart5_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-#endif
-
-/* spear320 machine specific clock structures */
-#ifdef CONFIG_MACH_SPEAR320
-/* can0 clock */
-static struct clk can0_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* can1 clock */
-static struct clk can1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* i2c1 clock */
-static struct clk i2c1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .recalc = &follow_parent,
-};
-
-/* ssp1 clock */
-static struct clk ssp1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* ssp2 clock */
-static struct clk ssp2_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* pwm clock */
-static struct clk pwm_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-#endif
-
-/* array of all spear 3xx clock lookups */
-static struct clk_lookup spear_clk_lookups[] = {
- CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
- /* root clks */
- CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
- CLKDEV_INIT(NULL, "osc_24m_clk", &osc_24m_clk),
- /* clock derived from 32 KHz osc clk */
- CLKDEV_INIT("fc900000.rtc", NULL, &rtc_clk),
- /* clock derived from 24 MHz osc clk */
- CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
- CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
- CLKDEV_INIT("fc880000.wdt", NULL, &wdt_clk),
- /* clock derived from pll1 clk */
- CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
- CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
- CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
- CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
- CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
- CLKDEV_INIT(NULL, "gpt1_synth_clk", &gpt1_synth_clk),
- CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
- CLKDEV_INIT("d0000000.serial", NULL, &uart_clk),
- CLKDEV_INIT("firda", NULL, &firda_clk),
- CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
- CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
- CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
- /* clock derived from pll3 clk */
- CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
- CLKDEV_INIT(NULL, "usbh_clk", &usbh_clk),
- /* clock derived from usbh clk */
- CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
- CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
- /* clock derived from ahb clk */
- CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
- CLKDEV_INIT("d0180000.i2c", NULL, &i2c_clk),
- CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
- CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
- CLKDEV_INIT("e0800000.eth", NULL, &gmac_clk),
- CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
- CLKDEV_INIT("c3", NULL, &c3_clk),
- /* clock derived from apb clk */
- CLKDEV_INIT("adc", NULL, &adc_clk),
- CLKDEV_INIT("d0100000.spi", NULL, &ssp0_clk),
- CLKDEV_INIT("fc980000.gpio", NULL, &gpio_clk),
-};
-
-/* array of all spear 300 clock lookups */
-#ifdef CONFIG_MACH_SPEAR300
-static struct clk_lookup spear300_clk_lookups[] = {
- CLKDEV_INIT("60000000.clcd", NULL, &clcd_clk),
- CLKDEV_INIT("94000000.flash", NULL, &fsmc_clk),
- CLKDEV_INIT("a9000000.gpio", NULL, &gpio1_clk),
- CLKDEV_INIT("a0000000.kbd", NULL, &kbd_clk),
- CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
-};
-
-void __init spear300_clk_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
- clk_register(&spear_clk_lookups[i]);
-
- for (i = 0; i < ARRAY_SIZE(spear300_clk_lookups); i++)
- clk_register(&spear300_clk_lookups[i]);
-
- clk_init();
-}
-#endif
-
-/* array of all spear 310 clock lookups */
-#ifdef CONFIG_MACH_SPEAR310
-static struct clk_lookup spear310_clk_lookups[] = {
- CLKDEV_INIT("44000000.flash", NULL, &fsmc_clk),
- CLKDEV_INIT(NULL, "emi", &emi_clk),
- CLKDEV_INIT("b2000000.serial", NULL, &uart1_clk),
- CLKDEV_INIT("b2080000.serial", NULL, &uart2_clk),
- CLKDEV_INIT("b2100000.serial", NULL, &uart3_clk),
- CLKDEV_INIT("b2180000.serial", NULL, &uart4_clk),
- CLKDEV_INIT("b2200000.serial", NULL, &uart5_clk),
-};
-
-void __init spear310_clk_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
- clk_register(&spear_clk_lookups[i]);
-
- for (i = 0; i < ARRAY_SIZE(spear310_clk_lookups); i++)
- clk_register(&spear310_clk_lookups[i]);
-
- clk_init();
-}
-#endif
-
-/* array of all spear 320 clock lookups */
-#ifdef CONFIG_MACH_SPEAR320
-static struct clk_lookup spear320_clk_lookups[] = {
- CLKDEV_INIT("90000000.clcd", NULL, &clcd_clk),
- CLKDEV_INIT("4c000000.flash", NULL, &fsmc_clk),
- CLKDEV_INIT("a7000000.i2c", NULL, &i2c1_clk),
- CLKDEV_INIT(NULL, "emi", &emi_clk),
- CLKDEV_INIT("pwm", NULL, &pwm_clk),
- CLKDEV_INIT("70000000.sdhci", NULL, &sdhci_clk),
- CLKDEV_INIT("c_can_platform.0", NULL, &can0_clk),
- CLKDEV_INIT("c_can_platform.1", NULL, &can1_clk),
- CLKDEV_INIT("a5000000.spi", NULL, &ssp1_clk),
- CLKDEV_INIT("a6000000.spi", NULL, &ssp2_clk),
- CLKDEV_INIT("a3000000.serial", NULL, &uart1_clk),
- CLKDEV_INIT("a4000000.serial", NULL, &uart2_clk),
-};
-
-void __init spear320_clk_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
- clk_register(&spear_clk_lookups[i]);
-
- for (i = 0; i < ARRAY_SIZE(spear320_clk_lookups); i++)
- clk_register(&spear320_clk_lookups[i]);
-
- clk_init();
-}
-#endif
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
index bdb304551caf..4a95b9453c2a 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;
extern struct pl08x_platform_data pl080_plat_data;
/* Add spear3xx family function declarations here */
-void __init spear_setup_timer(resource_size_t base, int irq);
+void __init spear_setup_of_timer(void);
+void __init spear3xx_clk_init(void);
void __init spear3xx_map_io(void);
void __init spear3xx_dt_init_irq(void);
void spear_restart(char, const char *);
-/* spear300 declarations */
-#ifdef CONFIG_MACH_SPEAR300
-void __init spear300_clk_init(void);
-
-#endif /* CONFIG_MACH_SPEAR300 */
-
-/* spear310 declarations */
-#ifdef CONFIG_MACH_SPEAR310
-void __init spear310_clk_init(void);
-
-#endif /* CONFIG_MACH_SPEAR310 */
-
-/* spear320 declarations */
-#ifdef CONFIG_MACH_SPEAR320
-void __init spear320_clk_init(void);
-
-#endif /* CONFIG_MACH_SPEAR320 */
-
#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 319620a1afb4..51bd62a0254c 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -16,7 +16,6 @@
/* FIXME: probe all these from DT */
#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1
-#define SPEAR3XX_IRQ_CPU_GPT1_1 2
#define SPEAR3XX_IRQ_GEN_RAS_1 28
#define SPEAR3XX_IRQ_GEN_RAS_2 29
#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 e0ab72e61507..18e2ac576f25 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 @@
#ifndef __MACH_MISC_REGS_H
#define __MACH_MISC_REGS_H
+#include <mach/spear.h>
+
#define MISC_BASE IOMEM(VA_SPEAR3XX_ICM3_MISC_REG_BASE)
#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
index 6d4dadc67633..51eb953148a9 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -26,7 +26,6 @@
/* ML1 - Multi Layer CPU Subsystem */
#define SPEAR3XX_ICM3_ML1_2_BASE UL(0xF0000000)
#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
-#define SPEAR3XX_CPU_TMR_BASE UL(0xF0000000)
/* ICM3 - Basic Subsystem */
#define SPEAR3XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
@@ -45,4 +44,17 @@
#define SPEAR_SYS_CTRL_BASE SPEAR3XX_ICM3_SYS_CTRL_BASE
#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR3XX_ICM3_SYS_CTRL_BASE
+/* SPEAr320 Macros */
+#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
+#define VA_SPEAR320_SOC_CONFIG_BASE UL(0xFE000000)
+#define SPEAR320_CONTROL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE)
+#define SPEAR320_EXT_CTRL_REG IOMEM(VA_SPEAR320_SOC_CONFIG_BASE + 0x0018)
+ #define SPEAR320_UARTX_PCLK_MASK 0x1
+ #define SPEAR320_UART2_PCLK_SHIFT 8
+ #define SPEAR320_UART3_PCLK_SHIFT 9
+ #define SPEAR320_UART4_PCLK_SHIFT 10
+ #define SPEAR320_UART5_PCLK_SHIFT 11
+ #define SPEAR320_UART6_PCLK_SHIFT 12
+ #define SPEAR320_RS485_PCLK_SHIFT 13
+
#endif /* __MACH_SPEAR3XX_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index f75fe25a620c..f74a05bdb829 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[] = {
static void __init spear300_map_io(void)
{
spear3xx_map_io();
- spear300_clk_init();
}
DT_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 f0842a58dc02..84dfb0900747 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[] = {
static void __init spear310_map_io(void)
{
spear3xx_map_io();
- spear310_clk_init();
}
DT_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 e8caeef50a5c..a88fa841d29d 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -27,7 +27,6 @@
#define SPEAR320_UART2_BASE UL(0xA4000000)
#define SPEAR320_SSP0_BASE UL(0xA5000000)
#define SPEAR320_SSP1_BASE UL(0xA6000000)
-#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
/* Interrupt registers offsets and masks */
#define SPEAR320_INT_STS_MASK_REG 0x04
@@ -481,10 +480,19 @@ static const char * const spear320_dt_board_compat[] = {
NULL,
};
+struct map_desc spear320_io_desc[] __initdata = {
+ {
+ .virtual = VA_SPEAR320_SOC_CONFIG_BASE,
+ .pfn = __phys_to_pfn(SPEAR320_SOC_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
+};
+
static void __init spear320_map_io(void)
{
+ iotable_init(spear320_io_desc, ARRAY_SIZE(spear320_io_desc));
spear3xx_map_io();
- spear320_clk_init();
}
DT_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 826ac20ef1e7..f22419ed74a8 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)
char pclk_name[] = "pll3_48m_clk";
struct clk *gpt_clk, *pclk;
+ spear3xx_clk_init();
+
/* get the system timer clock */
gpt_clk = clk_get_sys("gpt0", NULL);
if (IS_ERR(gpt_clk)) {
@@ -109,7 +111,7 @@ static void __init spear3xx_timer_init(void)
clk_put(gpt_clk);
clk_put(pclk);
- spear_setup_timer(SPEAR3XX_CPU_TMR_BASE, SPEAR3XX_IRQ_CPU_GPT1_1);
+ spear_setup_of_timer();
}
struct sys_timer spear3xx_timer = {
diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile
index 76e5750552fc..898831d93f37 100644
--- a/arch/arm/mach-spear6xx/Makefile
+++ b/arch/arm/mach-spear6xx/Makefile
@@ -3,4 +3,4 @@
#
# common files
-obj-y += clock.o spear6xx.o
+obj-y += spear6xx.o
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
deleted file mode 100644
index bef77d43db87..000000000000
--- a/arch/arm/mach-spear6xx/clock.c
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * arch/arm/mach-spear6xx/clock.c
- *
- * SPEAr6xx machines clock framework source file
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <plat/clock.h>
-#include <mach/misc_regs.h>
-#include <mach/spear.h>
-
-#define PLL1_CTR (MISC_BASE + 0x008)
-#define PLL1_FRQ (MISC_BASE + 0x00C)
-#define PLL1_MOD (MISC_BASE + 0x010)
-#define PLL2_CTR (MISC_BASE + 0x014)
-/* PLL_CTR register masks */
-#define PLL_ENABLE 2
-#define PLL_MODE_SHIFT 4
-#define PLL_MODE_MASK 0x3
-#define PLL_MODE_NORMAL 0
-#define PLL_MODE_FRACTION 1
-#define PLL_MODE_DITH_DSB 2
-#define PLL_MODE_DITH_SSB 3
-
-#define PLL2_FRQ (MISC_BASE + 0x018)
-/* PLL FRQ register masks */
-#define PLL_DIV_N_SHIFT 0
-#define PLL_DIV_N_MASK 0xFF
-#define PLL_DIV_P_SHIFT 8
-#define PLL_DIV_P_MASK 0x7
-#define PLL_NORM_FDBK_M_SHIFT 24
-#define PLL_NORM_FDBK_M_MASK 0xFF
-#define PLL_DITH_FDBK_M_SHIFT 16
-#define PLL_DITH_FDBK_M_MASK 0xFFFF
-
-#define PLL2_MOD (MISC_BASE + 0x01C)
-#define PLL_CLK_CFG (MISC_BASE + 0x020)
-#define CORE_CLK_CFG (MISC_BASE + 0x024)
-/* CORE CLK CFG register masks */
-#define PLL_HCLK_RATIO_SHIFT 10
-#define PLL_HCLK_RATIO_MASK 0x3
-#define HCLK_PCLK_RATIO_SHIFT 8
-#define HCLK_PCLK_RATIO_MASK 0x3
-
-#define PERIP_CLK_CFG (MISC_BASE + 0x028)
-/* PERIP_CLK_CFG register masks */
-#define CLCD_CLK_SHIFT 2
-#define CLCD_CLK_MASK 0x3
-#define UART_CLK_SHIFT 4
-#define UART_CLK_MASK 0x1
-#define FIRDA_CLK_SHIFT 5
-#define FIRDA_CLK_MASK 0x3
-#define GPT0_CLK_SHIFT 8
-#define GPT1_CLK_SHIFT 10
-#define GPT2_CLK_SHIFT 11
-#define GPT3_CLK_SHIFT 12
-#define GPT_CLK_MASK 0x1
-#define AUX_CLK_PLL3_VAL 0
-#define AUX_CLK_PLL1_VAL 1
-
-#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
-/* PERIP1_CLK_ENB register masks */
-#define UART0_CLK_ENB 3
-#define UART1_CLK_ENB 4
-#define SSP0_CLK_ENB 5
-#define SSP1_CLK_ENB 6
-#define I2C_CLK_ENB 7
-#define JPEG_CLK_ENB 8
-#define FSMC_CLK_ENB 9
-#define FIRDA_CLK_ENB 10
-#define GPT2_CLK_ENB 11
-#define GPT3_CLK_ENB 12
-#define GPIO2_CLK_ENB 13
-#define SSP2_CLK_ENB 14
-#define ADC_CLK_ENB 15
-#define GPT1_CLK_ENB 11
-#define RTC_CLK_ENB 17
-#define GPIO1_CLK_ENB 18
-#define DMA_CLK_ENB 19
-#define SMI_CLK_ENB 21
-#define CLCD_CLK_ENB 22
-#define GMAC_CLK_ENB 23
-#define USBD_CLK_ENB 24
-#define USBH0_CLK_ENB 25
-#define USBH1_CLK_ENB 26
-
-#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
-#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
-#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
-/* gpt synthesizer register masks */
-#define GPT_MSCALE_SHIFT 0
-#define GPT_MSCALE_MASK 0xFFF
-#define GPT_NSCALE_SHIFT 12
-#define GPT_NSCALE_MASK 0xF
-
-#define AMEM_CLK_CFG (MISC_BASE + 0x050)
-#define EXPI_CLK_CFG (MISC_BASE + 0x054)
-#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
-#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
-#define UART_CLK_SYNT (MISC_BASE + 0x064)
-#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
-#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
-#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
-#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
-#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
-/* aux clk synthesiser register masks for irda to ras4 */
-#define AUX_SYNT_ENB 31
-#define AUX_EQ_SEL_SHIFT 30
-#define AUX_EQ_SEL_MASK 1
-#define AUX_EQ1_SEL 0
-#define AUX_EQ2_SEL 1
-#define AUX_XSCALE_SHIFT 16
-#define AUX_XSCALE_MASK 0xFFF
-#define AUX_YSCALE_SHIFT 0
-#define AUX_YSCALE_MASK 0xFFF
-
-/* root clks */
-/* 32 KHz oscillator clock */
-static struct clk osc_32k_clk = {
- .flags = ALWAYS_ENABLED,
- .rate = 32000,
-};
-
-/* 30 MHz oscillator clock */
-static struct clk osc_30m_clk = {
- .flags = ALWAYS_ENABLED,
- .rate = 30000000,
-};
-
-/* clock derived from 32 KHz osc clk */
-/* rtc clock */
-static struct clk rtc_clk = {
- .pclk = &osc_32k_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = RTC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from 30 MHz osc clk */
-/* pll masks structure */
-static struct pll_clk_masks pll1_masks = {
- .mode_mask = PLL_MODE_MASK,
- .mode_shift = PLL_MODE_SHIFT,
- .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
- .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
- .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
- .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
- .div_p_mask = PLL_DIV_P_MASK,
- .div_p_shift = PLL_DIV_P_SHIFT,
- .div_n_mask = PLL_DIV_N_MASK,
- .div_n_shift = PLL_DIV_N_SHIFT,
-};
-
-/* pll1 configuration structure */
-static struct pll_clk_config pll1_config = {
- .mode_reg = PLL1_CTR,
- .cfg_reg = PLL1_FRQ,
- .masks = &pll1_masks,
-};
-
-/* pll rate configuration table, in ascending order of rates */
-struct pll_rate_tbl pll_rtbl[] = {
- {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
- {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
-};
-
-/* PLL1 clock */
-static struct clk pll1_clk = {
- .flags = ENABLED_ON_INIT,
- .pclk = &osc_30m_clk,
- .en_reg = PLL1_CTR,
- .en_reg_bit = PLL_ENABLE,
- .calc_rate = &pll_calc_rate,
- .recalc = &pll_clk_recalc,
- .set_rate = &pll_clk_set_rate,
- .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
- .private_data = &pll1_config,
-};
-
-/* PLL3 48 MHz clock */
-static struct clk pll3_48m_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &osc_30m_clk,
- .rate = 48000000,
-};
-
-/* watch dog timer clock */
-static struct clk wdt_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &osc_30m_clk,
- .recalc = &follow_parent,
-};
-
-/* clock derived from pll1 clk */
-/* cpu clock */
-static struct clk cpu_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .recalc = &follow_parent,
-};
-
-/* ahb masks structure */
-static struct bus_clk_masks ahb_masks = {
- .mask = PLL_HCLK_RATIO_MASK,
- .shift = PLL_HCLK_RATIO_SHIFT,
-};
-
-/* ahb configuration structure */
-static struct bus_clk_config ahb_config = {
- .reg = CORE_CLK_CFG,
- .masks = &ahb_masks,
-};
-
-/* ahb rate configuration table, in ascending order of rates */
-struct bus_rate_tbl bus_rtbl[] = {
- {.div = 3}, /* == parent divided by 4 */
- {.div = 2}, /* == parent divided by 3 */
- {.div = 1}, /* == parent divided by 2 */
- {.div = 0}, /* == parent divided by 1 */
-};
-
-/* ahb clock */
-static struct clk ahb_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &bus_calc_rate,
- .recalc = &bus_clk_recalc,
- .set_rate = &bus_clk_set_rate,
- .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
- .private_data = &ahb_config,
-};
-
-/* auxiliary synthesizers masks */
-static struct aux_clk_masks aux_masks = {
- .eq_sel_mask = AUX_EQ_SEL_MASK,
- .eq_sel_shift = AUX_EQ_SEL_SHIFT,
- .eq1_mask = AUX_EQ1_SEL,
- .eq2_mask = AUX_EQ2_SEL,
- .xscale_sel_mask = AUX_XSCALE_MASK,
- .xscale_sel_shift = AUX_XSCALE_SHIFT,
- .yscale_sel_mask = AUX_YSCALE_MASK,
- .yscale_sel_shift = AUX_YSCALE_SHIFT,
-};
-
-/* uart configurations */
-static struct aux_clk_config uart_synth_config = {
- .synth_reg = UART_CLK_SYNT,
- .masks = &aux_masks,
-};
-
-/* aux rate configuration table, in ascending order of rates */
-struct aux_rate_tbl aux_rtbl[] = {
- /* For PLL1 = 332 MHz */
- {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
- {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
- {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
-};
-
-/* uart synth clock */
-static struct clk uart_synth_clk = {
- .en_reg = UART_CLK_SYNT,
- .en_reg_bit = AUX_SYNT_ENB,
- .pclk = &pll1_clk,
- .calc_rate = &aux_calc_rate,
- .recalc = &aux_clk_recalc,
- .set_rate = &aux_clk_set_rate,
- .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
- .private_data = &uart_synth_config,
-};
-
-/* uart parents */
-static struct pclk_info uart_pclk_info[] = {
- {
- .pclk = &uart_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* uart parent select structure */
-static struct pclk_sel uart_pclk_sel = {
- .pclk_info = uart_pclk_info,
- .pclk_count = ARRAY_SIZE(uart_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = UART_CLK_MASK,
-};
-
-/* uart0 clock */
-static struct clk uart0_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = UART0_CLK_ENB,
- .pclk_sel = &uart_pclk_sel,
- .pclk_sel_shift = UART_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* uart1 clock */
-static struct clk uart1_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = UART1_CLK_ENB,
- .pclk_sel = &uart_pclk_sel,
- .pclk_sel_shift = UART_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* firda configurations */
-static struct aux_clk_config firda_synth_config = {
- .synth_reg = FIRDA_CLK_SYNT,
- .masks = &aux_masks,
-};
-
-/* firda synth clock */
-static struct clk firda_synth_clk = {
- .en_reg = FIRDA_CLK_SYNT,
- .en_reg_bit = AUX_SYNT_ENB,
- .pclk = &pll1_clk,
- .calc_rate = &aux_calc_rate,
- .recalc = &aux_clk_recalc,
- .set_rate = &aux_clk_set_rate,
- .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
- .private_data = &firda_synth_config,
-};
-
-/* firda parents */
-static struct pclk_info firda_pclk_info[] = {
- {
- .pclk = &firda_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* firda parent select structure */
-static struct pclk_sel firda_pclk_sel = {
- .pclk_info = firda_pclk_info,
- .pclk_count = ARRAY_SIZE(firda_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = FIRDA_CLK_MASK,
-};
-
-/* firda clock */
-static struct clk firda_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = FIRDA_CLK_ENB,
- .pclk_sel = &firda_pclk_sel,
- .pclk_sel_shift = FIRDA_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* clcd configurations */
-static struct aux_clk_config clcd_synth_config = {
- .synth_reg = CLCD_CLK_SYNT,
- .masks = &aux_masks,
-};
-
-/* firda synth clock */
-static struct clk clcd_synth_clk = {
- .en_reg = CLCD_CLK_SYNT,
- .en_reg_bit = AUX_SYNT_ENB,
- .pclk = &pll1_clk,
- .calc_rate = &aux_calc_rate,
- .recalc = &aux_clk_recalc,
- .set_rate = &aux_clk_set_rate,
- .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
- .private_data = &clcd_synth_config,
-};
-
-/* clcd parents */
-static struct pclk_info clcd_pclk_info[] = {
- {
- .pclk = &clcd_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* clcd parent select structure */
-static struct pclk_sel clcd_pclk_sel = {
- .pclk_info = clcd_pclk_info,
- .pclk_count = ARRAY_SIZE(clcd_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = CLCD_CLK_MASK,
-};
-
-/* clcd clock */
-static struct clk clcd_clk = {
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = CLCD_CLK_ENB,
- .pclk_sel = &clcd_pclk_sel,
- .pclk_sel_shift = CLCD_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt synthesizer masks */
-static struct gpt_clk_masks gpt_masks = {
- .mscale_sel_mask = GPT_MSCALE_MASK,
- .mscale_sel_shift = GPT_MSCALE_SHIFT,
- .nscale_sel_mask = GPT_NSCALE_MASK,
- .nscale_sel_shift = GPT_NSCALE_SHIFT,
-};
-
-/* gpt rate configuration table, in ascending order of rates */
-struct gpt_rate_tbl gpt_rtbl[] = {
- /* For pll1 = 332 MHz */
- {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
- {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
- {.mscale = 1, .nscale = 0}, /* 83 MHz */
-};
-
-/* gpt0 synth clk config*/
-static struct gpt_clk_config gpt0_synth_config = {
- .synth_reg = PRSC1_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt synth clock */
-static struct clk gpt0_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt0_synth_config,
-};
-
-/* gpt parents */
-static struct pclk_info gpt0_pclk_info[] = {
- {
- .pclk = &gpt0_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt0_pclk_sel = {
- .pclk_info = gpt0_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt0 ARM1 subsystem timer clock */
-static struct clk gpt0_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk_sel = &gpt0_pclk_sel,
- .pclk_sel_shift = GPT0_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-
-/* Note: gpt0 and gpt1 share same parent clocks */
-/* gpt parent select structure */
-static struct pclk_sel gpt1_pclk_sel = {
- .pclk_info = gpt0_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt1 timer clock */
-static struct clk gpt1_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk_sel = &gpt1_pclk_sel,
- .pclk_sel_shift = GPT1_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt2 synth clk config*/
-static struct gpt_clk_config gpt2_synth_config = {
- .synth_reg = PRSC2_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt synth clock */
-static struct clk gpt2_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt2_synth_config,
-};
-
-/* gpt parents */
-static struct pclk_info gpt2_pclk_info[] = {
- {
- .pclk = &gpt2_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt2_pclk_sel = {
- .pclk_info = gpt2_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt2 timer clock */
-static struct clk gpt2_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk_sel = &gpt2_pclk_sel,
- .pclk_sel_shift = GPT2_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* gpt3 synth clk config*/
-static struct gpt_clk_config gpt3_synth_config = {
- .synth_reg = PRSC3_CLK_CFG,
- .masks = &gpt_masks,
-};
-
-/* gpt synth clock */
-static struct clk gpt3_synth_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &pll1_clk,
- .calc_rate = &gpt_calc_rate,
- .recalc = &gpt_clk_recalc,
- .set_rate = &gpt_clk_set_rate,
- .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
- .private_data = &gpt3_synth_config,
-};
-
-/* gpt parents */
-static struct pclk_info gpt3_pclk_info[] = {
- {
- .pclk = &gpt3_synth_clk,
- .pclk_val = AUX_CLK_PLL1_VAL,
- }, {
- .pclk = &pll3_48m_clk,
- .pclk_val = AUX_CLK_PLL3_VAL,
- },
-};
-
-/* gpt parent select structure */
-static struct pclk_sel gpt3_pclk_sel = {
- .pclk_info = gpt3_pclk_info,
- .pclk_count = ARRAY_SIZE(gpt3_pclk_info),
- .pclk_sel_reg = PERIP_CLK_CFG,
- .pclk_sel_mask = GPT_CLK_MASK,
-};
-
-/* gpt3 timer clock */
-static struct clk gpt3_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk_sel = &gpt3_pclk_sel,
- .pclk_sel_shift = GPT3_CLK_SHIFT,
- .recalc = &follow_parent,
-};
-
-/* clock derived from pll3 clk */
-/* usbh0 clock */
-static struct clk usbh0_clk = {
- .pclk = &pll3_48m_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = USBH0_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* usbh1 clock */
-static struct clk usbh1_clk = {
- .pclk = &pll3_48m_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = USBH1_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* usbd clock */
-static struct clk usbd_clk = {
- .pclk = &pll3_48m_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = USBD_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from ahb clk */
-/* apb masks structure */
-static struct bus_clk_masks apb_masks = {
- .mask = HCLK_PCLK_RATIO_MASK,
- .shift = HCLK_PCLK_RATIO_SHIFT,
-};
-
-/* apb configuration structure */
-static struct bus_clk_config apb_config = {
- .reg = CORE_CLK_CFG,
- .masks = &apb_masks,
-};
-
-/* apb clock */
-static struct clk apb_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &ahb_clk,
- .calc_rate = &bus_calc_rate,
- .recalc = &bus_clk_recalc,
- .set_rate = &bus_clk_set_rate,
- .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
- .private_data = &apb_config,
-};
-
-/* i2c clock */
-static struct clk i2c_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = I2C_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* dma clock */
-static struct clk dma_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = DMA_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* jpeg clock */
-static struct clk jpeg_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = JPEG_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* gmac clock */
-static struct clk gmac_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GMAC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* smi clock */
-static struct clk smi_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SMI_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* fsmc clock */
-static struct clk fsmc_clk = {
- .pclk = &ahb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = FSMC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* clock derived from apb clk */
-/* adc clock */
-static struct clk adc_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = ADC_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* ssp0 clock */
-static struct clk ssp0_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SSP0_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* ssp1 clock */
-static struct clk ssp1_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SSP1_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* ssp2 clock */
-static struct clk ssp2_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = SSP2_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* gpio0 ARM subsystem clock */
-static struct clk gpio0_clk = {
- .flags = ALWAYS_ENABLED,
- .pclk = &apb_clk,
- .recalc = &follow_parent,
-};
-
-/* gpio1 clock */
-static struct clk gpio1_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GPIO1_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-/* gpio2 clock */
-static struct clk gpio2_clk = {
- .pclk = &apb_clk,
- .en_reg = PERIP1_CLK_ENB,
- .en_reg_bit = GPIO2_CLK_ENB,
- .recalc = &follow_parent,
-};
-
-static struct clk dummy_apb_pclk;
-
-/* array of all spear 6xx clock lookups */
-static struct clk_lookup spear_clk_lookups[] = {
- CLKDEV_INIT(NULL, "apb_pclk", &dummy_apb_pclk),
- /* root clks */
- CLKDEV_INIT(NULL, "osc_32k_clk", &osc_32k_clk),
- CLKDEV_INIT(NULL, "osc_30m_clk", &osc_30m_clk),
- /* clock derived from 32 KHz os clk */
- CLKDEV_INIT("rtc-spear", NULL, &rtc_clk),
- /* clock derived from 30 MHz os clk */
- CLKDEV_INIT(NULL, "pll1_clk", &pll1_clk),
- CLKDEV_INIT(NULL, "pll3_48m_clk", &pll3_48m_clk),
- CLKDEV_INIT("wdt", NULL, &wdt_clk),
- /* clock derived from pll1 clk */
- CLKDEV_INIT(NULL, "cpu_clk", &cpu_clk),
- CLKDEV_INIT(NULL, "ahb_clk", &ahb_clk),
- CLKDEV_INIT(NULL, "uart_synth_clk", &uart_synth_clk),
- CLKDEV_INIT(NULL, "firda_synth_clk", &firda_synth_clk),
- CLKDEV_INIT(NULL, "clcd_synth_clk", &clcd_synth_clk),
- CLKDEV_INIT(NULL, "gpt0_synth_clk", &gpt0_synth_clk),
- CLKDEV_INIT(NULL, "gpt2_synth_clk", &gpt2_synth_clk),
- CLKDEV_INIT(NULL, "gpt3_synth_clk", &gpt3_synth_clk),
- CLKDEV_INIT("d0000000.serial", NULL, &uart0_clk),
- CLKDEV_INIT("d0080000.serial", NULL, &uart1_clk),
- CLKDEV_INIT("firda", NULL, &firda_clk),
- CLKDEV_INIT("clcd", NULL, &clcd_clk),
- CLKDEV_INIT("gpt0", NULL, &gpt0_clk),
- CLKDEV_INIT("gpt1", NULL, &gpt1_clk),
- CLKDEV_INIT("gpt2", NULL, &gpt2_clk),
- CLKDEV_INIT("gpt3", NULL, &gpt3_clk),
- /* clock derived from pll3 clk */
- CLKDEV_INIT("designware_udc", NULL, &usbd_clk),
- CLKDEV_INIT(NULL, "usbh.0_clk", &usbh0_clk),
- CLKDEV_INIT(NULL, "usbh.1_clk", &usbh1_clk),
- /* clock derived from ahb clk */
- CLKDEV_INIT(NULL, "apb_clk", &apb_clk),
- CLKDEV_INIT("d0200000.i2c", NULL, &i2c_clk),
- CLKDEV_INIT("fc400000.dma", NULL, &dma_clk),
- CLKDEV_INIT("jpeg", NULL, &jpeg_clk),
- CLKDEV_INIT("gmac", NULL, &gmac_clk),
- CLKDEV_INIT("fc000000.flash", NULL, &smi_clk),
- CLKDEV_INIT("d1800000.flash", NULL, &fsmc_clk),
- /* clock derived from apb clk */
- CLKDEV_INIT("adc", NULL, &adc_clk),
- CLKDEV_INIT("ssp-pl022.0", NULL, &ssp0_clk),
- CLKDEV_INIT("ssp-pl022.1", NULL, &ssp1_clk),
- CLKDEV_INIT("ssp-pl022.2", NULL, &ssp2_clk),
- CLKDEV_INIT("f0100000.gpio", NULL, &gpio0_clk),
- CLKDEV_INIT("fc980000.gpio", NULL, &gpio1_clk),
- CLKDEV_INIT("d8100000.gpio", NULL, &gpio2_clk),
-};
-
-void __init spear6xx_clk_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
- clk_register(&spear_clk_lookups[i]);
-
- clk_init();
-}
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
index 7167fd331d86..65514b159370 100644
--- a/arch/arm/mach-spear6xx/include/mach/generic.h
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -16,7 +16,7 @@
#include <linux/init.h>
-void __init spear_setup_timer(resource_size_t base, int irq);
+void __init spear_setup_of_timer(void);
void spear_restart(char, const char *);
void __init spear6xx_clk_init(void);
diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h
index 2b735389e74b..37a5c411a866 100644
--- a/arch/arm/mach-spear6xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear6xx/include/mach/irqs.h
@@ -16,9 +16,6 @@
/* IRQ definitions */
/* VIC 1 */
-/* FIXME: probe this from DT */
-#define IRQ_CPU_GPT1_1 16
-
#define IRQ_VIC_END 64
/* 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 2b9aaa6cdd11..179e45774b3a 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 @@
#ifndef __MACH_MISC_REGS_H
#define __MACH_MISC_REGS_H
+#include <mach/spear.h>
+
#define MISC_BASE IOMEM(VA_SPEAR6XX_ICM3_MISC_REG_BASE)
#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
index d278ed047a53..cb8ed2f4dc85 100644
--- a/arch/arm/mach-spear6xx/include/mach/spear.h
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -25,7 +25,6 @@
/* ML-1, 2 - Multi Layer CPU Subsystem */
#define SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
#define VA_SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
-#define SPEAR6XX_CPU_TMR_BASE UL(0xF0000000)
/* ICM3 - Basic Subsystem */
#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 de194dbb8371..2e2e3596583e 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 = {
void __init spear6xx_map_io(void)
{
iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
-
- /* This will initialize clock framework */
- spear6xx_clk_init();
}
static void __init spear6xx_timer_init(void)
@@ -429,6 +426,8 @@ static void __init spear6xx_timer_init(void)
char pclk_name[] = "pll3_48m_clk";
struct clk *gpt_clk, *pclk;
+ spear6xx_clk_init();
+
/* get the system timer clock */
gpt_clk = clk_get_sys("gpt0", NULL);
if (IS_ERR(gpt_clk)) {
@@ -448,7 +447,7 @@ static void __init spear6xx_timer_init(void)
clk_put(gpt_clk);
clk_put(pclk);
- spear_setup_timer(SPEAR6XX_CPU_TMR_BASE, IRQ_CPU_GPT1_1);
+ spear_setup_of_timer();
}
struct sys_timer spear6xx_timer = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d0f2546706ca..6a113a9bb87a 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -50,6 +50,14 @@ config TEGRA_PCI
depends on ARCH_TEGRA_2x_SOC
select PCI
+config TEGRA_AHB
+ bool "Enable AHB driver for NVIDIA Tegra SoCs"
+ default y
+ help
+ Adds AHB configuration functionality for NVIDIA Tegra SoCs,
+ which controls AHB bus master arbitration and some
+ perfomance parameters(priority, prefech size).
+
comment "Tegra board type"
config MACH_HARMONY
@@ -111,7 +119,7 @@ config MACH_VENTANA
Support for the nVidia Ventana development platform
choice
- prompt "Low-level debug console UART"
+ prompt "Default low-level debug console UART"
default TEGRA_DEBUG_UART_NONE
config TEGRA_DEBUG_UART_NONE
@@ -134,6 +142,33 @@ config TEGRA_DEBUG_UARTE
endchoice
+choice
+ prompt "Automatic low-level debug console UART"
+ default TEGRA_DEBUG_UART_AUTO_NONE
+
+config TEGRA_DEBUG_UART_AUTO_NONE
+ bool "None"
+
+config TEGRA_DEBUG_UART_AUTO_ODMDATA
+ bool "Via ODMDATA"
+ help
+ Automatically determines which UART to use for low-level debug based
+ on the ODMDATA value. This value is part of the BCT, and is written
+ to the boot memory device using nvflash, or other flashing tool.
+ When bits 19:18 are 3, then bits 17:15 indicate which UART to use;
+ 0/1/2/3/4 are UART A/B/C/D/E.
+
+config TEGRA_DEBUG_UART_AUTO_SCRATCH
+ bool "Via UART scratch register"
+ help
+ Automatically determines which UART to use for low-level debug based
+ on the UART scratch register value. Some bootloaders put ASCII 'D'
+ in this register when they initialize their own console UART output.
+ Using this option allows the kernel to automatically pick the same
+ UART.
+
+endchoice
+
config TEGRA_SYSTEM_DMA
bool "Enable system DMA driver for NVIDIA Tegra SoCs"
default y
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index fac3eb1af17e..eb7249db50a5 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)")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_dt_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
.dt_compat = tegra20_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 5f7c03e972f3..4f76fa7a5da3 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 = {
OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
+ OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
{}
};
static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
/* name parent rate enabled */
{ "uarta", "pll_p", 408000000, true },
+ { "pll_a", "pll_p_out1", 564480000, true },
+ { "pll_a_out0", "pll_a", 11289600, true },
+ { "extern1", "pll_a_out0", 0, true },
+ { "clk_out_1", "extern1", 0, true },
+ { "i2s0", "pll_a_out0", 11289600, false},
+ { "i2s1", "pll_a_out0", 11289600, false},
+ { "i2s2", "pll_a_out0", 11289600, false},
+ { "i2s3", "pll_a_out0", 11289600, false},
+ { "i2s4", "pll_a_out0", 11289600, false},
{ NULL, NULL, 0, 0},
};
@@ -80,6 +90,7 @@ DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra30_dt_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
.dt_compat = tegra30_dt_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index b906b3b6077b..e65e837f4013 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")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_harmony_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index d0735c70d688..bbc1907e98a6 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)
static void paz00_usb_init(void)
{
+ tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_ULPI_RST;
+
platform_device_register(&tegra_ehci2_device);
platform_device_register(&tegra_ehci3_device);
}
@@ -179,7 +181,6 @@ static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
{ "uarta", "pll_p", 216000000, true },
{ "uartc", "pll_p", 216000000, true },
- { "pll_p_out4", "pll_p", 24000000, true },
{ "usbd", "clk_m", 12000000, false },
{ "usb2", "clk_m", 12000000, false },
{ "usb3", "clk_m", 12000000, false },
@@ -224,5 +225,6 @@ MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_paz00_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index 79064c7a7907..71e9f3fc7fba 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")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_seaboard_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
@@ -288,6 +289,7 @@ MACHINE_START(KAEN, "kaen")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_kaen_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
@@ -299,5 +301,6 @@ MACHINE_START(WARIO, "wario")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_wario_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index bc59b379c6fe..776aa9564d5d 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)
pdata = tegra_ehci1_device.dev.platform_data;
pdata->vbus_gpio = TRIMSLICE_GPIO_USB1_MODE;
+ tegra_ehci2_ulpi_phy_config.reset_gpio = TEGRA_GPIO_PV0;
+
platform_device_register(&tegra_ehci3_device);
platform_device_register(&tegra_ehci2_device);
platform_device_register(&tegra_ehci1_device);
@@ -176,5 +178,6 @@ MACHINE_START(TRIMSLICE, "trimslice")
.handle_irq = gic_handle_irq,
.timer = &tegra_timer,
.init_machine = tegra_trimslice_init,
+ .init_late = tegra_init_late,
.restart = tegra_assert_system_reset,
MACHINE_END
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 75d1543d77c0..65014968fc6c 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);
void __init tegra_dt_init_irq(void);
int __init tegra_pcie_init(bool init_port0, bool init_port1);
+void tegra_init_late(void);
+
+#ifdef CONFIG_DEBUG_FS
+int tegra_clk_debugfs_init(void);
+#else
+static inline int tegra_clk_debugfs_init(void) { return 0; }
+#endif
+
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) && defined(CONFIG_DEBUG_FS)
+int __init tegra_powergate_debugfs_init(void);
+#else
+static inline int tegra_powergate_debugfs_init(void) { return 0; }
+#endif
+
extern struct sys_timer tegra_timer;
#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 8dad8d18cb49..58f981c0819c 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)
return 0;
}
-static int __init clk_debugfs_init(void)
+int __init tegra_clk_debugfs_init(void)
{
struct clk *c;
struct dentry *d;
@@ -669,5 +669,4 @@ err_out:
return err;
}
-late_initcall(clk_debugfs_init);
#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 22df10fb9972..204a5c8b0b57 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[] = {
{ "pll_p_out1", "pll_p", 28800000, true },
{ "pll_p_out2", "pll_p", 48000000, true },
{ "pll_p_out3", "pll_p", 72000000, true },
- { "pll_p_out4", "pll_p", 108000000, true },
- { "sclk", "pll_p_out4", 108000000, true },
- { "hclk", "sclk", 108000000, true },
- { "pclk", "hclk", 54000000, true },
+ { "pll_p_out4", "pll_p", 24000000, true },
+ { "pll_c", "clk_m", 600000000, true },
+ { "pll_c_out1", "pll_c", 120000000, true },
+ { "sclk", "pll_c_out1", 120000000, true },
+ { "hclk", "sclk", 120000000, true },
+ { "pclk", "hclk", 60000000, true },
{ "csite", NULL, 0, true },
{ "emc", NULL, 0, true },
{ "cpu", NULL, 0, true },
@@ -93,6 +95,17 @@ static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
};
#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "clk_m", NULL, 0, true },
+ { "pll_p", "clk_m", 408000000, true },
+ { "pll_p_out1", "pll_p", 9600000, true },
+ { NULL, NULL, 0, 0},
+};
+#endif
+
+
static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
{
#ifdef CONFIG_CACHE_L2X0
@@ -127,8 +140,15 @@ void __init tegra30_init_early(void)
{
tegra_init_fuse();
tegra30_init_clocks();
+ tegra_clk_init_from_table(tegra30_clk_init_table);
tegra_init_cache(0x441, 0x551);
tegra_pmc_init();
tegra_powergate_init();
}
#endif
+
+void __init tegra_init_late(void)
+{
+ tegra_clk_debugfs_init();
+ tegra_powergate_debugfs_init();
+}
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 2d8dfa2faf8f..c70e65ffa36b 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[] = {
},
};
-static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
- /* All existing boards use GPIO PV0 for phy reset */
- .reset_gpio = TEGRA_GPIO_PV0,
+struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
+ .reset_gpio = -1,
.clk = "cdev2",
};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
index 138c642e59f4..4f5052726495 100644
--- a/arch/arm/mach-tegra/devices.h
+++ b/arch/arm/mach-tegra/devices.h
@@ -22,6 +22,10 @@
#include <linux/platform_device.h>
#include <linux/platform_data/tegra_usb.h>
+#include <mach/usb_phy.h>
+
+extern struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config;
+
extern struct tegra_ehci_platform_data tegra_ehci1_pdata;
extern struct tegra_ehci_platform_data tegra_ehci2_pdata;
extern 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 000000000000..e0f8c84b1d8c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra-ahb.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __MACH_TEGRA_AHB_H__
+#define __MACH_TEGRA_AHB_H__
+
+extern int tegra_ahb_enable_smmu(struct device_node *ahb);
+
+#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 5a440f315e57..937c4c50219e 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)
buf[0] = 0;
}
-/*
- * Setup before decompression. This is where we do UART selection for
- * earlyprintk and init the uart_base register.
- */
-static inline void arch_decomp_setup(void)
+static const struct {
+ u32 base;
+ u32 reset_reg;
+ u32 clock_reg;
+ u32 bit;
+} uarts[] = {
+ {
+ TEGRA_UARTA_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 6,
+ },
+ {
+ TEGRA_UARTB_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 7,
+ },
+ {
+ TEGRA_UARTC_BASE,
+ TEGRA_CLK_RESET_BASE + 0x08,
+ TEGRA_CLK_RESET_BASE + 0x14,
+ 23,
+ },
+ {
+ TEGRA_UARTD_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 1,
+ },
+ {
+ TEGRA_UARTE_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 2,
+ },
+};
+
+static inline bool uart_clocked(int i)
+{
+ if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
+ return false;
+
+ if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+ return false;
+
+ return true;
+}
+
+#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA
+int auto_odmdata(void)
+{
+ volatile u32 *pmc = (volatile u32 *)TEGRA_PMC_BASE;
+ u32 odmdata = pmc[0xa0 / 4];
+
+ /*
+ * Bits 19:18 are the console type: 0=default, 1=none, 2==DCC, 3==UART
+ * Some boards apparently swap the last two values, but we don't have
+ * any way of catering for that here, so we just accept either. If this
+ * doesn't make sense for your board, just don't enable this feature.
+ *
+ * Bits 17:15 indicate the UART to use, 0/1/2/3/4 are UART A/B/C/D/E.
+ */
+
+ switch ((odmdata >> 18) & 3) {
+ case 2:
+ case 3:
+ break;
+ default:
+ return -1;
+ }
+
+ return (odmdata >> 15) & 7;
+}
+#endif
+
+#ifdef CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH
+int auto_scratch(void)
{
- static const struct {
- u32 base;
- u32 reset_reg;
- u32 clock_reg;
- u32 bit;
- } uarts[] = {
- {
- TEGRA_UARTA_BASE,
- TEGRA_CLK_RESET_BASE + 0x04,
- TEGRA_CLK_RESET_BASE + 0x10,
- 6,
- },
- {
- TEGRA_UARTB_BASE,
- TEGRA_CLK_RESET_BASE + 0x04,
- TEGRA_CLK_RESET_BASE + 0x10,
- 7,
- },
- {
- TEGRA_UARTC_BASE,
- TEGRA_CLK_RESET_BASE + 0x08,
- TEGRA_CLK_RESET_BASE + 0x14,
- 23,
- },
- {
- TEGRA_UARTD_BASE,
- TEGRA_CLK_RESET_BASE + 0x0c,
- TEGRA_CLK_RESET_BASE + 0x18,
- 1,
- },
- {
- TEGRA_UARTE_BASE,
- TEGRA_CLK_RESET_BASE + 0x0c,
- TEGRA_CLK_RESET_BASE + 0x18,
- 2,
- },
- };
int i;
- volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
- u32 chip, div;
/*
* Look for the first UART that:
@@ -125,20 +159,60 @@ static inline void arch_decomp_setup(void)
* back to what's specified in TEGRA_DEBUG_UART_BASE.
*/
for (i = 0; i < ARRAY_SIZE(uarts); i++) {
- if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
- continue;
-
- if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+ if (!uart_clocked(i))
continue;
uart = (volatile u8 *)uarts[i].base;
if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
continue;
- break;
+ return i;
}
- if (i == ARRAY_SIZE(uarts))
- uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+
+ return -1;
+}
+#endif
+
+/*
+ * Setup before decompression. This is where we do UART selection for
+ * earlyprintk and init the uart_base register.
+ */
+static inline void arch_decomp_setup(void)
+{
+ int uart_id, auto_uart_id;
+ volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
+ u32 chip, div;
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTA)
+ uart_id = 0;
+#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
+ uart_id = 1;
+#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
+ uart_id = 2;
+#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
+ uart_id = 3;
+#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
+ uart_id = 4;
+#else
+ uart_id = -1;
+#endif
+
+#if defined(CONFIG_TEGRA_DEBUG_UART_AUTO_ODMDATA)
+ auto_uart_id = auto_odmdata();
+#elif defined(CONFIG_TEGRA_DEBUG_UART_AUTO_SCRATCH)
+ auto_uart_id = auto_scratch();
+#else
+ auto_uart_id = -1;
+#endif
+ if (auto_uart_id != -1)
+ uart_id = auto_uart_id;
+
+ if (uart_id < 0 || uart_id >= ARRAY_SIZE(uarts) ||
+ !uart_clocked(uart_id))
+ uart = NULL;
+ else
+ uart = (volatile u8 *)uarts[uart_id].base;
+
save_uart_address();
if (uart == NULL)
return;
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
index de1a0f602b28..935ce9f65590 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 {
struct usb_phy *ulpi;
};
-struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
- void *config, enum tegra_usb_phy_mode phy_mode);
+struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
+ void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode);
int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
index c238699ae86f..f5b12fb4ff12 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 = {
.release = single_release,
};
-static int __init powergate_debugfs_init(void)
+int __init tegra_powergate_debugfs_init(void)
{
struct dentry *d;
int err = -ENOMEM;
@@ -247,6 +247,4 @@ static int __init powergate_debugfs_init(void)
return err;
}
-late_initcall(powergate_debugfs_init);
-
#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index bae09b859891..b59315ce3691 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 = {
};
static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+ { 12000000, 600000000, 600, 12, 1, 8 },
+ { 13000000, 600000000, 600, 13, 1, 8 },
+ { 19200000, 600000000, 500, 16, 1, 6 },
+ { 26000000, 600000000, 600, 26, 1, 8 },
{ 0, 0, 0, 0, 0, 0 },
};
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
index 6d08b53f92d2..e33fe4b14a2a 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[] = {
CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
CLK_DUPLICATE("twd", "smp_twd", NULL),
CLK_DUPLICATE("vcp", "nvavp", "vcp"),
+ CLK_DUPLICATE("i2s0", NULL, "i2s0"),
+ CLK_DUPLICATE("i2s1", NULL, "i2s1"),
+ CLK_DUPLICATE("i2s2", NULL, "i2s2"),
+ CLK_DUPLICATE("i2s3", NULL, "i2s3"),
+ CLK_DUPLICATE("i2s4", NULL, "i2s4"),
+ CLK_DUPLICATE("dam0", NULL, "dam0"),
+ CLK_DUPLICATE("dam1", NULL, "dam1"),
+ CLK_DUPLICATE("dam2", NULL, "dam2"),
+ CLK_DUPLICATE("spdif_in", NULL, "spdif_in"),
};
struct clk *tegra_ptr_clks[] = {
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
index d71d2fed6721..54e353c8e304 100644
--- a/arch/arm/mach-tegra/usb_phy.c
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -26,6 +26,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h>
@@ -654,8 +655,8 @@ static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
clk_disable(phy->clk);
}
-struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
- void *config, enum tegra_usb_phy_mode phy_mode)
+struct tegra_usb_phy *tegra_usb_phy_open(struct device *dev, int instance,
+ void __iomem *regs, void *config, enum tegra_usb_phy_mode phy_mode)
{
struct tegra_usb_phy *phy;
struct tegra_ulpi_config *ulpi_config;
@@ -711,6 +712,16 @@ struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
err = -ENXIO;
goto err1;
}
+ if (!gpio_is_valid(ulpi_config->reset_gpio))
+ ulpi_config->reset_gpio =
+ of_get_named_gpio(dev->of_node,
+ "nvidia,phy-reset-gpio", 0);
+ if (!gpio_is_valid(ulpi_config->reset_gpio)) {
+ pr_err("%s: invalid reset gpio: %d\n", __func__,
+ ulpi_config->reset_gpio);
+ err = -EINVAL;
+ goto err1;
+ }
gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
gpio_direction_output(ulpi_config->reset_gpio, 0);
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 f943687acaf0..b23a643f03f4 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -785,6 +785,7 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
.timer = &ux500_timer,
.handle_irq = gic_handle_irq,
.init_machine = mop500_init_machine,
+ .init_late = ux500_init_late,
MACHINE_END
MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
@@ -794,6 +795,7 @@ MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
.timer = &ux500_timer,
.handle_irq = gic_handle_irq,
.init_machine = hrefv60_init_machine,
+ .init_late = ux500_init_late,
MACHINE_END
MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
@@ -804,6 +806,7 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform")
.timer = &ux500_timer,
.handle_irq = gic_handle_irq,
.init_machine = snowball_init_machine,
+ .init_late = ux500_init_late,
MACHINE_END
#ifdef CONFIG_MACH_UX500_DT
@@ -918,6 +921,7 @@ DT_MACHINE_START(U8500_DT, "ST-Ericsson U8500 platform (Device Tree Support)")
.timer = &ux500_timer,
.handle_irq = gic_handle_irq,
.init_machine = u8500_init_machine,
+ .init_late = ux500_init_late,
.dt_compat = u8500_dt_board_compat,
MACHINE_END
#endif
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index 1762c4728f1e..8d73b066a18d 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)
return 0;
}
-static int __init clk_debugfs_init(void)
+int __init clk_debugfs_init(void)
{
struct clk *c;
struct dentry *d;
@@ -657,7 +657,6 @@ err_out:
return err;
}
-late_initcall(clk_debugfs_init);
#endif /* defined(CONFIG_DEBUG_FS) */
unsigned long clk_smp_twd_rate = 500000000;
@@ -696,12 +695,11 @@ static struct notifier_block clk_twd_cpufreq_nb = {
.notifier_call = clk_twd_cpufreq_transition,
};
-static int clk_init_smp_twd_cpufreq(void)
+int clk_init_smp_twd_cpufreq(void)
{
return cpufreq_register_notifier(&clk_twd_cpufreq_nb,
CPUFREQ_TRANSITION_NOTIFIER);
}
-late_initcall(clk_init_smp_twd_cpufreq);
#endif
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
index d776ada08dbf..65d27a13f46d 100644
--- a/arch/arm/mach-ux500/clock.h
+++ b/arch/arm/mach-ux500/clock.h
@@ -150,3 +150,15 @@ struct clk clk_##_name = { \
int __init clk_db8500_ed_fixup(void);
int __init clk_init(void);
+
+#ifdef CONFIG_DEBUG_FS
+int clk_debugfs_init(void);
+#else
+static inline int clk_debugfs_init(void) { return 0; }
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+int clk_init_smp_twd_cpufreq(void);
+#else
+static inline int clk_init_smp_twd_cpufreq(void) { return 0; }
+#endif
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index a29a0e3adcf9..e2360e7c770d 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)
clk_init();
}
+void __init ux500_init_late(void)
+{
+ clk_debugfs_init();
+ clk_init_smp_twd_cpufreq();
+}
+
static const char * __init ux500_get_machine(void)
{
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 4e369f1645ec..8b7ed82a2866 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);
extern struct device * __init u8500_init_devices(void);
extern void __init ux500_init_irq(void);
+extern void __init ux500_init_late(void);
extern struct device *ux500_soc_device_init(const char *soc_id);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index db23ae4aaaab..ea6b43154090 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -17,8 +17,12 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/dma-contiguous.h>
#include <linux/highmem.h>
+#include <linux/memblock.h>
#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/vmalloc.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -26,9 +30,112 @@
#include <asm/tlbflush.h>
#include <asm/sizes.h>
#include <asm/mach/arch.h>
+#include <asm/dma-iommu.h>
+#include <asm/mach/map.h>
+#include <asm/system_info.h>
+#include <asm/dma-contiguous.h>
#include "mm.h"
+/*
+ * The DMA API is built upon the notion of "buffer ownership". A buffer
+ * is either exclusively owned by the CPU (and therefore may be accessed
+ * by it) or exclusively owned by the DMA device. These helper functions
+ * represent the transitions between these two ownership states.
+ *
+ * Note, however, that on later ARMs, this notion does not work due to
+ * speculative prefetches. We model our approach on the assumption that
+ * the CPU does do speculative prefetches, which means we clean caches
+ * before transfers and delay cache invalidation until transfer completion.
+ *
+ */
+static void __dma_page_cpu_to_dev(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+static void __dma_page_dev_to_cpu(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+
+/**
+ * arm_dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed. The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!arch_is_coherent())
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
+/**
+ * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation. The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
+ handle & ~PAGE_MASK, size, dir);
+}
+
+static void arm_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned int offset = handle & (PAGE_SIZE - 1);
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+}
+
+static void arm_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ unsigned int offset = handle & (PAGE_SIZE - 1);
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
+ if (!arch_is_coherent())
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+}
+
+static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
+
+struct dma_map_ops arm_dma_ops = {
+ .alloc = arm_dma_alloc,
+ .free = arm_dma_free,
+ .mmap = arm_dma_mmap,
+ .map_page = arm_dma_map_page,
+ .unmap_page = arm_dma_unmap_page,
+ .map_sg = arm_dma_map_sg,
+ .unmap_sg = arm_dma_unmap_sg,
+ .sync_single_for_cpu = arm_dma_sync_single_for_cpu,
+ .sync_single_for_device = arm_dma_sync_single_for_device,
+ .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_dma_sync_sg_for_device,
+ .set_dma_mask = arm_dma_set_mask,
+};
+EXPORT_SYMBOL(arm_dma_ops);
+
static u64 get_coherent_dma_mask(struct device *dev)
{
u64 mask = (u64)arm_dma_limit;
@@ -56,6 +163,21 @@ static u64 get_coherent_dma_mask(struct device *dev)
return mask;
}
+static void __dma_clear_buffer(struct page *page, size_t size)
+{
+ void *ptr;
+ /*
+ * Ensure that the allocated pages are zeroed, and that any data
+ * lurking in the kernel direct-mapped region is invalidated.
+ */
+ ptr = page_address(page);
+ if (ptr) {
+ memset(ptr, 0, size);
+ dmac_flush_range(ptr, ptr + size);
+ outer_flush_range(__pa(ptr), __pa(ptr) + size);
+ }
+}
+
/*
* Allocate a DMA buffer for 'dev' of size 'size' using the
* 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
{
unsigned long order = get_order(size);
struct page *page, *p, *e;
- void *ptr;
- u64 mask = get_coherent_dma_mask(dev);
-
-#ifdef CONFIG_DMA_API_DEBUG
- u64 limit = (mask + 1) & ~mask;
- if (limit && size >= limit) {
- dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
- size, mask);
- return NULL;
- }
-#endif
-
- if (!mask)
- return NULL;
-
- if (mask < 0xffffffffULL)
- gfp |= GFP_DMA;
page = alloc_pages(gfp, order);
if (!page)
@@ -93,14 +198,7 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
__free_page(p);
- /*
- * Ensure that the allocated pages are zeroed, and that any data
- * lurking in the kernel direct-mapped region is invalidated.
- */
- ptr = page_address(page);
- memset(ptr, 0, size);
- dmac_flush_range(ptr, ptr + size);
- outer_flush_range(__pa(ptr), __pa(ptr) + size);
+ __dma_clear_buffer(page, size);
return page;
}
@@ -170,6 +268,11 @@ static int __init consistent_init(void)
unsigned long base = consistent_base;
unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
+#ifndef CONFIG_ARM_DMA_USE_IOMMU
+ if (cpu_architecture() >= CPU_ARCH_ARMv6)
+ return 0;
+#endif
+
consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
if (!consistent_pte) {
pr_err("%s: no memory\n", __func__);
@@ -184,14 +287,14 @@ static int __init consistent_init(void)
pud = pud_alloc(&init_mm, pgd, base);
if (!pud) {
- printk(KERN_ERR "%s: no pud tables\n", __func__);
+ pr_err("%s: no pud tables\n", __func__);
ret = -ENOMEM;
break;
}
pmd = pmd_alloc(&init_mm, pud, base);
if (!pmd) {
- printk(KERN_ERR "%s: no pmd tables\n", __func__);
+ pr_err("%s: no pmd tables\n", __func__);
ret = -ENOMEM;
break;
}
@@ -199,7 +302,7 @@ static int __init consistent_init(void)
pte = pte_alloc_kernel(pmd, base);
if (!pte) {
- printk(KERN_ERR "%s: no pte tables\n", __func__);
+ pr_err("%s: no pte tables\n", __func__);
ret = -ENOMEM;
break;
}
@@ -210,9 +313,101 @@ static int __init consistent_init(void)
return ret;
}
-
core_initcall(consistent_init);
+static void *__alloc_from_contiguous(struct device *dev, size_t size,
+ pgprot_t prot, struct page **ret_page);
+
+static struct arm_vmregion_head coherent_head = {
+ .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
+ .vm_list = LIST_HEAD_INIT(coherent_head.vm_list),
+};
+
+size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8;
+
+static int __init early_coherent_pool(char *p)
+{
+ coherent_pool_size = memparse(p, &p);
+ return 0;
+}
+early_param("coherent_pool", early_coherent_pool);
+
+/*
+ * Initialise the coherent pool for atomic allocations.
+ */
+static int __init coherent_init(void)
+{
+ pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
+ size_t size = coherent_pool_size;
+ struct page *page;
+ void *ptr;
+
+ if (cpu_architecture() < CPU_ARCH_ARMv6)
+ return 0;
+
+ ptr = __alloc_from_contiguous(NULL, size, prot, &page);
+ if (ptr) {
+ coherent_head.vm_start = (unsigned long) ptr;
+ coherent_head.vm_end = (unsigned long) ptr + size;
+ printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n",
+ (unsigned)size / 1024);
+ return 0;
+ }
+ printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
+ (unsigned)size / 1024);
+ return -ENOMEM;
+}
+/*
+ * CMA is activated by core_initcall, so we must be called after it.
+ */
+postcore_initcall(coherent_init);
+
+struct dma_contig_early_reserve {
+ phys_addr_t base;
+ unsigned long size;
+};
+
+static struct dma_contig_early_reserve dma_mmu_remap[MAX_CMA_AREAS] __initdata;
+
+static int dma_mmu_remap_num __initdata;
+
+void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
+{
+ dma_mmu_remap[dma_mmu_remap_num].base = base;
+ dma_mmu_remap[dma_mmu_remap_num].size = size;
+ dma_mmu_remap_num++;
+}
+
+void __init dma_contiguous_remap(void)
+{
+ int i;
+ for (i = 0; i < dma_mmu_remap_num; i++) {
+ phys_addr_t start = dma_mmu_remap[i].base;
+ phys_addr_t end = start + dma_mmu_remap[i].size;
+ struct map_desc map;
+ unsigned long addr;
+
+ if (end > arm_lowmem_limit)
+ end = arm_lowmem_limit;
+ if (start >= end)
+ return;
+
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY_DMA_READY;
+
+ /*
+ * Clear previous low-memory mapping
+ */
+ for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
+ addr += PMD_SIZE)
+ pmd_clear(pmd_off_k(addr));
+
+ iotable_init(&map, 1);
+ }
+}
+
static void *
__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
const void *caller)
@@ -222,7 +417,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
int bit;
if (!consistent_pte) {
- printk(KERN_ERR "%s: not initialised\n", __func__);
+ pr_err("%s: not initialised\n", __func__);
dump_stack();
return NULL;
}
@@ -249,7 +444,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
pte = consistent_pte[idx] + off;
- c->vm_pages = page;
+ c->priv = page;
do {
BUG_ON(!pte_none(*pte));
@@ -281,14 +476,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
if (!c) {
- printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+ pr_err("%s: trying to free invalid coherent area: %p\n",
__func__, cpu_addr);
dump_stack();
return;
}
if ((c->vm_end - c->vm_start) != size) {
- printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+ pr_err("%s: freeing wrong coherent size (%ld != %d)\n",
__func__, c->vm_end - c->vm_start, size);
dump_stack();
size = c->vm_end - c->vm_start;
@@ -310,8 +505,8 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
}
if (pte_none(pte) || !pte_present(pte))
- printk(KERN_CRIT "%s: bad page in kernel page table\n",
- __func__);
+ pr_crit("%s: bad page in kernel page table\n",
+ __func__);
} while (size -= PAGE_SIZE);
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)
arm_vmregion_free(&consistent_head, c);
}
+static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
+ void *data)
+{
+ struct page *page = virt_to_page(addr);
+ pgprot_t prot = *(pgprot_t *)data;
+
+ set_pte_ext(pte, mk_pte(page, prot), 0);
+ return 0;
+}
+
+static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
+{
+ unsigned long start = (unsigned long) page_address(page);
+ unsigned end = start + size;
+
+ apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot);
+ dsb();
+ flush_tlb_kernel_range(start, end);
+}
+
+static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller)
+{
+ struct page *page;
+ void *ptr;
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+
+ ptr = __dma_alloc_remap(page, size, gfp, prot, caller);
+ if (!ptr) {
+ __dma_free_buffer(page, size);
+ return NULL;
+ }
+
+ *ret_page = page;
+ return ptr;
+}
+
+static void *__alloc_from_pool(struct device *dev, size_t size,
+ struct page **ret_page, const void *caller)
+{
+ struct arm_vmregion *c;
+ size_t align;
+
+ if (!coherent_head.vm_start) {
+ printk(KERN_ERR "%s: coherent pool not initialised!\n",
+ __func__);
+ dump_stack();
+ return NULL;
+ }
+
+ /*
+ * Align the region allocation - allocations from pool are rather
+ * small, so align them to their order in pages, minimum is a page
+ * size. This helps reduce fragmentation of the DMA space.
+ */
+ align = PAGE_SIZE << get_order(size);
+ c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller);
+ if (c) {
+ void *ptr = (void *)c->vm_start;
+ struct page *page = virt_to_page(ptr);
+ *ret_page = page;
+ return ptr;
+ }
+ return NULL;
+}
+
+static int __free_from_pool(void *cpu_addr, size_t size)
+{
+ unsigned long start = (unsigned long)cpu_addr;
+ unsigned long end = start + size;
+ struct arm_vmregion *c;
+
+ if (start < coherent_head.vm_start || end > coherent_head.vm_end)
+ return 0;
+
+ c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start);
+
+ if ((c->vm_end - c->vm_start) != size) {
+ printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+ __func__, c->vm_end - c->vm_start, size);
+ dump_stack();
+ size = c->vm_end - c->vm_start;
+ }
+
+ arm_vmregion_free(&coherent_head, c);
+ return 1;
+}
+
+static void *__alloc_from_contiguous(struct device *dev, size_t size,
+ pgprot_t prot, struct page **ret_page)
+{
+ unsigned long order = get_order(size);
+ size_t count = size >> PAGE_SHIFT;
+ struct page *page;
+
+ page = dma_alloc_from_contiguous(dev, count, order);
+ if (!page)
+ return NULL;
+
+ __dma_clear_buffer(page, size);
+ __dma_remap(page, size, prot);
+
+ *ret_page = page;
+ return page_address(page);
+}
+
+static void __free_from_contiguous(struct device *dev, struct page *page,
+ size_t size)
+{
+ __dma_remap(page, size, pgprot_kernel);
+ dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
+}
+
+static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
+{
+ prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
+ pgprot_writecombine(prot) :
+ pgprot_dmacoherent(prot);
+ return prot;
+}
+
+#define nommu() 0
+
#else /* !CONFIG_MMU */
-#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page)
-#define __dma_free_remap(addr, size) do { } while (0)
+#define nommu() 1
+
+#define __get_dma_pgprot(attrs, prot) __pgprot(0)
+#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL
+#define __alloc_from_pool(dev, size, ret_page, c) NULL
+#define __alloc_from_contiguous(dev, size, prot, ret) NULL
+#define __free_from_pool(cpu_addr, size) 0
+#define __free_from_contiguous(dev, page, size) do { } while (0)
+#define __dma_free_remap(cpu_addr, size) do { } while (0)
#endif /* CONFIG_MMU */
-static void *
-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
- pgprot_t prot, const void *caller)
+static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
+ struct page **ret_page)
+{
+ struct page *page;
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+
+ *ret_page = page;
+ return page_address(page);
+}
+
+
+
+static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, pgprot_t prot, const void *caller)
{
+ u64 mask = get_coherent_dma_mask(dev);
struct page *page;
void *addr;
+#ifdef CONFIG_DMA_API_DEBUG
+ u64 limit = (mask + 1) & ~mask;
+ if (limit && size >= limit) {
+ dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
+ size, mask);
+ return NULL;
+ }
+#endif
+
+ if (!mask)
+ return NULL;
+
+ if (mask < 0xffffffffULL)
+ gfp |= GFP_DMA;
+
/*
* Following is a work-around (a.k.a. hack) to prevent pages
* 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,
*/
gfp &= ~(__GFP_COMP);
- *handle = ~0;
+ *handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
- page = __dma_alloc_buffer(dev, size, gfp);
- if (!page)
- return NULL;
-
- if (!arch_is_coherent())
- addr = __dma_alloc_remap(page, size, gfp, prot, caller);
+ if (arch_is_coherent() || nommu())
+ addr = __alloc_simple_buffer(dev, size, gfp, &page);
+ else if (cpu_architecture() < CPU_ARCH_ARMv6)
+ addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
+ else if (gfp & GFP_ATOMIC)
+ addr = __alloc_from_pool(dev, size, &page, caller);
else
- addr = page_address(page);
+ addr = __alloc_from_contiguous(dev, size, prot, &page);
if (addr)
*handle = pfn_to_dma(dev, page_to_pfn(page));
- else
- __dma_free_buffer(page, size);
return addr;
}
@@ -366,138 +721,71 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
* Allocate DMA-coherent memory space and return both the kernel remapped
* virtual and bus address for that space.
*/
-void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
+ gfp_t gfp, struct dma_attrs *attrs)
{
+ pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
void *memory;
if (dma_alloc_from_coherent(dev, size, handle, &memory))
return memory;
- return __dma_alloc(dev, size, handle, gfp,
- pgprot_dmacoherent(pgprot_kernel),
+ return __dma_alloc(dev, size, handle, gfp, prot,
__builtin_return_address(0));
}
-EXPORT_SYMBOL(dma_alloc_coherent);
/*
- * Allocate a writecombining region, in much the same way as
- * dma_alloc_coherent above.
+ * Create userspace mapping for the DMA-coherent memory.
*/
-void *
-dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
-{
- return __dma_alloc(dev, size, handle, gfp,
- pgprot_writecombine(pgprot_kernel),
- __builtin_return_address(0));
-}
-EXPORT_SYMBOL(dma_alloc_writecombine);
-
-static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
+int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs)
{
int ret = -ENXIO;
#ifdef CONFIG_MMU
- unsigned long user_size, kern_size;
- struct arm_vmregion *c;
+ unsigned long pfn = dma_to_pfn(dev, dma_addr);
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
- user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ return ret;
- c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
- if (c) {
- unsigned long off = vma->vm_pgoff;
-
- kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
-
- if (off < kern_size &&
- user_size <= (kern_size - off)) {
- ret = remap_pfn_range(vma, vma->vm_start,
- page_to_pfn(c->vm_pages) + off,
- user_size << PAGE_SHIFT,
- vma->vm_page_prot);
- }
- }
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
#endif /* CONFIG_MMU */
return ret;
}
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
- vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
- return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_coherent);
-
-int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
-}
-EXPORT_SYMBOL(dma_mmap_writecombine);
-
/*
- * free a page as defined by the above mapping.
- * Must not be called with IRQs disabled.
+ * Free a buffer as defined by the above mapping.
*/
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
+void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
{
- WARN_ON(irqs_disabled());
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
return;
size = PAGE_ALIGN(size);
- if (!arch_is_coherent())
+ if (arch_is_coherent() || nommu()) {
+ __dma_free_buffer(page, size);
+ } else if (cpu_architecture() < CPU_ARCH_ARMv6) {
__dma_free_remap(cpu_addr, size);
-
- __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
-}
-EXPORT_SYMBOL(dma_free_coherent);
-
-/*
- * Make an area consistent for devices.
- * Note: Drivers should NOT use this function directly, as it will break
- * platforms with CONFIG_DMABOUNCE.
- * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
- */
-void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
- enum dma_data_direction dir)
-{
- unsigned long paddr;
-
- BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
-
- dmac_map_area(kaddr, size, dir);
-
- paddr = __pa(kaddr);
- if (dir == DMA_FROM_DEVICE) {
- outer_inv_range(paddr, paddr + size);
+ __dma_free_buffer(page, size);
} else {
- outer_clean_range(paddr, paddr + size);
- }
- /* FIXME: non-speculating: flush on bidirectional mappings? */
-}
-EXPORT_SYMBOL(___dma_single_cpu_to_dev);
-
-void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
- enum dma_data_direction dir)
-{
- BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
-
- /* FIXME: non-speculating: not required */
- /* don't bother invalidating if DMA to device */
- if (dir != DMA_TO_DEVICE) {
- unsigned long paddr = __pa(kaddr);
- outer_inv_range(paddr, paddr + size);
+ if (__free_from_pool(cpu_addr, size))
+ return;
+ /*
+ * Non-atomic allocations cannot be freed with IRQs disabled
+ */
+ WARN_ON(irqs_disabled());
+ __free_from_contiguous(dev, page, size);
}
-
- dmac_unmap_area(kaddr, size, dir);
}
-EXPORT_SYMBOL(___dma_single_dev_to_cpu);
static void dma_cache_maint_page(struct page *page, unsigned long offset,
size_t size, enum dma_data_direction dir,
@@ -543,7 +831,13 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
} while (left);
}
-void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
+/*
+ * Make an area consistent for devices.
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
+ */
+static void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
size_t size, enum dma_data_direction dir)
{
unsigned long paddr;
@@ -558,9 +852,8 @@ void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
}
/* FIXME: non-speculating: flush on bidirectional mappings? */
}
-EXPORT_SYMBOL(___dma_page_cpu_to_dev);
-void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
+static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
size_t size, enum dma_data_direction dir)
{
unsigned long paddr = page_to_phys(page) + off;
@@ -578,10 +871,9 @@ void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
set_bit(PG_dcache_clean, &page->flags);
}
-EXPORT_SYMBOL(___dma_page_dev_to_cpu);
/**
- * dma_map_sg - map a set of SG buffers for streaming mode DMA
+ * arm_dma_map_sg - map a set of SG buffers for streaming mode DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map
@@ -596,32 +888,32 @@ EXPORT_SYMBOL(___dma_page_dev_to_cpu);
* Device ownership issues as mentioned for dma_map_single are the same
* here.
*/
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
+int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
+ struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i, j;
- BUG_ON(!valid_dma_direction(dir));
-
for_each_sg(sg, s, nents, i) {
- s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
- s->length, dir);
+#ifdef CONFIG_NEED_SG_DMA_LENGTH
+ s->dma_length = s->length;
+#endif
+ s->dma_address = ops->map_page(dev, sg_page(s), s->offset,
+ s->length, dir, attrs);
if (dma_mapping_error(dev, s->dma_address))
goto bad_mapping;
}
- debug_dma_map_sg(dev, sg, nents, nents, dir);
return nents;
bad_mapping:
for_each_sg(sg, s, i, j)
- __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
return 0;
}
-EXPORT_SYMBOL(dma_map_sg);
/**
- * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * arm_dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to unmap (same as was passed to dma_map_sg)
@@ -630,70 +922,55 @@ EXPORT_SYMBOL(dma_map_sg);
* Unmap a set of streaming mode DMA translations. Again, CPU access
* rules concerning calls here are the same as for dma_unmap_single().
*/
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
+void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
+ struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
- int i;
- debug_dma_unmap_sg(dev, sg, nents, dir);
+ int i;
for_each_sg(sg, s, nents, i)
- __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
}
-EXPORT_SYMBOL(dma_unmap_sg);
/**
- * dma_sync_sg_for_cpu
+ * arm_dma_sync_sg_for_cpu
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map (returned from dma_map_sg)
* @dir: DMA transfer direction (same as was passed to dma_map_sg)
*/
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
+ struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i;
- for_each_sg(sg, s, nents, i) {
- if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
- sg_dma_len(s), dir))
- continue;
-
- __dma_page_dev_to_cpu(sg_page(s), s->offset,
- s->length, dir);
- }
-
- debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
+ for_each_sg(sg, s, nents, i)
+ ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
+ dir);
}
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
/**
- * dma_sync_sg_for_device
+ * arm_dma_sync_sg_for_device
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map (returned from dma_map_sg)
* @dir: DMA transfer direction (same as was passed to dma_map_sg)
*/
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
+ struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i;
- for_each_sg(sg, s, nents, i) {
- if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
- sg_dma_len(s), dir))
- continue;
-
- __dma_page_cpu_to_dev(sg_page(s), s->offset,
- s->length, dir);
- }
-
- debug_dma_sync_sg_for_device(dev, sg, nents, dir);
+ for_each_sg(sg, s, nents, i)
+ ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
+ dir);
}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
/*
* Return whether the given device DMA address mask can be supported
@@ -709,18 +986,15 @@ int dma_supported(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(dma_supported);
-int dma_set_mask(struct device *dev, u64 dma_mask)
+static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
{
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
-#ifndef CONFIG_DMABOUNCE
*dev->dma_mask = dma_mask;
-#endif
return 0;
}
-EXPORT_SYMBOL(dma_set_mask);
#define PREALLOC_DMA_DEBUG_ENTRIES 4096
@@ -733,3 +1007,679 @@ static int __init dma_debug_do_init(void)
return 0;
}
fs_initcall(dma_debug_do_init);
+
+#ifdef CONFIG_ARM_DMA_USE_IOMMU
+
+/* IOMMU */
+
+static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
+ size_t size)
+{
+ unsigned int order = get_order(size);
+ unsigned int align = 0;
+ unsigned int count, start;
+ unsigned long flags;
+
+ count = ((PAGE_ALIGN(size) >> PAGE_SHIFT) +
+ (1 << mapping->order) - 1) >> mapping->order;
+
+ if (order > mapping->order)
+ align = (1 << (order - mapping->order)) - 1;
+
+ spin_lock_irqsave(&mapping->lock, flags);
+ start = bitmap_find_next_zero_area(mapping->bitmap, mapping->bits, 0,
+ count, align);
+ if (start > mapping->bits) {
+ spin_unlock_irqrestore(&mapping->lock, flags);
+ return DMA_ERROR_CODE;
+ }
+
+ bitmap_set(mapping->bitmap, start, count);
+ spin_unlock_irqrestore(&mapping->lock, flags);
+
+ return mapping->base + (start << (mapping->order + PAGE_SHIFT));
+}
+
+static inline void __free_iova(struct dma_iommu_mapping *mapping,
+ dma_addr_t addr, size_t size)
+{
+ unsigned int start = (addr - mapping->base) >>
+ (mapping->order + PAGE_SHIFT);
+ unsigned int count = ((size >> PAGE_SHIFT) +
+ (1 << mapping->order) - 1) >> mapping->order;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mapping->lock, flags);
+ bitmap_clear(mapping->bitmap, start, count);
+ spin_unlock_irqrestore(&mapping->lock, flags);
+}
+
+static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+{
+ struct page **pages;
+ int count = size >> PAGE_SHIFT;
+ int array_size = count * sizeof(struct page *);
+ int i = 0;
+
+ if (array_size <= PAGE_SIZE)
+ pages = kzalloc(array_size, gfp);
+ else
+ pages = vzalloc(array_size);
+ if (!pages)
+ return NULL;
+
+ while (count) {
+ int j, order = __ffs(count);
+
+ pages[i] = alloc_pages(gfp | __GFP_NOWARN, order);
+ while (!pages[i] && order)
+ pages[i] = alloc_pages(gfp | __GFP_NOWARN, --order);
+ if (!pages[i])
+ goto error;
+
+ if (order)
+ split_page(pages[i], order);
+ j = 1 << order;
+ while (--j)
+ pages[i + j] = pages[i] + j;
+
+ __dma_clear_buffer(pages[i], PAGE_SIZE << order);
+ i += 1 << order;
+ count -= 1 << order;
+ }
+
+ return pages;
+error:
+ while (--i)
+ if (pages[i])
+ __free_pages(pages[i], 0);
+ if (array_size < PAGE_SIZE)
+ kfree(pages);
+ else
+ vfree(pages);
+ return NULL;
+}
+
+static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size)
+{
+ int count = size >> PAGE_SHIFT;
+ int array_size = count * sizeof(struct page *);
+ int i;
+ for (i = 0; i < count; i++)
+ if (pages[i])
+ __free_pages(pages[i], 0);
+ if (array_size < PAGE_SIZE)
+ kfree(pages);
+ else
+ vfree(pages);
+ return 0;
+}
+
+/*
+ * Create a CPU mapping for a specified pages
+ */
+static void *
+__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot)
+{
+ struct arm_vmregion *c;
+ size_t align;
+ size_t count = size >> PAGE_SHIFT;
+ int bit;
+
+ if (!consistent_pte[0]) {
+ pr_err("%s: not initialised\n", __func__);
+ dump_stack();
+ return NULL;
+ }
+
+ /*
+ * Align the virtual region allocation - maximum alignment is
+ * a section size, minimum is a page size. This helps reduce
+ * fragmentation of the DMA space, and also prevents allocations
+ * smaller than a section from crossing a section boundary.
+ */
+ bit = fls(size - 1);
+ if (bit > SECTION_SHIFT)
+ bit = SECTION_SHIFT;
+ align = 1 << bit;
+
+ /*
+ * Allocate a virtual address in the consistent mapping region.
+ */
+ c = arm_vmregion_alloc(&consistent_head, align, size,
+ gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL);
+ if (c) {
+ pte_t *pte;
+ int idx = CONSISTENT_PTE_INDEX(c->vm_start);
+ int i = 0;
+ u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+
+ pte = consistent_pte[idx] + off;
+ c->priv = pages;
+
+ do {
+ BUG_ON(!pte_none(*pte));
+
+ set_pte_ext(pte, mk_pte(pages[i], prot), 0);
+ pte++;
+ off++;
+ i++;
+ if (off >= PTRS_PER_PTE) {
+ off = 0;
+ pte = consistent_pte[++idx];
+ }
+ } while (i < count);
+
+ dsb();
+
+ return (void *)c->vm_start;
+ }
+ return NULL;
+}
+
+/*
+ * Create a mapping in device IO address space for specified pages
+ */
+static dma_addr_t
+__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ dma_addr_t dma_addr, iova;
+ int i, ret = DMA_ERROR_CODE;
+
+ dma_addr = __alloc_iova(mapping, size);
+ if (dma_addr == DMA_ERROR_CODE)
+ return dma_addr;
+
+ iova = dma_addr;
+ for (i = 0; i < count; ) {
+ unsigned int next_pfn = page_to_pfn(pages[i]) + 1;
+ phys_addr_t phys = page_to_phys(pages[i]);
+ unsigned int len, j;
+
+ for (j = i + 1; j < count; j++, next_pfn++)
+ if (page_to_pfn(pages[j]) != next_pfn)
+ break;
+
+ len = (j - i) << PAGE_SHIFT;
+ ret = iommu_map(mapping->domain, iova, phys, len, 0);
+ if (ret < 0)
+ goto fail;
+ iova += len;
+ i = j;
+ }
+ return dma_addr;
+fail:
+ iommu_unmap(mapping->domain, dma_addr, iova-dma_addr);
+ __free_iova(mapping, dma_addr, size);
+ return DMA_ERROR_CODE;
+}
+
+static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t size)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+
+ /*
+ * add optional in-page offset from iova to size and align
+ * result to page size
+ */
+ size = PAGE_ALIGN((iova & ~PAGE_MASK) + size);
+ iova &= PAGE_MASK;
+
+ iommu_unmap(mapping->domain, iova, size);
+ __free_iova(mapping, iova, size);
+ return 0;
+}
+
+static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+ pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
+ struct page **pages;
+ void *addr = NULL;
+
+ *handle = DMA_ERROR_CODE;
+ size = PAGE_ALIGN(size);
+
+ pages = __iommu_alloc_buffer(dev, size, gfp);
+ if (!pages)
+ return NULL;
+
+ *handle = __iommu_create_mapping(dev, pages, size);
+ if (*handle == DMA_ERROR_CODE)
+ goto err_buffer;
+
+ addr = __iommu_alloc_remap(pages, size, gfp, prot);
+ if (!addr)
+ goto err_mapping;
+
+ return addr;
+
+err_mapping:
+ __iommu_remove_mapping(dev, *handle, size);
+err_buffer:
+ __iommu_free_buffer(dev, pages, size);
+ return NULL;
+}
+
+static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs)
+{
+ struct arm_vmregion *c;
+
+ vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+ c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
+
+ if (c) {
+ struct page **pages = c->priv;
+
+ unsigned long uaddr = vma->vm_start;
+ unsigned long usize = vma->vm_end - vma->vm_start;
+ int i = 0;
+
+ do {
+ int ret;
+
+ ret = vm_insert_page(vma, uaddr, pages[i++]);
+ if (ret) {
+ pr_err("Remapping memory, error: %d\n", ret);
+ return ret;
+ }
+
+ uaddr += PAGE_SIZE;
+ usize -= PAGE_SIZE;
+ } while (usize > 0);
+ }
+ return 0;
+}
+
+/*
+ * free a page as defined by the above mapping.
+ * Must not be called with IRQs disabled.
+ */
+void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t handle, struct dma_attrs *attrs)
+{
+ struct arm_vmregion *c;
+ size = PAGE_ALIGN(size);
+
+ c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
+ if (c) {
+ struct page **pages = c->priv;
+ __dma_free_remap(cpu_addr, size);
+ __iommu_remove_mapping(dev, handle, size);
+ __iommu_free_buffer(dev, pages, size);
+ }
+}
+
+/*
+ * Map a part of the scatter-gather list into contiguous io address space
+ */
+static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
+ size_t size, dma_addr_t *handle,
+ enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova, iova_base;
+ int ret = 0;
+ unsigned int count;
+ struct scatterlist *s;
+
+ size = PAGE_ALIGN(size);
+ *handle = DMA_ERROR_CODE;
+
+ iova_base = iova = __alloc_iova(mapping, size);
+ if (iova == DMA_ERROR_CODE)
+ return -ENOMEM;
+
+ for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
+ phys_addr_t phys = page_to_phys(sg_page(s));
+ unsigned int len = PAGE_ALIGN(s->offset + s->length);
+
+ if (!arch_is_coherent())
+ __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+
+ ret = iommu_map(mapping->domain, iova, phys, len, 0);
+ if (ret < 0)
+ goto fail;
+ count += len >> PAGE_SHIFT;
+ iova += len;
+ }
+ *handle = iova_base;
+
+ return 0;
+fail:
+ iommu_unmap(mapping->domain, iova_base, count * PAGE_SIZE);
+ __free_iova(mapping, iova_base, size);
+ return ret;
+}
+
+/**
+ * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * The scatter gather list elements are merged together (if possible) and
+ * tagged with the appropriate dma address and length. They are obtained via
+ * sg_dma_{address,length}.
+ */
+int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct scatterlist *s = sg, *dma = sg, *start = sg;
+ int i, count = 0;
+ unsigned int offset = s->offset;
+ unsigned int size = s->offset + s->length;
+ unsigned int max = dma_get_max_seg_size(dev);
+
+ for (i = 1; i < nents; i++) {
+ s = sg_next(s);
+
+ s->dma_address = DMA_ERROR_CODE;
+ s->dma_length = 0;
+
+ if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address,
+ dir) < 0)
+ goto bad_mapping;
+
+ dma->dma_address += offset;
+ dma->dma_length = size - offset;
+
+ size = offset = s->offset;
+ start = s;
+ dma = sg_next(dma);
+ count += 1;
+ }
+ size += s->length;
+ }
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0)
+ goto bad_mapping;
+
+ dma->dma_address += offset;
+ dma->dma_length = size - offset;
+
+ return count+1;
+
+bad_mapping:
+ for_each_sg(sg, s, count, i)
+ __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s));
+ return 0;
+}
+
+/**
+ * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations. Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ if (sg_dma_len(s))
+ __iommu_remove_mapping(dev, sg_dma_address(s),
+ sg_dma_len(s));
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(sg_page(s), s->offset,
+ s->length, dir);
+ }
+}
+
+/**
+ * arm_iommu_sync_sg_for_cpu
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
+
+}
+
+/**
+ * arm_iommu_sync_sg_for_device
+ * @dev: valid struct device pointer
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i)
+ if (!arch_is_coherent())
+ __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
+}
+
+
+/**
+ * arm_iommu_map_page
+ * @dev: valid struct device pointer
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * IOMMU aware version of arm_dma_map_page()
+ */
+static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t dma_addr;
+ int ret, len = PAGE_ALIGN(size + offset);
+
+ if (!arch_is_coherent())
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+
+ dma_addr = __alloc_iova(mapping, len);
+ if (dma_addr == DMA_ERROR_CODE)
+ return dma_addr;
+
+ ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, 0);
+ if (ret < 0)
+ goto fail;
+
+ return dma_addr + offset;
+fail:
+ __free_iova(mapping, dma_addr, len);
+ return DMA_ERROR_CODE;
+}
+
+/**
+ * arm_iommu_unmap_page
+ * @dev: valid struct device pointer
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * IOMMU aware version of arm_dma_unmap_page()
+ */
+static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ int offset = handle & ~PAGE_MASK;
+ int len = PAGE_ALIGN(size + offset);
+
+ if (!iova)
+ return;
+
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+
+ iommu_unmap(mapping->domain, iova, len);
+ __free_iova(mapping, iova, len);
+}
+
+static void arm_iommu_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ unsigned int offset = handle & ~PAGE_MASK;
+
+ if (!iova)
+ return;
+
+ if (!arch_is_coherent())
+ __dma_page_dev_to_cpu(page, offset, size, dir);
+}
+
+static void arm_iommu_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ struct dma_iommu_mapping *mapping = dev->archdata.mapping;
+ dma_addr_t iova = handle & PAGE_MASK;
+ struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
+ unsigned int offset = handle & ~PAGE_MASK;
+
+ if (!iova)
+ return;
+
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+}
+
+struct dma_map_ops iommu_ops = {
+ .alloc = arm_iommu_alloc_attrs,
+ .free = arm_iommu_free_attrs,
+ .mmap = arm_iommu_mmap_attrs,
+
+ .map_page = arm_iommu_map_page,
+ .unmap_page = arm_iommu_unmap_page,
+ .sync_single_for_cpu = arm_iommu_sync_single_for_cpu,
+ .sync_single_for_device = arm_iommu_sync_single_for_device,
+
+ .map_sg = arm_iommu_map_sg,
+ .unmap_sg = arm_iommu_unmap_sg,
+ .sync_sg_for_cpu = arm_iommu_sync_sg_for_cpu,
+ .sync_sg_for_device = arm_iommu_sync_sg_for_device,
+};
+
+/**
+ * arm_iommu_create_mapping
+ * @bus: pointer to the bus holding the client device (for IOMMU calls)
+ * @base: start address of the valid IO address space
+ * @size: size of the valid IO address space
+ * @order: accuracy of the IO addresses allocations
+ *
+ * Creates a mapping structure which holds information about used/unused
+ * IO address ranges, which is required to perform memory allocation and
+ * mapping with IOMMU aware functions.
+ *
+ * The client device need to be attached to the mapping with
+ * arm_iommu_attach_device function.
+ */
+struct dma_iommu_mapping *
+arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
+ int order)
+{
+ unsigned int count = size >> (PAGE_SHIFT + order);
+ unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
+ struct dma_iommu_mapping *mapping;
+ int err = -ENOMEM;
+
+ if (!count)
+ return ERR_PTR(-EINVAL);
+
+ mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
+ if (!mapping)
+ goto err;
+
+ mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!mapping->bitmap)
+ goto err2;
+
+ mapping->base = base;
+ mapping->bits = BITS_PER_BYTE * bitmap_size;
+ mapping->order = order;
+ spin_lock_init(&mapping->lock);
+
+ mapping->domain = iommu_domain_alloc(bus);
+ if (!mapping->domain)
+ goto err3;
+
+ kref_init(&mapping->kref);
+ return mapping;
+err3:
+ kfree(mapping->bitmap);
+err2:
+ kfree(mapping);
+err:
+ return ERR_PTR(err);
+}
+
+static void release_iommu_mapping(struct kref *kref)
+{
+ struct dma_iommu_mapping *mapping =
+ container_of(kref, struct dma_iommu_mapping, kref);
+
+ iommu_domain_free(mapping->domain);
+ kfree(mapping->bitmap);
+ kfree(mapping);
+}
+
+void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
+{
+ if (mapping)
+ kref_put(&mapping->kref, release_iommu_mapping);
+}
+
+/**
+ * arm_iommu_attach_device
+ * @dev: valid struct device pointer
+ * @mapping: io address space mapping structure (returned from
+ * arm_iommu_create_mapping)
+ *
+ * Attaches specified io address space mapping to the provided device,
+ * this replaces the dma operations (dma_map_ops pointer) with the
+ * IOMMU aware version. More than one client might be attached to
+ * the same io address space mapping.
+ */
+int arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping)
+{
+ int err;
+
+ err = iommu_attach_device(mapping->domain, dev);
+ if (err)
+ return err;
+
+ kref_get(&mapping->kref);
+ dev->archdata.mapping = mapping;
+ set_dma_ops(dev, &iommu_ops);
+
+ pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev));
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8f5813bbffb5..c21d06c7dd7e 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -20,6 +20,7 @@
#include <linux/highmem.h>
#include <linux/gfp.h>
#include <linux/memblock.h>
+#include <linux/dma-contiguous.h>
#include <asm/mach-types.h>
#include <asm/memblock.h>
@@ -226,6 +227,17 @@ static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
}
#endif
+void __init setup_dma_zone(struct machine_desc *mdesc)
+{
+#ifdef CONFIG_ZONE_DMA
+ if (mdesc->dma_zone_size) {
+ arm_dma_zone_size = mdesc->dma_zone_size;
+ arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
+ } else
+ arm_dma_limit = 0xffffffff;
+#endif
+}
+
static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
unsigned long max_high)
{
@@ -273,12 +285,9 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
* Adjust the sizes according to any special requirements for
* this machine type.
*/
- if (arm_dma_zone_size) {
+ if (arm_dma_zone_size)
arm_adjust_dma_zone(zone_size, zhole_size,
arm_dma_zone_size >> PAGE_SHIFT);
- arm_dma_limit = PHYS_OFFSET + arm_dma_zone_size - 1;
- } else
- arm_dma_limit = 0xffffffff;
#endif
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)
if (mdesc->reserve)
mdesc->reserve();
+ /*
+ * reserve memory for DMA contigouos allocations,
+ * must come from DMA area inside low memory
+ */
+ dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
+
arm_memblock_steal_permitted = false;
memblock_allow_resize();
memblock_dump_all();
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 27f4a619b35d..93dc0c17cdcb 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -67,5 +67,8 @@ extern u32 arm_dma_limit;
#define arm_dma_limit ((u32)~0)
#endif
+extern phys_addr_t arm_lowmem_limit;
+
void __init bootmem_init(void);
void arm_mm_memblock_reserve(void);
+void dma_contiguous_remap(void);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index aa78de8bfdd3..e5dad60b558b 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -288,6 +288,11 @@ static struct mem_type mem_types[] = {
PMD_SECT_UNCACHED | PMD_SECT_XN,
.domain = DOMAIN_KERNEL,
},
+ [MT_MEMORY_DMA_READY] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_KERNEL,
+ },
};
const struct mem_type *get_mem_type(unsigned int type)
@@ -429,6 +434,7 @@ static void __init build_mem_type_table(void)
if (arch_is_coherent() && cpu_is_xsc3()) {
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
}
@@ -460,6 +466,7 @@ static void __init build_mem_type_table(void)
mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
}
@@ -512,6 +519,7 @@ static void __init build_mem_type_table(void)
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
mem_types[MT_ROM].prot_sect |= cp->pmd;
@@ -596,7 +604,7 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
* L1 entries, whereas PGDs refer to a group of L1 entries making
* up one logical pointer to an L2 table.
*/
- if (((addr | end | phys) & ~SECTION_MASK) == 0) {
+ if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
pmd_t *p = pmd;
#ifndef CONFIG_ARM_LPAE
@@ -814,7 +822,7 @@ static int __init early_vmalloc(char *arg)
}
early_param("vmalloc", early_vmalloc);
-static phys_addr_t lowmem_limit __initdata = 0;
+phys_addr_t arm_lowmem_limit __initdata = 0;
void __init sanity_check_meminfo(void)
{
@@ -897,8 +905,8 @@ void __init sanity_check_meminfo(void)
bank->size = newsize;
}
#endif
- if (!bank->highmem && bank->start + bank->size > lowmem_limit)
- lowmem_limit = bank->start + bank->size;
+ if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
+ arm_lowmem_limit = bank->start + bank->size;
j++;
}
@@ -923,8 +931,8 @@ void __init sanity_check_meminfo(void)
}
#endif
meminfo.nr_banks = j;
- high_memory = __va(lowmem_limit - 1) + 1;
- memblock_set_current_limit(lowmem_limit);
+ high_memory = __va(arm_lowmem_limit - 1) + 1;
+ memblock_set_current_limit(arm_lowmem_limit);
}
static inline void prepare_page_table(void)
@@ -949,8 +957,8 @@ static inline void prepare_page_table(void)
* Find the end of the first block of lowmem.
*/
end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
- if (end >= lowmem_limit)
- end = lowmem_limit;
+ if (end >= arm_lowmem_limit)
+ end = arm_lowmem_limit;
/*
* Clear out all the kernel space mappings, except for the first
@@ -1093,8 +1101,8 @@ static void __init map_lowmem(void)
phys_addr_t end = start + reg->size;
struct map_desc map;
- if (end > lowmem_limit)
- end = lowmem_limit;
+ if (end > arm_lowmem_limit)
+ end = arm_lowmem_limit;
if (start >= end)
break;
@@ -1115,11 +1123,12 @@ void __init paging_init(struct machine_desc *mdesc)
{
void *zero_page;
- memblock_set_current_limit(lowmem_limit);
+ memblock_set_current_limit(arm_lowmem_limit);
build_mem_type_table();
prepare_page_table();
map_lowmem();
+ dma_contiguous_remap();
devicemaps_init(mdesc);
kmap_init();
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 162be662c088..bf312c354a21 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -17,7 +17,7 @@ struct arm_vmregion {
struct list_head vm_list;
unsigned long vm_start;
unsigned long vm_end;
- struct page *vm_pages;
+ void *priv;
int vm_active;
const void *caller;
};
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 2ed3ab173add..5079787273d2 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -41,6 +41,7 @@
#include <mach/clock.h>
#include <mach/hardware.h>
+#ifndef CONFIG_COMMON_CLK
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
@@ -200,6 +201,16 @@ struct clk *clk_get_parent(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_parent);
+#else
+
+/*
+ * Lock to protect the clock module (ccm) registers. Used
+ * on all i.MXs
+ */
+DEFINE_SPINLOCK(imx_ccm_lock);
+
+#endif /* CONFIG_COMMON_CLK */
+
/*
* Get the resulting clock rate from a PLL register value and the input
* 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 753a5988d85c..bd940c795cbb 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -23,6 +23,7 @@
#ifndef __ASSEMBLY__
#include <linux/list.h>
+#ifndef CONFIG_COMMON_CLK
struct module;
struct clk {
@@ -59,6 +60,9 @@ struct clk {
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
+#endif /* CONFIG_COMMON_CLK */
+
+extern spinlock_t imx_ccm_lock;
unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 0319c4a0cafa..cf663d84e7c1 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);
extern void imx50_soc_init(void);
extern void imx51_soc_init(void);
extern void imx53_soc_init(void);
+extern void imx51_init_late(void);
extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
extern int mx1_clocks_init(unsigned long fref);
@@ -149,4 +150,10 @@ extern void imx6q_pm_init(void);
static inline void imx6q_pm_init(void) {}
#endif
+#ifdef CONFIG_NEON
+extern int mx51_neon_fixup(void);
+#else
+static inline int mx51_neon_fixup(void) { return 0; }
+#endif
+
#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 8ddda365f1a0..761e45f9456f 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 @@
#define UART_PADDR MX51_UART1_BASE_ADDR
#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
#define UART_PADDR MX53_UART1_BASE_ADDR
+#elif defined (CONFIG_DEBUG_IMX6Q_UART2)
+#define UART_PADDR MX6Q_UART2_BASE_ADDR
#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
#define UART_PADDR MX6Q_UART4_BASE_ADDR
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx6q.h b/arch/arm/plat-mxc/include/mach/mx6q.h
index 254a561a2799..f7e7dbac8f4b 100644
--- a/arch/arm/plat-mxc/include/mach/mx6q.h
+++ b/arch/arm/plat-mxc/include/mach/mx6q.h
@@ -27,6 +27,8 @@
#define MX6Q_CCM_SIZE 0x4000
#define MX6Q_ANATOP_BASE_ADDR 0x020c8000
#define MX6Q_ANATOP_SIZE 0x1000
+#define MX6Q_UART2_BASE_ADDR 0x021e8000
+#define MX6Q_UART2_SIZE 0x4000
#define MX6Q_UART4_BASE_ADDR 0x021f0000
#define MX6Q_UART4_SIZE 0x4000
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 7daf7c9a413b..99f958ca6cb8 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -25,6 +25,7 @@
#include <linux/irq.h>
#include <linux/clockchips.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <mach/hardware.h>
#include <asm/sched_clock.h>
@@ -282,6 +283,19 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
uint32_t tctl_val;
+ struct clk *timer_ipg_clk;
+
+ if (!timer_clk) {
+ timer_clk = clk_get_sys("imx-gpt.0", "per");
+ if (IS_ERR(timer_clk)) {
+ pr_err("i.MX timer: unable to get clk\n");
+ return;
+ }
+
+ timer_ipg_clk = clk_get_sys("imx-gpt.0", "ipg");
+ if (!IS_ERR(timer_ipg_clk))
+ clk_prepare_enable(timer_ipg_clk);
+ }
clk_prepare_enable(timer_clk);
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 44ae077dbc28..2132c4f389e1 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -28,19 +28,20 @@
#include <plat/clock.h>
+/* OMAP2_32KSYNCNT_CR_OFF: offset of 32ksync counter register */
+#define OMAP2_32KSYNCNT_CR_OFF 0x10
+
/*
* 32KHz clocksource ... always available, on pretty most chips except
* OMAP 730 and 1510. Other timers could be used as clocksources, with
* higher resolution in free-running counter modes (e.g. 12 MHz xtal),
* but systems won't necessarily want to spend resources that way.
*/
-static void __iomem *timer_32k_base;
-
-#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
+static void __iomem *sync32k_cnt_reg;
static u32 notrace omap_32k_read_sched_clock(void)
{
- return timer_32k_base ? __raw_readl(timer_32k_base) : 0;
+ return sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
}
/**
@@ -60,7 +61,7 @@ static void omap_read_persistent_clock(struct timespec *ts)
struct timespec *tsp = &persistent_ts;
last_cycles = cycles;
- cycles = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
+ cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
delta = cycles - last_cycles;
nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
@@ -69,55 +70,41 @@ static void omap_read_persistent_clock(struct timespec *ts)
*ts = *tsp;
}
-int __init omap_init_clocksource_32k(void)
+/**
+ * omap_init_clocksource_32k - setup and register counter 32k as a
+ * kernel clocksource
+ * @pbase: base addr of counter_32k module
+ * @size: size of counter_32k to map
+ *
+ * Returns 0 upon success or negative error code upon failure.
+ *
+ */
+int __init omap_init_clocksource_32k(void __iomem *vbase)
{
- static char err[] __initdata = KERN_ERR
- "%s: can't register clocksource!\n";
-
- if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
- u32 pbase;
- unsigned long size = SZ_4K;
- void __iomem *base;
- struct clk *sync_32k_ick;
-
- if (cpu_is_omap16xx()) {
- pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED;
- size = SZ_1K;
- } else if (cpu_is_omap2420())
- pbase = OMAP2420_32KSYNCT_BASE + 0x10;
- else if (cpu_is_omap2430())
- pbase = OMAP2430_32KSYNCT_BASE + 0x10;
- else if (cpu_is_omap34xx())
- pbase = OMAP3430_32KSYNCT_BASE + 0x10;
- else if (cpu_is_omap44xx())
- pbase = OMAP4430_32KSYNCT_BASE + 0x10;
- else
- return -ENODEV;
-
- /* For this to work we must have a static mapping in io.c for this area */
- base = ioremap(pbase, size);
- if (!base)
- return -ENODEV;
-
- sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
- if (!IS_ERR(sync_32k_ick))
- clk_enable(sync_32k_ick);
-
- timer_32k_base = base;
-
- /*
- * 120000 rough estimate from the calculations in
- * __clocksource_updatefreq_scale.
- */
- clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
- 32768, NSEC_PER_SEC, 120000);
-
- if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
- clocksource_mmio_readl_up))
- printk(err, "32k_counter");
-
- setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
- register_persistent_clock(NULL, omap_read_persistent_clock);
+ int ret;
+
+ /*
+ * 32k sync Counter register offset is at 0x10
+ */
+ sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF;
+
+ /*
+ * 120000 rough estimate from the calculations in
+ * __clocksource_updatefreq_scale.
+ */
+ clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
+ 32768, NSEC_PER_SEC, 120000);
+
+ ret = clocksource_mmio_init(sync32k_cnt_reg, "32k_counter", 32768,
+ 250, 32, clocksource_mmio_readl_up);
+ if (ret) {
+ pr_err("32k_counter: can't register clocksource\n");
+ return ret;
}
+
+ setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
+ register_persistent_clock(NULL, omap_read_persistent_clock);
+ pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
+
return 0;
}
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 09b07d252892..1cba9273d2cb 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -28,54 +28,6 @@
#include <plat/menelaus.h>
#include <plat/omap44xx.h>
-#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
- defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-
-#define OMAP_MMC_NR_RES 2
-
-/*
- * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
- */
-int __init omap_mmc_add(const char *name, int id, unsigned long base,
- unsigned long size, unsigned int irq,
- struct omap_mmc_platform_data *data)
-{
- struct platform_device *pdev;
- struct resource res[OMAP_MMC_NR_RES];
- int ret;
-
- pdev = platform_device_alloc(name, id);
- if (!pdev)
- return -ENOMEM;
-
- memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
- res[0].start = base;
- res[0].end = base + size - 1;
- res[0].flags = IORESOURCE_MEM;
- res[1].start = res[1].end = irq;
- res[1].flags = IORESOURCE_IRQ;
-
- ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
- if (ret == 0)
- ret = platform_device_add_data(pdev, data, sizeof(*data));
- if (ret)
- goto fail;
-
- ret = platform_device_add(pdev);
- if (ret)
- goto fail;
-
- /* return device handle to board setup code */
- data->dev = &pdev->dev;
- return 0;
-
-fail:
- platform_device_put(pdev);
- return ret;
-}
-
-#endif
-
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
@@ -109,79 +61,6 @@ static void omap_init_rng(void)
static inline void omap_init_rng(void) {}
#endif
-/*-------------------------------------------------------------------------*/
-
-/* Numbering for the SPI-capable controllers when used for SPI:
- * spi = 1
- * uwire = 2
- * mmc1..2 = 3..4
- * mcbsp1..3 = 5..7
- */
-
-#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
-
-#define OMAP_UWIRE_BASE 0xfffb3000
-
-static struct resource uwire_resources[] = {
- {
- .start = OMAP_UWIRE_BASE,
- .end = OMAP_UWIRE_BASE + 0x20,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device omap_uwire_device = {
- .name = "omap_uwire",
- .id = -1,
- .num_resources = ARRAY_SIZE(uwire_resources),
- .resource = uwire_resources,
-};
-
-static void omap_init_uwire(void)
-{
- /* FIXME define and use a boot tag; not all boards will be hooking
- * up devices to the microwire controller, and multi-board configs
- * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
- */
-
- /* board-specific code must configure chipselects (only a few
- * are normally used) and SCLK/SDI/SDO (each has two choices).
- */
- (void) platform_device_register(&omap_uwire_device);
-}
-#else
-static inline void omap_init_uwire(void) {}
-#endif
-
-#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
-
-static phys_addr_t omap_dsp_phys_mempool_base;
-
-void __init omap_dsp_reserve_sdram_memblock(void)
-{
- phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
- phys_addr_t paddr;
-
- if (!size)
- return;
-
- paddr = arm_memblock_steal(size, SZ_1M);
- if (!paddr) {
- pr_err("%s: failed to reserve %llx bytes\n",
- __func__, (unsigned long long)size);
- return;
- }
-
- omap_dsp_phys_mempool_base = paddr;
-}
-
-phys_addr_t omap_dsp_get_mempool_base(void)
-{
- return omap_dsp_phys_mempool_base;
-}
-EXPORT_SYMBOL(omap_dsp_get_mempool_base);
-#endif
-
/*
* This gets called after board-specific INIT_MACHINE, and initializes most
* on-chip peripherals accessible on this board (except for few like USB):
@@ -208,7 +87,6 @@ static int __init omap_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
omap_init_rng();
- omap_init_uwire();
return 0;
}
arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 987e6101267d..cb16ade437cb 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,
}
l = p->dma_read(CCR, lch);
l &= ~((1 << 6) | (1 << 26));
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
+ if (cpu_class_is_omap2() && !cpu_is_omap242x())
l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
else
l |= ((read_prio & 0x1) << 6);
@@ -2080,7 +2080,7 @@ static int __devinit omap_system_dma_probe(struct platform_device *pdev)
}
}
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
+ if (cpu_class_is_omap2() && !cpu_is_omap242x())
omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
DMA_DEFAULT_FIFO_DEPTH, 0);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index c4ed35e89fbd..3b0cfeb33d05 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,
static void omap_timer_restore_context(struct omap_dm_timer *timer)
{
- __raw_writel(timer->context.tiocp_cfg,
- timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
if (timer->revision == 1)
__raw_writel(timer->context.tistat, timer->sys_stat);
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index a557b8484e6c..d1cb6f527b7e 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -30,7 +30,7 @@
#include <plat/i2c.h>
#include <plat/omap_hwmod.h>
-extern int __init omap_init_clocksource_32k(void);
+extern int __init omap_init_clocksource_32k(void __iomem *vbase);
extern void __init omap_check_revision(void);
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 4bdf14ec6747..297245dba66e 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)
IS_OMAP_CLASS(24xx, 0x24)
IS_OMAP_CLASS(34xx, 0x34)
IS_OMAP_CLASS(44xx, 0x44)
+IS_AM_CLASS(35xx, 0x35)
IS_AM_CLASS(33xx, 0x33)
IS_TI_CLASS(81xx, 0x81)
@@ -148,6 +149,7 @@ IS_AM_SUBCLASS(335x, 0x335)
#define cpu_is_ti81xx() 0
#define cpu_is_ti816x() 0
#define cpu_is_ti814x() 0
+#define soc_is_am35xx() 0
#define cpu_is_am33xx() 0
#define cpu_is_am335x() 0
#define cpu_is_omap44xx() 0
@@ -357,6 +359,7 @@ IS_OMAP_TYPE(3517, 0x3517)
# undef cpu_is_ti81xx
# undef cpu_is_ti816x
# undef cpu_is_ti814x
+# undef soc_is_am35xx
# undef cpu_is_am33xx
# undef cpu_is_am335x
# define cpu_is_omap3430() is_omap3430()
@@ -378,6 +381,7 @@ IS_OMAP_TYPE(3517, 0x3517)
# define cpu_is_ti81xx() is_ti81xx()
# define cpu_is_ti816x() is_ti816x()
# define cpu_is_ti814x() is_ti814x()
+# define soc_is_am35xx() is_am35xx()
# define cpu_is_am33xx() is_am33xx()
# define cpu_is_am335x() is_am335x()
#endif
@@ -433,6 +437,10 @@ IS_OMAP_TYPE(3517, 0x3517)
#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
+#define AM35XX_CLASS 0x35170034
+#define AM35XX_REV_ES1_0 AM35XX_CLASS
+#define AM35XX_REV_ES1_1 (AM35XX_CLASS | (0x1 << 8))
+
#define AM335X_CLASS 0x33500034
#define AM335X_REV_ES1_0 AM335X_CLASS
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 42afb4c45517..c5811d4409b0 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -312,6 +312,11 @@
#define CLEAR_CSR_ON_READ BIT(0xC)
#define IS_WORD_16 BIT(0xD)
+/* Defines for DMA Capabilities */
+#define DMA_HAS_TRANSPARENT_CAPS (0x1 << 18)
+#define DMA_HAS_CONSTANT_FILL_CAPS (0x1 << 19)
+#define DMA_HAS_DESCRIPTOR_CAPS (0x3 << 20)
+
enum omap_reg_offsets {
GCR, 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 bdf871a84d62..5da73562e486 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;
struct timer_regs {
u32 tidr;
- u32 tiocp_cfg;
u32 tistat;
u32 tisr;
u32 tier;
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 3e7ae0f0215f..a7754a886d42 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,
void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers);
void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data);
-int omap_mmc_add(const char *name, int id, unsigned long base,
- unsigned long size, unsigned int irq,
- struct omap_mmc_platform_data *data);
#else
static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
int nr_controllers)
@@ -188,12 +185,6 @@ static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
{
}
-static inline int omap_mmc_add(const char *name, int id, unsigned long base,
- unsigned long size, unsigned int irq,
- struct omap_mmc_platform_data *data)
-{
- return 0;
-}
#endif
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 74daf5ed1432..61fd837624a8 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -14,15 +14,41 @@
#include <linux/dma-mapping.h>
#include <linux/serial_8250.h>
#include <linux/ata_platform.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <net/dsa.h>
-#include <linux/spi/orion_spi.h>
-#include <plat/orion_wdt.h>
#include <plat/mv_xor.h>
#include <plat/ehci-orion.h>
#include <mach/bridge-regs.h>
+/* Create a clkdev entry for a given device/clk */
+void __init orion_clkdev_add(const char *con_id, const char *dev_id,
+ struct clk *clk)
+{
+ struct clk_lookup *cl;
+
+ cl = clkdev_alloc(clk, con_id, dev_id);
+ if (cl)
+ clkdev_add(cl);
+}
+
+/* Create clkdev entries for all orion platforms except kirkwood.
+ Kirkwood has gated clocks for some of its peripherals, so creates
+ its own clkdev entries. For all the other orion devices, create
+ clkdev entries to the tclk. */
+void __init orion_clkdev_init(struct clk *tclk)
+{
+ orion_clkdev_add(NULL, "orion_spi.0", tclk);
+ orion_clkdev_add(NULL, "orion_spi.1", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk);
+ orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk);
+ orion_clkdev_add(NULL, "orion_wdt", tclk);
+}
+
/* Fill in the resources structure and link it into the platform
device structure. There is always a memory region, and nearly
always an interrupt.*/
@@ -49,6 +75,12 @@ static void fill_resources(struct platform_device *device,
/*****************************************************************************
* UART
****************************************************************************/
+static unsigned long __init uart_get_clk_rate(struct clk *clk)
+{
+ clk_prepare_enable(clk);
+ return clk_get_rate(clk);
+}
+
static void __init uart_complete(
struct platform_device *orion_uart,
struct plat_serial8250_port *data,
@@ -56,12 +88,12 @@ static void __init uart_complete(
unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk)
+ struct clk *clk)
{
data->mapbase = mapbase;
data->membase = (void __iomem *)membase;
data->irq = irq;
- data->uartclk = uartclk;
+ data->uartclk = uart_get_clk_rate(clk);
orion_uart->dev.platform_data = data;
fill_resources(orion_uart, resources, mapbase, 0xff, irq);
@@ -90,10 +122,10 @@ static struct platform_device orion_uart0 = {
void __init orion_uart0_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk)
+ struct clk *clk)
{
uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
- membase, mapbase, irq, uartclk);
+ membase, mapbase, irq, clk);
}
/*****************************************************************************
@@ -118,10 +150,10 @@ static struct platform_device orion_uart1 = {
void __init orion_uart1_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk)
+ struct clk *clk)
{
uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
- membase, mapbase, irq, uartclk);
+ membase, mapbase, irq, clk);
}
/*****************************************************************************
@@ -146,10 +178,10 @@ static struct platform_device orion_uart2 = {
void __init orion_uart2_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk)
+ struct clk *clk)
{
uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources,
- membase, mapbase, irq, uartclk);
+ membase, mapbase, irq, clk);
}
/*****************************************************************************
@@ -174,10 +206,10 @@ static struct platform_device orion_uart3 = {
void __init orion_uart3_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk)
+ struct clk *clk)
{
uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources,
- membase, mapbase, irq, uartclk);
+ membase, mapbase, irq, clk);
}
/*****************************************************************************
@@ -203,13 +235,11 @@ void __init orion_rtc_init(unsigned long mapbase,
****************************************************************************/
static __init void ge_complete(
struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
- int tclk,
struct resource *orion_ge_resource, unsigned long irq,
struct platform_device *orion_ge_shared,
struct mv643xx_eth_platform_data *eth_data,
struct platform_device *orion_ge)
{
- orion_ge_shared_data->t_clk = tclk;
orion_ge_resource->start = irq;
orion_ge_resource->end = irq;
eth_data->shared = orion_ge_shared;
@@ -260,12 +290,11 @@ static struct platform_device orion_ge00 = {
void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk)
+ unsigned long irq_err)
{
fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
- ge_complete(&orion_ge00_shared_data, tclk,
+ ge_complete(&orion_ge00_shared_data,
orion_ge00_resources, irq, &orion_ge00_shared,
eth_data, &orion_ge00);
}
@@ -313,12 +342,11 @@ static struct platform_device orion_ge01 = {
void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk)
+ unsigned long irq_err)
{
fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
- ge_complete(&orion_ge01_shared_data, tclk,
+ ge_complete(&orion_ge01_shared_data,
orion_ge01_resources, irq, &orion_ge01_shared,
eth_data, &orion_ge01);
}
@@ -366,12 +394,11 @@ static struct platform_device orion_ge10 = {
void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk)
+ unsigned long irq_err)
{
fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
- ge_complete(&orion_ge10_shared_data, tclk,
+ ge_complete(&orion_ge10_shared_data,
orion_ge10_resources, irq, &orion_ge10_shared,
eth_data, &orion_ge10);
}
@@ -419,12 +446,11 @@ static struct platform_device orion_ge11 = {
void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk)
+ unsigned long irq_err)
{
fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
mapbase + 0x2000, SZ_16K - 1, irq_err);
- ge_complete(&orion_ge11_shared_data, tclk,
+ ge_complete(&orion_ge11_shared_data,
orion_ge11_resources, irq, &orion_ge11_shared,
eth_data, &orion_ge11);
}
@@ -521,44 +547,32 @@ void __init orion_i2c_1_init(unsigned long mapbase,
/*****************************************************************************
* SPI
****************************************************************************/
-static struct orion_spi_info orion_spi_plat_data;
static struct resource orion_spi_resources;
static struct platform_device orion_spi = {
.name = "orion_spi",
.id = 0,
- .dev = {
- .platform_data = &orion_spi_plat_data,
- },
};
-static struct orion_spi_info orion_spi_1_plat_data;
static struct resource orion_spi_1_resources;
static struct platform_device orion_spi_1 = {
.name = "orion_spi",
.id = 1,
- .dev = {
- .platform_data = &orion_spi_1_plat_data,
- },
};
/* Note: The SPI silicon core does have interrupts. However the
* current Linux software driver does not use interrupts. */
-void __init orion_spi_init(unsigned long mapbase,
- unsigned long tclk)
+void __init orion_spi_init(unsigned long mapbase)
{
- orion_spi_plat_data.tclk = tclk;
fill_resources(&orion_spi, &orion_spi_resources,
mapbase, SZ_512 - 1, NO_IRQ);
platform_device_register(&orion_spi);
}
-void __init orion_spi_1_init(unsigned long mapbase,
- unsigned long tclk)
+void __init orion_spi_1_init(unsigned long mapbase)
{
- orion_spi_1_plat_data.tclk = tclk;
fill_resources(&orion_spi_1, &orion_spi_1_resources,
mapbase, SZ_512 - 1, NO_IRQ);
platform_device_register(&orion_spi_1);
@@ -567,24 +581,18 @@ void __init orion_spi_1_init(unsigned long mapbase,
/*****************************************************************************
* Watchdog
****************************************************************************/
-static struct orion_wdt_platform_data orion_wdt_data;
-
static struct resource orion_wdt_resource =
DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28);
static struct platform_device orion_wdt_device = {
.name = "orion_wdt",
.id = -1,
- .dev = {
- .platform_data = &orion_wdt_data,
- },
- .resource = &orion_wdt_resource,
.num_resources = 1,
+ .resource = &orion_wdt_resource,
};
-void __init orion_wdt_init(unsigned long tclk)
+void __init orion_wdt_init(void)
{
- orion_wdt_data.tclk = tclk;
platform_device_register(&orion_wdt_device);
}
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index a7fa005a5a0e..e00fdb213609 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;
void __init orion_uart0_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk);
+ struct clk *clk);
void __init orion_uart1_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk);
+ struct clk *clk);
void __init orion_uart2_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk);
+ struct clk *clk);
void __init orion_uart3_init(unsigned int membase,
resource_size_t mapbase,
unsigned int irq,
- unsigned int uartclk);
+ struct clk *clk);
void __init orion_rtc_init(unsigned long mapbase,
unsigned long irq);
@@ -39,29 +39,26 @@ void __init orion_rtc_init(unsigned long mapbase,
void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk);
+ unsigned long irq_err);
void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk);
+ unsigned long irq_err);
void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk);
+ unsigned long irq_err);
void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
unsigned long mapbase,
unsigned long irq,
- unsigned long irq_err,
- int tclk);
+ unsigned long irq_err);
void __init orion_ge00_switch_init(struct dsa_platform_data *d,
int irq);
+
void __init orion_i2c_init(unsigned long mapbase,
unsigned long irq,
unsigned long freq_m);
@@ -70,13 +67,11 @@ void __init orion_i2c_1_init(unsigned long mapbase,
unsigned long irq,
unsigned long freq_m);
-void __init orion_spi_init(unsigned long mapbase,
- unsigned long tclk);
+void __init orion_spi_init(unsigned long mapbase);
-void __init orion_spi_1_init(unsigned long mapbase,
- unsigned long tclk);
+void __init orion_spi_1_init(unsigned long mapbase);
-void __init orion_wdt_init(unsigned long tclk);
+void __init orion_wdt_init(void);
void __init orion_xor0_init(unsigned long mapbase_low,
unsigned long mapbase_high,
@@ -106,4 +101,9 @@ void __init orion_crypto_init(unsigned long mapbase,
unsigned long srambase,
unsigned long sram_size,
unsigned long irq);
+
+void __init orion_clkdev_add(const char *con_id, const char *dev_id,
+ struct clk *clk);
+
+void __init orion_clkdev_init(struct clk *tclk);
#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 665c362a2fba..000000000000
--- a/arch/arm/plat-orion/include/plat/orion_wdt.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * arch/arm/plat-orion/include/plat/orion_wdt.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_ORION_WDT_H
-#define __PLAT_ORION_WDT_H
-
-struct orion_wdt_platform_data {
- u32 tclk; /* no <linux/clk.h> support yet */
-};
-
-
-#endif
-
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
index 86dbb5bdb172..f20a321088a2 100644
--- a/arch/arm/plat-orion/pcie.c
+++ b/arch/arm/plat-orion/pcie.c
@@ -52,12 +52,12 @@
#define PCIE_DEBUG_SOFT_RESET (1<<20)
-u32 __init orion_pcie_dev_id(void __iomem *base)
+u32 orion_pcie_dev_id(void __iomem *base)
{
return readl(base + PCIE_DEV_ID_OFF) >> 16;
}
-u32 __init orion_pcie_rev(void __iomem *base)
+u32 orion_pcie_rev(void __iomem *base)
{
return readl(base + PCIE_DEV_REV_OFF) & 0xff;
}
diff --git a/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
index abcc36eb1242..5ce8d5e6ea51 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 {
/* direct keys */
int direct_key_num;
unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
+ /* the key output may be low active */
+ int direct_key_low_active;
+ /* give board a chance to choose the start direct key */
+ unsigned int direct_key_mask;
/* rotary encoders 0 */
int enable_rotary0;
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 2467b800cc76..9f60549c8da1 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -12,10 +12,7 @@ obj- :=
# Core files
-obj-y += cpu.o
obj-y += irq.o
-obj-y += dev-uart.o
-obj-y += clock.o
obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o
obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o
@@ -23,9 +20,6 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
# Architecture dependent builds
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += irq-pm.o
-obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
obj-$(CONFIG_S3C24XX_DMA) += dma.o
obj-$(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 931d26d1a54b..000000000000
--- a/arch/arm/plat-s3c24xx/clock.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C24XX Core clock control support
- *
- * Based on, and code from linux/arch/arm/mach-versatile/clock.c
- **
- ** Copyright (C) 2004 ARM Limited.
- ** Written by Deep Blue Solutions Limited.
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/cpu-freq.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-
-/* initialise all the clocks */
-
-void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
- unsigned long hclk,
- unsigned long pclk)
-{
- clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
- clk_xtal.rate);
-
- clk_mpll.rate = fclk;
- clk_h.rate = hclk;
- clk_p.rate = pclk;
- clk_f.rate = fclk;
-}
diff --git a/arch/arm/plat-s3c24xx/dev-uart.c b/arch/arm/plat-s3c24xx/dev-uart.c
deleted file mode 100644
index 9ab22e662fff..000000000000
--- a/arch/arm/plat-s3c24xx/dev-uart.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/dev-uart.c
- *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Base S3C24XX UART resource and platform device definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/serial_core.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-#include <plat/regs-serial.h>
-
-/* Serial port registrations */
-
-static struct resource s3c2410_uart0_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART0,
- .end = S3C2410_PA_UART0 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX0,
- .end = IRQ_S3CUART_ERR0,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c2410_uart1_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART1,
- .end = S3C2410_PA_UART1 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX1,
- .end = IRQ_S3CUART_ERR1,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c2410_uart2_resource[] = {
- [0] = {
- .start = S3C2410_PA_UART2,
- .end = S3C2410_PA_UART2 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX2,
- .end = IRQ_S3CUART_ERR2,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct resource s3c2410_uart3_resource[] = {
- [0] = {
- .start = S3C2443_PA_UART3,
- .end = S3C2443_PA_UART3 + 0x3fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_S3CUART_RX3,
- .end = IRQ_S3CUART_ERR3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
- [0] = {
- .resources = s3c2410_uart0_resource,
- .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
- },
- [1] = {
- .resources = s3c2410_uart1_resource,
- .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
- },
- [2] = {
- .resources = s3c2410_uart2_resource,
- .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
- },
- [3] = {
- .resources = s3c2410_uart3_resource,
- .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
- },
-};
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
deleted file mode 100644
index 96bea3202304..000000000000
--- a/arch/arm/plat-s5p/Kconfig
+++ /dev/null
@@ -1,140 +0,0 @@
-# arch/arm/plat-s5p/Kconfig
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-config PLAT_S5P
- bool
- depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
- default y
- select ARM_VIC if !ARCH_EXYNOS
- select ARM_GIC if ARCH_EXYNOS
- select GIC_NON_BANKED if ARCH_EXYNOS4
- select NO_IOPORT
- select ARCH_REQUIRE_GPIOLIB
- select S3C_GPIO_TRACK
- select S5P_GPIO_DRVSTR
- select SAMSUNG_GPIOLIB_4BIT
- select PLAT_SAMSUNG
- select SAMSUNG_CLKSRC
- select SAMSUNG_IRQ_VIC_TIMER
- help
- Base platform code for Samsung's S5P series SoC.
-
-config S5P_EXT_INT
- bool
- help
- Use the external interrupts (other than GPIO interrupts.)
- Note: Do not choose this for S5P6440 and S5P6450.
-
-config S5P_GPIO_INT
- bool
- help
- Common code for the GPIO interrupts (other than external interrupts.)
-
-config S5P_HRT
- bool
- select SAMSUNG_DEV_PWM
- help
- Use the High Resolution timer support
-
-config S5P_DEV_UART
- def_bool y
- depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
-
-config S5P_PM
- bool
- help
- Common code for power management support on S5P and newer SoCs
- Note: Do not select this for S5P6440 and S5P6450.
-
-comment "System MMU"
-
-config S5P_SYSTEM_MMU
- bool "S5P SYSTEM MMU"
- depends on ARCH_EXYNOS4
- help
- Say Y here if you want to enable System MMU
-
-config S5P_SLEEP
- bool
- help
- Internal config node to apply common S5P sleep management code.
- Can be selected by S5P and newer SoCs with similar sleep procedure.
-
-config S5P_DEV_FIMC0
- bool
- help
- Compile in platform device definitions for FIMC controller 0
-
-config S5P_DEV_FIMC1
- bool
- help
- Compile in platform device definitions for FIMC controller 1
-
-config S5P_DEV_FIMC2
- bool
- help
- Compile in platform device definitions for FIMC controller 2
-
-config S5P_DEV_FIMC3
- bool
- help
- Compile in platform device definitions for FIMC controller 3
-
-config S5P_DEV_JPEG
- bool
- help
- Compile in platform device definitions for JPEG codec
-
-config S5P_DEV_G2D
- bool
- help
- Compile in platform device definitions for G2D device
-
-config S5P_DEV_FIMD0
- bool
- help
- Compile in platform device definitions for FIMD controller 0
-
-config S5P_DEV_I2C_HDMIPHY
- bool
- help
- Compile in platform device definitions for I2C HDMIPHY controller
-
-config S5P_DEV_MFC
- bool
- help
- Compile in platform device definitions for MFC
-
-config S5P_DEV_ONENAND
- bool
- help
- Compile in platform device definition for OneNAND controller
-
-config S5P_DEV_CSIS0
- bool
- help
- Compile in platform device definitions for MIPI-CSIS channel 0
-
-config S5P_DEV_CSIS1
- bool
- help
- Compile in platform device definitions for MIPI-CSIS channel 1
-
-config S5P_DEV_TV
- bool
- help
- Compile in platform device definition for TV interface
-
-config S5P_DEV_USB_EHCI
- bool
- help
- Compile in platform device definition for USB EHCI
-
-config S5P_SETUP_MIPIPHY
- bool
- help
- 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 4bd824136659..000000000000
--- a/arch/arm/plat-s5p/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# arch/arm/plat-s5p/Makefile
-#
-# Copyright (c) 2009 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n := dummy.o
-obj- :=
-
-# Core files
-
-obj-y += clock.o
-obj-y += irq.o
-obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
-obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
-obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
-obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o
-obj-$(CONFIG_S5P_SLEEP) += sleep.o
-obj-$(CONFIG_S5P_HRT) += s5p-time.o
-
-# devices
-
-obj-$(CONFIG_S5P_DEV_UART) += dev-uart.o
-obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
-obj-$(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 c8bec9c7655d..000000000000
--- a/arch/arm/plat-s5p/sysmmu.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/* linux/arch/arm/plat-s5p/sysmmu.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/export.h>
-
-#include <asm/pgtable.h>
-
-#include <mach/map.h>
-#include <mach/regs-sysmmu.h>
-#include <plat/sysmmu.h>
-
-#define CTRL_ENABLE 0x5
-#define CTRL_BLOCK 0x7
-#define CTRL_DISABLE 0x0
-
-static struct device *dev;
-
-static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
- S5P_PAGE_FAULT_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AW_FAULT_ADDR,
- S5P_DEFAULT_SLAVE_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AW_FAULT_ADDR,
- S5P_AW_FAULT_ADDR
-};
-
-static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
- "PAGE FAULT",
- "AR MULTI-HIT FAULT",
- "AW MULTI-HIT FAULT",
- "BUS ERROR",
- "AR SECURITY PROTECTION FAULT",
- "AR ACCESS PROTECTION FAULT",
- "AW SECURITY PROTECTION FAULT",
- "AW ACCESS PROTECTION FAULT"
-};
-
-static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])(
- enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr);
-
-/*
- * If adjacent 2 bits are true, the system MMU is enabled.
- * The system MMU is disabled, otherwise.
- */
-static unsigned long sysmmu_states;
-
-static inline void set_sysmmu_active(sysmmu_ips ips)
-{
- sysmmu_states |= 3 << (ips * 2);
-}
-
-static inline void set_sysmmu_inactive(sysmmu_ips ips)
-{
- sysmmu_states &= ~(3 << (ips * 2));
-}
-
-static inline int is_sysmmu_active(sysmmu_ips ips)
-{
- return sysmmu_states & (3 << (ips * 2));
-}
-
-static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM];
-
-static inline void sysmmu_block(sysmmu_ips ips)
-{
- __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL);
- dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void sysmmu_unblock(sysmmu_ips ips)
-{
- __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
- dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips)
-{
- __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH);
- dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd)
-{
- if (unlikely(pgd == 0)) {
- pgd = (unsigned long)ZERO_PAGE(0);
- __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */
- } else {
- __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */
- }
-
- __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
-
- dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n",
- sysmmu_ips_name[ips], pgd);
- __sysmmu_tlb_invalidate(ips);
-}
-
-void sysmmu_set_fault_handler(sysmmu_ips ips,
- int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr))
-{
- BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM)));
- fault_handlers[ips] = handler;
-}
-
-static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
-{
- /* SYSMMU is in blocked when interrupt occurred. */
- unsigned long base = 0;
- sysmmu_ips ips = (sysmmu_ips)dev_id;
- enum S5P_SYSMMU_INTERRUPT_TYPE itype;
-
- itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
- __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS));
-
- BUG_ON(!((itype >= 0) && (itype < 8)));
-
- dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype],
- sysmmu_ips_name[ips]);
-
- if (fault_handlers[ips]) {
- unsigned long addr;
-
- base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
- addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]);
-
- if (fault_handlers[ips](itype, base, addr)) {
- __raw_writel(1 << itype,
- sysmmusfrs[ips] + S5P_INT_CLEAR);
- dev_notice(dev, "%s from %s is resolved."
- " Retrying translation.\n",
- sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
- } else {
- base = 0;
- }
- }
-
- sysmmu_unblock(ips);
-
- if (!base)
- dev_notice(dev, "%s from %s is not handled.\n",
- sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
-
- return IRQ_HANDLED;
-}
-
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
-{
- if (is_sysmmu_active(ips)) {
- sysmmu_block(ips);
- __sysmmu_set_ptbase(ips, pgd);
- sysmmu_unblock(ips);
- } else {
- dev_dbg(dev, "%s is disabled. "
- "Skipping initializing page table base.\n",
- sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
-{
- if (!is_sysmmu_active(ips)) {
- sysmmu_clk_enable(ips);
-
- __sysmmu_set_ptbase(ips, pgd);
-
- __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
-
- set_sysmmu_active(ips);
- dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]);
- } else {
- dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_disable(sysmmu_ips ips)
-{
- if (is_sysmmu_active(ips)) {
- __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
- set_sysmmu_inactive(ips);
- sysmmu_clk_disable(ips);
- dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
- } else {
- dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
-{
- if (is_sysmmu_active(ips)) {
- sysmmu_block(ips);
- __sysmmu_tlb_invalidate(ips);
- sysmmu_unblock(ips);
- } else {
- dev_dbg(dev, "%s is disabled. "
- "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]);
- }
-}
-
-static int s5p_sysmmu_probe(struct platform_device *pdev)
-{
- int i, ret;
- struct resource *res, *mem;
-
- dev = &pdev->dev;
-
- for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
- int irq;
-
- sysmmu_clk_init(dev, i);
- sysmmu_clk_disable(i);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- if (!res) {
- dev_err(dev, "Failed to get the resource of %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENODEV;
- goto err_res;
- }
-
- mem = request_mem_region(res->start, resource_size(res),
- pdev->name);
- if (!mem) {
- dev_err(dev, "Failed to request the memory region of %s.\n",
- sysmmu_ips_name[i]);
- ret = -EBUSY;
- goto err_res;
- }
-
- sysmmusfrs[i] = ioremap(res->start, resource_size(res));
- if (!sysmmusfrs[i]) {
- dev_err(dev, "Failed to ioremap() for %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENXIO;
- goto err_reg;
- }
-
- irq = platform_get_irq(pdev, i);
- if (irq <= 0) {
- dev_err(dev, "Failed to get the IRQ resource of %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENOENT;
- goto err_map;
- }
-
- if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED,
- pdev->name, (void *)i)) {
- dev_err(dev, "Failed to request IRQ for %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENOENT;
- goto err_map;
- }
- }
-
- return 0;
-
-err_map:
- iounmap(sysmmusfrs[i]);
-err_reg:
- release_mem_region(mem->start, resource_size(mem));
-err_res:
- return ret;
-}
-
-static int s5p_sysmmu_remove(struct platform_device *pdev)
-{
- return 0;
-}
-int s5p_sysmmu_runtime_suspend(struct device *dev)
-{
- return 0;
-}
-
-int s5p_sysmmu_runtime_resume(struct device *dev)
-{
- return 0;
-}
-
-const struct dev_pm_ops s5p_sysmmu_pm_ops = {
- .runtime_suspend = s5p_sysmmu_runtime_suspend,
- .runtime_resume = s5p_sysmmu_runtime_resume,
-};
-
-static struct platform_driver s5p_sysmmu_driver = {
- .probe = s5p_sysmmu_probe,
- .remove = s5p_sysmmu_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "s5p-sysmmu",
- .pm = &s5p_sysmmu_pm_ops,
- }
-};
-
-static int __init s5p_sysmmu_init(void)
-{
- return platform_driver_register(&s5p_sysmmu_driver);
-}
-arch_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index a0ffc77da809..a2fae4ea0936 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -13,6 +13,24 @@ config PLAT_SAMSUNG
help
Base platform code for all Samsung SoC based systems
+config PLAT_S5P
+ bool
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ default y
+ select ARM_VIC if !ARCH_EXYNOS
+ select ARM_GIC if ARCH_EXYNOS
+ select GIC_NON_BANKED if ARCH_EXYNOS4
+ select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
+ select S3C_GPIO_TRACK
+ select S5P_GPIO_DRVSTR
+ select SAMSUNG_GPIOLIB_4BIT
+ select PLAT_SAMSUNG
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ help
+ Base platform code for Samsung's S5P series SoC.
+
if PLAT_SAMSUNG
# boot configurations
@@ -50,6 +68,14 @@ config S3C_LOWLEVEL_UART_PORT
this configuration should be between zero and two. The port
must have been initialised by the boot-loader before use.
+# timer options
+
+config S5P_HRT
+ bool
+ select SAMSUNG_DEV_PWM
+ help
+ Use the High Resolution timer support
+
# clock options
config SAMSUNG_CLKSRC
@@ -58,6 +84,11 @@ config SAMSUNG_CLKSRC
Select the clock code for the clksrc implementation
used by newer systems such as the S3C64XX.
+config S5P_CLOCK
+ def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ help
+ Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
+
# options for IRQ support
config SAMSUNG_IRQ_VIC_TIMER
@@ -65,6 +96,22 @@ config SAMSUNG_IRQ_VIC_TIMER
help
Internal configuration to build the VIC timer interrupt code.
+config S5P_IRQ
+ def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ help
+ Support common interrup part for ARCH_S5P and ARCH_EXYNOS SoCs
+
+config S5P_EXT_INT
+ bool
+ help
+ Use the external interrupts (other than GPIO interrupts.)
+ Note: Do not choose this for S5P6440 and S5P6450.
+
+config S5P_GPIO_INT
+ bool
+ help
+ Common code for the GPIO interrupts (other than external interrupts.)
+
# options for gpio configuration support
config SAMSUNG_GPIOLIB_4BIT
@@ -117,6 +164,12 @@ config S3C_GPIO_TRACK
Internal configuration option to enable the s3c specific gpio
chip tracking if the platform requires it.
+# uart options
+
+config S5P_DEV_UART
+ def_bool y
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
+
# ADC driver
config S3C_ADC
@@ -274,6 +327,76 @@ config SAMSUNG_DEV_BACKLIGHT
help
Compile in platform device definition LCD backlight with PWM Timer
+config S5P_DEV_CSIS0
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 0
+
+config S5P_DEV_CSIS1
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 1
+
+config S5P_DEV_FIMC0
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 0
+
+config S5P_DEV_FIMC1
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 1
+
+config S5P_DEV_FIMC2
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 2
+
+config S5P_DEV_FIMC3
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 3
+
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
+config S5P_DEV_G2D
+ bool
+ help
+ Compile in platform device definitions for G2D device
+
+config S5P_DEV_I2C_HDMIPHY
+ bool
+ help
+ Compile in platform device definitions for I2C HDMIPHY controller
+
+config S5P_DEV_JPEG
+ bool
+ help
+ Compile in platform device definitions for JPEG codec
+
+config S5P_DEV_MFC
+ bool
+ help
+ Compile in setup memory (init) code for MFC
+
+config S5P_DEV_ONENAND
+ bool
+ help
+ Compile in platform device definition for OneNAND controller
+
+config S5P_DEV_TV
+ bool
+ help
+ Compile in platform device definition for TV interface
+
+config S5P_DEV_USB_EHCI
+ bool
+ help
+ Compile in platform device definition for USB EHCI
+
config S3C24XX_PWM
bool "PWM device support"
select HAVE_PWM
@@ -281,6 +404,11 @@ config S3C24XX_PWM
Support for exporting the PWM timer blocks via the pwm device
system
+config S5P_SETUP_MIPIPHY
+ bool
+ help
+ Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
# DMA
config S3C_DMA
@@ -291,7 +419,7 @@ config S3C_DMA
config SAMSUNG_DMADEV
bool
select DMADEVICES
- select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
+ select PL330_DMA if (ARCH_EXYNOS5 || ARCH_EXYNOS4 || CPU_S5PV210 || CPU_S5PC100 || \
CPU_S5P6450 || CPU_S5P6440)
select ARM_AMBA
help
@@ -351,6 +479,18 @@ config SAMSUNG_WAKEMASK
and above. This code allows a set of interrupt to wakeup-mask
mappings. See <plat/wakeup-mask.h>
+config S5P_PM
+ bool
+ help
+ Common code for power management support on S5P and newer SoCs
+ Note: Do not select this for S5P6440 and S5P6450.
+
+config S5P_SLEEP
+ bool
+ help
+ Internal config node to apply common S5P sleep management code.
+ Can be selected by S5P and newer SoCs with similar sleep procedure.
+
comment "Power Domain"
config SAMSUNG_PD
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 6012366f33cb..860b2db4db15 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -13,12 +13,18 @@ obj- :=
obj-y += init.o cpu.o
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
+obj-$(CONFIG_S5P_HRT) += s5p-time.o
+
obj-y += clock.o
obj-y += pwm-clock.o
obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
+obj-$(CONFIG_S5P_CLOCK) += s5p-clock.o
obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
+obj-$(CONFIG_S5P_IRQ) += s5p-irq.o
+obj-$(CONFIG_S5P_EXT_INT) += s5p-irq-eint.o
+obj-$(CONFIG_S5P_GPIO_INT) += s5p-irq-gpioint.o
# ADC
@@ -30,9 +36,13 @@ obj-y += platformdata.o
obj-y += devs.o
obj-y += dev-uart.o
+obj-$(CONFIG_S5P_DEV_MFC) += s5p-dev-mfc.o
+obj-$(CONFIG_S5P_DEV_UART) += s5p-dev-uart.o
obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
+obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+
# DMA support
obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
@@ -47,6 +57,9 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
+obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o
+obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o
+
# PD support
obj-$(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 787ceaca0be8..0721293fad63 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;
extern struct bus_type s3c6410_subsys;
extern struct bus_type s5p64x0_subsys;
extern struct bus_type s5pv210_subsys;
-extern struct bus_type exynos4_subsys;
+extern struct bus_type exynos_subsys;
extern void (*s5pc1xx_idle)(void);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 2155d4af62a3..61ca2f356c52 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;
extern struct platform_device exynos4_device_pcm2;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_spdif;
-extern struct platform_device exynos4_device_sysmmu;
+
+extern struct platform_device exynos_device_drm;
extern struct platform_device samsung_asoc_dma;
extern 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 0670f37aaaed..d384a8016b47 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 {
DMACH_MIPI_HSI5,
DMACH_MIPI_HSI6,
DMACH_MIPI_HSI7,
+ DMACH_DISP1,
DMACH_MTOM_0,
DMACH_MTOM_1,
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 1de4b32f98e9..8364b4bea8b8 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;
extern struct clk s5p_clk_27m;
extern struct clk clk_fout_apll;
extern struct clk clk_fout_bpll;
+extern struct clk clk_fout_bpll_div2;
extern struct clk clk_fout_cpll;
extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_mpll_div2;
extern struct clk clk_fout_epll;
extern struct clk clk_fout_dpll;
extern struct clk clk_fout_vpll;
@@ -42,8 +44,10 @@ extern struct clk clk_vpll;
extern struct clksrc_sources clk_src_apll;
extern struct clksrc_sources clk_src_bpll;
+extern struct clksrc_sources clk_src_bpll_fout;
extern struct clksrc_sources clk_src_cpll;
extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_mpll_fout;
extern struct clksrc_sources clk_src_epll;
extern struct clksrc_sources clk_src_dpll;
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 5fe8ee01a5ba..000000000000
--- a/arch/arm/plat-samsung/include/plat/sysmmu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung System MMU driver for S5P platform
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __PLAT_SAMSUNG_SYSMMU_H
-#define __PLAT_SAMSUNG_SYSMMU_H __FILE__
-
-enum S5P_SYSMMU_INTERRUPT_TYPE {
- SYSMMU_PAGEFAULT,
- SYSMMU_AR_MULTIHIT,
- SYSMMU_AW_MULTIHIT,
- SYSMMU_BUSERROR,
- SYSMMU_AR_SECURITY,
- SYSMMU_AR_ACCESS,
- SYSMMU_AW_SECURITY,
- SYSMMU_AW_PROTECTION, /* 7 */
- SYSMMU_FAULTS_NUM
-};
-
-#ifdef CONFIG_S5P_SYSTEM_MMU
-
-#include <mach/sysmmu.h>
-
-/**
- * s5p_sysmmu_enable() - enable system mmu of ip
- * @ips: The ip connected system mmu.
- * #pgd: Base physical address of the 1st level page table
- *
- * This function enable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_disable() - disable sysmmu mmu of ip
- * @ips: The ip connected system mmu.
- *
- * This function disable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_disable(sysmmu_ips ips);
-
-/**
- * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
- * @ips: The ip connected system mmu.
- * @pgd: The page table base address.
- *
- * This function set page table base address
- * When system mmu transfer address from virtaul address to physical address,
- * system mmu refer address information from page table
- */
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
- * @ips: The ip connected system mmu.
- *
- * This function flush all TLB entry in system mmu
- */
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
-
-/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @ips is
- * SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- * translated. This is 0 if @ips is SYSMMU_BUSERROR.
- * Called when interrupt occurred by the System MMUs
- * The device drivers of peripheral devices that has a System MMU can implement
- * a fault handler to resolve address translation fault by System MMU.
- * The meanings of return value and parameters are described below.
-
- * return value: non-zero if the fault is correctly resolved.
- * zero if the fault is not handled.
- */
-void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
- int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr));
-#else
-#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
-#define s5p_sysmmu_disable(ips) do { } while (0)
-#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
-#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
-#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
-#endif
-#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-samsung/s5p-clock.c
index f68a9bb11948..031a61899bef 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-samsung/s5p-clock.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/clock.c
- *
+/*
* Copyright 2009 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
@@ -68,6 +67,11 @@ struct clk clk_fout_bpll = {
.id = -1,
};
+struct clk clk_fout_bpll_div2 = {
+ .name = "fout_bpll_div2",
+ .id = -1,
+};
+
/* CPLL clock output */
struct clk clk_fout_cpll = {
@@ -83,6 +87,11 @@ struct clk clk_fout_mpll = {
.id = -1,
};
+struct clk clk_fout_mpll_div2 = {
+ .name = "fout_mpll_div2",
+ .id = -1,
+};
+
/* EPLL clock output */
struct clk clk_fout_epll = {
.name = "fout_epll",
@@ -126,6 +135,16 @@ struct clksrc_sources clk_src_bpll = {
.nr_sources = ARRAY_SIZE(clk_src_bpll_list),
};
+static struct clk *clk_src_bpll_fout_list[] = {
+ [0] = &clk_fout_bpll_div2,
+ [1] = &clk_fout_bpll,
+};
+
+struct clksrc_sources clk_src_bpll_fout = {
+ .sources = clk_src_bpll_fout_list,
+ .nr_sources = ARRAY_SIZE(clk_src_bpll_fout_list),
+};
+
/* Possible clock sources for CPLL Mux */
static struct clk *clk_src_cpll_list[] = {
[0] = &clk_fin_cpll,
@@ -148,6 +167,16 @@ struct clksrc_sources clk_src_mpll = {
.nr_sources = ARRAY_SIZE(clk_src_mpll_list),
};
+static struct clk *clk_src_mpll_fout_list[] = {
+ [0] = &clk_fout_mpll_div2,
+ [1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll_fout = {
+ .sources = clk_src_mpll_fout_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_fout_list),
+};
+
/* Possible clock sources for EPLL Mux */
static struct clk *clk_src_epll_list[] = {
[0] = &clk_fin_epll,
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-samsung/s5p-dev-mfc.c
index a30d36b7f61b..ad6089465e2a 100644
--- a/arch/arm/plat-s5p/dev-mfc.c
+++ b/arch/arm/plat-samsung/s5p-dev-mfc.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/dev-mfc.c
- *
+/*
* Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
*
* Base S5P MFC resource and device definitions
@@ -9,7 +8,6 @@
* published by the Free Software Foundation.
*/
-
#include <linux/kernel.h>
#include <linux/interrupt.h>
#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 c9308db36183..cafa3deddcc1 100644
--- a/arch/arm/plat-s5p/dev-uart.c
+++ b/arch/arm/plat-samsung/s5p-dev-uart.c
@@ -1,6 +1,5 @@
-/* linux/arch/arm/plat-s5p/dev-uart.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+/*
+ * Copyright (c) 2009,2012 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Base S5P UART resource and device definitions
@@ -14,6 +13,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
@@ -26,86 +26,38 @@
/* Serial port registrations */
static struct resource s5p_uart0_resource[] = {
- [0] = {
- .start = S5P_PA_UART0,
- .end = S5P_PA_UART0 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART0,
- .end = IRQ_UART0,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART0, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART0),
};
static struct resource s5p_uart1_resource[] = {
- [0] = {
- .start = S5P_PA_UART1,
- .end = S5P_PA_UART1 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART1,
- .end = IRQ_UART1,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART1, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART1),
};
static struct resource s5p_uart2_resource[] = {
- [0] = {
- .start = S5P_PA_UART2,
- .end = S5P_PA_UART2 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART2,
- .end = IRQ_UART2,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART2, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART2),
};
static struct resource s5p_uart3_resource[] = {
#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
- [0] = {
- .start = S5P_PA_UART3,
- .end = S5P_PA_UART3 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART3,
- .end = IRQ_UART3,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART3, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART3),
#endif
};
static struct resource s5p_uart4_resource[] = {
#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
- [0] = {
- .start = S5P_PA_UART4,
- .end = S5P_PA_UART4 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART4,
- .end = IRQ_UART4,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART4, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART4),
#endif
};
static struct resource s5p_uart5_resource[] = {
#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
- [0] = {
- .start = S5P_PA_UART5,
- .end = S5P_PA_UART5 + S5P_SZ_UART - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_UART5,
- .end = IRQ_UART5,
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(S5P_PA_UART5, S5P_SZ_UART),
+ [1] = DEFINE_RES_IRQ(IRQ_UART5),
#endif
};
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-samsung/s5p-irq-eint.c
index 139c050918c5..33bd3f3d20f5 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-samsung/s5p-irq-eint.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/irq-eint.c
- *
+/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-samsung/s5p-irq-gpioint.c
index 82c7311017a2..f9431fe5b06e 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-samsung/s5p-irq-gpioint.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/irq-gpioint.c
- *
+/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* Author: Kyungmin Park <kyungmin.park@samsung.com>
* 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 d1bfecae6c9f..7c1e3b7072fc 100644
--- a/arch/arm/plat-s5p/irq-pm.c
+++ b/arch/arm/plat-samsung/s5p-irq-pm.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/irq-pm.c
- *
+/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-samsung/s5p-irq.c
index afdaa1082b9f..dfb47d638f03 100644
--- a/arch/arm/plat-s5p/irq.c
+++ b/arch/arm/plat-samsung/s5p-irq.c
@@ -1,5 +1,4 @@
-/* arch/arm/plat-s5p/irq.c
- *
+/*
* Copyright (c) 2009 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-samsung/s5p-pm.c
index d15dc47b0e3d..0747468f0936 100644
--- a/arch/arm/plat-s5p/pm.c
+++ b/arch/arm/plat-samsung/s5p-pm.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/pm.c
- *
+/*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
index 006bd01eda02..bdf6dadf8790 100644
--- a/arch/arm/plat-s5p/sleep.S
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/sleep.S
- *
+/*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c
index 17c0a2c58dfd..028b6e877eb9 100644
--- a/arch/arm/plat-s5p/s5p-time.c
+++ b/arch/arm/plat-samsung/s5p-time.c
@@ -1,5 +1,4 @@
-/* linux/arch/arm/plat-s5p/s5p-time.c
- *
+/*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
diff --git a/arch/arm/plat-s5p/setup-mipiphy.c b/arch/arm/plat-samsung/setup-mipiphy.c
index 683c466c0e6a..683c466c0e6a 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 387655b5ce05..4404f82d5979 100644
--- a/arch/arm/plat-spear/Kconfig
+++ b/arch/arm/plat-spear/Kconfig
@@ -8,6 +8,17 @@ choice
prompt "ST SPEAr Family"
default ARCH_SPEAR3XX
+config ARCH_SPEAR13XX
+ bool "ST SPEAr13xx with Device Tree"
+ select ARM_GIC
+ select CPU_V7
+ select USE_OF
+ select HAVE_SMP
+ select MIGHT_HAVE_CACHE_L2X0
+ select PINCTRL
+ help
+ Supports for ARM's SPEAR13XX family
+
config ARCH_SPEAR3XX
bool "ST SPEAr3xx with Device Tree"
select ARM_VIC
@@ -27,6 +38,7 @@ config ARCH_SPEAR6XX
endchoice
# Adding SPEAr machine specific configuration files
+source "arch/arm/mach-spear13xx/Kconfig"
source "arch/arm/mach-spear3xx/Kconfig"
source "arch/arm/mach-spear6xx/Kconfig"
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
index 7744802c83e7..2607bd05c525 100644
--- a/arch/arm/plat-spear/Makefile
+++ b/arch/arm/plat-spear/Makefile
@@ -3,6 +3,7 @@
#
# Common support
-obj-y := clock.o restart.o time.o pl080.o
+obj-y := restart.o time.o
-obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o
+obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o shirq.o
+obj-$(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 67dd00381ea6..000000000000
--- a/arch/arm/plat-spear/clock.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
- * arch/arm/plat-spear/clock.c
- *
- * Clock framework for SPEAr platform
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/bug.h>
-#include <linux/clk.h>
-#include <linux/debugfs.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <plat/clock.h>
-
-static DEFINE_SPINLOCK(clocks_lock);
-static LIST_HEAD(root_clks);
-#ifdef CONFIG_DEBUG_FS
-static LIST_HEAD(clocks);
-#endif
-
-static void propagate_rate(struct clk *, int on_init);
-#ifdef CONFIG_DEBUG_FS
-static int clk_debugfs_reparent(struct clk *);
-#endif
-
-static int generic_clk_enable(struct clk *clk)
-{
- unsigned int val;
-
- if (!clk->en_reg)
- return -EFAULT;
-
- val = readl(clk->en_reg);
- if (unlikely(clk->flags & RESET_TO_ENABLE))
- val &= ~(1 << clk->en_reg_bit);
- else
- val |= 1 << clk->en_reg_bit;
-
- writel(val, clk->en_reg);
-
- return 0;
-}
-
-static void generic_clk_disable(struct clk *clk)
-{
- unsigned int val;
-
- if (!clk->en_reg)
- return;
-
- val = readl(clk->en_reg);
- if (unlikely(clk->flags & RESET_TO_ENABLE))
- val |= 1 << clk->en_reg_bit;
- else
- val &= ~(1 << clk->en_reg_bit);
-
- writel(val, clk->en_reg);
-}
-
-/* generic clk ops */
-static struct clkops generic_clkops = {
- .enable = generic_clk_enable,
- .disable = generic_clk_disable,
-};
-
-/* returns current programmed clocks clock info structure */
-static struct pclk_info *pclk_info_get(struct clk *clk)
-{
- unsigned int val, i;
- struct pclk_info *info = NULL;
-
- val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
- & clk->pclk_sel->pclk_sel_mask;
-
- for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
- if (clk->pclk_sel->pclk_info[i].pclk_val == val)
- info = &clk->pclk_sel->pclk_info[i];
- }
-
- return info;
-}
-
-/*
- * Set Update pclk, and pclk_info of clk and add clock sibling node to current
- * parents children list
- */
-static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&clocks_lock, flags);
- list_del(&clk->sibling);
- list_add(&clk->sibling, &pclk_info->pclk->children);
-
- clk->pclk = pclk_info->pclk;
- spin_unlock_irqrestore(&clocks_lock, flags);
-
-#ifdef CONFIG_DEBUG_FS
- clk_debugfs_reparent(clk);
-#endif
-}
-
-static void do_clk_disable(struct clk *clk)
-{
- if (!clk)
- return;
-
- if (!clk->usage_count) {
- WARN_ON(1);
- return;
- }
-
- clk->usage_count--;
-
- if (clk->usage_count == 0) {
- /*
- * Surely, there are no active childrens or direct users
- * of this clock
- */
- if (clk->pclk)
- do_clk_disable(clk->pclk);
-
- if (clk->ops && clk->ops->disable)
- clk->ops->disable(clk);
- }
-}
-
-static int do_clk_enable(struct clk *clk)
-{
- int ret = 0;
-
- if (!clk)
- return -EFAULT;
-
- if (clk->usage_count == 0) {
- if (clk->pclk) {
- ret = do_clk_enable(clk->pclk);
- if (ret)
- goto err;
- }
- if (clk->ops && clk->ops->enable) {
- ret = clk->ops->enable(clk);
- if (ret) {
- if (clk->pclk)
- do_clk_disable(clk->pclk);
- goto err;
- }
- }
- /*
- * Since the clock is going to be used for the first
- * time please reclac
- */
- if (clk->recalc) {
- ret = clk->recalc(clk);
- if (ret)
- goto err;
- }
- }
- clk->usage_count++;
-err:
- return ret;
-}
-
-/*
- * clk_enable - inform the system when the clock source should be running.
- * @clk: clock source
- *
- * If the clock can not be enabled/disabled, this should return success.
- *
- * Returns success (0) or negative errno.
- */
-int clk_enable(struct clk *clk)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&clocks_lock, flags);
- ret = do_clk_enable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-/*
- * clk_disable - inform the system when the clock source is no longer required.
- * @clk: clock source
- *
- * Inform the system that a clock source is no longer required by
- * a driver and may be shut down.
- *
- * Implementation detail: if the clock source is shared between
- * multiple drivers, clk_enable() calls must be balanced by the
- * same number of clk_disable() calls for the clock source to be
- * disabled.
- */
-void clk_disable(struct clk *clk)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&clocks_lock, flags);
- do_clk_disable(clk);
- spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/**
- * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
- * This is only valid once the clock source has been enabled.
- * @clk: clock source
- */
-unsigned long clk_get_rate(struct clk *clk)
-{
- unsigned long flags, rate;
-
- spin_lock_irqsave(&clocks_lock, flags);
- rate = clk->rate;
- spin_unlock_irqrestore(&clocks_lock, flags);
-
- return rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/**
- * clk_set_parent - set the parent clock source for this clock
- * @clk: clock source
- * @parent: parent clock source
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
- int i, found = 0, val = 0;
- unsigned long flags;
-
- if (!clk || !parent)
- return -EFAULT;
- if (clk->pclk == parent)
- return 0;
- if (!clk->pclk_sel)
- return -EPERM;
-
- /* check if requested parent is in clk parent list */
- for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
- if (clk->pclk_sel->pclk_info[i].pclk == parent) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- return -EINVAL;
-
- spin_lock_irqsave(&clocks_lock, flags);
- /* reflect parent change in hardware */
- val = readl(clk->pclk_sel->pclk_sel_reg);
- val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
- val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
- writel(val, clk->pclk_sel->pclk_sel_reg);
- spin_unlock_irqrestore(&clocks_lock, flags);
-
- /* reflect parent change in software */
- clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
-
- propagate_rate(clk, 0);
- return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-/**
- * clk_set_rate - set the clock rate for a clock source
- * @clk: clock source
- * @rate: desired clock rate in Hz
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long flags;
- int ret = -EINVAL;
-
- if (!clk || !rate)
- return -EFAULT;
-
- if (clk->set_rate) {
- spin_lock_irqsave(&clocks_lock, flags);
- ret = clk->set_rate(clk, rate);
- if (!ret)
- /* if successful -> propagate */
- propagate_rate(clk, 0);
- spin_unlock_irqrestore(&clocks_lock, flags);
- } else if (clk->pclk) {
- u32 mult = clk->div_factor ? clk->div_factor : 1;
- ret = clk_set_rate(clk->pclk, mult * rate);
- }
-
- return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/* registers clock in platform clock framework */
-void clk_register(struct clk_lookup *cl)
-{
- struct clk *clk;
- unsigned long flags;
-
- if (!cl || !cl->clk)
- return;
- clk = cl->clk;
-
- spin_lock_irqsave(&clocks_lock, flags);
-
- INIT_LIST_HEAD(&clk->children);
- if (clk->flags & ALWAYS_ENABLED)
- clk->ops = NULL;
- else if (!clk->ops)
- clk->ops = &generic_clkops;
-
- /* root clock don't have any parents */
- if (!clk->pclk && !clk->pclk_sel) {
- list_add(&clk->sibling, &root_clks);
- } else if (clk->pclk && !clk->pclk_sel) {
- /* add clocks with only one parent to parent's children list */
- list_add(&clk->sibling, &clk->pclk->children);
- } else {
- /* clocks with more than one parent */
- struct pclk_info *pclk_info;
-
- pclk_info = pclk_info_get(clk);
- if (!pclk_info) {
- pr_err("CLKDEV: invalid pclk info of clk with"
- " %s dev_id and %s con_id\n",
- cl->dev_id, cl->con_id);
- } else {
- clk->pclk = pclk_info->pclk;
- list_add(&clk->sibling, &pclk_info->pclk->children);
- }
- }
-
- spin_unlock_irqrestore(&clocks_lock, flags);
-
- /* debugfs specific */
-#ifdef CONFIG_DEBUG_FS
- list_add(&clk->node, &clocks);
- clk->cl = cl;
-#endif
-
- /* add clock to arm clockdev framework */
- clkdev_add(cl);
-}
-
-/**
- * propagate_rate - recalculate and propagate all clocks to children
- * @pclk: parent clock required to be propogated
- * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
- *
- * Recalculates all children clocks
- */
-void propagate_rate(struct clk *pclk, int on_init)
-{
- struct clk *clk, *_temp;
- int ret = 0;
-
- list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
- if (clk->recalc) {
- ret = clk->recalc(clk);
- /*
- * recalc will return error if clk out is not programmed
- * In this case configure default rate.
- */
- if (ret && clk->set_rate)
- clk->set_rate(clk, 0);
- }
- propagate_rate(clk, on_init);
-
- if (!on_init)
- continue;
-
- /* Enable clks enabled on init, in software view */
- if (clk->flags & ENABLED_ON_INIT)
- do_clk_enable(clk);
- }
-}
-
-/**
- * round_rate_index - return closest programmable rate index in rate_config tbl
- * @clk: ptr to clock structure
- * @drate: desired rate
- * @rate: final rate will be returned in this variable only.
- *
- * Finds index in rate_config for highest clk rate which is less than
- * requested rate. If there is no clk rate lesser than requested rate then
- * -EINVAL is returned. This routine assumes that rate_config is written
- * in incrementing order of clk rates.
- * If drate passed is zero then default rate is programmed.
- */
-static int
-round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate)
-{
- unsigned long tmp = 0, prev_rate = 0;
- int index;
-
- if (!clk->calc_rate)
- return -EFAULT;
-
- if (!drate)
- return -EINVAL;
-
- /*
- * This loops ends on two conditions:
- * - as soon as clk is found with rate greater than requested rate.
- * - if all clks in rate_config are smaller than requested rate.
- */
- for (index = 0; index < clk->rate_config.count; index++) {
- prev_rate = tmp;
- tmp = clk->calc_rate(clk, index);
- if (drate < tmp) {
- index--;
- break;
- }
- }
- /* return if can't find suitable clock */
- if (index < 0) {
- index = -EINVAL;
- *rate = 0;
- } else if (index == clk->rate_config.count) {
- /* program with highest clk rate possible */
- index = clk->rate_config.count - 1;
- *rate = tmp;
- } else
- *rate = prev_rate;
-
- return index;
-}
-
-/**
- * clk_round_rate - adjust a rate to the exact rate a clock can provide
- * @clk: clock source
- * @rate: desired clock rate in Hz
- *
- * Returns rounded clock rate in Hz, or negative errno.
- */
-long clk_round_rate(struct clk *clk, unsigned long drate)
-{
- long rate = 0;
- int index;
-
- /*
- * propagate call to parent who supports calc_rate. Similar approach is
- * used in clk_set_rate.
- */
- if (!clk->calc_rate) {
- u32 mult;
- if (!clk->pclk)
- return clk->rate;
-
- mult = clk->div_factor ? clk->div_factor : 1;
- return clk_round_rate(clk->pclk, mult * drate) / mult;
- }
-
- index = round_rate_index(clk, drate, &rate);
- if (index >= 0)
- return rate;
- else
- return index;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/*All below functions are called with lock held */
-
-/*
- * Calculates pll clk rate for specific value of mode, m, n and p
- *
- * In normal mode
- * rate = (2 * M[15:8] * Fin)/(N * 2^P)
- *
- * In Dithered mode
- * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
- */
-unsigned long pll_calc_rate(struct clk *clk, int index)
-{
- unsigned long rate = clk->pclk->rate;
- struct pll_rate_tbl *tbls = clk->rate_config.tbls;
- unsigned int mode;
-
- mode = tbls[index].mode ? 256 : 1;
- return (((2 * rate / 10000) * tbls[index].m) /
- (mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
-}
-
-/*
- * calculates current programmed rate of pll1
- *
- * In normal mode
- * rate = (2 * M[15:8] * Fin)/(N * 2^P)
- *
- * In Dithered mode
- * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
- */
-int pll_clk_recalc(struct clk *clk)
-{
- struct pll_clk_config *config = clk->private_data;
- unsigned int num = 2, den = 0, val, mode = 0;
-
- mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
- config->masks->mode_mask;
-
- val = readl(config->cfg_reg);
- /* calculate denominator */
- den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
- den = 1 << den;
- den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
-
- /* calculate numerator & denominator */
- if (!mode) {
- /* Normal mode */
- num *= (val >> config->masks->norm_fdbk_m_shift) &
- config->masks->norm_fdbk_m_mask;
- } else {
- /* Dithered mode */
- num *= (val >> config->masks->dith_fdbk_m_shift) &
- config->masks->dith_fdbk_m_mask;
- den *= 256;
- }
-
- if (!den)
- return -EINVAL;
-
- clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
- return 0;
-}
-
-/*
- * Configures new clock rate of pll
- */
-int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
-{
- struct pll_rate_tbl *tbls = clk->rate_config.tbls;
- struct pll_clk_config *config = clk->private_data;
- unsigned long val, rate;
- int i;
-
- i = round_rate_index(clk, desired_rate, &rate);
- if (i < 0)
- return i;
-
- val = readl(config->mode_reg) &
- ~(config->masks->mode_mask << config->masks->mode_shift);
- val |= (tbls[i].mode & config->masks->mode_mask) <<
- config->masks->mode_shift;
- writel(val, config->mode_reg);
-
- val = readl(config->cfg_reg) &
- ~(config->masks->div_p_mask << config->masks->div_p_shift);
- val |= (tbls[i].p & config->masks->div_p_mask) <<
- config->masks->div_p_shift;
- val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
- val |= (tbls[i].n & config->masks->div_n_mask) <<
- config->masks->div_n_shift;
- val &= ~(config->masks->dith_fdbk_m_mask <<
- config->masks->dith_fdbk_m_shift);
- if (tbls[i].mode)
- val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
- config->masks->dith_fdbk_m_shift;
- else
- val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
- config->masks->norm_fdbk_m_shift;
-
- writel(val, config->cfg_reg);
-
- clk->rate = rate;
-
- return 0;
-}
-
-/*
- * Calculates ahb, apb clk rate for specific value of div
- */
-unsigned long bus_calc_rate(struct clk *clk, int index)
-{
- unsigned long rate = clk->pclk->rate;
- struct bus_rate_tbl *tbls = clk->rate_config.tbls;
-
- return rate / (tbls[index].div + 1);
-}
-
-/* calculates current programmed rate of ahb or apb bus */
-int bus_clk_recalc(struct clk *clk)
-{
- struct bus_clk_config *config = clk->private_data;
- unsigned int div;
-
- div = ((readl(config->reg) >> config->masks->shift) &
- config->masks->mask) + 1;
-
- if (!div)
- return -EINVAL;
-
- clk->rate = (unsigned long)clk->pclk->rate / div;
- return 0;
-}
-
-/* Configures new clock rate of AHB OR APB bus */
-int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
-{
- struct bus_rate_tbl *tbls = clk->rate_config.tbls;
- struct bus_clk_config *config = clk->private_data;
- unsigned long val, rate;
- int i;
-
- i = round_rate_index(clk, desired_rate, &rate);
- if (i < 0)
- return i;
-
- val = readl(config->reg) &
- ~(config->masks->mask << config->masks->shift);
- val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
- writel(val, config->reg);
-
- clk->rate = rate;
-
- return 0;
-}
-
-/*
- * gives rate for different values of eq, x and y
- *
- * Fout from synthesizer can be given from two equations:
- * Fout1 = (Fin * X/Y)/2 EQ1
- * Fout2 = Fin * X/Y EQ2
- */
-unsigned long aux_calc_rate(struct clk *clk, int index)
-{
- unsigned long rate = clk->pclk->rate;
- struct aux_rate_tbl *tbls = clk->rate_config.tbls;
- u8 eq = tbls[index].eq ? 1 : 2;
-
- return (((rate/10000) * tbls[index].xscale) /
- (tbls[index].yscale * eq)) * 10000;
-}
-
-/*
- * calculates current programmed rate of auxiliary synthesizers
- * used by: UART, FIRDA
- *
- * Fout from synthesizer can be given from two equations:
- * Fout1 = (Fin * X/Y)/2
- * Fout2 = Fin * X/Y
- *
- * Selection of eqn 1 or 2 is programmed in register
- */
-int aux_clk_recalc(struct clk *clk)
-{
- struct aux_clk_config *config = clk->private_data;
- unsigned int num = 1, den = 1, val, eqn;
-
- val = readl(config->synth_reg);
-
- eqn = (val >> config->masks->eq_sel_shift) &
- config->masks->eq_sel_mask;
- if (eqn == config->masks->eq1_mask)
- den *= 2;
-
- /* calculate numerator */
- num = (val >> config->masks->xscale_sel_shift) &
- config->masks->xscale_sel_mask;
-
- /* calculate denominator */
- den *= (val >> config->masks->yscale_sel_shift) &
- config->masks->yscale_sel_mask;
-
- if (!den)
- return -EINVAL;
-
- clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
- return 0;
-}
-
-/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
-int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
-{
- struct aux_rate_tbl *tbls = clk->rate_config.tbls;
- struct aux_clk_config *config = clk->private_data;
- unsigned long val, rate;
- int i;
-
- i = round_rate_index(clk, desired_rate, &rate);
- if (i < 0)
- return i;
-
- val = readl(config->synth_reg) &
- ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
- val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
- config->masks->eq_sel_shift;
- val &= ~(config->masks->xscale_sel_mask <<
- config->masks->xscale_sel_shift);
- val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
- config->masks->xscale_sel_shift;
- val &= ~(config->masks->yscale_sel_mask <<
- config->masks->yscale_sel_shift);
- val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
- config->masks->yscale_sel_shift;
- writel(val, config->synth_reg);
-
- clk->rate = rate;
-
- return 0;
-}
-
-/*
- * Calculates gpt clk rate for different values of mscale and nscale
- *
- * Fout= Fin/((2 ^ (N+1)) * (M+1))
- */
-unsigned long gpt_calc_rate(struct clk *clk, int index)
-{
- unsigned long rate = clk->pclk->rate;
- struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
-
- return rate / ((1 << (tbls[index].nscale + 1)) *
- (tbls[index].mscale + 1));
-}
-
-/*
- * calculates current programmed rate of gpt synthesizers
- * Fout from synthesizer can be given from below equations:
- * Fout= Fin/((2 ^ (N+1)) * (M+1))
- */
-int gpt_clk_recalc(struct clk *clk)
-{
- struct gpt_clk_config *config = clk->private_data;
- unsigned int div = 1, val;
-
- val = readl(config->synth_reg);
- div += (val >> config->masks->mscale_sel_shift) &
- config->masks->mscale_sel_mask;
- div *= 1 << (((val >> config->masks->nscale_sel_shift) &
- config->masks->nscale_sel_mask) + 1);
-
- if (!div)
- return -EINVAL;
-
- clk->rate = (unsigned long)clk->pclk->rate / div;
- return 0;
-}
-
-/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
-int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
-{
- struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
- struct gpt_clk_config *config = clk->private_data;
- unsigned long val, rate;
- int i;
-
- i = round_rate_index(clk, desired_rate, &rate);
- if (i < 0)
- return i;
-
- val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
- config->masks->mscale_sel_shift);
- val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
- config->masks->mscale_sel_shift;
- val &= ~(config->masks->nscale_sel_mask <<
- config->masks->nscale_sel_shift);
- val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
- config->masks->nscale_sel_shift;
- writel(val, config->synth_reg);
-
- clk->rate = rate;
-
- return 0;
-}
-
-/*
- * Calculates clcd clk rate for different values of div
- *
- * Fout from synthesizer can be given from below equation:
- * Fout= Fin/2*div (division factor)
- * div is 17 bits:-
- * 0-13 (fractional part)
- * 14-16 (integer part)
- * To calculate Fout we left shift val by 14 bits and divide Fin by
- * complete div (including fractional part) and then right shift the
- * result by 14 places.
- */
-unsigned long clcd_calc_rate(struct clk *clk, int index)
-{
- unsigned long rate = clk->pclk->rate;
- struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
-
- rate /= 1000;
- rate <<= 12;
- rate /= (2 * tbls[index].div);
- rate >>= 12;
- rate *= 1000;
-
- return rate;
-}
-
-/*
- * calculates current programmed rate of clcd synthesizer
- * Fout from synthesizer can be given from below equation:
- * Fout= Fin/2*div (division factor)
- * div is 17 bits:-
- * 0-13 (fractional part)
- * 14-16 (integer part)
- * To calculate Fout we left shift val by 14 bits and divide Fin by
- * complete div (including fractional part) and then right shift the
- * result by 14 places.
- */
-int clcd_clk_recalc(struct clk *clk)
-{
- struct clcd_clk_config *config = clk->private_data;
- unsigned int div = 1;
- unsigned long prate;
- unsigned int val;
-
- val = readl(config->synth_reg);
- div = (val >> config->masks->div_factor_shift) &
- config->masks->div_factor_mask;
-
- if (!div)
- return -EINVAL;
-
- prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
-
- clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
- clk->rate *= 1000;
- return 0;
-}
-
-/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
-int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
-{
- struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
- struct clcd_clk_config *config = clk->private_data;
- unsigned long val, rate;
- int i;
-
- i = round_rate_index(clk, desired_rate, &rate);
- if (i < 0)
- return i;
-
- val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
- config->masks->div_factor_shift);
- val |= (tbls[i].div & config->masks->div_factor_mask) <<
- config->masks->div_factor_shift;
- writel(val, config->synth_reg);
-
- clk->rate = rate;
-
- return 0;
-}
-
-/*
- * Used for clocks that always have value as the parent clock divided by a
- * fixed divisor
- */
-int follow_parent(struct clk *clk)
-{
- unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
-
- clk->rate = clk->pclk->rate/div_factor;
- return 0;
-}
-
-/**
- * recalc_root_clocks - recalculate and propagate all root clocks
- *
- * Recalculates all root clocks (clocks with no parent), which if the
- * clock's .recalc is set correctly, should also propagate their rates.
- */
-void recalc_root_clocks(void)
-{
- struct clk *pclk;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&clocks_lock, flags);
- list_for_each_entry(pclk, &root_clks, sibling) {
- if (pclk->recalc) {
- ret = pclk->recalc(pclk);
- /*
- * recalc will return error if clk out is not programmed
- * In this case configure default clock.
- */
- if (ret && pclk->set_rate)
- pclk->set_rate(pclk, 0);
- }
- propagate_rate(pclk, 1);
- /* Enable clks enabled on init, in software view */
- if (pclk->flags & ENABLED_ON_INIT)
- do_clk_enable(pclk);
- }
- spin_unlock_irqrestore(&clocks_lock, flags);
-}
-
-void __init clk_init(void)
-{
- recalc_root_clocks();
-}
-
-#ifdef CONFIG_DEBUG_FS
-/*
- * debugfs support to trace clock tree hierarchy and attributes
- */
-static struct dentry *clk_debugfs_root;
-static int clk_debugfs_register_one(struct clk *c)
-{
- int err;
- struct dentry *d;
- struct clk *pa = c->pclk;
- char s[255];
- char *p = s;
-
- if (c) {
- if (c->cl->con_id)
- p += sprintf(p, "%s", c->cl->con_id);
- if (c->cl->dev_id)
- p += sprintf(p, "%s", c->cl->dev_id);
- }
- d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
- if (!d)
- return -ENOMEM;
- c->dent = d;
-
- d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
- (u32 *)&c->usage_count);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
- if (!d) {
- err = -ENOMEM;
- goto err_out;
- }
- return 0;
-
-err_out:
- debugfs_remove_recursive(c->dent);
- return err;
-}
-
-static int clk_debugfs_register(struct clk *c)
-{
- int err;
- struct clk *pa = c->pclk;
-
- if (pa && !pa->dent) {
- err = clk_debugfs_register(pa);
- if (err)
- return err;
- }
-
- if (!c->dent) {
- err = clk_debugfs_register_one(c);
- if (err)
- return err;
- }
- return 0;
-}
-
-static int __init clk_debugfs_init(void)
-{
- struct clk *c;
- struct dentry *d;
- int err;
-
- d = debugfs_create_dir("clock", NULL);
- if (!d)
- return -ENOMEM;
- clk_debugfs_root = d;
-
- list_for_each_entry(c, &clocks, node) {
- err = clk_debugfs_register(c);
- if (err)
- goto err_out;
- }
- return 0;
-err_out:
- debugfs_remove_recursive(clk_debugfs_root);
- return err;
-}
-late_initcall(clk_debugfs_init);
-
-static int clk_debugfs_reparent(struct clk *c)
-{
- debugfs_remove(c->dent);
- return clk_debugfs_register_one(c);
-}
-#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 0062bafef12d..000000000000
--- a/arch/arm/plat-spear/include/plat/clock.h
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/clock.h
- *
- * Clock framework definitions for SPEAr platform
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_CLOCK_H
-#define __PLAT_CLOCK_H
-
-#include <linux/list.h>
-#include <linux/clkdev.h>
-#include <linux/types.h>
-
-/* clk structure flags */
-#define ALWAYS_ENABLED (1 << 0) /* clock always enabled */
-#define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */
-#define ENABLED_ON_INIT (1 << 2) /* clocks enabled at init */
-
-/**
- * struct clkops - clock operations
- * @enable: pointer to clock enable function
- * @disable: pointer to clock disable function
- */
-struct clkops {
- int (*enable) (struct clk *);
- void (*disable) (struct clk *);
-};
-
-/**
- * struct pclk_info - parents info
- * @pclk: pointer to parent clk
- * @pclk_val: value to be written for selecting this parent
- */
-struct pclk_info {
- struct clk *pclk;
- u8 pclk_val;
-};
-
-/**
- * struct pclk_sel - parents selection configuration
- * @pclk_info: pointer to array of parent clock info
- * @pclk_count: number of parents
- * @pclk_sel_reg: register for selecting a parent
- * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
- */
-struct pclk_sel {
- struct pclk_info *pclk_info;
- u8 pclk_count;
- void __iomem *pclk_sel_reg;
- unsigned int pclk_sel_mask;
-};
-
-/**
- * struct rate_config - clk rate configurations
- * @tbls: array of device specific clk rate tables, in ascending order of rates
- * @count: size of tbls array
- * @default_index: default setting when originally disabled
- */
-struct rate_config {
- void *tbls;
- u8 count;
- u8 default_index;
-};
-
-/**
- * struct clk - clock structure
- * @usage_count: num of users who enabled this clock
- * @flags: flags for clock properties
- * @rate: programmed clock rate in Hz
- * @en_reg: clk enable/disable reg
- * @en_reg_bit: clk enable/disable bit
- * @ops: clk enable/disable ops - generic_clkops selected if NULL
- * @recalc: pointer to clock rate recalculate function
- * @set_rate: pointer to clock set rate function
- * @calc_rate: pointer to clock get rate function for index
- * @rate_config: rate configuration information, used by set_rate
- * @div_factor: division factor to parent clock.
- * @pclk: current parent clk
- * @pclk_sel: pointer to parent selection structure
- * @pclk_sel_shift: register shift for selecting parent of this clock
- * @children: list for childrens or this clock
- * @sibling: node for list of clocks having same parents
- * @private_data: clock specific private data
- * @node: list to maintain clocks linearly
- * @cl: clocklook up associated with this clock
- * @dent: object for debugfs
- */
-struct clk {
- unsigned int usage_count;
- unsigned int flags;
- unsigned long rate;
- void __iomem *en_reg;
- u8 en_reg_bit;
- const struct clkops *ops;
- int (*recalc) (struct clk *);
- int (*set_rate) (struct clk *, unsigned long rate);
- unsigned long (*calc_rate)(struct clk *, int index);
- struct rate_config rate_config;
- unsigned int div_factor;
-
- struct clk *pclk;
- struct pclk_sel *pclk_sel;
- unsigned int pclk_sel_shift;
-
- struct list_head children;
- struct list_head sibling;
- void *private_data;
-#ifdef CONFIG_DEBUG_FS
- struct list_head node;
- struct clk_lookup *cl;
- struct dentry *dent;
-#endif
-};
-
-/* pll configuration structure */
-struct pll_clk_masks {
- u32 mode_mask;
- u32 mode_shift;
-
- u32 norm_fdbk_m_mask;
- u32 norm_fdbk_m_shift;
- u32 dith_fdbk_m_mask;
- u32 dith_fdbk_m_shift;
- u32 div_p_mask;
- u32 div_p_shift;
- u32 div_n_mask;
- u32 div_n_shift;
-};
-
-struct pll_clk_config {
- void __iomem *mode_reg;
- void __iomem *cfg_reg;
- struct pll_clk_masks *masks;
-};
-
-/* pll clk rate config structure */
-struct pll_rate_tbl {
- u8 mode;
- u16 m;
- u8 n;
- u8 p;
-};
-
-/* ahb and apb bus configuration structure */
-struct bus_clk_masks {
- u32 mask;
- u32 shift;
-};
-
-struct bus_clk_config {
- void __iomem *reg;
- struct bus_clk_masks *masks;
-};
-
-/* ahb and apb clk bus rate config structure */
-struct bus_rate_tbl {
- u8 div;
-};
-
-/* Aux clk configuration structure: applicable to UART and FIRDA */
-struct aux_clk_masks {
- u32 eq_sel_mask;
- u32 eq_sel_shift;
- u32 eq1_mask;
- u32 eq2_mask;
- u32 xscale_sel_mask;
- u32 xscale_sel_shift;
- u32 yscale_sel_mask;
- u32 yscale_sel_shift;
-};
-
-struct aux_clk_config {
- void __iomem *synth_reg;
- struct aux_clk_masks *masks;
-};
-
-/* aux clk rate config structure */
-struct aux_rate_tbl {
- u16 xscale;
- u16 yscale;
- u8 eq;
-};
-
-/* GPT clk configuration structure */
-struct gpt_clk_masks {
- u32 mscale_sel_mask;
- u32 mscale_sel_shift;
- u32 nscale_sel_mask;
- u32 nscale_sel_shift;
-};
-
-struct gpt_clk_config {
- void __iomem *synth_reg;
- struct gpt_clk_masks *masks;
-};
-
-/* gpt clk rate config structure */
-struct gpt_rate_tbl {
- u16 mscale;
- u16 nscale;
-};
-
-/* clcd clk configuration structure */
-struct clcd_synth_masks {
- u32 div_factor_mask;
- u32 div_factor_shift;
-};
-
-struct clcd_clk_config {
- void __iomem *synth_reg;
- struct clcd_synth_masks *masks;
-};
-
-/* clcd clk rate config structure */
-struct clcd_rate_tbl {
- u16 div;
-};
-
-/* platform specific clock functions */
-void __init clk_init(void);
-void clk_register(struct clk_lookup *cl);
-void recalc_root_clocks(void);
-
-/* clock recalc & set rate functions */
-int follow_parent(struct clk *clk);
-unsigned long pll_calc_rate(struct clk *clk, int index);
-int pll_clk_recalc(struct clk *clk);
-int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
-unsigned long bus_calc_rate(struct clk *clk, int index);
-int bus_clk_recalc(struct clk *clk);
-int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
-unsigned long gpt_calc_rate(struct clk *clk, int index);
-int gpt_clk_recalc(struct clk *clk);
-int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
-unsigned long aux_calc_rate(struct clk *clk, int index);
-int aux_clk_recalc(struct clk *clk);
-int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
-unsigned long clcd_calc_rate(struct clk *clk, int index);
-int clcd_clk_recalc(struct clk *clk);
-int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
-
-#endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/restart.c b/arch/arm/plat-spear/restart.c
index 4471a232713a..ea0a61302b7e 100644
--- a/arch/arm/plat-spear/restart.c
+++ b/arch/arm/plat-spear/restart.c
@@ -16,6 +16,7 @@
#include <mach/spear.h>
#include <mach/generic.h>
+#define SPEAR13XX_SYS_SW_RES (VA_MISC_BASE + 0x204)
void spear_restart(char mode, const char *cmd)
{
if (mode == 's') {
@@ -23,6 +24,10 @@ void spear_restart(char mode, const char *cmd)
soft_restart(0);
} else {
/* hardware reset, Use on-chip reset capability */
+#ifdef CONFIG_ARCH_SPEAR13XX
+ writel_relaxed(0x01, SPEAR13XX_SYS_SW_RES);
+#else
sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+#endif
}
}
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
index a3164d1647fd..03321af5de9f 100644
--- a/arch/arm/plat-spear/time.c
+++ b/arch/arm/plat-spear/time.c
@@ -18,6 +18,8 @@
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include <linux/time.h>
#include <linux/irq.h>
#include <asm/mach/time.h>
@@ -197,19 +199,32 @@ static void __init spear_clockevent_init(int irq)
setup_irq(irq, &spear_timer_irq);
}
-void __init spear_setup_timer(resource_size_t base, int irq)
+const static struct of_device_id timer_of_match[] __initconst = {
+ { .compatible = "st,spear-timer", },
+ { },
+};
+
+void __init spear_setup_of_timer(void)
{
- int ret;
+ struct device_node *np;
+ int irq, ret;
+
+ np = of_find_matching_node(NULL, timer_of_match);
+ if (!np) {
+ pr_err("%s: No timer passed via DT\n", __func__);
+ return;
+ }
- if (!request_mem_region(base, SZ_1K, "gpt0")) {
- pr_err("%s:cannot get IO addr\n", __func__);
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ pr_err("%s: No irq passed for timer via DT\n", __func__);
return;
}
- gpt_base = ioremap(base, SZ_1K);
+ gpt_base = of_iomap(np, 0);
if (!gpt_base) {
- pr_err("%s:ioremap failed for gpt\n", __func__);
- goto err_mem;
+ pr_err("%s: of iomap failed\n", __func__);
+ return;
}
gpt_clk = clk_get_sys("gpt0", NULL);
@@ -218,10 +233,10 @@ void __init spear_setup_timer(resource_size_t base, int irq)
goto err_iomap;
}
- ret = clk_enable(gpt_clk);
+ ret = clk_prepare_enable(gpt_clk);
if (ret < 0) {
- pr_err("%s:couldn't enable gpt clock\n", __func__);
- goto err_clk;
+ pr_err("%s:couldn't prepare-enable gpt clock\n", __func__);
+ goto err_prepare_enable_clk;
}
spear_clockevent_init(irq);
@@ -229,10 +244,8 @@ void __init spear_setup_timer(resource_size_t base, int irq)
return;
-err_clk:
+err_prepare_enable_clk:
clk_put(gpt_clk);
err_iomap:
iounmap(gpt_base);
-err_mem:
- release_mem_region(base, SZ_1K);
}
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
deleted file mode 100644
index 74f99c688c8d..000000000000
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*!***************************************************************************
-*!
-*! FILE NAME : ds1302.c
-*!
-*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
-*!
-*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
-*!
-*! ---------------------------------------------------------------------------
-*!
-*! (C) Copyright 1999-2007 Axis Communications AB, LUND, SWEDEN
-*!
-*!***************************************************************************/
-
-
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/bcd.h>
-#include <linux/capability.h>
-
-#include <asm/uaccess.h>
-#include <arch/svinto.h>
-#include <asm/io.h>
-#include <asm/rtc.h>
-#include <arch/io_interface_mux.h>
-
-#include "i2c.h"
-
-#define RTC_MAJOR_NR 121 /* local major, change later */
-
-static DEFINE_MUTEX(ds1302_mutex);
-static const char ds1302_name[] = "ds1302";
-
-/* The DS1302 might be connected to different bits on different products.
- * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
- * but SDA can have a selected direction.
- * For now, only PORT_PB is hardcoded.
- */
-
-/* The RST bit may be on either the Generic Port or Port PB. */
-#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
-#define TK_RST_DIR(x)
-#else
-#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
-#define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
-#endif
-
-
-#define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
-#define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
-
-#define TK_SDA_IN() ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1)
-/* 1 is out, 0 is in */
-#define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
-#define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
-
-
-/*
- * The reason for tempudelay and not udelay is that loops_per_usec
- * (used in udelay) is not set when functions here are called from time.c
- */
-
-static void tempudelay(int usecs)
-{
- volatile int loops;
-
- for(loops = usecs * 12; loops > 0; loops--)
- /* nothing */;
-}
-
-
-/* Send 8 bits. */
-static void
-out_byte(unsigned char x)
-{
- int i;
- TK_SDA_DIR(1);
- for (i = 8; i--;) {
- /* The chip latches incoming bits on the rising edge of SCL. */
- TK_SCL_OUT(0);
- TK_SDA_OUT(x & 1);
- tempudelay(1);
- TK_SCL_OUT(1);
- tempudelay(1);
- x >>= 1;
- }
- TK_SDA_DIR(0);
-}
-
-static unsigned char
-in_byte(void)
-{
- unsigned char x = 0;
- int i;
-
- /* Read byte. Bits come LSB first, on the falling edge of SCL.
- * Assume SDA is in input direction already.
- */
- TK_SDA_DIR(0);
-
- for (i = 8; i--;) {
- TK_SCL_OUT(0);
- tempudelay(1);
- x >>= 1;
- x |= (TK_SDA_IN() << 7);
- TK_SCL_OUT(1);
- tempudelay(1);
- }
-
- return x;
-}
-
-/* Prepares for a transaction by de-activating RST (active-low). */
-
-static void
-start(void)
-{
- TK_SCL_OUT(0);
- tempudelay(1);
- TK_RST_OUT(0);
- tempudelay(5);
- TK_RST_OUT(1);
-}
-
-/* Ends a transaction by taking RST active again. */
-
-static void
-stop(void)
-{
- tempudelay(2);
- TK_RST_OUT(0);
-}
-
-/* Enable writing. */
-
-static void
-ds1302_wenable(void)
-{
- start();
- out_byte(0x8e); /* Write control register */
- out_byte(0x00); /* Disable write protect bit 7 = 0 */
- stop();
-}
-
-/* Disable writing. */
-
-static void
-ds1302_wdisable(void)
-{
- start();
- out_byte(0x8e); /* Write control register */
- out_byte(0x80); /* Disable write protect bit 7 = 0 */
- stop();
-}
-
-
-
-/* Read a byte from the selected register in the DS1302. */
-
-unsigned char
-ds1302_readreg(int reg)
-{
- unsigned char x;
-
- start();
- out_byte(0x81 | (reg << 1)); /* read register */
- x = in_byte();
- stop();
-
- return x;
-}
-
-/* Write a byte to the selected register. */
-
-void
-ds1302_writereg(int reg, unsigned char val)
-{
-#ifndef CONFIG_ETRAX_RTC_READONLY
- int do_writereg = 1;
-#else
- int do_writereg = 0;
-
- if (reg == RTC_TRICKLECHARGER)
- do_writereg = 1;
-#endif
-
- if (do_writereg) {
- ds1302_wenable();
- start();
- out_byte(0x80 | (reg << 1)); /* write register */
- out_byte(val);
- stop();
- ds1302_wdisable();
- }
-}
-
-void
-get_rtc_time(struct rtc_time *rtc_tm)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
- rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
- rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
- rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
- rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
- rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
-
- local_irq_restore(flags);
-
- rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
- rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
- rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
- rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
- rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
- rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
-
- /*
- * Account for differences between how the RTC uses the values
- * and how they are defined in a struct rtc_time;
- */
-
- if (rtc_tm->tm_year <= 69)
- rtc_tm->tm_year += 100;
-
- rtc_tm->tm_mon--;
-}
-
-static unsigned char days_in_mo[] =
- {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
-
-static int rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- unsigned long flags;
-
- switch(cmd) {
- case RTC_RD_TIME: /* read the time/date from RTC */
- {
- struct rtc_time rtc_tm;
-
- memset(&rtc_tm, 0, sizeof (struct rtc_time));
- get_rtc_time(&rtc_tm);
- if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
- return -EFAULT;
- return 0;
- }
-
- case RTC_SET_TIME: /* set the RTC */
- {
- struct rtc_time rtc_tm;
- unsigned char mon, day, hrs, min, sec, leap_yr;
- unsigned int yrs;
-
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
- return -EFAULT;
-
- yrs = rtc_tm.tm_year + 1900;
- mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
- day = rtc_tm.tm_mday;
- hrs = rtc_tm.tm_hour;
- min = rtc_tm.tm_min;
- sec = rtc_tm.tm_sec;
-
-
- if ((yrs < 1970) || (yrs > 2069))
- return -EINVAL;
-
- leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
- if ((mon > 12) || (day == 0))
- return -EINVAL;
-
- if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
- return -EINVAL;
-
- if ((hrs >= 24) || (min >= 60) || (sec >= 60))
- return -EINVAL;
-
- if (yrs >= 2000)
- yrs -= 2000; /* RTC (0, 1, ... 69) */
- else
- yrs -= 1900; /* RTC (70, 71, ... 99) */
-
- sec = bin2bcd(sec);
- min = bin2bcd(min);
- hrs = bin2bcd(hrs);
- day = bin2bcd(day);
- mon = bin2bcd(mon);
- yrs = bin2bcd(yrs);
-
- local_irq_save(flags);
- CMOS_WRITE(yrs, RTC_YEAR);
- CMOS_WRITE(mon, RTC_MONTH);
- CMOS_WRITE(day, RTC_DAY_OF_MONTH);
- CMOS_WRITE(hrs, RTC_HOURS);
- CMOS_WRITE(min, RTC_MINUTES);
- CMOS_WRITE(sec, RTC_SECONDS);
- local_irq_restore(flags);
-
- /* Notice that at this point, the RTC is updated but
- * the kernel is still running with the old time.
- * You need to set that separately with settimeofday
- * or adjtimex.
- */
- return 0;
- }
-
- case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
- {
- int tcs_val;
-
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
- return -EFAULT;
-
- tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
- ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
- return 0;
- }
- case RTC_VL_READ:
- {
- /* TODO:
- * Implement voltage low detection support
- */
- printk(KERN_WARNING "DS1302: RTC Voltage Low detection"
- " is not supported\n");
- return 0;
- }
- case RTC_VL_CLR:
- {
- /* TODO:
- * Nothing to do since Voltage Low detection is not supported
- */
- return 0;
- }
- default:
- return -ENOIOCTLCMD;
- }
-}
-
-static long rtc_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- mutex_lock(&ds1302_mutex);
- ret = rtc_ioctl(file, cmd, arg);
- mutex_unlock(&ds1302_mutex);
-
- return ret;
-}
-
-static void
-print_rtc_status(void)
-{
- struct rtc_time tm;
-
- get_rtc_time(&tm);
-
- /*
- * There is no way to tell if the luser has the RTC set for local
- * time or for Universal Standard Time (GMT). Probably local though.
- */
-
- printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-}
-
-/* The various file operations we support. */
-
-static const struct file_operations rtc_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = rtc_unlocked_ioctl,
- .llseek = noop_llseek,
-};
-
-/* Probe for the chip by writing something to its RAM and try reading it back. */
-
-#define MAGIC_PATTERN 0x42
-
-static int __init
-ds1302_probe(void)
-{
- int retval, res;
-
- TK_RST_DIR(1);
- TK_SCL_DIR(1);
- TK_SDA_DIR(0);
-
- /* Try to talk to timekeeper. */
-
- ds1302_wenable();
- start();
- out_byte(0xc0); /* write RAM byte 0 */
- out_byte(MAGIC_PATTERN); /* write something magic */
- start();
- out_byte(0xc1); /* read RAM byte 0 */
-
- if((res = in_byte()) == MAGIC_PATTERN) {
- stop();
- ds1302_wdisable();
- printk(KERN_INFO "%s: RTC found.\n", ds1302_name);
- printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
- ds1302_name,
- CONFIG_ETRAX_DS1302_SDABIT,
- CONFIG_ETRAX_DS1302_SCLBIT,
-#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
- "GENIO",
-#else
- "PB",
-#endif
- CONFIG_ETRAX_DS1302_RSTBIT);
- print_rtc_status();
- retval = 1;
- } else {
- stop();
- retval = 0;
- }
-
- return retval;
-}
-
-
-/* Just probe for the RTC and register the device to handle the ioctl needed. */
-
-int __init
-ds1302_init(void)
-{
-#ifdef CONFIG_ETRAX_I2C
- i2c_init();
-#endif
-
- if (!ds1302_probe()) {
-#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-#if CONFIG_ETRAX_DS1302_RSTBIT == 27
- /*
- * The only way to set g27 to output is to enable ATA.
- *
- * Make sure that R_GEN_CONFIG is setup correct.
- */
- /* Allocating the ATA interface will grab almost all
- * pins in I/O groups a, b, c and d. A consequence of
- * allocating the ATA interface is that the fixed
- * interfaces shared RAM, parallel port 0, parallel
- * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port
- * 1, SCSI-W, serial port 2, serial port 3,
- * synchronous serial port 3 and USB port 2 and almost
- * all GPIO pins on port g cannot be used.
- */
- if (cris_request_io_interface(if_ata, "ds1302/ATA")) {
- printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
- return -1;
- }
-
-#elif CONFIG_ETRAX_DS1302_RSTBIT == 0
- if (cris_io_interface_allocate_pins(if_gpio_grp_a,
- 'g',
- CONFIG_ETRAX_DS1302_RSTBIT,
- CONFIG_ETRAX_DS1302_RSTBIT)) {
- printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
- return -1;
- }
-
- /* Set the direction of this bit to out. */
- genconfig_shadow = ((genconfig_shadow &
- ~IO_MASK(R_GEN_CONFIG, g0dir)) |
- (IO_STATE(R_GEN_CONFIG, g0dir, out)));
- *R_GEN_CONFIG = genconfig_shadow;
-#endif
- if (!ds1302_probe()) {
- printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
- return -1;
- }
-#else
- printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
- return -1;
-#endif
- }
- /* Initialise trickle charger */
- ds1302_writereg(RTC_TRICKLECHARGER,
- RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
- /* Start clock by resetting CLOCK_HALT */
- ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
- return 0;
-}
-
-static int __init ds1302_register(void)
-{
- ds1302_init();
- if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
- printk(KERN_INFO "%s: unable to get major %d for rtc\n",
- ds1302_name, RTC_MAJOR_NR);
- return -1;
- }
- return 0;
-
-}
-
-module_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 9da056860c92..000000000000
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * PCF8563 RTC
- *
- * From Phillips' datasheet:
- *
- * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interrupt output and voltage
- * low detector are also provided. All address and data are transferred
- * serially via two-line bidirectional I2C-bus. Maximum bus speed is
- * 400 kbits/s. The built-in word address register is incremented
- * automatically after each written or read byte.
- *
- * Copyright (c) 2002-2007, Axis Communications AB
- * All rights reserved.
- *
- * Author: Tobias Anderberg <tobiasa@axis.com>.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <linux/delay.h>
-#include <linux/bcd.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/rtc.h>
-
-#include "i2c.h"
-
-#define PCF8563_MAJOR 121 /* Local major number. */
-#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
-#define PCF8563_NAME "PCF8563"
-#define DRIVER_VERSION "$Revision: 1.24 $"
-
-/* I2C bus slave registers. */
-#define RTC_I2C_READ 0xa3
-#define RTC_I2C_WRITE 0xa2
-
-/* Two simple wrapper macros, saves a few keystrokes. */
-#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
-#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
-
-static DEFINE_MUTEX(pcf8563_mutex);
-static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
-
-static const unsigned char days_in_month[] =
- { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-static long pcf8563_unlocked_ioctl(struct file *, unsigned int, unsigned long);
-
-/* Cache VL bit value read at driver init since writing the RTC_SECOND
- * register clears the VL status.
- */
-static int voltage_low;
-
-static const struct file_operations pcf8563_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = pcf8563_unlocked_ioctl,
- .llseek = noop_llseek,
-};
-
-unsigned char
-pcf8563_readreg(int reg)
-{
- unsigned char res = rtc_read(reg);
-
- /* The PCF8563 does not return 0 for unimplemented bits. */
- switch (reg) {
- case RTC_SECONDS:
- case RTC_MINUTES:
- res &= 0x7F;
- break;
- case RTC_HOURS:
- case RTC_DAY_OF_MONTH:
- res &= 0x3F;
- break;
- case RTC_WEEKDAY:
- res &= 0x07;
- break;
- case RTC_MONTH:
- res &= 0x1F;
- break;
- case RTC_CONTROL1:
- res &= 0xA8;
- break;
- case RTC_CONTROL2:
- res &= 0x1F;
- break;
- case RTC_CLOCKOUT_FREQ:
- case RTC_TIMER_CONTROL:
- res &= 0x83;
- break;
- }
- return res;
-}
-
-void
-pcf8563_writereg(int reg, unsigned char val)
-{
- rtc_write(reg, val);
-}
-
-void
-get_rtc_time(struct rtc_time *tm)
-{
- tm->tm_sec = rtc_read(RTC_SECONDS);
- tm->tm_min = rtc_read(RTC_MINUTES);
- tm->tm_hour = rtc_read(RTC_HOURS);
- tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
- tm->tm_wday = rtc_read(RTC_WEEKDAY);
- tm->tm_mon = rtc_read(RTC_MONTH);
- tm->tm_year = rtc_read(RTC_YEAR);
-
- if (tm->tm_sec & 0x80) {
- printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time "
- "information is no longer guaranteed!\n", PCF8563_NAME);
- }
-
- tm->tm_year = bcd2bin(tm->tm_year) +
- ((tm->tm_mon & 0x80) ? 100 : 0);
- tm->tm_sec &= 0x7F;
- tm->tm_min &= 0x7F;
- tm->tm_hour &= 0x3F;
- tm->tm_mday &= 0x3F;
- tm->tm_wday &= 0x07; /* Not coded in BCD. */
- tm->tm_mon &= 0x1F;
-
- tm->tm_sec = bcd2bin(tm->tm_sec);
- tm->tm_min = bcd2bin(tm->tm_min);
- tm->tm_hour = bcd2bin(tm->tm_hour);
- tm->tm_mday = bcd2bin(tm->tm_mday);
- tm->tm_mon = bcd2bin(tm->tm_mon);
- tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
-}
-
-int __init
-pcf8563_init(void)
-{
- static int res;
- static int first = 1;
-
- if (!first)
- return res;
- first = 0;
-
- /* Initiate the i2c protocol. */
- res = i2c_init();
- if (res < 0) {
- printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
- return res;
- }
-
- /*
- * First of all we need to reset the chip. This is done by
- * clearing control1, control2 and clk freq and resetting
- * all alarms.
- */
- if (rtc_write(RTC_CONTROL1, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_CONTROL2, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
- goto err;
-
- /* Reset the alarms. */
- if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
- goto err;
-
- /* Check for low voltage, and warn about it. */
- if (rtc_read(RTC_SECONDS) & 0x80) {
- voltage_low = 1;
- printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
- "date/time information is no longer guaranteed!\n",
- PCF8563_NAME);
- }
-
- return res;
-
-err:
- printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
- res = -1;
- return res;
-}
-
-void __exit
-pcf8563_exit(void)
-{
- unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME);
-}
-
-/*
- * ioctl calls for this driver. Why return -ENOTTY upon error? Because
- * POSIX says so!
- */
-static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- /* Some sanity checks. */
- if (_IOC_TYPE(cmd) != RTC_MAGIC)
- return -ENOTTY;
-
- if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
- return -ENOTTY;
-
- switch (cmd) {
- case RTC_RD_TIME:
- {
- struct rtc_time tm;
-
- mutex_lock(&rtc_lock);
- memset(&tm, 0, sizeof tm);
- get_rtc_time(&tm);
-
- if (copy_to_user((struct rtc_time *) arg, &tm,
- sizeof tm)) {
- mutex_unlock(&rtc_lock);
- return -EFAULT;
- }
-
- mutex_unlock(&rtc_lock);
-
- return 0;
- }
- case RTC_SET_TIME:
- {
- int leap;
- int year;
- int century;
- struct rtc_time tm;
-
- memset(&tm, 0, sizeof tm);
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
- return -EFAULT;
-
- /* Convert from struct tm to struct rtc_time. */
- tm.tm_year += 1900;
- tm.tm_mon += 1;
-
- /*
- * Check if tm.tm_year is a leap year. A year is a leap
- * year if it is divisible by 4 but not 100, except
- * that years divisible by 400 _are_ leap years.
- */
- year = tm.tm_year;
- leap = (tm.tm_mon == 2) &&
- ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
-
- /* Perform some sanity checks. */
- if ((tm.tm_year < 1970) ||
- (tm.tm_mon > 12) ||
- (tm.tm_mday == 0) ||
- (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
- (tm.tm_wday >= 7) ||
- (tm.tm_hour >= 24) ||
- (tm.tm_min >= 60) ||
- (tm.tm_sec >= 60))
- return -EINVAL;
-
- century = (tm.tm_year >= 2000) ? 0x80 : 0;
- tm.tm_year = tm.tm_year % 100;
-
- tm.tm_year = bin2bcd(tm.tm_year);
- tm.tm_mon = bin2bcd(tm.tm_mon);
- tm.tm_mday = bin2bcd(tm.tm_mday);
- tm.tm_hour = bin2bcd(tm.tm_hour);
- tm.tm_min = bin2bcd(tm.tm_min);
- tm.tm_sec = bin2bcd(tm.tm_sec);
- tm.tm_mon |= century;
-
- mutex_lock(&rtc_lock);
-
- rtc_write(RTC_YEAR, tm.tm_year);
- rtc_write(RTC_MONTH, tm.tm_mon);
- rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
- rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
- rtc_write(RTC_HOURS, tm.tm_hour);
- rtc_write(RTC_MINUTES, tm.tm_min);
- rtc_write(RTC_SECONDS, tm.tm_sec);
-
- mutex_unlock(&rtc_lock);
-
- return 0;
- }
- case RTC_VL_READ:
- if (voltage_low) {
- printk(KERN_ERR "%s: RTC Voltage Low - "
- "reliable date/time information is no "
- "longer guaranteed!\n", PCF8563_NAME);
- }
-
- if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
- return -EFAULT;
- return 0;
-
- case RTC_VL_CLR:
- {
- /* Clear the VL bit in the seconds register in case
- * the time has not been set already (which would
- * have cleared it). This does not really matter
- * because of the cached voltage_low value but do it
- * anyway for consistency. */
-
- int ret = rtc_read(RTC_SECONDS);
-
- rtc_write(RTC_SECONDS, (ret & 0x7F));
-
- /* Clear the cached value. */
- voltage_low = 0;
-
- return 0;
- }
- default:
- return -ENOTTY;
- }
-
- return 0;
-}
-
-static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- mutex_lock(&pcf8563_mutex);
- ret = pcf8563_ioctl(filp, cmd, arg);
- mutex_unlock(&pcf8563_mutex);
-
- return ret;
-}
-
-static int __init pcf8563_register(void)
-{
- if (pcf8563_init() < 0) {
- printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
- "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
- return -1;
- }
-
- if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
- printk(KERN_INFO "%s: Unable to get major number %d for RTC device.\n",
- PCF8563_NAME, PCF8563_MAJOR);
- return -1;
- }
-
- printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
- DRIVER_VERSION);
-
- /* Check for low voltage, and warn about it. */
- if (voltage_low) {
- printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
- "information is no longer guaranteed!\n", PCF8563_NAME);
- }
-
- return 0;
-}
-
-module_init(pcf8563_register);
-module_exit(pcf8563_exit);
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 8a8196ee8ce8..082f1890bacb 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -21,8 +21,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
-#include <asm/rtc.h>
-
#include <arch/svinto.h>
#include <asm/fasttimer.h>
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index b579dd02e098..37e6d2c50b76 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);
/* Write a value to a specified register in the stack of a thread other
than the current thread. */
-static write_stack_register (int thread_id, int regno, char *valptr);
+static int write_stack_register(int thread_id, int regno, char *valptr);
/* Read a value from a specified register in the register image. Returns the
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 20c85b5dc7d0..bcffcb6a9415 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -19,16 +19,12 @@
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/delay.h>
-#include <asm/rtc.h>
#include <asm/irq_regs.h>
/* define this if you need to use print_timestamp */
/* it will make jiffies at 96 hz instead of 100 hz though */
#undef USE_CASCADE_TIMERS
-extern int set_rtc_mmss(unsigned long nowtime);
-extern int have_rtc;
-
unsigned long get_ns_in_jiffie(void)
{
unsigned char timer_count, t1;
@@ -203,11 +199,6 @@ time_init(void)
*/
loops_per_usec = 50;
- if(RTC_INIT() < 0)
- have_rtc = 0;
- else
- have_rtc = 1;
-
/* Setup the etrax timers
* Base frequency is 25000 hz, divider 250 -> 100 HZ
* 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 36e9a9c5239b..725153edb764 100644
--- a/arch/cris/arch-v10/lib/Makefile
+++ b/arch/cris/arch-v10/lib/Makefile
@@ -2,8 +2,5 @@
# Makefile for Etrax-specific library files..
#
-
-EXTRA_AFLAGS := -traditional
-
lib-y = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index 642c6fed43d7..f8476d9e856b 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
if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH;
- p = kmalloc(padlen, alloc_flag);
+ p = kzalloc(padlen, alloc_flag);
if (!p) return -ENOMEM;
*p = 0x80;
- memset(p+1, 0, padlen - 1);
DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
@@ -1426,11 +1425,10 @@ static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, cha
if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH;
- p = kmalloc(padlen, alloc_flag);
+ p = kzalloc(padlen, alloc_flag);
if (!p) return -ENOMEM;
*p = 0x80;
- memset(p+1, 0, padlen - 1);
DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index f7ad9e8637df..f085229cf870 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)
void
ptrace_disable(struct task_struct *child)
{
- unsigned long tmp;
-
/* Deconfigure SPC and S-bit. */
user_disable_single_step(child);
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 6773fc83a670..8c4b45efd7b6 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -18,7 +18,6 @@
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/delay.h>
-#include <asm/rtc.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
@@ -67,7 +66,6 @@ unsigned long timer_regs[NR_CPUS] =
};
extern int set_rtc_mmss(unsigned long nowtime);
-extern int have_rtc;
#ifdef CONFIG_CPU_FREQ
static int
@@ -265,11 +263,6 @@ void __init time_init(void)
*/
loops_per_usec = 50;
- if(RTC_INIT() < 0)
- have_rtc = 0;
- else
- have_rtc = 1;
-
/* Start CPU local timer. */
cris_timer_init();
diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
index 1de779f4f240..7caf25d58e6b 100644
--- a/arch/cris/include/arch-v32/arch/cache.h
+++ b/arch/cris/include/arch-v32/arch/cache.h
@@ -7,7 +7,7 @@
#define L1_CACHE_BYTES 32
#define L1_CACHE_SHIFT 5
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
void flush_dma_list(dma_descr_data *descr);
void 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 956eea246b97..04d02a51c5e9 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -6,5 +6,4 @@ header-y += arch-v32/
header-y += ethernet.h
header-y += etraxgpio.h
header-y += rs485.h
-header-y += rtc.h
header-y += sync_serial.h
diff --git a/arch/cris/include/asm/posix_types.h b/arch/cris/include/asm/posix_types.h
index 72b3cd6eda0b..234891c74e2b 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;
typedef unsigned short __kernel_old_dev_t;
#define __kernel_old_dev_t __kernel_old_dev_t
+#include <asm-generic/posix_types.h>
+
#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 17d3019529e1..000000000000
--- a/arch/cris/include/asm/rtc.h
+++ /dev/null
@@ -1,107 +0,0 @@
-
-#ifndef __RTC_H__
-#define __RTC_H__
-
-#ifdef CONFIG_ETRAX_DS1302
- /* Dallas DS1302 clock/calendar register numbers. */
-# define RTC_SECONDS 0
-# define RTC_MINUTES 1
-# define RTC_HOURS 2
-# define RTC_DAY_OF_MONTH 3
-# define RTC_MONTH 4
-# define RTC_WEEKDAY 5
-# define RTC_YEAR 6
-# define RTC_CONTROL 7
-
- /* Bits in CONTROL register. */
-# define RTC_CONTROL_WRITEPROTECT 0x80
-# define RTC_TRICKLECHARGER 8
-
- /* Bits in TRICKLECHARGER register TCS TCS TCS TCS DS DS RS RS. */
-# define RTC_TCR_PATTERN 0xA0 /* 1010xxxx */
-# define RTC_TCR_1DIOD 0x04 /* xxxx01xx */
-# define RTC_TCR_2DIOD 0x08 /* xxxx10xx */
-# define RTC_TCR_DISABLED 0x00 /* xxxxxx00 Disabled */
-# define RTC_TCR_2KOHM 0x01 /* xxxxxx01 2KOhm */
-# define RTC_TCR_4KOHM 0x02 /* xxxxxx10 4kOhm */
-# define RTC_TCR_8KOHM 0x03 /* xxxxxx11 8kOhm */
-
-#elif defined(CONFIG_ETRAX_PCF8563)
- /* I2C bus slave registers. */
-# define RTC_I2C_READ 0xa3
-# define RTC_I2C_WRITE 0xa2
-
- /* Phillips PCF8563 registers. */
-# define RTC_CONTROL1 0x00 /* Control/Status register 1. */
-# define RTC_CONTROL2 0x01 /* Control/Status register 2. */
-# define RTC_CLOCKOUT_FREQ 0x0d /* CLKOUT frequency. */
-# define RTC_TIMER_CONTROL 0x0e /* Timer control. */
-# define RTC_TIMER_CNTDOWN 0x0f /* Timer countdown. */
-
- /* BCD encoded clock registers. */
-# define RTC_SECONDS 0x02
-# define RTC_MINUTES 0x03
-# define RTC_HOURS 0x04
-# define RTC_DAY_OF_MONTH 0x05
-# define RTC_WEEKDAY 0x06 /* Not coded in BCD! */
-# define RTC_MONTH 0x07
-# define RTC_YEAR 0x08
-# define RTC_MINUTE_ALARM 0x09
-# define RTC_HOUR_ALARM 0x0a
-# define RTC_DAY_ALARM 0x0b
-# define RTC_WEEKDAY_ALARM 0x0c
-
-#endif
-
-#ifdef CONFIG_ETRAX_DS1302
-extern unsigned char ds1302_readreg(int reg);
-extern void ds1302_writereg(int reg, unsigned char val);
-extern int ds1302_init(void);
-# define CMOS_READ(x) ds1302_readreg(x)
-# define CMOS_WRITE(val,reg) ds1302_writereg(reg,val)
-# define RTC_INIT() ds1302_init()
-#elif defined(CONFIG_ETRAX_PCF8563)
-extern unsigned char pcf8563_readreg(int reg);
-extern void pcf8563_writereg(int reg, unsigned char val);
-extern int pcf8563_init(void);
-# define CMOS_READ(x) pcf8563_readreg(x)
-# define CMOS_WRITE(val,reg) pcf8563_writereg(reg,val)
-# define RTC_INIT() pcf8563_init()
-#else
- /* No RTC configured so we shouldn't try to access any. */
-# define CMOS_READ(x) 42
-# define CMOS_WRITE(x,y)
-# define RTC_INIT() (-1)
-#endif
-
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-struct rtc_time {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
-};
-
-/* ioctl() calls that are permitted to the /dev/rtc interface. */
-#define RTC_MAGIC 'p'
-/* Read RTC time. */
-#define RTC_RD_TIME _IOR(RTC_MAGIC, 0x09, struct rtc_time)
-/* Set RTC time. */
-#define RTC_SET_TIME _IOW(RTC_MAGIC, 0x0a, struct rtc_time)
-#define RTC_SET_CHARGE _IOW(RTC_MAGIC, 0x0b, int)
-/* Voltage low detector */
-#define RTC_VL_READ _IOR(RTC_MAGIC, 0x13, int)
-/* Clear voltage low information */
-#define RTC_VL_CLR _IO(RTC_MAGIC, 0x14)
-#define RTC_MAX_IOCTL 0x14
-
-#endif /* __RTC_H__ */
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index 4e73092e85c0..277ffc459e4b 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -21,7 +21,6 @@
*
*/
-#include <asm/rtc.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/param.h>
@@ -32,7 +31,8 @@
#include <linux/profile.h>
#include <linux/sched.h> /* just for sched_clock() - funny that */
-int have_rtc; /* used to remember if we have an RTC or not */;
+
+#define D(x)
#define TICK_SIZE tick
@@ -50,78 +50,16 @@ u32 arch_gettimeoffset(void)
}
#endif
-/*
- * BUG: This routine does not handle hour overflow properly; it just
- * sets the minutes. Usually you'll only notice that after reboot!
- */
-
int set_rtc_mmss(unsigned long nowtime)
{
- int retval = 0;
- int real_seconds, real_minutes, cmos_minutes;
-
- printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime);
-
- if(!have_rtc)
- return 0;
-
- cmos_minutes = CMOS_READ(RTC_MINUTES);
- cmos_minutes = bcd2bin(cmos_minutes);
-
- /*
- * since we're only adjusting minutes and seconds,
- * don't interfere with hour overflow. This avoids
- * messing with unknown time zones but requires your
- * RTC not to be off by more than 15 minutes
- */
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
- real_minutes %= 60;
-
- if (abs(real_minutes - cmos_minutes) < 30) {
- real_seconds = bin2bcd(real_seconds);
- real_minutes = bin2bcd(real_minutes);
- CMOS_WRITE(real_seconds,RTC_SECONDS);
- CMOS_WRITE(real_minutes,RTC_MINUTES);
- } else {
- printk_once(KERN_NOTICE
- "set_rtc_mmss: can't update from %d to %d\n",
- cmos_minutes, real_minutes);
- retval = -1;
- }
-
- return retval;
+ D(printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime));
+ return 0;
}
/* grab the time from the RTC chip */
-
-unsigned long
-get_cmos_time(void)
+unsigned long get_cmos_time(void)
{
- unsigned int year, mon, day, hour, min, sec;
- if(!have_rtc)
- return 0;
-
- sec = CMOS_READ(RTC_SECONDS);
- min = CMOS_READ(RTC_MINUTES);
- hour = CMOS_READ(RTC_HOURS);
- day = CMOS_READ(RTC_DAY_OF_MONTH);
- mon = CMOS_READ(RTC_MONTH);
- year = CMOS_READ(RTC_YEAR);
-
- sec = bcd2bin(sec);
- min = bcd2bin(min);
- hour = bcd2bin(hour);
- day = bcd2bin(day);
- mon = bcd2bin(mon);
- year = bcd2bin(year);
-
- if ((year += 1900) < 1970)
- year += 100;
-
- return mktime(year, mon, day, hour, min, sec);
+ return 0;
}
@@ -132,7 +70,7 @@ int update_persistent_clock(struct timespec now)
void read_persistent_clock(struct timespec *ts)
{
- ts->tv_sec = get_cmos_time();
+ ts->tv_sec = 0;
ts->tv_nsec = 0;
}
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
index a6990cb0f098..a68b983dcea1 100644
--- a/arch/cris/kernel/vmlinux.lds.S
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -52,6 +52,7 @@ SECTIONS
EXCEPTION_TABLE(4)
+ _sdata = .;
RODATA
. = ALIGN (4);
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index b4760d86e1bb..45fd542cf173 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,
struct vm_area_struct * vma;
siginfo_t info;
int fault;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ ((writeaccess & 1) ? FAULT_FLAG_WRITE : 0);
D(printk(KERN_DEBUG
"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,
if (in_atomic() || !mm)
goto no_context;
+retry:
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
if (!vma)
@@ -163,7 +166,11 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
* the fault.
*/
- fault = handle_mm_fault(mm, vma, address, (writeaccess & 1) ? FAULT_FLAG_WRITE : 0);
+ fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -171,10 +178,24 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+ /*
+ * No need to up_read(&mm->mmap_sem) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+
+ goto retry;
+ }
+ }
up_read(&mm->mmap_sem);
return;
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 4932247d078a..49765b53f637 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -19,6 +19,8 @@ config OPENRISC
select GENERIC_CPU_DEVICES
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
config MMU
def_bool y
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index c936483bc8e2..3f35c38d7b64 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -66,3 +66,4 @@ generic-y += topology.h
generic-y += types.h
generic-y += ucontext.h
generic-y += user.h
+generic-y += word-at-a-time.h
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index f5abaa0ffc38..ab2e7a198a4c 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)
return size;
}
-extern int __strncpy_from_user(char *dst, const char *src, long count);
+#define user_addr_max() \
+ (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
-static inline long strncpy_from_user(char *dst, const char *src, long count)
-{
- if (access_ok(VERIFY_READ, src, 1))
- return __strncpy_from_user(dst, src, count);
- return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-
-extern int __strnlen_user(const char *str, long len, unsigned long top);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- *
- * The `top' parameter to __strnlen_user is to make sure that
- * we can never overflow from the user area into kernel space.
- */
-static inline long strnlen_user(const char __user *str, long len)
-{
- unsigned long top = (unsigned long)get_fs();
- unsigned long res = 0;
-
- if (__addr_ok(str))
- res = __strnlen_user(str, len, top);
-
- return res;
-}
+extern long strncpy_from_user(char *dest, const char __user *src, long count);
-#define strlen_user(str) strnlen_user(str, TASK_SIZE-1)
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
#endif /* __ASM_OPENRISC_UACCESS_H */
diff --git a/arch/openrisc/lib/string.S b/arch/openrisc/lib/string.S
index 465f04bc7deb..c09fee7dec14 100644
--- a/arch/openrisc/lib/string.S
+++ b/arch/openrisc/lib/string.S
@@ -103,102 +103,3 @@ __clear_user:
.section __ex_table, "a"
.long 9b, 99b // write fault
.previous
-
-/*
- * long strncpy_from_user(char *dst, const char *src, long count)
- *
- *
- */
- .global __strncpy_from_user
-__strncpy_from_user:
- l.addi r1,r1,-16
- l.sw 0(r1),r6
- l.sw 4(r1),r5
- l.sw 8(r1),r4
- l.sw 12(r1),r3
-
- l.addi r11,r5,0
-2: l.sfeq r5,r0
- l.bf 1f
- l.addi r5,r5,-1
-8: l.lbz r6,0(r4)
- l.sfeq r6,r0
- l.bf 1f
-9: l.sb 0(r3),r6
- l.addi r3,r3,1
- l.j 2b
- l.addi r4,r4,1
-1:
- l.lwz r6,0(r1)
- l.addi r5,r5,1
- l.sub r11,r11,r5 // r11 holds the return value
-
- l.lwz r6,0(r1)
- l.lwz r5,4(r1)
- l.lwz r4,8(r1)
- l.lwz r3,12(r1)
- l.jr r9
- l.addi r1,r1,16
-
- .section .fixup, "ax"
-99:
- l.movhi r11,hi(-EFAULT)
- l.ori r11,r11,lo(-EFAULT)
-
- l.lwz r6,0(r1)
- l.lwz r5,4(r1)
- l.lwz r4,8(r1)
- l.lwz r3,12(r1)
- l.jr r9
- l.addi r1,r1,16
- .previous
-
- .section __ex_table, "a"
- .long 8b, 99b // read fault
- .previous
-
-/*
- * extern int __strnlen_user(const char *str, long len, unsigned long top);
- *
- *
- * RTRN: - length of a string including NUL termination character
- * - on page fault 0
- */
-
- .global __strnlen_user
-__strnlen_user:
- l.addi r1,r1,-8
- l.sw 0(r1),r6
- l.sw 4(r1),r3
-
- l.addi r11,r0,0
-2: l.sfeq r11,r4
- l.bf 1f
- l.addi r11,r11,1
-8: l.lbz r6,0(r3)
- l.sfeq r6,r0
- l.bf 1f
- l.sfgeu r3,r5 // are we over the top ?
- l.bf 99f
- l.j 2b
- l.addi r3,r3,1
-
-1:
- l.lwz r6,0(r1)
- l.lwz r3,4(r1)
- l.jr r9
- l.addi r1,r1,8
-
- .section .fixup, "ax"
-99:
- l.addi r11,r0,0
-
- l.lwz r6,0(r1)
- l.lwz r3,4(r1)
- l.jr r9
- l.addi r1,r1,8
- .previous
-
- .section __ex_table, "a"
- .long 8b, 99b // read fault
- .previous
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 00b9874e2240..050cb371a69e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,8 @@ config PPC
select GENERIC_CMOS_UPDATE
select GENERIC_TIME_VSYSCALL
select GENERIC_CLOCKEVENTS
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
config EARLY_PRINTK
bool
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index 7e283c891b7f..fe0d60935e9b 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -119,6 +119,7 @@
sdhc@2e000 {
status = "disabled";
sdhci,1-bit-only;
+ bus-width = <1>;
};
par_io@e0100 {
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index bd0fb8495154..17bb40cad5bf 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -40,6 +40,8 @@
#define segment_eq(a, b) ((a).seg == (b).seg)
+#define user_addr_max() (get_fs().seg)
+
#ifdef __powerpc64__
/*
* 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)
return size;
}
-extern int __strncpy_from_user(char *dst, const char __user *src, long count);
-
-static inline long strncpy_from_user(char *dst, const char __user *src,
- long count)
-{
- might_sleep();
- if (likely(access_ok(VERIFY_READ, src, 1)))
- return __strncpy_from_user(dst, src, count);
- return -EFAULT;
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 for error
- */
-extern int __strnlen_user(const char __user *str, long len, unsigned long top);
-
-/*
- * Returns the length of the string at str (including the null byte),
- * or 0 if we hit a page we can't access,
- * or something > len if we didn't find a null byte.
- *
- * The `top' parameter to __strnlen_user is to make sure that
- * we can never overflow from the user area into kernel space.
- */
-static inline int strnlen_user(const char __user *str, long len)
-{
- unsigned long top = current->thread.fs.seg;
-
- if ((unsigned long)str > top)
- return 0;
- return __strnlen_user(str, len, top);
-}
-
-#define strlen_user(str) strnlen_user((str), 0x7ffffffe)
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
#endif /* __ASSEMBLY__ */
#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 000000000000..d0b6d4ac6dda
--- /dev/null
+++ b/arch/powerpc/include/asm/word-at-a-time.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_WORD_AT_A_TIME_H
+#define _ASM_WORD_AT_A_TIME_H
+
+/*
+ * Word-at-a-time interfaces for PowerPC.
+ */
+
+#include <linux/kernel.h>
+#include <asm/asm-compat.h>
+
+struct word_at_a_time {
+ const unsigned long high_bits, low_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0xfe) + 1, REPEAT_BYTE(0x7f) }
+
+/* Bit set in the bytes that have a zero */
+static inline long prep_zero_mask(unsigned long val, unsigned long rhs, const struct word_at_a_time *c)
+{
+ unsigned long mask = (val & c->low_bits) + c->low_bits;
+ return ~(mask | rhs);
+}
+
+#define create_zero_mask(mask) (mask)
+
+static inline long find_zero(unsigned long mask)
+{
+ long leading_zero_bits;
+
+ asm (PPC_CNTLZL "%0,%1" : "=r" (leading_zero_bits) : "r" (mask));
+ return leading_zero_bits >> 3;
+}
+
+static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c)
+{
+ unsigned long rhs = val | c->low_bits;
+ *data = rhs;
+ return (val + c->high_bits) & ~rhs;
+}
+
+#endif /* _ASM_WORD_AT_A_TIME_H */
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index d1f2aafcbe8c..3e4031581c65 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -85,8 +85,6 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
EXPORT_SYMBOL(__copy_tofrom_user);
EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(copy_page);
#if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S
index 455881a5563f..093d6316435c 100644
--- a/arch/powerpc/lib/string.S
+++ b/arch/powerpc/lib/string.S
@@ -160,48 +160,3 @@ _GLOBAL(__clear_user)
PPC_LONG 1b,91b
PPC_LONG 8b,92b
.text
-
-_GLOBAL(__strncpy_from_user)
- addi r6,r3,-1
- addi r4,r4,-1
- cmpwi 0,r5,0
- beq 2f
- mtctr r5
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r6)
- bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
- beq 3f
-2: addi r6,r6,1
-3: subf r3,r3,r6
- blr
-99: li r3,-EFAULT
- blr
-
- .section __ex_table,"a"
- PPC_LONG 1b,99b
- .text
-
-/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
-_GLOBAL(__strnlen_user)
- addi r7,r3,-1
- subf r6,r7,r5 /* top+1 - str */
- cmplw 0,r4,r6
- bge 0f
- mr r6,r4
-0: mtctr r6 /* ctr = min(len, top - str) */
-1: lbzu r0,1(r7) /* get next byte */
- cmpwi 0,r0,0
- bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */
- addi r7,r7,1
- subf r3,r3,r7 /* number of bytes we have looked at */
- beqlr /* return if we found a 0 byte */
- cmpw 0,r3,r4 /* did we look at all len bytes? */
- blt 99f /* if not, must have hit top */
- addi r3,r4,1 /* return len + 1 to indicate no null found */
- blr
-99: li r3,0 /* bad address, return 0 */
- blr
-
- .section __ex_table,"a"
- PPC_LONG 1b,99b
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 15e9e05740da..83bd051754e1 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -35,6 +35,7 @@ config SPARC
select GENERIC_CMOS_UPDATE
select GENERIC_CLOCKEVENTS
select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
config SPARC32
def_bool !64BIT
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 2c2e38821f60..67f83e0a0d68 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += div64.h
generic-y += local64.h
generic-y += irq_regs.h
generic-y += local.h
+generic-y += word-at-a-time.h
diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
index 59586b57ef1a..53a28dd59f59 100644
--- a/arch/sparc/include/asm/uaccess_32.h
+++ b/arch/sparc/include/asm/uaccess_32.h
@@ -16,6 +16,8 @@
#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+
#define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE
@@ -304,24 +306,8 @@ static inline unsigned long clear_user(void __user *addr, unsigned long n)
return n;
}
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
-
-static inline long strlen_user(const char __user *str)
-{
- if (!access_ok(VERIFY_READ, str, 0))
- return 0;
- else
- return __strlen_user(str);
-}
-
-static inline long strnlen_user(const char __user *str, long len)
-{
- if (!access_ok(VERIFY_READ, str, 0))
- return 0;
- else
- return __strnlen_user(str, len);
-}
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
#endif /* __ASSEMBLY__ */
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index dcdfb89cbf3f..7c831d848b4e 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -17,6 +17,8 @@
#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+
/*
* Sparc64 is segmented, though more like the M68K than the I386.
* 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);
#define clear_user __clear_user
-extern long __strlen_user(const char __user *);
-extern long __strnlen_user(const char __user *, long len);
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
-#define strlen_user __strlen_user
-#define strnlen_user __strnlen_user
#define __copy_to_user_inatomic ___copy_to_user
#define __copy_from_user_inatomic ___copy_from_user
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 943d98dc4cdb..dff4096f3dec 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -10,7 +10,6 @@ lib-y += strlen.o
lib-y += checksum_$(BITS).o
lib-$(CONFIG_SPARC32) += blockops.o
lib-y += memscan_$(BITS).o memcmp.o strncmp_$(BITS).o
-lib-y += strlen_user_$(BITS).o
lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
lib-$(CONFIG_SPARC32) += copy_user.o locks.o
lib-$(CONFIG_SPARC64) += atomic_64.o
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index 6b278abdb63d..3b31218cafc6 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -15,8 +15,6 @@
/* string functions */
EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(__strlen_user);
-EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(strncmp);
/* 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 8c8a371df3c9..000000000000
--- a/arch/sparc/lib/strlen_user_32.S
+++ /dev/null
@@ -1,109 +0,0 @@
-/* strlen_user.S: Sparc optimized strlen_user code
- *
- * Return length of string in userspace including terminating 0
- * or 0 for error
- *
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#define LO_MAGIC 0x01010101
-#define HI_MAGIC 0x80808080
-
-10:
- ldub [%o0], %o5
- cmp %o5, 0
- be 1f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be 4f
- or %o4, %lo(HI_MAGIC), %o3
-11:
- ldub [%o0], %o5
- cmp %o5, 0
- be 2f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be 5f
- sethi %hi(LO_MAGIC), %o4
-12:
- ldub [%o0], %o5
- cmp %o5, 0
- be 3f
- add %o0, 1, %o0
- b 13f
- or %o4, %lo(LO_MAGIC), %o2
-1:
- retl
- mov 1, %o0
-2:
- retl
- mov 2, %o0
-3:
- retl
- mov 3, %o0
-
- .align 4
- .global __strlen_user, __strnlen_user
-__strlen_user:
- sethi %hi(32768), %o1
-__strnlen_user:
- mov %o1, %g1
- mov %o0, %o1
- andcc %o0, 3, %g0
- bne 10b
- sethi %hi(HI_MAGIC), %o4
- or %o4, %lo(HI_MAGIC), %o3
-4:
- sethi %hi(LO_MAGIC), %o4
-5:
- or %o4, %lo(LO_MAGIC), %o2
-13:
- ld [%o0], %o5
-2:
- sub %o5, %o2, %o4
- andcc %o4, %o3, %g0
- bne 82f
- add %o0, 4, %o0
- sub %o0, %o1, %g2
-81: cmp %g2, %g1
- blu 13b
- mov %o0, %o4
- ba,a 1f
-
- /* Check every byte. */
-82: srl %o5, 24, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o0, -3, %o4
- srl %o5, 16, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o4, 1, %o4
- srl %o5, 8, %g5
- andcc %g5, 0xff, %g0
- be 1f
- add %o4, 1, %o4
- andcc %o5, 0xff, %g0
- bne 81b
- sub %o0, %o1, %g2
-
- add %o4, 1, %o4
-1:
- retl
- sub %o4, %o1, %o0
-
- .section .fixup,#alloc,#execinstr
- .align 4
-9:
- retl
- clr %o0
-
- .section __ex_table,#alloc
- .align 4
-
- .word 10b, 9b
- .word 11b, 9b
- .word 12b, 9b
- .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 c3df71fa4928..000000000000
--- a/arch/sparc/lib/strlen_user_64.S
+++ /dev/null
@@ -1,97 +0,0 @@
-/* strlen_user.S: Sparc64 optimized strlen_user code
- *
- * Return length of string in userspace including terminating 0
- * or 0 for error
- *
- * Copyright (C) 1991,1996 Free Software Foundation
- * Copyright (C) 1996,1999 David S. Miller (davem@redhat.com)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-
-#include <linux/linkage.h>
-#include <asm/asi.h>
-
-#define LO_MAGIC 0x01010101
-#define HI_MAGIC 0x80808080
-
- .align 4
-ENTRY(__strlen_user)
- sethi %hi(32768), %o1
-ENTRY(__strnlen_user)
- mov %o1, %g1
- mov %o0, %o1
- andcc %o0, 3, %g0
- be,pt %icc, 9f
- sethi %hi(HI_MAGIC), %o4
-10: lduba [%o0] %asi, %o5
- brz,pn %o5, 21f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be,pn %icc, 4f
- or %o4, %lo(HI_MAGIC), %o3
-11: lduba [%o0] %asi, %o5
- brz,pn %o5, 22f
- add %o0, 1, %o0
- andcc %o0, 3, %g0
- be,pt %icc, 13f
- srl %o3, 7, %o2
-12: lduba [%o0] %asi, %o5
- brz,pn %o5, 23f
- add %o0, 1, %o0
- ba,pt %icc, 2f
-15: lda [%o0] %asi, %o5
-9: or %o4, %lo(HI_MAGIC), %o3
-4: srl %o3, 7, %o2
-13: lda [%o0] %asi, %o5
-2: sub %o5, %o2, %o4
- andcc %o4, %o3, %g0
- bne,pn %icc, 82f
- add %o0, 4, %o0
- sub %o0, %o1, %g2
-81: cmp %g2, %g1
- blu,pt %icc, 13b
- mov %o0, %o4
- ba,a,pt %xcc, 1f
-
- /* Check every byte. */
-82: srl %o5, 24, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o0, -3, %o4
- srl %o5, 16, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o4, 1, %o4
- srl %o5, 8, %g7
- andcc %g7, 0xff, %g0
- be,pn %icc, 1f
- add %o4, 1, %o4
- andcc %o5, 0xff, %g0
- bne,pt %icc, 81b
- sub %o0, %o1, %g2
- add %o4, 1, %o4
-1: retl
- sub %o4, %o1, %o0
-21: retl
- mov 1, %o0
-22: retl
- mov 2, %o0
-23: retl
- mov 3, %o0
-ENDPROC(__strlen_user)
-ENDPROC(__strnlen_user)
-
- .section .fixup,#alloc,#execinstr
- .align 4
-30:
- retl
- clr %o0
-
- .section __ex_table,"a"
- .align 4
-
- .word 10b, 30b
- .word 11b, 30b
- .word 12b, 30b
- .word 15b, 30b
- .word 13b, 30b
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 6ad6219fc47e..fe128816c448 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -48,6 +48,14 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK
config SYS_SUPPORTS_HUGETLBFS
def_bool y
+# Support for additional huge page sizes besides HPAGE_SIZE.
+# The software support is currently only present in the TILE-Gx
+# hypervisor. TILEPro in any case does not support page sizes
+# larger than the default HPAGE_SIZE.
+config HUGETLB_SUPER_PAGES
+ depends on HUGETLB_PAGE && TILEGX
+ def_bool y
+
# FIXME: tilegx can implement a more efficient rwsem.
config RWSEM_GENERIC_SPINLOCK
def_bool y
@@ -107,16 +115,14 @@ config HVC_TILE
select HVC_DRIVER
def_bool y
-# Please note: TILE-Gx support is not yet finalized; this is
-# the preliminary support. TILE-Gx drivers are only provided
-# with the alpha or beta test versions for Tilera customers.
config TILEGX
- depends on EXPERIMENTAL
bool "Building with TILE-Gx (64-bit) compiler and toolchain"
+config TILEPRO
+ def_bool !TILEGX
+
config 64BIT
- depends on TILEGX
- def_bool y
+ def_bool TILEGX
config ARCH_DEFCONFIG
string
@@ -137,6 +143,31 @@ config NR_CPUS
smaller kernel memory footprint results from using a smaller
value on chips with fewer tiles.
+if TILEGX
+
+choice
+ prompt "Kernel page size"
+ default PAGE_SIZE_64KB
+ help
+ This lets you select the page size of the kernel. For best
+ performance on memory-intensive applications, a page size of 64KB
+ is recommended. For workloads involving many small files, many
+ connections, etc., it may be better to select 16KB, which uses
+ memory more efficiently at some cost in TLB performance.
+
+ Note that this option is TILE-Gx specific; currently
+ TILEPro page size is set by rebuilding the hypervisor.
+
+config PAGE_SIZE_16KB
+ bool "16KB"
+
+config PAGE_SIZE_64KB
+ bool "64KB"
+
+endchoice
+
+endif
+
source "kernel/Kconfig.hz"
config KEXEC
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
index 9520bc5a4b7f..e20b0a0b64a1 100644
--- a/arch/tile/Makefile
+++ b/arch/tile/Makefile
@@ -34,7 +34,12 @@ LIBGCC_PATH := \
$(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
# Provide the path to use for "make defconfig".
-KBUILD_DEFCONFIG := $(ARCH)_defconfig
+# We default to the newer TILE-Gx architecture if only "tile" is given.
+ifeq ($(ARCH),tile)
+ KBUILD_DEFCONFIG := tilegx_defconfig
+else
+ KBUILD_DEFCONFIG := $(ARCH)_defconfig
+endif
# Used as a file extension when useful, e.g. head_$(BITS).o
# 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 bbc1f4c924ee..78bbce2fb19a 100644
--- a/arch/tile/include/arch/spr_def_32.h
+++ b/arch/tile/include/arch/spr_def_32.h
@@ -65,6 +65,31 @@
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
#define SPR_FAIL 0x4e09
+#define SPR_IDN_AVAIL_EN 0x3e05
+#define SPR_IDN_CA_DATA 0x0b00
+#define SPR_IDN_DATA_AVAIL 0x0b03
+#define SPR_IDN_DEADLOCK_TIMEOUT 0x3406
+#define SPR_IDN_DEMUX_CA_COUNT 0x0a05
+#define SPR_IDN_DEMUX_COUNT_0 0x0a06
+#define SPR_IDN_DEMUX_COUNT_1 0x0a07
+#define SPR_IDN_DEMUX_CTL 0x0a08
+#define SPR_IDN_DEMUX_QUEUE_SEL 0x0a0a
+#define SPR_IDN_DEMUX_STATUS 0x0a0b
+#define SPR_IDN_DEMUX_WRITE_FIFO 0x0a0c
+#define SPR_IDN_DIRECTION_PROTECT 0x2e05
+#define SPR_IDN_PENDING 0x0a0e
+#define SPR_IDN_REFILL_EN 0x0e05
+#define SPR_IDN_SP_FIFO_DATA 0x0a0f
+#define SPR_IDN_SP_FIFO_SEL 0x0a10
+#define SPR_IDN_SP_FREEZE 0x0a11
+#define SPR_IDN_SP_FREEZE__SP_FRZ_MASK 0x1
+#define SPR_IDN_SP_FREEZE__DEMUX_FRZ_MASK 0x2
+#define SPR_IDN_SP_FREEZE__NON_DEST_EXT_MASK 0x4
+#define SPR_IDN_SP_STATE 0x0a12
+#define SPR_IDN_TAG_0 0x0a13
+#define SPR_IDN_TAG_1 0x0a14
+#define SPR_IDN_TAG_VALID 0x0a15
+#define SPR_IDN_TILE_COORD 0x0a16
#define SPR_INTCTRL_0_STATUS 0x4a07
#define SPR_INTCTRL_1_STATUS 0x4807
#define SPR_INTCTRL_2_STATUS 0x4607
@@ -87,12 +112,36 @@
#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
#define SPR_INTERRUPT_MASK_SET_2_0 0x460c
#define SPR_INTERRUPT_MASK_SET_2_1 0x460d
+#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x6000
+#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x6001
+#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x6002
#define SPR_MPL_DMA_CPL_SET_0 0x5800
#define SPR_MPL_DMA_CPL_SET_1 0x5801
#define SPR_MPL_DMA_CPL_SET_2 0x5802
#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
#define SPR_MPL_DMA_NOTIFY_SET_2 0x3802
+#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
+#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
+#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
+#define SPR_MPL_IDN_AVAIL_SET_0 0x3e00
+#define SPR_MPL_IDN_AVAIL_SET_1 0x3e01
+#define SPR_MPL_IDN_AVAIL_SET_2 0x3e02
+#define SPR_MPL_IDN_CA_SET_0 0x3a00
+#define SPR_MPL_IDN_CA_SET_1 0x3a01
+#define SPR_MPL_IDN_CA_SET_2 0x3a02
+#define SPR_MPL_IDN_COMPLETE_SET_0 0x1200
+#define SPR_MPL_IDN_COMPLETE_SET_1 0x1201
+#define SPR_MPL_IDN_COMPLETE_SET_2 0x1202
+#define SPR_MPL_IDN_FIREWALL_SET_0 0x2e00
+#define SPR_MPL_IDN_FIREWALL_SET_1 0x2e01
+#define SPR_MPL_IDN_FIREWALL_SET_2 0x2e02
+#define SPR_MPL_IDN_REFILL_SET_0 0x0e00
+#define SPR_MPL_IDN_REFILL_SET_1 0x0e01
+#define SPR_MPL_IDN_REFILL_SET_2 0x0e02
+#define SPR_MPL_IDN_TIMER_SET_0 0x3400
+#define SPR_MPL_IDN_TIMER_SET_1 0x3401
+#define SPR_MPL_IDN_TIMER_SET_2 0x3402
#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
#define SPR_MPL_INTCTRL_0_SET_2 0x4a02
@@ -102,6 +151,9 @@
#define SPR_MPL_INTCTRL_2_SET_0 0x4600
#define SPR_MPL_INTCTRL_2_SET_1 0x4601
#define SPR_MPL_INTCTRL_2_SET_2 0x4602
+#define SPR_MPL_PERF_COUNT_SET_0 0x4200
+#define SPR_MPL_PERF_COUNT_SET_1 0x4201
+#define SPR_MPL_PERF_COUNT_SET_2 0x4202
#define SPR_MPL_SN_ACCESS_SET_0 0x0800
#define SPR_MPL_SN_ACCESS_SET_1 0x0801
#define SPR_MPL_SN_ACCESS_SET_2 0x0802
@@ -181,6 +233,7 @@
#define SPR_UDN_DEMUX_STATUS 0x0c0d
#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e
#define SPR_UDN_DIRECTION_PROTECT 0x3005
+#define SPR_UDN_PENDING 0x0c10
#define SPR_UDN_REFILL_EN 0x1005
#define SPR_UDN_SP_FIFO_DATA 0x0c11
#define SPR_UDN_SP_FIFO_SEL 0x0c12
@@ -195,6 +248,9 @@
#define SPR_UDN_TAG_3 0x0c18
#define SPR_UDN_TAG_VALID 0x0c19
#define SPR_UDN_TILE_COORD 0x0c1a
+#define SPR_WATCH_CTL 0x4209
+#define SPR_WATCH_MASK 0x420a
+#define SPR_WATCH_VAL 0x420b
#endif /* !defined(__ARCH_SPR_DEF_H__) */
diff --git a/arch/tile/include/arch/spr_def_64.h b/arch/tile/include/arch/spr_def_64.h
index cd3e5f95d5fd..0da86faa3370 100644
--- a/arch/tile/include/arch/spr_def_64.h
+++ b/arch/tile/include/arch/spr_def_64.h
@@ -52,6 +52,13 @@
#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
#define SPR_EX_CONTEXT_2_1__ICS_MASK 0x4
#define SPR_FAIL 0x2707
+#define SPR_IDN_AVAIL_EN 0x1a05
+#define SPR_IDN_DATA_AVAIL 0x0a80
+#define SPR_IDN_DEADLOCK_TIMEOUT 0x1806
+#define SPR_IDN_DEMUX_COUNT_0 0x0a05
+#define SPR_IDN_DEMUX_COUNT_1 0x0a06
+#define SPR_IDN_DIRECTION_PROTECT 0x1405
+#define SPR_IDN_PENDING 0x0a08
#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
#define SPR_INTCTRL_0_STATUS 0x2505
#define SPR_INTCTRL_1_STATUS 0x2405
@@ -88,9 +95,27 @@
#define SPR_IPI_MASK_SET_0 0x1f0a
#define SPR_IPI_MASK_SET_1 0x1e0a
#define SPR_IPI_MASK_SET_2 0x1d0a
+#define SPR_MPL_AUX_PERF_COUNT_SET_0 0x2100
+#define SPR_MPL_AUX_PERF_COUNT_SET_1 0x2101
+#define SPR_MPL_AUX_PERF_COUNT_SET_2 0x2102
#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
+#define SPR_MPL_IDN_ACCESS_SET_0 0x0a00
+#define SPR_MPL_IDN_ACCESS_SET_1 0x0a01
+#define SPR_MPL_IDN_ACCESS_SET_2 0x0a02
+#define SPR_MPL_IDN_AVAIL_SET_0 0x1a00
+#define SPR_MPL_IDN_AVAIL_SET_1 0x1a01
+#define SPR_MPL_IDN_AVAIL_SET_2 0x1a02
+#define SPR_MPL_IDN_COMPLETE_SET_0 0x0500
+#define SPR_MPL_IDN_COMPLETE_SET_1 0x0501
+#define SPR_MPL_IDN_COMPLETE_SET_2 0x0502
+#define SPR_MPL_IDN_FIREWALL_SET_0 0x1400
+#define SPR_MPL_IDN_FIREWALL_SET_1 0x1401
+#define SPR_MPL_IDN_FIREWALL_SET_2 0x1402
+#define SPR_MPL_IDN_TIMER_SET_0 0x1800
+#define SPR_MPL_IDN_TIMER_SET_1 0x1801
+#define SPR_MPL_IDN_TIMER_SET_2 0x1802
#define SPR_MPL_INTCTRL_0_SET_0 0x2500
#define SPR_MPL_INTCTRL_0_SET_1 0x2501
#define SPR_MPL_INTCTRL_0_SET_2 0x2502
@@ -100,6 +125,21 @@
#define SPR_MPL_INTCTRL_2_SET_0 0x2300
#define SPR_MPL_INTCTRL_2_SET_1 0x2301
#define SPR_MPL_INTCTRL_2_SET_2 0x2302
+#define SPR_MPL_IPI_0 0x1f04
+#define SPR_MPL_IPI_0_SET_0 0x1f00
+#define SPR_MPL_IPI_0_SET_1 0x1f01
+#define SPR_MPL_IPI_0_SET_2 0x1f02
+#define SPR_MPL_IPI_1 0x1e04
+#define SPR_MPL_IPI_1_SET_0 0x1e00
+#define SPR_MPL_IPI_1_SET_1 0x1e01
+#define SPR_MPL_IPI_1_SET_2 0x1e02
+#define SPR_MPL_IPI_2 0x1d04
+#define SPR_MPL_IPI_2_SET_0 0x1d00
+#define SPR_MPL_IPI_2_SET_1 0x1d01
+#define SPR_MPL_IPI_2_SET_2 0x1d02
+#define SPR_MPL_PERF_COUNT_SET_0 0x2000
+#define SPR_MPL_PERF_COUNT_SET_1 0x2001
+#define SPR_MPL_PERF_COUNT_SET_2 0x2002
#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
@@ -167,6 +207,9 @@
#define SPR_UDN_DEMUX_COUNT_2 0x0b07
#define SPR_UDN_DEMUX_COUNT_3 0x0b08
#define SPR_UDN_DIRECTION_PROTECT 0x1505
+#define SPR_UDN_PENDING 0x0b0a
+#define SPR_WATCH_MASK 0x200a
+#define SPR_WATCH_VAL 0x200b
#endif /* !defined(__ARCH_SPR_DEF_H__) */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 0bb42642343a..143473e3a0bb 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
header-y += ../arch/
+header-y += cachectl.h
header-y += ucontext.h
header-y += hardwall.h
@@ -21,7 +22,6 @@ generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += kdebug.h
generic-y += local.h
-generic-y += module.h
generic-y += msgbuf.h
generic-y += mutex.h
generic-y += param.h
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
index 54d1da826f93..e7fb5cfb9597 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);
void __atomic_fault_unlock(int *lock_ptr);
#endif
+/* Return a pointer to the lock for the given address. */
+int *__atomic_hashed_lock(volatile void *v);
+
/* Private helper routines in lib/atomic_asm_32.S */
+struct __get_user {
+ unsigned long val;
+ int err;
+};
extern struct __get_user __atomic_cmpxchg(volatile int *p,
int *lock, int o, int n);
extern 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);
extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
int *lock, u64 o, u64 n);
+/* Return failure from the atomic wrappers. */
+struct __get_user __atomic_bad_address(int __user *addr);
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_TILE_ATOMIC_32_H */
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
index 16f1fa51fea1..bd186c4eaa50 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)
return __builtin_ffs(x);
}
+static inline int fls64(__u64 w)
+{
+ return (sizeof(__u64) * 8) - __builtin_clzll(w);
+}
+
/**
* fls - find last set bit in word
* @x: the word to search
@@ -90,12 +95,7 @@ static inline int ffs(int x)
*/
static inline int fls(int x)
{
- return (sizeof(int) * 8) - __builtin_clz(x);
-}
-
-static inline int fls64(__u64 w)
-{
- return (sizeof(__u64) * 8) - __builtin_clzll(w);
+ return fls64((unsigned int) x);
}
static 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 9558416d578b..fb72ecf49218 100644
--- a/arch/tile/include/asm/byteorder.h
+++ b/arch/tile/include/asm/byteorder.h
@@ -1 +1,21 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#if defined (__BIG_ENDIAN__)
+#include <linux/byteorder/big_endian.h>
+#elif defined (__LITTLE_ENDIAN__)
#include <linux/byteorder/little_endian.h>
+#else
+#error "__BIG_ENDIAN__ or __LITTLE_ENDIAN__ must be defined."
+#endif
diff --git a/arch/tile/include/asm/cachectl.h b/arch/tile/include/asm/cachectl.h
new file mode 100644
index 000000000000..af4c9f9154d1
--- /dev/null
+++ b/arch/tile/include/asm/cachectl.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_CACHECTL_H
+#define _ASM_TILE_CACHECTL_H
+
+/*
+ * Options for cacheflush system call.
+ *
+ * The ICACHE flush is performed on all cores currently running the
+ * current process's address space. The intent is for user
+ * applications to be able to modify code, invoke the system call,
+ * then allow arbitrary other threads in the same address space to see
+ * the newly-modified code. Passing a length of CHIP_L1I_CACHE_SIZE()
+ * or more invalidates the entire icache on all cores in the address
+ * spaces. (Note: currently this option invalidates the entire icache
+ * regardless of the requested address and length, but we may choose
+ * to honor the arguments at some point.)
+ *
+ * Flush and invalidation of memory can normally be performed with the
+ * __insn_flush(), __insn_inv(), and __insn_finv() instructions from
+ * userspace. The DCACHE option to the system call allows userspace
+ * to flush the entire L1+L2 data cache from the core. In this case,
+ * the address and length arguments are not used. The DCACHE flush is
+ * restricted to the current core, not all cores in the address space.
+ */
+#define ICACHE (1<<0) /* invalidate L1 instruction cache */
+#define DCACHE (1<<1) /* flush and invalidate data cache */
+#define BCACHE (ICACHE|DCACHE) /* flush both caches */
+
+#endif /* _ASM_TILE_CACHECTL_H */
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index 4b4b28969a65..69adc08d36a5 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,
long compat_sys_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval);
-/* Tilera Linux syscalls that don't have "compat" versions. */
-#define compat_sys_flush_cache sys_flush_cache
-
/* These are the intvec_64.S trampolines. */
long _compat_sys_execve(const char __user *path,
const compat_uptr_t __user *argv,
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
index 623a6bb741c1..d16d006d660e 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];
#else
#define ELF_CLASS ELFCLASS32
#endif
+#ifdef __BIG_ENDIAN__
+#define ELF_DATA ELFDATA2MSB
+#else
#define ELF_DATA ELFDATA2LSB
+#endif
/*
* There seems to be a bug in how compat_binfmt_elf.c works: it
@@ -59,6 +63,7 @@ enum { ELF_ARCH = CHIP_ELF_TYPE() };
*/
#define elf_check_arch(x) \
((x)->e_ident[EI_CLASS] == ELF_CLASS && \
+ (x)->e_ident[EI_DATA] == ELF_DATA && \
(x)->e_machine == CHIP_ELF_TYPE())
/* 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 d03ec124a598..5909ac3d7218 100644
--- a/arch/tile/include/asm/futex.h
+++ b/arch/tile/include/asm/futex.h
@@ -28,29 +28,81 @@
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
+#include <asm/atomic.h>
-extern struct __get_user futex_set(u32 __user *v, int i);
-extern struct __get_user futex_add(u32 __user *v, int n);
-extern struct __get_user futex_or(u32 __user *v, int n);
-extern struct __get_user futex_andn(u32 __user *v, int n);
-extern struct __get_user futex_cmpxchg(u32 __user *v, int o, int n);
+/*
+ * Support macros for futex operations. Do not use these macros directly.
+ * They assume "ret", "val", "oparg", and "uaddr" in the lexical context.
+ * __futex_cmpxchg() additionally assumes "oldval".
+ */
+
+#ifdef __tilegx__
+
+#define __futex_asm(OP) \
+ asm("1: {" #OP " %1, %3, %4; movei %0, 0 }\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "0: { movei %0, %5; j 9f }\n" \
+ ".section __ex_table,\"a\"\n" \
+ ".quad 1b, 0b\n" \
+ ".popsection\n" \
+ "9:" \
+ : "=r" (ret), "=r" (val), "+m" (*(uaddr)) \
+ : "r" (uaddr), "r" (oparg), "i" (-EFAULT))
+
+#define __futex_set() __futex_asm(exch4)
+#define __futex_add() __futex_asm(fetchadd4)
+#define __futex_or() __futex_asm(fetchor4)
+#define __futex_andn() ({ oparg = ~oparg; __futex_asm(fetchand4); })
+#define __futex_cmpxchg() \
+ ({ __insn_mtspr(SPR_CMPEXCH_VALUE, oldval); __futex_asm(cmpexch4); })
+
+#define __futex_xor() \
+ ({ \
+ u32 oldval, n = oparg; \
+ if ((ret = __get_user(oldval, uaddr)) == 0) { \
+ do { \
+ oparg = oldval ^ n; \
+ __futex_cmpxchg(); \
+ } while (ret == 0 && oldval != val); \
+ } \
+ })
+
+/* No need to prefetch, since the atomic ops go to the home cache anyway. */
+#define __futex_prolog()
-#ifndef __tilegx__
-extern struct __get_user futex_xor(u32 __user *v, int n);
#else
-static inline struct __get_user futex_xor(u32 __user *uaddr, int n)
-{
- struct __get_user asm_ret = __get_user_4(uaddr);
- if (!asm_ret.err) {
- int oldval, newval;
- do {
- oldval = asm_ret.val;
- newval = oldval ^ n;
- asm_ret = futex_cmpxchg(uaddr, oldval, newval);
- } while (asm_ret.err == 0 && oldval != asm_ret.val);
+
+#define __futex_call(FN) \
+ { \
+ struct __get_user gu = FN((u32 __force *)uaddr, lock, oparg); \
+ val = gu.val; \
+ ret = gu.err; \
}
- return asm_ret;
-}
+
+#define __futex_set() __futex_call(__atomic_xchg)
+#define __futex_add() __futex_call(__atomic_xchg_add)
+#define __futex_or() __futex_call(__atomic_or)
+#define __futex_andn() __futex_call(__atomic_andn)
+#define __futex_xor() __futex_call(__atomic_xor)
+
+#define __futex_cmpxchg() \
+ { \
+ struct __get_user gu = __atomic_cmpxchg((u32 __force *)uaddr, \
+ lock, oldval, oparg); \
+ val = gu.val; \
+ ret = gu.err; \
+ }
+
+/*
+ * Find the lock pointer for the atomic calls to use, and issue a
+ * prefetch to the user address to bring it into cache. Similar to
+ * __atomic_setup(), but we can't do a read into the L1 since it might
+ * fault; instead we do a prefetch into the L2.
+ */
+#define __futex_prolog() \
+ int *lock; \
+ __insn_prefetch(uaddr); \
+ lock = __atomic_hashed_lock((int __force *)uaddr)
#endif
static 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)
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
- int ret;
- struct __get_user asm_ret;
+ int uninitialized_var(val), ret;
+
+ __futex_prolog();
+
+ /* The 32-bit futex code makes this assumption, so validate it here. */
+ BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
@@ -71,46 +127,45 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
- asm_ret = futex_set(uaddr, oparg);
+ __futex_set();
break;
case FUTEX_OP_ADD:
- asm_ret = futex_add(uaddr, oparg);
+ __futex_add();
break;
case FUTEX_OP_OR:
- asm_ret = futex_or(uaddr, oparg);
+ __futex_or();
break;
case FUTEX_OP_ANDN:
- asm_ret = futex_andn(uaddr, oparg);
+ __futex_andn();
break;
case FUTEX_OP_XOR:
- asm_ret = futex_xor(uaddr, oparg);
+ __futex_xor();
break;
default:
- asm_ret.err = -ENOSYS;
+ ret = -ENOSYS;
+ break;
}
pagefault_enable();
- ret = asm_ret.err;
-
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ:
- ret = (asm_ret.val == cmparg);
+ ret = (val == cmparg);
break;
case FUTEX_OP_CMP_NE:
- ret = (asm_ret.val != cmparg);
+ ret = (val != cmparg);
break;
case FUTEX_OP_CMP_LT:
- ret = (asm_ret.val < cmparg);
+ ret = (val < cmparg);
break;
case FUTEX_OP_CMP_GE:
- ret = (asm_ret.val >= cmparg);
+ ret = (val >= cmparg);
break;
case FUTEX_OP_CMP_LE:
- ret = (asm_ret.val <= cmparg);
+ ret = (val <= cmparg);
break;
case FUTEX_OP_CMP_GT:
- ret = (asm_ret.val > cmparg);
+ ret = (val > cmparg);
break;
default:
ret = -ENOSYS;
@@ -120,22 +175,20 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
}
static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
- u32 oldval, u32 newval)
+ u32 oldval, u32 oparg)
{
- struct __get_user asm_ret;
+ int ret, val;
+
+ __futex_prolog();
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
- asm_ret = futex_cmpxchg(uaddr, oldval, newval);
- *uval = asm_ret.val;
- return asm_ret.err;
-}
+ __futex_cmpxchg();
-#ifndef __tilegx__
-/* Return failure from the atomic wrappers. */
-struct __get_user __atomic_bad_address(int __user *addr);
-#endif
+ *uval = val;
+ return ret;
+}
#endif /* !__ASSEMBLY__ */
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h
index 2ac422848c7d..47514a58d685 100644
--- a/arch/tile/include/asm/hardwall.h
+++ b/arch/tile/include/asm/hardwall.h
@@ -11,12 +11,14 @@
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
- * Provide methods for the HARDWALL_FILE for accessing the UDN.
+ * Provide methods for access control of per-cpu resources like
+ * UDN, IDN, or IPI.
*/
#ifndef _ASM_TILE_HARDWALL_H
#define _ASM_TILE_HARDWALL_H
+#include <arch/chip.h>
#include <linux/ioctl.h>
#define HARDWALL_IOCTL_BASE 0xa2
@@ -24,8 +26,9 @@
/*
* The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
* The resulting ioctl value is passed to the kernel in conjunction
- * with a pointer to a little-endian bitmask of cpus, which must be
- * physically in a rectangular configuration on the chip.
+ * with a pointer to a standard kernel bitmask of cpus.
+ * For network resources (UDN or IDN) the bitmask must physically
+ * represent a rectangular configuration on the chip.
* The "size" is the number of bytes of cpu mask data.
*/
#define _HARDWALL_CREATE 1
@@ -44,13 +47,7 @@
#define HARDWALL_GET_ID \
_IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
-#ifndef __KERNEL__
-
-/* This is the canonical name expected by userspace. */
-#define HARDWALL_FILE "/dev/hardwall"
-
-#else
-
+#ifdef __KERNEL__
/* /proc hooks for hardwall. */
struct proc_dir_entry;
#ifdef CONFIG_HARDWALL
@@ -59,7 +56,6 @@ int proc_pid_hardwall(struct task_struct *task, char *buffer);
#else
static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
#endif
-
#endif
#endif /* _ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index d396d1805163..b2042380a5aa 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)
{
}
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
+ struct page *page, int writable)
+{
+ size_t pagesize = huge_page_size(hstate_vma(vma));
+ if (pagesize != PUD_SIZE && pagesize != PMD_SIZE)
+ entry = pte_mksuper(entry);
+ return entry;
+}
+#define arch_make_huge_pte arch_make_huge_pte
+
+/* Sizes to scale up page size for PTEs with HV_PTE_SUPER bit. */
+enum {
+ HUGE_SHIFT_PGDIR = 0,
+ HUGE_SHIFT_PMD = 1,
+ HUGE_SHIFT_PAGE = 2,
+ HUGE_SHIFT_ENTRIES
+};
+extern int huge_shift[HUGE_SHIFT_ENTRIES];
+#endif
+
#endif /* _ASM_TILE_HUGETLB_H */
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
index 5db0ce54284d..b4e96fef2cf8 100644
--- a/arch/tile/include/asm/irqflags.h
+++ b/arch/tile/include/asm/irqflags.h
@@ -28,10 +28,10 @@
*/
#if CHIP_HAS_AUX_PERF_COUNTERS()
#define LINUX_MASKABLE_INTERRUPTS_HI \
- (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT)))
+ (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT)))
#else
#define LINUX_MASKABLE_INTERRUPTS_HI \
- (~(INT_MASK_HI(INT_PERF_COUNT)))
+ (~(INT_MASK_HI(INT_PERF_COUNT)))
#endif
#else
@@ -90,6 +90,14 @@
__insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_0, (unsigned long)(__m)); \
__insn_mtspr(SPR_INTERRUPT_MASK_RESET_K_1, (unsigned long)(__m>>32)); \
} while (0)
+#define interrupt_mask_save_mask() \
+ (__insn_mfspr(SPR_INTERRUPT_MASK_SET_K_0) | \
+ (((unsigned long long)__insn_mfspr(SPR_INTERRUPT_MASK_SET_K_1))<<32))
+#define interrupt_mask_restore_mask(mask) do { \
+ unsigned long long __m = (mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_K_0, (unsigned long)(__m)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_K_1, (unsigned long)(__m>>32)); \
+} while (0)
#else
#define interrupt_mask_set(n) \
__insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (1UL << (n)))
@@ -101,6 +109,10 @@
__insn_mtspr(SPR_INTERRUPT_MASK_SET_K, (mask))
#define interrupt_mask_reset_mask(mask) \
__insn_mtspr(SPR_INTERRUPT_MASK_RESET_K, (mask))
+#define interrupt_mask_save_mask() \
+ __insn_mfspr(SPR_INTERRUPT_MASK_K)
+#define interrupt_mask_restore_mask(mask) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_K, (mask))
#endif
/*
@@ -122,7 +134,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
/* Disable all interrupts, including NMIs. */
#define arch_local_irq_disable_all() \
- interrupt_mask_set_mask(-1UL)
+ interrupt_mask_set_mask(-1ULL)
/* Re-enable all maskable interrupts. */
#define arch_local_irq_enable() \
@@ -179,7 +191,7 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
#ifdef __tilegx__
#if INT_MEM_ERROR != 0
-# error Fix IRQ_DISABLED() macro
+# error Fix IRQS_DISABLED() macro
#endif
/* Return 0 or 1 to indicate whether interrupts are currently disabled. */
@@ -207,9 +219,10 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
mtspr SPR_INTERRUPT_MASK_SET_K, tmp
/* Enable interrupts. */
-#define IRQ_ENABLE(tmp0, tmp1) \
+#define IRQ_ENABLE_LOAD(tmp0, tmp1) \
GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
- ld tmp0, tmp0; \
+ ld tmp0, tmp0
+#define IRQ_ENABLE_APPLY(tmp0, tmp1) \
mtspr SPR_INTERRUPT_MASK_RESET_K, tmp0
#else /* !__tilegx__ */
@@ -253,17 +266,22 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp
/* Enable interrupts. */
-#define IRQ_ENABLE(tmp0, tmp1) \
+#define IRQ_ENABLE_LOAD(tmp0, tmp1) \
GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
{ \
lw tmp0, tmp0; \
addi tmp1, tmp0, 4 \
}; \
- lw tmp1, tmp1; \
+ lw tmp1, tmp1
+#define IRQ_ENABLE_APPLY(tmp0, tmp1) \
mtspr SPR_INTERRUPT_MASK_RESET_K_0, tmp0; \
mtspr SPR_INTERRUPT_MASK_RESET_K_1, tmp1
#endif
+#define IRQ_ENABLE(tmp0, tmp1) \
+ IRQ_ENABLE_LOAD(tmp0, tmp1); \
+ IRQ_ENABLE_APPLY(tmp0, tmp1)
+
/*
* Do the CPU's IRQ-state tracing from assembly code. We call a
* 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 c11a6cc73bb8..fc98ccfc98ac 100644
--- a/arch/tile/include/asm/kexec.h
+++ b/arch/tile/include/asm/kexec.h
@@ -19,12 +19,24 @@
#include <asm/page.h>
+#ifndef __tilegx__
/* Maximum physical address we can use pages from. */
#define KEXEC_SOURCE_MEMORY_LIMIT TASK_SIZE
/* Maximum address we can reach in physical address mode. */
#define KEXEC_DESTINATION_MEMORY_LIMIT TASK_SIZE
/* Maximum address we can use for the control code buffer. */
#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+#else
+/* We need to limit the memory below PGDIR_SIZE since
+ * we only setup page table for [0, PGDIR_SIZE) before final kexec.
+ */
+/* Maximum physical address we can use pages from. */
+#define KEXEC_SOURCE_MEMORY_LIMIT PGDIR_SIZE
+/* Maximum address we can reach in physical address mode. */
+#define KEXEC_DESTINATION_MEMORY_LIMIT PGDIR_SIZE
+/* Maximum address we can use for the control code buffer. */
+#define KEXEC_CONTROL_MEMORY_LIMIT PGDIR_SIZE
+#endif
#define KEXEC_CONTROL_PAGE_SIZE PAGE_SIZE
diff --git a/arch/tile/include/asm/mmu.h b/arch/tile/include/asm/mmu.h
index 92f94c77b6e4..e2c789096795 100644
--- a/arch/tile/include/asm/mmu.h
+++ b/arch/tile/include/asm/mmu.h
@@ -21,7 +21,7 @@ struct mm_context {
* Written under the mmap_sem semaphore; read without the
* semaphore but atomically, but it is conservatively set.
*/
- unsigned int priority_cached;
+ unsigned long priority_cached;
};
typedef 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 15fb24641120..37f0b741dee7 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)
return 0;
}
-/* Note that arch/tile/kernel/head.S also calls hv_install_context() */
+/*
+ * Note that arch/tile/kernel/head_NN.S and arch/tile/mm/migrate_NN.S
+ * also call hv_install_context().
+ */
static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot)
{
/* FIXME: DIRECTIO should not always be set. FIXME. */
- int rc = hv_install_context(__pa(pgdir), prot, asid, HV_CTX_DIRECTIO);
+ int rc = hv_install_context(__pa(pgdir), prot, asid,
+ HV_CTX_DIRECTIO | CTX_PAGE_FLAG);
if (rc < 0)
panic("hv_install_context failed: %d", rc);
}
diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h
new file mode 100644
index 000000000000..44ed07ccd3d2
--- /dev/null
+++ b/arch/tile/include/asm/module.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_MODULE_H
+#define _ASM_TILE_MODULE_H
+
+#include <arch/chip.h>
+
+#include <asm-generic/module.h>
+
+/* We can't use modules built with different page sizes. */
+#if defined(CONFIG_PAGE_SIZE_16KB)
+# define MODULE_PGSZ " 16KB"
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+# define MODULE_PGSZ " 64KB"
+#else
+# define MODULE_PGSZ ""
+#endif
+
+/* We don't really support no-SMP so tag if someone tries. */
+#ifdef CONFIG_SMP
+#define MODULE_NOSMP ""
+#else
+#define MODULE_NOSMP " nosmp"
+#endif
+
+#define MODULE_ARCH_VERMAGIC CHIP_ARCH_NAME MODULE_PGSZ MODULE_NOSMP
+
+#endif /* _ASM_TILE_MODULE_H */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
index db93518fac03..9d9131e5c552 100644
--- a/arch/tile/include/asm/page.h
+++ b/arch/tile/include/asm/page.h
@@ -20,8 +20,17 @@
#include <arch/chip.h>
/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
-#define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
-#define HPAGE_SHIFT HV_LOG2_PAGE_SIZE_LARGE
+#if defined(CONFIG_PAGE_SIZE_16KB)
+#define PAGE_SHIFT 14
+#define CTX_PAGE_FLAG HV_CTX_PG_SM_16K
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+#define PAGE_SHIFT 16
+#define CTX_PAGE_FLAG HV_CTX_PG_SM_64K
+#else
+#define PAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_SMALL
+#define CTX_PAGE_FLAG 0
+#endif
+#define HPAGE_SHIFT HV_LOG2_DEFAULT_PAGE_SIZE_LARGE
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
@@ -78,8 +87,7 @@ typedef HV_PTE pgprot_t;
/*
* User L2 page tables are managed as one L2 page table per page,
* because we use the page allocator for them. This keeps the allocation
- * simple and makes it potentially useful to implement HIGHPTE at some point.
- * However, it's also inefficient, since L2 page tables are much smaller
+ * simple, but it's also inefficient, since L2 page tables are much smaller
* than pages (currently 2KB vs 64KB). So we should revisit this.
*/
typedef struct page *pgtable_t;
@@ -128,7 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size)
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
-#define HUGE_MAX_HSTATE 2
+#define HUGE_MAX_HSTATE 6
#ifdef CONFIG_HUGETLB_PAGE
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h
index e919c0bdc22d..1b902508b664 100644
--- a/arch/tile/include/asm/pgalloc.h
+++ b/arch/tile/include/asm/pgalloc.h
@@ -19,24 +19,24 @@
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <asm/fixmap.h>
+#include <asm/page.h>
#include <hv/hypervisor.h>
/* Bits for the size of the second-level page table. */
-#define L2_KERNEL_PGTABLE_SHIFT \
- (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL + HV_LOG2_PTE_SIZE)
+#define L2_KERNEL_PGTABLE_SHIFT _HV_LOG2_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
+
+/* How big is a kernel L2 page table? */
+#define L2_KERNEL_PGTABLE_SIZE (1UL << L2_KERNEL_PGTABLE_SHIFT)
/* We currently allocate user L2 page tables by page (unlike kernel L2s). */
-#if L2_KERNEL_PGTABLE_SHIFT < HV_LOG2_PAGE_SIZE_SMALL
-#define L2_USER_PGTABLE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
+#if L2_KERNEL_PGTABLE_SHIFT < PAGE_SHIFT
+#define L2_USER_PGTABLE_SHIFT PAGE_SHIFT
#else
#define L2_USER_PGTABLE_SHIFT L2_KERNEL_PGTABLE_SHIFT
#endif
/* How many pages do we need, as an "order", for a user L2 page table? */
-#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - HV_LOG2_PAGE_SIZE_SMALL)
-
-/* How big is a kernel L2 page table? */
-#define L2_KERNEL_PGTABLE_SIZE (1 << L2_KERNEL_PGTABLE_SHIFT)
+#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - PAGE_SHIFT)
static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
{
@@ -50,14 +50,14 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *ptep)
{
- set_pmd(pmd, ptfn_pmd(__pa(ptep) >> HV_LOG2_PAGE_TABLE_ALIGN,
+ set_pmd(pmd, ptfn_pmd(HV_CPA_TO_PTFN(__pa(ptep)),
__pgprot(_PAGE_PRESENT)));
}
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
pgtable_t page)
{
- set_pmd(pmd, ptfn_pmd(HV_PFN_TO_PTFN(page_to_pfn(page)),
+ set_pmd(pmd, ptfn_pmd(HV_CPA_TO_PTFN(PFN_PHYS(page_to_pfn(page))),
__pgprot(_PAGE_PRESENT)));
}
@@ -68,8 +68,20 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
extern pgd_t *pgd_alloc(struct mm_struct *mm);
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
-extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
-extern void pte_free(struct mm_struct *mm, struct page *pte);
+extern pgtable_t pgtable_alloc_one(struct mm_struct *mm, unsigned long address,
+ int order);
+extern void pgtable_free(struct mm_struct *mm, struct page *pte, int order);
+
+static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ return pgtable_alloc_one(mm, address, L2_USER_PGTABLE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, struct page *pte)
+{
+ pgtable_free(mm, pte, L2_USER_PGTABLE_ORDER);
+}
#define pmd_pgtable(pmd) pmd_page(pmd)
@@ -85,8 +97,13 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
pte_free(mm, virt_to_page(pte));
}
-extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
- unsigned long address);
+extern void __pgtable_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address, int order);
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address)
+{
+ __pgtable_free_tlb(tlb, pte, address, L2_USER_PGTABLE_ORDER);
+}
#define check_pgt_cache() do { } while (0)
@@ -104,19 +121,44 @@ void shatter_pmd(pmd_t *pmd);
void shatter_huge_page(unsigned long addr);
#ifdef __tilegx__
-/* We share a single page allocator for both L1 and L2 page tables. */
-#if HV_L1_SIZE != HV_L2_SIZE
-# error Rework assumption that L1 and L2 page tables are same size.
-#endif
-#define L1_USER_PGTABLE_ORDER L2_USER_PGTABLE_ORDER
+
#define pud_populate(mm, pud, pmd) \
pmd_populate_kernel((mm), (pmd_t *)(pud), (pte_t *)(pmd))
-#define pmd_alloc_one(mm, addr) \
- ((pmd_t *)page_to_virt(pte_alloc_one((mm), (addr))))
-#define pmd_free(mm, pmdp) \
- pte_free((mm), virt_to_page(pmdp))
-#define __pmd_free_tlb(tlb, pmdp, address) \
- __pte_free_tlb((tlb), virt_to_page(pmdp), (address))
+
+/* Bits for the size of the L1 (intermediate) page table. */
+#define L1_KERNEL_PGTABLE_SHIFT _HV_LOG2_L1_SIZE(HPAGE_SHIFT)
+
+/* How big is a kernel L2 page table? */
+#define L1_KERNEL_PGTABLE_SIZE (1UL << L1_KERNEL_PGTABLE_SHIFT)
+
+/* We currently allocate L1 page tables by page. */
+#if L1_KERNEL_PGTABLE_SHIFT < PAGE_SHIFT
+#define L1_USER_PGTABLE_SHIFT PAGE_SHIFT
+#else
+#define L1_USER_PGTABLE_SHIFT L1_KERNEL_PGTABLE_SHIFT
#endif
+/* How many pages do we need, as an "order", for an L1 page table? */
+#define L1_USER_PGTABLE_ORDER (L1_USER_PGTABLE_SHIFT - PAGE_SHIFT)
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ struct page *p = pgtable_alloc_one(mm, address, L1_USER_PGTABLE_ORDER);
+ return (pmd_t *)page_to_virt(p);
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmdp)
+{
+ pgtable_free(mm, virt_to_page(pmdp), L1_USER_PGTABLE_ORDER);
+}
+
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
+ unsigned long address)
+{
+ __pgtable_free_tlb(tlb, virt_to_page(pmdp), address,
+ L1_USER_PGTABLE_ORDER);
+}
+
+#endif /* __tilegx__ */
+
#endif /* _ASM_TILE_PGALLOC_H */
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
index 67490910774d..73b1a4c9ad03 100644
--- a/arch/tile/include/asm/pgtable.h
+++ b/arch/tile/include/asm/pgtable.h
@@ -27,8 +27,10 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
+#include <linux/pfn.h>
#include <asm/processor.h>
#include <asm/fixmap.h>
+#include <asm/page.h>
struct mm_struct;
struct vm_area_struct;
@@ -69,6 +71,7 @@ extern void set_page_homes(void);
#define _PAGE_PRESENT HV_PTE_PRESENT
#define _PAGE_HUGE_PAGE HV_PTE_PAGE
+#define _PAGE_SUPER_PAGE HV_PTE_SUPER
#define _PAGE_READABLE HV_PTE_READABLE
#define _PAGE_WRITABLE HV_PTE_WRITABLE
#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE
@@ -85,6 +88,7 @@ extern void set_page_homes(void);
#define _PAGE_ALL (\
_PAGE_PRESENT | \
_PAGE_HUGE_PAGE | \
+ _PAGE_SUPER_PAGE | \
_PAGE_READABLE | \
_PAGE_WRITABLE | \
_PAGE_EXECUTABLE | \
@@ -162,7 +166,7 @@ extern void set_page_homes(void);
(pgprot_t) { ((oldprot).val & ~_PAGE_ALL) | (newprot).val }
/* Just setting the PFN to zero suffices. */
-#define pte_pgprot(x) hv_pte_set_pfn((x), 0)
+#define pte_pgprot(x) hv_pte_set_pa((x), 0)
/*
* For PTEs and PDEs, we must clear the Present bit first when
@@ -187,6 +191,7 @@ static inline void __pte_clear(pte_t *ptep)
* Undefined behaviour if not..
*/
#define pte_present hv_pte_get_present
+#define pte_mknotpresent hv_pte_clear_present
#define pte_user hv_pte_get_user
#define pte_read hv_pte_get_readable
#define pte_dirty hv_pte_get_dirty
@@ -194,6 +199,7 @@ static inline void __pte_clear(pte_t *ptep)
#define pte_write hv_pte_get_writable
#define pte_exec hv_pte_get_executable
#define pte_huge hv_pte_get_page
+#define pte_super hv_pte_get_super
#define pte_rdprotect hv_pte_clear_readable
#define pte_exprotect hv_pte_clear_executable
#define pte_mkclean hv_pte_clear_dirty
@@ -206,6 +212,7 @@ static inline void __pte_clear(pte_t *ptep)
#define pte_mkyoung hv_pte_set_accessed
#define pte_mkwrite hv_pte_set_writable
#define pte_mkhuge hv_pte_set_page
+#define pte_mksuper hv_pte_set_super
#define pte_special(pte) 0
#define pte_mkspecial(pte) (pte)
@@ -261,7 +268,7 @@ static inline int pte_none(pte_t pte)
static inline unsigned long pte_pfn(pte_t pte)
{
- return hv_pte_get_pfn(pte);
+ return PFN_DOWN(hv_pte_get_pa(pte));
}
/* 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);
static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
{
- return hv_pte_set_pfn(prot, pfn);
+ return hv_pte_set_pa(prot, PFN_PHYS(pfn));
}
/* Support for priority mappings. */
@@ -312,7 +319,7 @@ extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next);
*/
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
- return pfn_pte(hv_pte_get_pfn(pte), newprot);
+ return pfn_pte(pte_pfn(pte), newprot);
}
/*
@@ -335,13 +342,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*/
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-#if defined(CONFIG_HIGHPTE)
-extern pte_t *pte_offset_map(pmd_t *, unsigned long address);
-#define pte_unmap(pte) kunmap_atomic(pte)
-#else
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
#define pte_unmap(pte) do { } while (0)
-#endif
/* Clear a non-executable kernel PTE and flush it from the TLB. */
#define kpte_clear_flush(ptep, vaddr) \
@@ -410,6 +412,46 @@ static inline unsigned long pmd_index(unsigned long address)
return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
}
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address,
+ pmd_t *pmdp)
+{
+ return ptep_test_and_clear_young(vma, address, pmdp_ptep(pmdp));
+}
+
+#define __HAVE_ARCH_PMDP_SET_WRPROTECT
+static inline void pmdp_set_wrprotect(struct mm_struct *mm,
+ unsigned long address, pmd_t *pmdp)
+{
+ ptep_set_wrprotect(mm, address, pmdp_ptep(pmdp));
+}
+
+
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+ unsigned long address,
+ pmd_t *pmdp)
+{
+ return pte_pmd(ptep_get_and_clear(mm, address, pmdp_ptep(pmdp)));
+}
+
+static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
+{
+ set_pte(pmdp_ptep(pmdp), pmd_pte(pmdval));
+}
+
+#define set_pmd_at(mm, addr, pmdp, pmdval) __set_pmd(pmdp, pmdval)
+
+/* Create a pmd from a PTFN. */
+static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
+{
+ return pte_pmd(hv_pte_set_ptfn(prot, ptfn));
+}
+
+/* Return the page-table frame number (ptfn) that a pmd_t points at. */
+#define pmd_ptfn(pmd) hv_pte_get_ptfn(pmd_pte(pmd))
+
/*
* A given kernel pmd_t maps to a specific virtual address (either a
* 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)
* OK for pte_lockptr(), since we just end up with potentially one
* lock being used for several pte_t arrays.
*/
-#define pmd_page(pmd) pfn_to_page(HV_PTFN_TO_PFN(pmd_ptfn(pmd)))
+#define pmd_page(pmd) pfn_to_page(PFN_DOWN(HV_PTFN_TO_CPA(pmd_ptfn(pmd))))
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ __pte_clear(pmdp_ptep(pmdp));
+}
+
+#define pmd_mknotpresent(pmd) pte_pmd(pte_mknotpresent(pmd_pte(pmd)))
+#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
+#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+#define pmd_write(pmd) pte_write(pmd_pte(pmd))
+#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_huge_page(pmd) pte_huge(pmd_pte(pmd))
+#define pmd_mkhuge(pmd) pte_pmd(pte_mkhuge(pmd_pte(pmd)))
+#define __HAVE_ARCH_PMD_WRITE
+
+#define pfn_pmd(pfn, pgprot) pte_pmd(pfn_pte((pfn), (pgprot)))
+#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
+#define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot))
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+ return pfn_pmd(pmd_pfn(pmd), newprot);
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define has_transparent_hugepage() 1
+#define pmd_trans_huge pmd_huge_page
+
+static inline pmd_t pmd_mksplitting(pmd_t pmd)
+{
+ return pte_pmd(hv_pte_set_client2(pmd_pte(pmd)));
+}
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+ return hv_pte_get_client2(pmd_pte(pmd));
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
/*
* 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)
return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
}
-static inline int pmd_huge_page(pmd_t pmd)
-{
- return pmd_val(pmd) & _PAGE_HUGE_PAGE;
-}
-
#include <asm-generic/pgtable.h>
/* Support /proc/NN/pgtable API. */
struct seq_file;
int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
- unsigned long vaddr, pte_t *ptep, void **datap);
+ unsigned long vaddr, unsigned long pagesize,
+ pte_t *ptep, void **datap);
#endif /* !__ASSEMBLY__ */
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h
index 9f98529761fd..4ce4a7a99c24 100644
--- a/arch/tile/include/asm/pgtable_32.h
+++ b/arch/tile/include/asm/pgtable_32.h
@@ -20,11 +20,12 @@
* The level-1 index is defined by the huge page size. A PGD is composed
* of PTRS_PER_PGD pgd_t's and is the top level of the page table.
*/
-#define PGDIR_SHIFT HV_LOG2_PAGE_SIZE_LARGE
-#define PGDIR_SIZE HV_PAGE_SIZE_LARGE
+#define PGDIR_SHIFT HPAGE_SHIFT
+#define PGDIR_SIZE HPAGE_SIZE
#define PGDIR_MASK (~(PGDIR_SIZE-1))
-#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
-#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t))
+#define PTRS_PER_PGD _HV_L1_ENTRIES(HPAGE_SHIFT)
+#define PGD_INDEX(va) _HV_L1_INDEX(va, HPAGE_SHIFT)
+#define SIZEOF_PGD _HV_L1_SIZE(HPAGE_SHIFT)
/*
* The level-2 index is defined by the difference between the huge
@@ -33,8 +34,9 @@
* Note that the hypervisor docs use PTE for what we call pte_t, so
* this nomenclature is somewhat confusing.
*/
-#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
-#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t))
+#define PTRS_PER_PTE _HV_L2_ENTRIES(HPAGE_SHIFT, PAGE_SHIFT)
+#define PTE_INDEX(va) _HV_L2_INDEX(va, HPAGE_SHIFT, PAGE_SHIFT)
+#define SIZEOF_PTE _HV_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
#ifndef __ASSEMBLY__
@@ -111,24 +113,14 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
return pte;
}
-static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
-{
- set_pte(&pmdp->pud.pgd, pmdval.pud.pgd);
-}
-
-/* Create a pmd from a PTFN. */
-static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
-{
- return (pmd_t){ { hv_pte_set_ptfn(prot, ptfn) } };
-}
-
-/* Return the page-table frame number (ptfn) that a pmd_t points at. */
-#define pmd_ptfn(pmd) hv_pte_get_ptfn((pmd).pud.pgd)
-
-static inline void pmd_clear(pmd_t *pmdp)
-{
- __pte_clear(&pmdp->pud.pgd);
-}
+/*
+ * pmds are wrappers around pgds, which are the same as ptes.
+ * It's often convenient to "cast" back and forth and use the pte methods,
+ * which are the methods supplied by the hypervisor.
+ */
+#define pmd_pte(pmd) ((pmd).pud.pgd)
+#define pmdp_ptep(pmdp) (&(pmdp)->pud.pgd)
+#define pte_pmd(pte) ((pmd_t){ { (pte) } })
#endif /* __ASSEMBLY__ */
diff --git a/arch/tile/include/asm/pgtable_64.h b/arch/tile/include/asm/pgtable_64.h
index fd80328523b4..2492fa5478e7 100644
--- a/arch/tile/include/asm/pgtable_64.h
+++ b/arch/tile/include/asm/pgtable_64.h
@@ -21,17 +21,19 @@
#define PGDIR_SIZE HV_L1_SPAN
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD HV_L0_ENTRIES
-#define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t))
+#define PGD_INDEX(va) HV_L0_INDEX(va)
+#define SIZEOF_PGD HV_L0_SIZE
/*
* The level-1 index is defined by the huge page size. A PMD is composed
* of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
*/
-#define PMD_SHIFT HV_LOG2_PAGE_SIZE_LARGE
-#define PMD_SIZE HV_PAGE_SIZE_LARGE
+#define PMD_SHIFT HPAGE_SHIFT
+#define PMD_SIZE HPAGE_SIZE
#define PMD_MASK (~(PMD_SIZE-1))
-#define PTRS_PER_PMD (1 << (PGDIR_SHIFT - PMD_SHIFT))
-#define SIZEOF_PMD (PTRS_PER_PMD * sizeof(pmd_t))
+#define PTRS_PER_PMD _HV_L1_ENTRIES(HPAGE_SHIFT)
+#define PMD_INDEX(va) _HV_L1_INDEX(va, HPAGE_SHIFT)
+#define SIZEOF_PMD _HV_L1_SIZE(HPAGE_SHIFT)
/*
* The level-2 index is defined by the difference between the huge
@@ -40,17 +42,19 @@
* Note that the hypervisor docs use PTE for what we call pte_t, so
* this nomenclature is somewhat confusing.
*/
-#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
-#define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t))
+#define PTRS_PER_PTE _HV_L2_ENTRIES(HPAGE_SHIFT, PAGE_SHIFT)
+#define PTE_INDEX(va) _HV_L2_INDEX(va, HPAGE_SHIFT, PAGE_SHIFT)
+#define SIZEOF_PTE _HV_L2_SIZE(HPAGE_SHIFT, PAGE_SHIFT)
/*
- * Align the vmalloc area to an L2 page table, and leave a guard page
- * at the beginning and end. The vmalloc code also puts in an internal
+ * Align the vmalloc area to an L2 page table. Omit guard pages at
+ * the beginning and end for simplicity (particularly in the per-cpu
+ * memory allocation code). The vmalloc code puts in an internal
* guard page between each allocation.
*/
#define _VMALLOC_END HUGE_VMAP_BASE
-#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE)
-#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE)
+#define VMALLOC_END _VMALLOC_END
+#define VMALLOC_START _VMALLOC_START
#define HUGE_VMAP_END (HUGE_VMAP_BASE + PGDIR_SIZE)
@@ -98,7 +102,7 @@ static inline int pud_bad(pud_t pud)
* A pud_t points to a pmd_t array. Since we can have multiple per
* page, we don't have a one-to-one mapping of pud_t's to pages.
*/
-#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud)))
+#define pud_page(pud) pfn_to_page(PFN_DOWN(HV_PTFN_TO_CPA(pud_ptfn(pud))))
static inline unsigned long pud_index(unsigned long address)
{
@@ -108,28 +112,6 @@ static inline unsigned long pud_index(unsigned long address)
#define pmd_offset(pud, address) \
((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
-static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
-{
- set_pte(pmdp, pmdval);
-}
-
-/* Create a pmd from a PTFN and pgprot. */
-static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
-{
- return hv_pte_set_ptfn(prot, ptfn);
-}
-
-/* Return the page-table frame number (ptfn) that a pmd_t points at. */
-static inline unsigned long pmd_ptfn(pmd_t pmd)
-{
- return hv_pte_get_ptfn(pmd);
-}
-
-static inline void pmd_clear(pmd_t *pmdp)
-{
- __pte_clear(pmdp);
-}
-
/* Normalize an address to having the correct high bits set. */
#define pgd_addr_normalize pgd_addr_normalize
static 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,
return hv_pte(__insn_exch(&ptep->val, 0UL));
}
+/*
+ * pmds are the same as pgds and ptes, so converting is a no-op.
+ */
+#define pmd_pte(pmd) (pmd)
+#define pmdp_ptep(pmdp) (pmdp)
+#define pte_pmd(pte) (pte)
+
#endif /* __ASSEMBLY__ */
#endif /* _ASM_TILE_PGTABLE_64_H */
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
index 15cd8a4a06ce..8c4dd9ff91eb 100644
--- a/arch/tile/include/asm/processor.h
+++ b/arch/tile/include/asm/processor.h
@@ -76,6 +76,17 @@ struct async_tlb {
#ifdef CONFIG_HARDWALL
struct hardwall_info;
+struct hardwall_task {
+ /* Which hardwall is this task tied to? (or NULL if none) */
+ struct hardwall_info *info;
+ /* Chains this task into the list at info->task_head. */
+ struct list_head list;
+};
+#ifdef __tilepro__
+#define HARDWALL_TYPES 1 /* udn */
+#else
+#define HARDWALL_TYPES 3 /* udn, idn, and ipi */
+#endif
#endif
struct thread_struct {
@@ -116,10 +127,8 @@ struct thread_struct {
unsigned long dstream_pf;
#endif
#ifdef CONFIG_HARDWALL
- /* Is this task tied to an activated hardwall? */
- struct hardwall_info *hardwall;
- /* Chains this task into the list at hardwall->list. */
- struct list_head hardwall_list;
+ /* Hardwall information for various resources. */
+ struct hardwall_task hardwall[HARDWALL_TYPES];
#endif
#if CHIP_HAS_TILE_DMA()
/* Async DMA TLB fault information */
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
index e58613e0752f..c67eb70ea78e 100644
--- a/arch/tile/include/asm/setup.h
+++ b/arch/tile/include/asm/setup.h
@@ -41,15 +41,15 @@ void restrict_dma_mpls(void);
#ifdef CONFIG_HARDWALL
/* User-level network management functions */
void reset_network_state(void);
-void grant_network_mpls(void);
-void restrict_network_mpls(void);
struct task_struct;
-int hardwall_deactivate(struct task_struct *task);
+void hardwall_switch_tasks(struct task_struct *prev, struct task_struct *next);
+void hardwall_deactivate_all(struct task_struct *task);
+int hardwall_ipi_valid(int cpu);
/* Hook hardwall code into changes in affinity. */
#define arch_set_cpus_allowed(p, new_mask) do { \
- if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \
- hardwall_deactivate(p); \
+ if (!cpumask_equal(&p->cpus_allowed, new_mask)) \
+ hardwall_deactivate_all(p); \
} while (0)
#endif
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h
index 3b5507c31eae..06f0464cfed9 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,
u32 len, int advice);
int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi, int advice);
-long sys_flush_cache(void);
+long sys_cacheflush(unsigned long addr, unsigned long len,
+ unsigned long flags);
#ifndef __tilegx__ /* No mmap() in the 32-bit kernel. */
#define sys_mmap sys_mmap
#endif
diff --git a/arch/tile/include/asm/tlbflush.h b/arch/tile/include/asm/tlbflush.h
index 96199d214fb8..dcf91b25a1e5 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);
/* The hypervisor tells us what ASIDs are available to us. */
extern int min_asid, max_asid;
-static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
-{
- return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
-}
-
/* Pass as vma pointer for non-executable mapping, if no vma available. */
-#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL)
+#define FLUSH_NONEXEC ((struct vm_area_struct *)-1UL)
/* Flush a single user page on this cpu. */
-static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
+static inline void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr,
unsigned long page_size)
{
@@ -60,7 +55,7 @@ static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
}
/* Flush range of user pages on this cpu. */
-static inline void local_flush_tlb_pages(const struct vm_area_struct *vma,
+static inline void local_flush_tlb_pages(struct vm_area_struct *vma,
unsigned long addr,
unsigned long page_size,
unsigned long len)
@@ -117,10 +112,10 @@ extern void flush_tlb_all(void);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void flush_tlb_current_task(void);
extern void flush_tlb_mm(struct mm_struct *);
-extern void flush_tlb_page(const struct vm_area_struct *, unsigned long);
-extern void flush_tlb_page_mm(const struct vm_area_struct *,
+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+extern void flush_tlb_page_mm(struct vm_area_struct *,
struct mm_struct *, unsigned long);
-extern void flush_tlb_range(const struct vm_area_struct *,
+extern void flush_tlb_range(struct vm_area_struct *,
unsigned long start, unsigned long end);
#define flush_tlb() flush_tlb_current_task()
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
index ef34d2caa5b1..c3dd275f25e2 100644
--- a/arch/tile/include/asm/uaccess.h
+++ b/arch/tile/include/asm/uaccess.h
@@ -114,45 +114,75 @@ struct exception_table_entry {
extern int fixup_exception(struct pt_regs *regs);
/*
- * We return the __get_user_N function results in a structure,
- * thus in r0 and r1. If "err" is zero, "val" is the result
- * of the read; otherwise, "err" is -EFAULT.
- *
- * We rarely need 8-byte values on a 32-bit architecture, but
- * we size the structure to accommodate. In practice, for the
- * the smaller reads, we can zero the high word for free, and
- * the caller will ignore it by virtue of casting anyway.
+ * Support macros for __get_user().
+ *
+ * Implementation note: The "case 8" logic of casting to the type of
+ * the result of subtracting the value from itself is basically a way
+ * of keeping all integer types the same, but casting any pointers to
+ * ptrdiff_t, i.e. also an integer type. This way there are no
+ * questionable casts seen by the compiler on an ILP32 platform.
+ *
+ * Note that __get_user() and __put_user() assume proper alignment.
*/
-struct __get_user {
- unsigned long long val;
- int err;
-};
-/*
- * FIXME: we should express these as inline extended assembler, since
- * they're fundamentally just a variable dereference and some
- * supporting exception_table gunk. Note that (a la i386) we can
- * extend the copy_to_user and copy_from_user routines to call into
- * such extended assembler routines, though we will have to use a
- * different return code in that case (1, 2, or 4, rather than -EFAULT).
- */
-extern struct __get_user __get_user_1(const void __user *);
-extern struct __get_user __get_user_2(const void __user *);
-extern struct __get_user __get_user_4(const void __user *);
-extern struct __get_user __get_user_8(const void __user *);
-extern int __put_user_1(long, void __user *);
-extern int __put_user_2(long, void __user *);
-extern int __put_user_4(long, void __user *);
-extern int __put_user_8(long long, void __user *);
-
-/* Unimplemented routines to cause linker failures */
-extern struct __get_user __get_user_bad(void);
-extern int __put_user_bad(void);
+#ifdef __LP64__
+#define _ASM_PTR ".quad"
+#else
+#define _ASM_PTR ".long"
+#endif
+
+#define __get_user_asm(OP, x, ptr, ret) \
+ asm volatile("1: {" #OP " %1, %2; movei %0, 0 }\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "0: { movei %1, 0; movei %0, %3 }\n" \
+ "j 9f\n" \
+ ".section __ex_table,\"a\"\n" \
+ _ASM_PTR " 1b, 0b\n" \
+ ".popsection\n" \
+ "9:" \
+ : "=r" (ret), "=r" (x) \
+ : "r" (ptr), "i" (-EFAULT))
+
+#ifdef __tilegx__
+#define __get_user_1(x, ptr, ret) __get_user_asm(ld1u, x, ptr, ret)
+#define __get_user_2(x, ptr, ret) __get_user_asm(ld2u, x, ptr, ret)
+#define __get_user_4(x, ptr, ret) __get_user_asm(ld4u, x, ptr, ret)
+#define __get_user_8(x, ptr, ret) __get_user_asm(ld, x, ptr, ret)
+#else
+#define __get_user_1(x, ptr, ret) __get_user_asm(lb_u, x, ptr, ret)
+#define __get_user_2(x, ptr, ret) __get_user_asm(lh_u, x, ptr, ret)
+#define __get_user_4(x, ptr, ret) __get_user_asm(lw, x, ptr, ret)
+#ifdef __LITTLE_ENDIAN
+#define __lo32(a, b) a
+#define __hi32(a, b) b
+#else
+#define __lo32(a, b) b
+#define __hi32(a, b) a
+#endif
+#define __get_user_8(x, ptr, ret) \
+ ({ \
+ unsigned int __a, __b; \
+ asm volatile("1: { lw %1, %3; addi %2, %3, 4 }\n" \
+ "2: { lw %2, %2; movei %0, 0 }\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "0: { movei %1, 0; movei %2, 0 }\n" \
+ "{ movei %0, %4; j 9f }\n" \
+ ".section __ex_table,\"a\"\n" \
+ ".word 1b, 0b\n" \
+ ".word 2b, 0b\n" \
+ ".popsection\n" \
+ "9:" \
+ : "=r" (ret), "=r" (__a), "=&r" (__b) \
+ : "r" (ptr), "i" (-EFAULT)); \
+ (x) = (__typeof(x))(__typeof((x)-(x))) \
+ (((u64)__hi32(__a, __b) << 32) | \
+ __lo32(__a, __b)); \
+ })
+#endif
+
+extern int __get_user_bad(void)
+ __attribute__((warning("sizeof __get_user argument not 1, 2, 4 or 8")));
-/*
- * Careful: we have to cast the result to the type of the pointer
- * for sign reasons.
- */
/**
* __get_user: - Get a simple variable from user space, with less checking.
* @x: Variable to store result.
@@ -174,30 +204,62 @@ extern int __put_user_bad(void);
* function.
*/
#define __get_user(x, ptr) \
-({ struct __get_user __ret; \
- __typeof__(*(ptr)) const __user *__gu_addr = (ptr); \
- __chk_user_ptr(__gu_addr); \
- switch (sizeof(*(__gu_addr))) { \
- case 1: \
- __ret = __get_user_1(__gu_addr); \
- break; \
- case 2: \
- __ret = __get_user_2(__gu_addr); \
- break; \
- case 4: \
- __ret = __get_user_4(__gu_addr); \
- break; \
- case 8: \
- __ret = __get_user_8(__gu_addr); \
- break; \
- default: \
- __ret = __get_user_bad(); \
- break; \
- } \
- (x) = (__typeof__(*__gu_addr)) (__typeof__(*__gu_addr - *__gu_addr)) \
- __ret.val; \
- __ret.err; \
-})
+ ({ \
+ int __ret; \
+ __chk_user_ptr(ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: __get_user_1(x, ptr, __ret); break; \
+ case 2: __get_user_2(x, ptr, __ret); break; \
+ case 4: __get_user_4(x, ptr, __ret); break; \
+ case 8: __get_user_8(x, ptr, __ret); break; \
+ default: __ret = __get_user_bad(); break; \
+ } \
+ __ret; \
+ })
+
+/* Support macros for __put_user(). */
+
+#define __put_user_asm(OP, x, ptr, ret) \
+ asm volatile("1: {" #OP " %1, %2; movei %0, 0 }\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "0: { movei %0, %3; j 9f }\n" \
+ ".section __ex_table,\"a\"\n" \
+ _ASM_PTR " 1b, 0b\n" \
+ ".popsection\n" \
+ "9:" \
+ : "=r" (ret) \
+ : "r" (ptr), "r" (x), "i" (-EFAULT))
+
+#ifdef __tilegx__
+#define __put_user_1(x, ptr, ret) __put_user_asm(st1, x, ptr, ret)
+#define __put_user_2(x, ptr, ret) __put_user_asm(st2, x, ptr, ret)
+#define __put_user_4(x, ptr, ret) __put_user_asm(st4, x, ptr, ret)
+#define __put_user_8(x, ptr, ret) __put_user_asm(st, x, ptr, ret)
+#else
+#define __put_user_1(x, ptr, ret) __put_user_asm(sb, x, ptr, ret)
+#define __put_user_2(x, ptr, ret) __put_user_asm(sh, x, ptr, ret)
+#define __put_user_4(x, ptr, ret) __put_user_asm(sw, x, ptr, ret)
+#define __put_user_8(x, ptr, ret) \
+ ({ \
+ u64 __x = (__typeof((x)-(x)))(x); \
+ int __lo = (int) __x, __hi = (int) (__x >> 32); \
+ asm volatile("1: { sw %1, %2; addi %0, %1, 4 }\n" \
+ "2: { sw %0, %3; movei %0, 0 }\n" \
+ ".pushsection .fixup,\"ax\"\n" \
+ "0: { movei %0, %4; j 9f }\n" \
+ ".section __ex_table,\"a\"\n" \
+ ".word 1b, 0b\n" \
+ ".word 2b, 0b\n" \
+ ".popsection\n" \
+ "9:" \
+ : "=&r" (ret) \
+ : "r" (ptr), "r" (__lo32(__lo, __hi)), \
+ "r" (__hi32(__lo, __hi)), "i" (-EFAULT)); \
+ })
+#endif
+
+extern int __put_user_bad(void)
+ __attribute__((warning("sizeof __put_user argument not 1, 2, 4 or 8")));
/**
* __put_user: - Write a simple value into user space, with less checking.
@@ -217,39 +279,19 @@ extern int __put_user_bad(void);
* function.
*
* Returns zero on success, or -EFAULT on error.
- *
- * Implementation note: The "case 8" logic of casting to the type of
- * the result of subtracting the value from itself is basically a way
- * of keeping all integer types the same, but casting any pointers to
- * ptrdiff_t, i.e. also an integer type. This way there are no
- * questionable casts seen by the compiler on an ILP32 platform.
*/
#define __put_user(x, ptr) \
({ \
- int __pu_err = 0; \
- __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
- typeof(*__pu_addr) __pu_val = (x); \
- __chk_user_ptr(__pu_addr); \
- switch (sizeof(__pu_val)) { \
- case 1: \
- __pu_err = __put_user_1((long)__pu_val, __pu_addr); \
- break; \
- case 2: \
- __pu_err = __put_user_2((long)__pu_val, __pu_addr); \
- break; \
- case 4: \
- __pu_err = __put_user_4((long)__pu_val, __pu_addr); \
- break; \
- case 8: \
- __pu_err = \
- __put_user_8((__typeof__(__pu_val - __pu_val))__pu_val,\
- __pu_addr); \
- break; \
- default: \
- __pu_err = __put_user_bad(); \
- break; \
+ int __ret; \
+ __chk_user_ptr(ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: __put_user_1(x, ptr, __ret); break; \
+ case 2: __put_user_2(x, ptr, __ret); break; \
+ case 4: __put_user_4(x, ptr, __ret); break; \
+ case 8: __put_user_8(x, ptr, __ret); break; \
+ default: __ret = __put_user_bad(); break; \
} \
- __pu_err; \
+ __ret; \
})
/*
@@ -378,7 +420,7 @@ static inline unsigned long __must_check copy_from_user(void *to,
/**
* __copy_in_user() - copy data within user space, with less checking.
* @to: Destination address, in user space.
- * @from: Source address, in kernel space.
+ * @from: Source address, in user space.
* @n: Number of bytes to copy.
*
* 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 f70bf1c541f1..a017246ca0ce 100644
--- a/arch/tile/include/asm/unistd.h
+++ b/arch/tile/include/asm/unistd.h
@@ -24,8 +24,8 @@
#include <asm-generic/unistd.h>
/* Additional Tilera-specific syscalls. */
-#define __NR_flush_cache (__NR_arch_specific_syscall + 1)
-__SYSCALL(__NR_flush_cache, sys_flush_cache)
+#define __NR_cacheflush (__NR_arch_specific_syscall + 1)
+__SYSCALL(__NR_cacheflush, sys_cacheflush)
#ifndef __tilegx__
/* "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 f13188ac281a..2a20b266d944 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;
* linux's "MAX_SKB_FRAGS", and presumably over-estimates by one, for
* our page size of exactly 65536. We add one for a "body" fragment.
*/
-#define LEPP_MAX_FRAGS (65536 / HV_PAGE_SIZE_SMALL + 2 + 1)
+#define LEPP_MAX_FRAGS (65536 / HV_DEFAULT_PAGE_SIZE_SMALL + 2 + 1)
/** Total number of bytes needed for an lepp_tso_cmd_t. */
#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 72ec1e972f15..ccd847e2347f 100644
--- a/arch/tile/include/hv/hypervisor.h
+++ b/arch/tile/include/hv/hypervisor.h
@@ -17,8 +17,8 @@
* The hypervisor's public API.
*/
-#ifndef _TILE_HV_H
-#define _TILE_HV_H
+#ifndef _HV_HV_H
+#define _HV_HV_H
#include <arch/chip.h>
@@ -42,25 +42,45 @@
*/
#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
-/** The log2 of the size of small pages, in bytes. This value should
- * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
+/** The log2 of the initial size of small pages, in bytes.
+ * See HV_DEFAULT_PAGE_SIZE_SMALL.
*/
-#define HV_LOG2_PAGE_SIZE_SMALL 16
+#define HV_LOG2_DEFAULT_PAGE_SIZE_SMALL 16
-/** The size of small pages, in bytes. This value should be verified
+/** The initial size of small pages, in bytes. This value should be verified
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
+ * It may also be modified when installing a new context.
*/
-#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
+#define HV_DEFAULT_PAGE_SIZE_SMALL \
+ (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_SMALL)
-/** The log2 of the size of large pages, in bytes. This value should be
- * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
+/** The log2 of the initial size of large pages, in bytes.
+ * See HV_DEFAULT_PAGE_SIZE_LARGE.
*/
-#define HV_LOG2_PAGE_SIZE_LARGE 24
+#define HV_LOG2_DEFAULT_PAGE_SIZE_LARGE 24
-/** The size of large pages, in bytes. This value should be verified
+/** The initial size of large pages, in bytes. This value should be verified
* at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
+ * It may also be modified when installing a new context.
*/
-#define HV_PAGE_SIZE_LARGE (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_LARGE)
+#define HV_DEFAULT_PAGE_SIZE_LARGE \
+ (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_LARGE)
+
+#if CHIP_VA_WIDTH() > 32
+
+/** The log2 of the initial size of jumbo pages, in bytes.
+ * See HV_DEFAULT_PAGE_SIZE_JUMBO.
+ */
+#define HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO 32
+
+/** The initial size of jumbo pages, in bytes. This value should
+ * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO).
+ * It may also be modified when installing a new context.
+ */
+#define HV_DEFAULT_PAGE_SIZE_JUMBO \
+ (__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO)
+
+#endif
/** The log2 of the granularity at which page tables must be aligned;
* in other words, the CPA for a page table must have this many zero
@@ -280,8 +300,11 @@
#define HV_DISPATCH_GET_IPI_PTE 56
#endif
+/** hv_set_pte_super_shift */
+#define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57
+
/** One more than the largest dispatch value */
-#define _HV_DISPATCH_END 57
+#define _HV_DISPATCH_END 58
#ifndef __ASSEMBLER__
@@ -401,7 +424,18 @@ typedef enum {
* that the temperature has hit an upper limit and is no longer being
* accurately tracked.
*/
- HV_SYSCONF_BOARD_TEMP = 6
+ HV_SYSCONF_BOARD_TEMP = 6,
+
+ /** Legal page size bitmask for hv_install_context().
+ * For example, if 16KB and 64KB small pages are supported,
+ * it would return "HV_CTX_PG_SM_16K | HV_CTX_PG_SM_64K".
+ */
+ HV_SYSCONF_VALID_PAGE_SIZES = 7,
+
+ /** The size of jumbo pages, in bytes.
+ * If no jumbo pages are available, zero will be returned.
+ */
+ HV_SYSCONF_PAGE_SIZE_JUMBO = 8,
} HV_SysconfQuery;
@@ -474,7 +508,19 @@ typedef enum {
HV_CONFSTR_SWITCH_CONTROL = 14,
/** Chip revision level. */
- HV_CONFSTR_CHIP_REV = 15
+ HV_CONFSTR_CHIP_REV = 15,
+
+ /** CPU module part number. */
+ HV_CONFSTR_CPUMOD_PART_NUM = 16,
+
+ /** CPU module serial number. */
+ HV_CONFSTR_CPUMOD_SERIAL_NUM = 17,
+
+ /** CPU module revision level. */
+ HV_CONFSTR_CPUMOD_REV = 18,
+
+ /** Human-readable CPU module description. */
+ HV_CONFSTR_CPUMOD_DESC = 19
} HV_ConfstrQuery;
@@ -494,11 +540,16 @@ int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
/** Tile coordinate */
typedef struct
{
+#ifndef __BIG_ENDIAN__
/** X coordinate, relative to supervisor's top-left coordinate */
int x;
/** Y coordinate, relative to supervisor's top-left coordinate */
int y;
+#else
+ int y;
+ int x;
+#endif
} HV_Coord;
@@ -649,6 +700,12 @@ void hv_set_rtc(HV_RTCTime time);
* new page table does not need to contain any mapping for the
* hv_install_context address itself.
*
+ * At most one HV_CTX_PG_SM_* flag may be specified in "flags";
+ * if multiple flags are specified, HV_EINVAL is returned.
+ * Specifying none of the flags results in using the default page size.
+ * All cores participating in a given client must request the same
+ * page size, or the results are undefined.
+ *
* @param page_table Root of the page table.
* @param access PTE providing info on how to read the page table. This
* 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,
#define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from
PL0. */
+#define HV_CTX_PG_SM_4K 0x10 /**< Use 4K small pages, if available. */
+#define HV_CTX_PG_SM_16K 0x20 /**< Use 16K small pages, if available. */
+#define HV_CTX_PG_SM_64K 0x40 /**< Use 64K small pages, if available. */
+#define HV_CTX_PG_SM_MASK 0xf0 /**< Mask of all possible small pages. */
+
#ifndef __ASSEMBLER__
+
+/** Set the number of pages ganged together by HV_PTE_SUPER at a
+ * particular level of the page table.
+ *
+ * The current TILE-Gx hardware only supports powers of four
+ * (i.e. log2_count must be a multiple of two), and the requested
+ * "super" page size must be less than the span of the next level in
+ * the page table. The largest size that can be requested is 64GB.
+ *
+ * The shift value is initially "0" for all page table levels,
+ * indicating that the HV_PTE_SUPER bit is effectively ignored.
+ *
+ * If you change the count from one non-zero value to another, the
+ * hypervisor will flush the entire TLB and TSB to avoid confusion.
+ *
+ * @param level Page table level (0, 1, or 2)
+ * @param log2_count Base-2 log of the number of pages to gang together,
+ * i.e. how much to shift left the base page size for the super page size.
+ * @return Zero on success, or a hypervisor error code on failure.
+ */
+int hv_set_pte_super_shift(int level, int log2_count);
+
+
/** Value returned from hv_inquire_context(). */
typedef struct
{
@@ -986,8 +1071,13 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
/** A range of ASID values. */
typedef struct
{
+#ifndef __BIG_ENDIAN__
HV_ASID start; /**< First ASID in the range. */
unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
+#else
+ unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
+ HV_ASID start; /**< First ASID in the range. */
+#endif
} HV_ASIDRange;
/** Returns information about a range of ASIDs.
@@ -1238,11 +1328,14 @@ HV_Errno hv_set_command_line(HV_VirtAddr buf, int length);
* with the existing priority pages) or "red/black" (if they don't).
* The bitmask provides information on which parts of the cache
* have been used for pinned pages so far on this tile; if (1 << N)
- * appears in the bitmask, that indicates that a page has been marked
- * "priority" whose PFN equals N, mod 8.
+ * appears in the bitmask, that indicates that a 4KB region of the
+ * cache starting at (N * 4KB) is in use by a "priority" page.
+ * The portion of cache used by a particular page can be computed
+ * by taking the page's PA, modulo CHIP_L2_CACHE_SIZE(), and setting
+ * all the "4KB" bits corresponding to the actual page size.
* @param bitmask A bitmap of priority page set values
*/
-void hv_set_caching(unsigned int bitmask);
+void hv_set_caching(unsigned long bitmask);
/** Zero out a specified number of pages.
@@ -1308,6 +1401,7 @@ typedef enum
/** Message recipient. */
typedef struct
{
+#ifndef __BIG_ENDIAN__
/** X coordinate, relative to supervisor's top-left coordinate */
unsigned int x:11;
@@ -1316,6 +1410,11 @@ typedef struct
/** Status of this recipient */
HV_Recip_State state:10;
+#else //__BIG_ENDIAN__
+ HV_Recip_State state:10;
+ unsigned int y:11;
+ unsigned int x:11;
+#endif
} HV_Recipient;
/** Send a message to a set of recipients.
@@ -1851,12 +1950,12 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
- /* Bits 13-15 are reserved for
+ /* Bits 13-14 are reserved for
future use. */
+#define HV_PTE_INDEX_SUPER 15 /**< Pages ganged together for TLB */
#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
- /* Bit 19 is reserved for
- future use. */
+#define HV_PTE_INDEX_CLIENT2 19 /**< Page client state 2 */
#define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits
of word */
#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,
of word */
#define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */
-/** Position of the PFN field within the PTE (subset of the PTFN). */
-#define HV_PTE_INDEX_PFN (HV_PTE_INDEX_PTFN + (HV_LOG2_PAGE_SIZE_SMALL - \
- HV_LOG2_PAGE_TABLE_ALIGN))
-
-/** Length of the PFN field within the PTE (subset of the PTFN). */
-#define HV_PTE_INDEX_PFN_BITS (HV_PTE_INDEX_PTFN_BITS - \
- (HV_LOG2_PAGE_SIZE_SMALL - \
- HV_LOG2_PAGE_TABLE_ALIGN))
-
/*
* Legal values for the PTE's mode field
*/
@@ -1957,7 +2047,10 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
/** Does this PTE map a page?
*
- * If this bit is set in the level-1 page table, the entry should be
+ * If this bit is set in a level-0 page table, the entry should be
+ * interpreted as a level-2 page table entry mapping a jumbo page.
+ *
+ * If this bit is set in a level-1 page table, the entry should be
* interpreted as a level-2 page table entry mapping a large page.
*
* 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,
*/
#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)
+/** Does this PTE implicitly reference multiple pages?
+ *
+ * If this bit is set in the page table (either in the level-2 page table,
+ * or in a higher level page table in conjunction with the PAGE bit)
+ * then the PTE specifies a range of contiguous pages, not a single page.
+ * The hv_set_pte_super_shift() allows you to specify the count for
+ * each level of the page table.
+ *
+ * Note: this bit is not supported on TILEPro systems.
+ */
+#define HV_PTE_SUPER (__HV_PTE_ONE << HV_PTE_INDEX_SUPER)
+
/** Is this a global (non-ASID) mapping?
*
* 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,
*/
#define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1)
+/** Client-private bit in PTE.
+ *
+ * This bit is guaranteed not to be inspected or modified by the
+ * hypervisor.
+ */
+#define HV_PTE_CLIENT2 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT2)
+
/** Non-coherent (NC) bit in PTE.
*
* 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) \
*/
_HV_BIT(present, PRESENT)
_HV_BIT(page, PAGE)
+_HV_BIT(super, SUPER)
_HV_BIT(client0, CLIENT0)
_HV_BIT(client1, CLIENT1)
+_HV_BIT(client2, CLIENT2)
_HV_BIT(migrating, MIGRATING)
_HV_BIT(nc, NC)
_HV_BIT(readable, READABLE)
@@ -2222,40 +2336,11 @@ hv_pte_set_mode(HV_PTE pte, unsigned int val)
*
* This field contains the upper bits of the CPA (client physical
* address) of the target page; the complete CPA is this field with
- * HV_LOG2_PAGE_SIZE_SMALL zero bits appended to it.
- *
- * For PTEs in a level-1 page table where the Page bit is set, the
- * CPA must be aligned modulo the large page size.
- */
-static __inline unsigned int
-hv_pte_get_pfn(const HV_PTE pte)
-{
- return pte.val >> HV_PTE_INDEX_PFN;
-}
-
-
-/** Set the page frame number into a PTE. See hv_pte_get_pfn. */
-static __inline HV_PTE
-hv_pte_set_pfn(HV_PTE pte, unsigned int val)
-{
- /*
- * Note that the use of "PTFN" in the next line is intentional; we
- * don't want any garbage lower bits left in that field.
- */
- pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS) - 1) << HV_PTE_INDEX_PTFN);
- pte.val |= (__hv64) val << HV_PTE_INDEX_PFN;
- return pte;
-}
-
-/** Get the page table frame number from the PTE.
- *
- * This field contains the upper bits of the CPA (client physical
- * address) of the target page table; the complete CPA is this field with
- * with HV_PAGE_TABLE_ALIGN zero bits appended to it.
+ * HV_LOG2_PAGE_TABLE_ALIGN zero bits appended to it.
*
- * For PTEs in a level-1 page table when the Page bit is not set, the
- * CPA must be aligned modulo the sticter of HV_PAGE_TABLE_ALIGN and
- * the level-2 page table size.
+ * For all PTEs in the lowest-level page table, and for all PTEs with
+ * the Page bit set in all page tables, the CPA must be aligned modulo
+ * the relevant page size.
*/
static __inline unsigned long
hv_pte_get_ptfn(const HV_PTE pte)
@@ -2263,7 +2348,6 @@ hv_pte_get_ptfn(const HV_PTE pte)
return pte.val >> HV_PTE_INDEX_PTFN;
}
-
/** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */
static __inline HV_PTE
hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
@@ -2273,6 +2357,20 @@ hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
return pte;
}
+/** Get the client physical address from the PTE. See hv_pte_set_ptfn. */
+static __inline HV_PhysAddr
+hv_pte_get_pa(const HV_PTE pte)
+{
+ return (__hv64) hv_pte_get_ptfn(pte) << HV_LOG2_PAGE_TABLE_ALIGN;
+}
+
+/** Set the client physical address into a PTE. See hv_pte_get_ptfn. */
+static __inline HV_PTE
+hv_pte_set_pa(HV_PTE pte, HV_PhysAddr pa)
+{
+ return hv_pte_set_ptfn(pte, pa >> HV_LOG2_PAGE_TABLE_ALIGN);
+}
+
/** Get the remote tile caching this page.
*
@@ -2308,28 +2406,20 @@ hv_pte_set_lotar(HV_PTE pte, unsigned int val)
#endif /* !__ASSEMBLER__ */
-/** Converts a client physical address to a pfn. */
-#define HV_CPA_TO_PFN(p) ((p) >> HV_LOG2_PAGE_SIZE_SMALL)
-
-/** Converts a pfn to a client physical address. */
-#define HV_PFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_SIZE_SMALL)
-
/** Converts a client physical address to a ptfn. */
#define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN)
/** Converts a ptfn to a client physical address. */
#define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN)
-/** Converts a ptfn to a pfn. */
-#define HV_PTFN_TO_PFN(p) \
- ((p) >> (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
-
-/** Converts a pfn to a ptfn. */
-#define HV_PFN_TO_PTFN(p) \
- ((p) << (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
-
#if CHIP_VA_WIDTH() > 32
+/*
+ * Note that we currently do not allow customizing the page size
+ * of the L0 pages, but fix them at 4GB, so we do not use the
+ * "_HV_xxx" nomenclature for the L0 macros.
+ */
+
/** Log number of HV_PTE entries in L0 page table */
#define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN)
@@ -2359,69 +2449,104 @@ hv_pte_set_lotar(HV_PTE pte, unsigned int val)
#endif /* CHIP_VA_WIDTH() > 32 */
/** Log number of HV_PTE entries in L1 page table */
-#define HV_LOG2_L1_ENTRIES (HV_LOG2_L1_SPAN - HV_LOG2_PAGE_SIZE_LARGE)
+#define _HV_LOG2_L1_ENTRIES(log2_page_size_large) \
+ (HV_LOG2_L1_SPAN - log2_page_size_large)
/** Number of HV_PTE entries in L1 page table */
-#define HV_L1_ENTRIES (1 << HV_LOG2_L1_ENTRIES)
+#define _HV_L1_ENTRIES(log2_page_size_large) \
+ (1 << _HV_LOG2_L1_ENTRIES(log2_page_size_large))
/** Log size of L1 page table in bytes */
-#define HV_LOG2_L1_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L1_ENTRIES)
+#define _HV_LOG2_L1_SIZE(log2_page_size_large) \
+ (HV_LOG2_PTE_SIZE + _HV_LOG2_L1_ENTRIES(log2_page_size_large))
/** Size of L1 page table in bytes */
-#define HV_L1_SIZE (1 << HV_LOG2_L1_SIZE)
+#define _HV_L1_SIZE(log2_page_size_large) \
+ (1 << _HV_LOG2_L1_SIZE(log2_page_size_large))
/** Log number of HV_PTE entries in level-2 page table */
-#define HV_LOG2_L2_ENTRIES (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)
+#define _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
+ (log2_page_size_large - log2_page_size_small)
/** Number of HV_PTE entries in level-2 page table */
-#define HV_L2_ENTRIES (1 << HV_LOG2_L2_ENTRIES)
+#define _HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) \
+ (1 << _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
/** Log size of level-2 page table in bytes */
-#define HV_LOG2_L2_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L2_ENTRIES)
+#define _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small) \
+ (HV_LOG2_PTE_SIZE + \
+ _HV_LOG2_L2_ENTRIES(log2_page_size_large, log2_page_size_small))
/** Size of level-2 page table in bytes */
-#define HV_L2_SIZE (1 << HV_LOG2_L2_SIZE)
+#define _HV_L2_SIZE(log2_page_size_large, log2_page_size_small) \
+ (1 << _HV_LOG2_L2_SIZE(log2_page_size_large, log2_page_size_small))
#ifdef __ASSEMBLER__
#if CHIP_VA_WIDTH() > 32
/** Index in L1 for a specific VA */
-#define HV_L1_INDEX(va) \
- (((va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
+#define _HV_L1_INDEX(va, log2_page_size_large) \
+ (((va) >> log2_page_size_large) & (_HV_L1_ENTRIES(log2_page_size_large) - 1))
#else /* CHIP_VA_WIDTH() > 32 */
/** Index in L1 for a specific VA */
-#define HV_L1_INDEX(va) \
- (((va) >> HV_LOG2_PAGE_SIZE_LARGE))
+#define _HV_L1_INDEX(va, log2_page_size_large) \
+ (((va) >> log2_page_size_large))
#endif /* CHIP_VA_WIDTH() > 32 */
/** Index in level-2 page table for a specific VA */
-#define HV_L2_INDEX(va) \
- (((va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
+#define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
+ (((va) >> log2_page_size_small) & \
+ (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
#else /* __ASSEMBLER __ */
#if CHIP_VA_WIDTH() > 32
/** Index in L1 for a specific VA */
-#define HV_L1_INDEX(va) \
- (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
+#define _HV_L1_INDEX(va, log2_page_size_large) \
+ (((HV_VirtAddr)(va) >> log2_page_size_large) & \
+ (_HV_L1_ENTRIES(log2_page_size_large) - 1))
#else /* CHIP_VA_WIDTH() > 32 */
/** Index in L1 for a specific VA */
-#define HV_L1_INDEX(va) \
- (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE))
+#define _HV_L1_INDEX(va, log2_page_size_large) \
+ (((HV_VirtAddr)(va) >> log2_page_size_large))
#endif /* CHIP_VA_WIDTH() > 32 */
/** Index in level-2 page table for a specific VA */
-#define HV_L2_INDEX(va) \
- (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
+#define _HV_L2_INDEX(va, log2_page_size_large, log2_page_size_small) \
+ (((HV_VirtAddr)(va) >> log2_page_size_small) & \
+ (_HV_L2_ENTRIES(log2_page_size_large, log2_page_size_small) - 1))
#endif /* __ASSEMBLER __ */
-#endif /* _TILE_HV_H */
+/** Position of the PFN field within the PTE (subset of the PTFN). */
+#define _HV_PTE_INDEX_PFN(log2_page_size) \
+ (HV_PTE_INDEX_PTFN + (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
+
+/** Length of the PFN field within the PTE (subset of the PTFN). */
+#define _HV_PTE_INDEX_PFN_BITS(log2_page_size) \
+ (HV_PTE_INDEX_PTFN_BITS - (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
+
+/** Converts a client physical address to a pfn. */
+#define _HV_CPA_TO_PFN(p, log2_page_size) ((p) >> log2_page_size)
+
+/** Converts a pfn to a client physical address. */
+#define _HV_PFN_TO_CPA(p, log2_page_size) \
+ (((HV_PhysAddr)(p)) << log2_page_size)
+
+/** Converts a ptfn to a pfn. */
+#define _HV_PTFN_TO_PFN(p, log2_page_size) \
+ ((p) >> (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
+
+/** Converts a pfn to a ptfn. */
+#define _HV_PFN_TO_PTFN(p, log2_page_size) \
+ ((p) << (log2_page_size - HV_LOG2_PAGE_TABLE_ALIGN))
+
+#endif /* _HV_HV_H */
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
index 0d826faf8f35..5de99248d8df 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 \
intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
obj-$(CONFIG_HARDWALL) += hardwall.o
-obj-$(CONFIG_TILEGX) += futex_64.o
obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o
obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index ec91568df880..133c4b56a99e 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -100,8 +100,9 @@ STD_ENTRY(smp_nap)
*/
STD_ENTRY(_cpu_idle)
movei r1, 1
+ IRQ_ENABLE_LOAD(r2, r3)
mtspr INTERRUPT_CRITICAL_SECTION, r1
- IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
+ IRQ_ENABLE_APPLY(r2, r3) /* unmask, but still with ICS set */
mtspr INTERRUPT_CRITICAL_SECTION, zero
.global _cpu_idle_nap
_cpu_idle_nap:
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
index 8c41891aab34..20273ee37deb 100644
--- a/arch/tile/kernel/hardwall.c
+++ b/arch/tile/kernel/hardwall.c
@@ -33,59 +33,157 @@
/*
- * This data structure tracks the rectangle data, etc., associated
- * one-to-one with a "struct file *" from opening HARDWALL_FILE.
+ * Implement a per-cpu "hardwall" resource class such as UDN or IPI.
+ * We use "hardwall" nomenclature throughout for historical reasons.
+ * The lock here controls access to the list data structure as well as
+ * to the items on the list.
+ */
+struct hardwall_type {
+ int index;
+ int is_xdn;
+ int is_idn;
+ int disabled;
+ const char *name;
+ struct list_head list;
+ spinlock_t lock;
+ struct proc_dir_entry *proc_dir;
+};
+
+enum hardwall_index {
+ HARDWALL_UDN = 0,
+#ifndef __tilepro__
+ HARDWALL_IDN = 1,
+ HARDWALL_IPI = 2,
+#endif
+ _HARDWALL_TYPES
+};
+
+static struct hardwall_type hardwall_types[] = {
+ { /* user-space access to UDN */
+ 0,
+ 1,
+ 0,
+ 0,
+ "udn",
+ LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
+ __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock),
+ NULL
+ },
+#ifndef __tilepro__
+ { /* user-space access to IDN */
+ 1,
+ 1,
+ 1,
+ 1, /* disabled pending hypervisor support */
+ "idn",
+ LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
+ __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock),
+ NULL
+ },
+ { /* access to user-space IPI */
+ 2,
+ 0,
+ 0,
+ 0,
+ "ipi",
+ LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
+ __SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock),
+ NULL
+ },
+#endif
+};
+
+/*
+ * This data structure tracks the cpu data, etc., associated
+ * one-to-one with a "struct file *" from opening a hardwall device file.
* Note that the file's private data points back to this structure.
*/
struct hardwall_info {
- struct list_head list; /* "rectangles" list */
+ struct list_head list; /* for hardwall_types.list */
struct list_head task_head; /* head of tasks in this hardwall */
- struct cpumask cpumask; /* cpus in the rectangle */
+ struct hardwall_type *type; /* type of this resource */
+ struct cpumask cpumask; /* cpus reserved */
+ int id; /* integer id for this hardwall */
+ int teardown_in_progress; /* are we tearing this one down? */
+
+ /* Remaining fields only valid for user-network resources. */
int ulhc_x; /* upper left hand corner x coord */
int ulhc_y; /* upper left hand corner y coord */
int width; /* rectangle width */
int height; /* rectangle height */
- int id; /* integer id for this hardwall */
- int teardown_in_progress; /* are we tearing this one down? */
+#if CHIP_HAS_REV1_XDN()
+ atomic_t xdn_pending_count; /* cores in phase 1 of drain */
+#endif
};
-/* Currently allocated hardwall rectangles */
-static LIST_HEAD(rectangles);
/* /proc/tile/hardwall */
static struct proc_dir_entry *hardwall_proc_dir;
/* Functions to manage files in /proc/tile/hardwall. */
-static void hardwall_add_proc(struct hardwall_info *rect);
-static void hardwall_remove_proc(struct hardwall_info *rect);
-
-/*
- * Guard changes to the hardwall data structures.
- * This could be finer grained (e.g. one lock for the list of hardwall
- * rectangles, then separate embedded locks for each one's list of tasks),
- * but there are subtle correctness issues when trying to start with
- * a task's "hardwall" pointer and lock the correct rectangle's embedded
- * lock in the presence of a simultaneous deactivation, so it seems
- * easier to have a single lock, given that none of these data
- * structures are touched very frequently during normal operation.
- */
-static DEFINE_SPINLOCK(hardwall_lock);
+static void hardwall_add_proc(struct hardwall_info *);
+static void hardwall_remove_proc(struct hardwall_info *);
/* Allow disabling UDN access. */
-static int udn_disabled;
static int __init noudn(char *str)
{
pr_info("User-space UDN access is disabled\n");
- udn_disabled = 1;
+ hardwall_types[HARDWALL_UDN].disabled = 1;
return 0;
}
early_param("noudn", noudn);
+#ifndef __tilepro__
+/* Allow disabling IDN access. */
+static int __init noidn(char *str)
+{
+ pr_info("User-space IDN access is disabled\n");
+ hardwall_types[HARDWALL_IDN].disabled = 1;
+ return 0;
+}
+early_param("noidn", noidn);
+
+/* Allow disabling IPI access. */
+static int __init noipi(char *str)
+{
+ pr_info("User-space IPI access is disabled\n");
+ hardwall_types[HARDWALL_IPI].disabled = 1;
+ return 0;
+}
+early_param("noipi", noipi);
+#endif
+
/*
- * Low-level primitives
+ * Low-level primitives for UDN/IDN
*/
+#ifdef __tilepro__
+#define mtspr_XDN(hwt, name, val) \
+ do { (void)(hwt); __insn_mtspr(SPR_UDN_##name, (val)); } while (0)
+#define mtspr_MPL_XDN(hwt, name, val) \
+ do { (void)(hwt); __insn_mtspr(SPR_MPL_UDN_##name, (val)); } while (0)
+#define mfspr_XDN(hwt, name) \
+ ((void)(hwt), __insn_mfspr(SPR_UDN_##name))
+#else
+#define mtspr_XDN(hwt, name, val) \
+ do { \
+ if ((hwt)->is_idn) \
+ __insn_mtspr(SPR_IDN_##name, (val)); \
+ else \
+ __insn_mtspr(SPR_UDN_##name, (val)); \
+ } while (0)
+#define mtspr_MPL_XDN(hwt, name, val) \
+ do { \
+ if ((hwt)->is_idn) \
+ __insn_mtspr(SPR_MPL_IDN_##name, (val)); \
+ else \
+ __insn_mtspr(SPR_MPL_UDN_##name, (val)); \
+ } while (0)
+#define mfspr_XDN(hwt, name) \
+ ((hwt)->is_idn ? __insn_mfspr(SPR_IDN_##name) : __insn_mfspr(SPR_UDN_##name))
+#endif
+
/* Set a CPU bit if the CPU is online. */
#define cpu_online_set(cpu, dst) do { \
if (cpu_online(cpu)) \
@@ -101,7 +199,7 @@ static int contains(struct hardwall_info *r, int x, int y)
}
/* Compute the rectangle parameters and validate the cpumask. */
-static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
+static int check_rectangle(struct hardwall_info *r, struct cpumask *mask)
{
int x, y, cpu, ulhc, lrhc;
@@ -114,8 +212,6 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
r->ulhc_y = cpu_y(ulhc);
r->width = cpu_x(lrhc) - r->ulhc_x + 1;
r->height = cpu_y(lrhc) - r->ulhc_y + 1;
- cpumask_copy(&r->cpumask, mask);
- r->id = ulhc; /* The ulhc cpu id can be the hardwall id. */
/* Width and height must be positive */
if (r->width <= 0 || r->height <= 0)
@@ -128,7 +224,7 @@ static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
return -EINVAL;
/*
- * Note that offline cpus can't be drained when this UDN
+ * Note that offline cpus can't be drained when this user network
* rectangle eventually closes. We used to detect this
* situation and print a warning, but it annoyed users and
* 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)
return 0;
}
-/* Do the two given rectangles overlap on any cpu? */
-static int overlaps(struct hardwall_info *a, struct hardwall_info *b)
-{
- return a->ulhc_x + a->width > b->ulhc_x && /* A not to the left */
- b->ulhc_x + b->width > a->ulhc_x && /* B not to the left */
- a->ulhc_y + a->height > b->ulhc_y && /* A not above */
- b->ulhc_y + b->height > a->ulhc_y; /* B not above */
-}
-
-
/*
* Hardware management of hardwall setup, teardown, trapping,
* and enabling/disabling PL0 access to the networks.
@@ -157,23 +243,35 @@ enum direction_protect {
N_PROTECT = (1 << 0),
E_PROTECT = (1 << 1),
S_PROTECT = (1 << 2),
- W_PROTECT = (1 << 3)
+ W_PROTECT = (1 << 3),
+ C_PROTECT = (1 << 4),
};
-static void enable_firewall_interrupts(void)
+static inline int xdn_which_interrupt(struct hardwall_type *hwt)
+{
+#ifndef __tilepro__
+ if (hwt->is_idn)
+ return INT_IDN_FIREWALL;
+#endif
+ return INT_UDN_FIREWALL;
+}
+
+static void enable_firewall_interrupts(struct hardwall_type *hwt)
{
- arch_local_irq_unmask_now(INT_UDN_FIREWALL);
+ arch_local_irq_unmask_now(xdn_which_interrupt(hwt));
}
-static void disable_firewall_interrupts(void)
+static void disable_firewall_interrupts(struct hardwall_type *hwt)
{
- arch_local_irq_mask_now(INT_UDN_FIREWALL);
+ arch_local_irq_mask_now(xdn_which_interrupt(hwt));
}
/* Set up hardwall on this cpu based on the passed hardwall_info. */
-static void hardwall_setup_ipi_func(void *info)
+static void hardwall_setup_func(void *info)
{
struct hardwall_info *r = info;
+ struct hardwall_type *hwt = r->type;
+
int cpu = smp_processor_id();
int x = cpu % smp_width;
int y = cpu / smp_width;
@@ -187,13 +285,12 @@ static void hardwall_setup_ipi_func(void *info)
if (y == r->ulhc_y + r->height - 1)
bits |= S_PROTECT;
BUG_ON(bits == 0);
- __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, bits);
- enable_firewall_interrupts();
-
+ mtspr_XDN(hwt, DIRECTION_PROTECT, bits);
+ enable_firewall_interrupts(hwt);
}
/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */
-static void hardwall_setup(struct hardwall_info *r)
+static void hardwall_protect_rectangle(struct hardwall_info *r)
{
int x, y, cpu, delta;
struct cpumask rect_cpus;
@@ -217,37 +314,50 @@ static void hardwall_setup(struct hardwall_info *r)
}
/* Then tell all the cpus to set up their protection SPR */
- on_each_cpu_mask(&rect_cpus, hardwall_setup_ipi_func, r, 1);
+ on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1);
}
void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
{
struct hardwall_info *rect;
+ struct hardwall_type *hwt;
struct task_struct *p;
struct siginfo info;
- int x, y;
int cpu = smp_processor_id();
int found_processes;
unsigned long flags;
-
struct pt_regs *old_regs = set_irq_regs(regs);
+
irq_enter();
+ /* Figure out which network trapped. */
+ switch (fault_num) {
+#ifndef __tilepro__
+ case INT_IDN_FIREWALL:
+ hwt = &hardwall_types[HARDWALL_IDN];
+ break;
+#endif
+ case INT_UDN_FIREWALL:
+ hwt = &hardwall_types[HARDWALL_UDN];
+ break;
+ default:
+ BUG();
+ }
+ BUG_ON(hwt->disabled);
+
/* This tile trapped a network access; find the rectangle. */
- x = cpu % smp_width;
- y = cpu / smp_width;
- spin_lock_irqsave(&hardwall_lock, flags);
- list_for_each_entry(rect, &rectangles, list) {
- if (contains(rect, x, y))
+ spin_lock_irqsave(&hwt->lock, flags);
+ list_for_each_entry(rect, &hwt->list, list) {
+ if (cpumask_test_cpu(cpu, &rect->cpumask))
break;
}
/*
* It shouldn't be possible not to find this cpu on the
* rectangle list, since only cpus in rectangles get hardwalled.
- * The hardwall is only removed after the UDN is drained.
+ * The hardwall is only removed after the user network is drained.
*/
- BUG_ON(&rect->list == &rectangles);
+ BUG_ON(&rect->list == &hwt->list);
/*
* 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)
* to quiesce.
*/
if (rect->teardown_in_progress) {
- pr_notice("cpu %d: detected hardwall violation %#lx"
+ pr_notice("cpu %d: detected %s hardwall violation %#lx"
" while teardown already in progress\n",
- cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
+ cpu, hwt->name,
+ (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
goto done;
}
/*
* Kill off any process that is activated in this rectangle.
* We bypass security to deliver the signal, since it must be
- * one of the activated processes that generated the UDN
+ * one of the activated processes that generated the user network
* message that caused this trap, and all the activated
* processes shared a single open file so are pretty tightly
* bound together from a security point of view to begin with.
*/
rect->teardown_in_progress = 1;
wmb(); /* Ensure visibility of rectangle before notifying processes. */
- pr_notice("cpu %d: detected hardwall violation %#lx...\n",
- cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
+ pr_notice("cpu %d: detected %s hardwall violation %#lx...\n",
+ cpu, hwt->name, (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_HARDWALL;
found_processes = 0;
- list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
- BUG_ON(p->thread.hardwall != rect);
+ list_for_each_entry(p, &rect->task_head,
+ thread.hardwall[hwt->index].list) {
+ BUG_ON(p->thread.hardwall[hwt->index].info != rect);
if (!(p->flags & PF_EXITING)) {
found_processes = 1;
pr_notice("hardwall: killing %d\n", p->pid);
@@ -289,7 +401,7 @@ void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
pr_notice("hardwall: no associated processes!\n");
done:
- spin_unlock_irqrestore(&hardwall_lock, flags);
+ spin_unlock_irqrestore(&hwt->lock, flags);
/*
* 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)
* haven't yet drained the network, and that would allow packets
* to cross out of the hardwall region.
*/
- disable_firewall_interrupts();
+ disable_firewall_interrupts(hwt);
irq_exit();
set_irq_regs(old_regs);
}
-/* Allow access from user space to the UDN. */
-void grant_network_mpls(void)
+/* Allow access from user space to the user network. */
+void grant_hardwall_mpls(struct hardwall_type *hwt)
{
- __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_0, 1);
- __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_0, 1);
- __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_0, 1);
- __insn_mtspr(SPR_MPL_UDN_TIMER_SET_0, 1);
+#ifndef __tilepro__
+ if (!hwt->is_xdn) {
+ __insn_mtspr(SPR_MPL_IPI_0_SET_0, 1);
+ return;
+ }
+#endif
+ mtspr_MPL_XDN(hwt, ACCESS_SET_0, 1);
+ mtspr_MPL_XDN(hwt, AVAIL_SET_0, 1);
+ mtspr_MPL_XDN(hwt, COMPLETE_SET_0, 1);
+ mtspr_MPL_XDN(hwt, TIMER_SET_0, 1);
#if !CHIP_HAS_REV1_XDN()
- __insn_mtspr(SPR_MPL_UDN_REFILL_SET_0, 1);
- __insn_mtspr(SPR_MPL_UDN_CA_SET_0, 1);
+ mtspr_MPL_XDN(hwt, REFILL_SET_0, 1);
+ mtspr_MPL_XDN(hwt, CA_SET_0, 1);
#endif
}
-/* Deny access from user space to the UDN. */
-void restrict_network_mpls(void)
+/* Deny access from user space to the user network. */
+void restrict_hardwall_mpls(struct hardwall_type *hwt)
{
- __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_1, 1);
- __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_1, 1);
- __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_1, 1);
- __insn_mtspr(SPR_MPL_UDN_TIMER_SET_1, 1);
+#ifndef __tilepro__
+ if (!hwt->is_xdn) {
+ __insn_mtspr(SPR_MPL_IPI_0_SET_1, 1);
+ return;
+ }
+#endif
+ mtspr_MPL_XDN(hwt, ACCESS_SET_1, 1);
+ mtspr_MPL_XDN(hwt, AVAIL_SET_1, 1);
+ mtspr_MPL_XDN(hwt, COMPLETE_SET_1, 1);
+ mtspr_MPL_XDN(hwt, TIMER_SET_1, 1);
#if !CHIP_HAS_REV1_XDN()
- __insn_mtspr(SPR_MPL_UDN_REFILL_SET_1, 1);
- __insn_mtspr(SPR_MPL_UDN_CA_SET_1, 1);
+ mtspr_MPL_XDN(hwt, REFILL_SET_1, 1);
+ mtspr_MPL_XDN(hwt, CA_SET_1, 1);
#endif
}
+/* Restrict or deny as necessary for the task we're switching to. */
+void hardwall_switch_tasks(struct task_struct *prev,
+ struct task_struct *next)
+{
+ int i;
+ for (i = 0; i < HARDWALL_TYPES; ++i) {
+ if (prev->thread.hardwall[i].info != NULL) {
+ if (next->thread.hardwall[i].info == NULL)
+ restrict_hardwall_mpls(&hardwall_types[i]);
+ } else if (next->thread.hardwall[i].info != NULL) {
+ grant_hardwall_mpls(&hardwall_types[i]);
+ }
+ }
+}
+
+/* Does this task have the right to IPI the given cpu? */
+int hardwall_ipi_valid(int cpu)
+{
+#ifdef __tilegx__
+ struct hardwall_info *info =
+ current->thread.hardwall[HARDWALL_IPI].info;
+ return info && cpumask_test_cpu(cpu, &info->cpumask);
+#else
+ return 0;
+#endif
+}
/*
- * Code to create, activate, deactivate, and destroy hardwall rectangles.
+ * Code to create, activate, deactivate, and destroy hardwall resources.
*/
-/* Create a hardwall for the given rectangle */
-static struct hardwall_info *hardwall_create(
- size_t size, const unsigned char __user *bits)
+/* Create a hardwall for the given resource */
+static struct hardwall_info *hardwall_create(struct hardwall_type *hwt,
+ size_t size,
+ const unsigned char __user *bits)
{
- struct hardwall_info *iter, *rect;
+ struct hardwall_info *iter, *info;
struct cpumask mask;
unsigned long flags;
int rc;
@@ -370,55 +521,62 @@ static struct hardwall_info *hardwall_create(
}
}
- /* Allocate a new rectangle optimistically. */
- rect = kmalloc(sizeof(struct hardwall_info),
+ /* Allocate a new hardwall_info optimistically. */
+ info = kmalloc(sizeof(struct hardwall_info),
GFP_KERNEL | __GFP_ZERO);
- if (rect == NULL)
+ if (info == NULL)
return ERR_PTR(-ENOMEM);
- INIT_LIST_HEAD(&rect->task_head);
+ INIT_LIST_HEAD(&info->task_head);
+ info->type = hwt;
/* Compute the rectangle size and validate that it's plausible. */
- rc = setup_rectangle(rect, &mask);
- if (rc != 0) {
- kfree(rect);
- return ERR_PTR(rc);
+ cpumask_copy(&info->cpumask, &mask);
+ info->id = find_first_bit(cpumask_bits(&mask), nr_cpumask_bits);
+ if (hwt->is_xdn) {
+ rc = check_rectangle(info, &mask);
+ if (rc != 0) {
+ kfree(info);
+ return ERR_PTR(rc);
+ }
}
/* Confirm it doesn't overlap and add it to the list. */
- spin_lock_irqsave(&hardwall_lock, flags);
- list_for_each_entry(iter, &rectangles, list) {
- if (overlaps(iter, rect)) {
- spin_unlock_irqrestore(&hardwall_lock, flags);
- kfree(rect);
+ spin_lock_irqsave(&hwt->lock, flags);
+ list_for_each_entry(iter, &hwt->list, list) {
+ if (cpumask_intersects(&iter->cpumask, &info->cpumask)) {
+ spin_unlock_irqrestore(&hwt->lock, flags);
+ kfree(info);
return ERR_PTR(-EBUSY);
}
}
- list_add_tail(&rect->list, &rectangles);
- spin_unlock_irqrestore(&hardwall_lock, flags);
+ list_add_tail(&info->list, &hwt->list);
+ spin_unlock_irqrestore(&hwt->lock, flags);
/* Set up appropriate hardwalling on all affected cpus. */
- hardwall_setup(rect);
+ if (hwt->is_xdn)
+ hardwall_protect_rectangle(info);
/* Create a /proc/tile/hardwall entry. */
- hardwall_add_proc(rect);
+ hardwall_add_proc(info);
- return rect;
+ return info;
}
/* Activate a given hardwall on this cpu for this process. */
-static int hardwall_activate(struct hardwall_info *rect)
+static int hardwall_activate(struct hardwall_info *info)
{
- int cpu, x, y;
+ int cpu;
unsigned long flags;
struct task_struct *p = current;
struct thread_struct *ts = &p->thread;
+ struct hardwall_type *hwt;
- /* Require a rectangle. */
- if (rect == NULL)
+ /* Require a hardwall. */
+ if (info == NULL)
return -ENODATA;
- /* Not allowed to activate a rectangle that is being torn down. */
- if (rect->teardown_in_progress)
+ /* Not allowed to activate a hardwall that is being torn down. */
+ if (info->teardown_in_progress)
return -EINVAL;
/*
@@ -428,78 +586,87 @@ static int hardwall_activate(struct hardwall_info *rect)
if (cpumask_weight(&p->cpus_allowed) != 1)
return -EPERM;
- /* Make sure we are bound to a cpu in this rectangle. */
+ /* Make sure we are bound to a cpu assigned to this resource. */
cpu = smp_processor_id();
BUG_ON(cpumask_first(&p->cpus_allowed) != cpu);
- x = cpu_x(cpu);
- y = cpu_y(cpu);
- if (!contains(rect, x, y))
+ if (!cpumask_test_cpu(cpu, &info->cpumask))
return -EINVAL;
/* If we are already bound to this hardwall, it's a no-op. */
- if (ts->hardwall) {
- BUG_ON(ts->hardwall != rect);
+ hwt = info->type;
+ if (ts->hardwall[hwt->index].info) {
+ BUG_ON(ts->hardwall[hwt->index].info != info);
return 0;
}
- /* Success! This process gets to use the user networks on this cpu. */
- ts->hardwall = rect;
- spin_lock_irqsave(&hardwall_lock, flags);
- list_add(&ts->hardwall_list, &rect->task_head);
- spin_unlock_irqrestore(&hardwall_lock, flags);
- grant_network_mpls();
- printk(KERN_DEBUG "Pid %d (%s) activated for hardwall: cpu %d\n",
- p->pid, p->comm, cpu);
+ /* Success! This process gets to use the resource on this cpu. */
+ ts->hardwall[hwt->index].info = info;
+ spin_lock_irqsave(&hwt->lock, flags);
+ list_add(&ts->hardwall[hwt->index].list, &info->task_head);
+ spin_unlock_irqrestore(&hwt->lock, flags);
+ grant_hardwall_mpls(hwt);
+ printk(KERN_DEBUG "Pid %d (%s) activated for %s hardwall: cpu %d\n",
+ p->pid, p->comm, hwt->name, cpu);
return 0;
}
/*
- * Deactivate a task's hardwall. Must hold hardwall_lock.
+ * Deactivate a task's hardwall. Must hold lock for hardwall_type.
* This method may be called from free_task(), so we don't want to
* rely on too many fields of struct task_struct still being valid.
* We assume the cpus_allowed, pid, and comm fields are still valid.
*/
-static void _hardwall_deactivate(struct task_struct *task)
+static void _hardwall_deactivate(struct hardwall_type *hwt,
+ struct task_struct *task)
{
struct thread_struct *ts = &task->thread;
if (cpumask_weight(&task->cpus_allowed) != 1) {
- pr_err("pid %d (%s) releasing networks with"
+ pr_err("pid %d (%s) releasing %s hardwall with"
" an affinity mask containing %d cpus!\n",
- task->pid, task->comm,
+ task->pid, task->comm, hwt->name,
cpumask_weight(&task->cpus_allowed));
BUG();
}
- BUG_ON(ts->hardwall == NULL);
- ts->hardwall = NULL;
- list_del(&ts->hardwall_list);
+ BUG_ON(ts->hardwall[hwt->index].info == NULL);
+ ts->hardwall[hwt->index].info = NULL;
+ list_del(&ts->hardwall[hwt->index].list);
if (task == current)
- restrict_network_mpls();
+ restrict_hardwall_mpls(hwt);
}
/* Deactivate a task's hardwall. */
-int hardwall_deactivate(struct task_struct *task)
+static int hardwall_deactivate(struct hardwall_type *hwt,
+ struct task_struct *task)
{
unsigned long flags;
int activated;
- spin_lock_irqsave(&hardwall_lock, flags);
- activated = (task->thread.hardwall != NULL);
+ spin_lock_irqsave(&hwt->lock, flags);
+ activated = (task->thread.hardwall[hwt->index].info != NULL);
if (activated)
- _hardwall_deactivate(task);
- spin_unlock_irqrestore(&hardwall_lock, flags);
+ _hardwall_deactivate(hwt, task);
+ spin_unlock_irqrestore(&hwt->lock, flags);
if (!activated)
return -EINVAL;
- printk(KERN_DEBUG "Pid %d (%s) deactivated for hardwall: cpu %d\n",
- task->pid, task->comm, smp_processor_id());
+ printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n",
+ task->pid, task->comm, hwt->name, smp_processor_id());
return 0;
}
-/* Stop a UDN switch before draining the network. */
-static void stop_udn_switch(void *ignored)
+void hardwall_deactivate_all(struct task_struct *task)
+{
+ int i;
+ for (i = 0; i < HARDWALL_TYPES; ++i)
+ if (task->thread.hardwall[i].info)
+ hardwall_deactivate(&hardwall_types[i], task);
+}
+
+/* Stop the switch before draining the network. */
+static void stop_xdn_switch(void *arg)
{
#if !CHIP_HAS_REV1_XDN()
/* Freeze the switch and the demux. */
@@ -507,13 +674,71 @@ static void stop_udn_switch(void *ignored)
SPR_UDN_SP_FREEZE__SP_FRZ_MASK |
SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK |
SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK);
+#else
+ /*
+ * Drop all packets bound for the core or off the edge.
+ * We rely on the normal hardwall protection setup code
+ * to have set the low four bits to trigger firewall interrupts,
+ * and shift those bits up to trigger "drop on send" semantics,
+ * plus adding "drop on send to core" for all switches.
+ * In practice it seems the switches latch the DIRECTION_PROTECT
+ * SPR so they won't start dropping if they're already
+ * delivering the last message to the core, but it doesn't
+ * hurt to enable it here.
+ */
+ struct hardwall_type *hwt = arg;
+ unsigned long protect = mfspr_XDN(hwt, DIRECTION_PROTECT);
+ mtspr_XDN(hwt, DIRECTION_PROTECT, (protect | C_PROTECT) << 5);
#endif
}
+static void empty_xdn_demuxes(struct hardwall_type *hwt)
+{
+#ifndef __tilepro__
+ if (hwt->is_idn) {
+ while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 0))
+ (void) __tile_idn0_receive();
+ while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 1))
+ (void) __tile_idn1_receive();
+ return;
+ }
+#endif
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
+ (void) __tile_udn0_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
+ (void) __tile_udn1_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
+ (void) __tile_udn2_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
+ (void) __tile_udn3_receive();
+}
+
/* Drain all the state from a stopped switch. */
-static void drain_udn_switch(void *ignored)
+static void drain_xdn_switch(void *arg)
{
-#if !CHIP_HAS_REV1_XDN()
+ struct hardwall_info *info = arg;
+ struct hardwall_type *hwt = info->type;
+
+#if CHIP_HAS_REV1_XDN()
+ /*
+ * The switches have been configured to drop any messages
+ * destined for cores (or off the edge of the rectangle).
+ * But the current message may continue to be delivered,
+ * so we wait until all the cores have finished any pending
+ * messages before we stop draining.
+ */
+ int pending = mfspr_XDN(hwt, PENDING);
+ while (pending--) {
+ empty_xdn_demuxes(hwt);
+ if (hwt->is_idn)
+ __tile_idn_send(0);
+ else
+ __tile_udn_send(0);
+ }
+ atomic_dec(&info->xdn_pending_count);
+ while (atomic_read(&info->xdn_pending_count))
+ empty_xdn_demuxes(hwt);
+#else
int i;
int from_tile_words, ca_count;
@@ -533,15 +758,7 @@ static void drain_udn_switch(void *ignored)
(void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO);
/* Empty out demuxes. */
- while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
- (void) __tile_udn0_receive();
- while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
- (void) __tile_udn1_receive();
- while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
- (void) __tile_udn2_receive();
- while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
- (void) __tile_udn3_receive();
- BUG_ON((__insn_mfspr(SPR_UDN_DATA_AVAIL) & 0xF) != 0);
+ empty_xdn_demuxes(hwt);
/* Empty out catch all. */
ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT);
@@ -563,21 +780,25 @@ static void drain_udn_switch(void *ignored)
#endif
}
-/* Reset random UDN state registers at boot up and during hardwall teardown. */
-void reset_network_state(void)
+/* Reset random XDN state registers at boot up and during hardwall teardown. */
+static void reset_xdn_network_state(struct hardwall_type *hwt)
{
-#if !CHIP_HAS_REV1_XDN()
- /* Reset UDN coordinates to their standard value */
- unsigned int cpu = smp_processor_id();
- unsigned int x = cpu % smp_width;
- unsigned int y = cpu / smp_width;
-#endif
-
- if (udn_disabled)
+ if (hwt->disabled)
return;
+ /* Clear out other random registers so we have a clean slate. */
+ mtspr_XDN(hwt, DIRECTION_PROTECT, 0);
+ mtspr_XDN(hwt, AVAIL_EN, 0);
+ mtspr_XDN(hwt, DEADLOCK_TIMEOUT, 0);
+
#if !CHIP_HAS_REV1_XDN()
- __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
+ /* Reset UDN coordinates to their standard value */
+ {
+ unsigned int cpu = smp_processor_id();
+ unsigned int x = cpu % smp_width;
+ unsigned int y = cpu / smp_width;
+ __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
+ }
/* Set demux tags to predefined values and enable them. */
__insn_mtspr(SPR_UDN_TAG_VALID, 0xf);
@@ -585,56 +806,50 @@ void reset_network_state(void)
__insn_mtspr(SPR_UDN_TAG_1, (1 << 1));
__insn_mtspr(SPR_UDN_TAG_2, (1 << 2));
__insn_mtspr(SPR_UDN_TAG_3, (1 << 3));
-#endif
- /* Clear out other random registers so we have a clean slate. */
- __insn_mtspr(SPR_UDN_AVAIL_EN, 0);
- __insn_mtspr(SPR_UDN_DEADLOCK_TIMEOUT, 0);
-#if !CHIP_HAS_REV1_XDN()
+ /* Set other rev0 random registers to a clean state. */
__insn_mtspr(SPR_UDN_REFILL_EN, 0);
__insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0);
__insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0);
-#endif
/* Start the switch and demux. */
-#if !CHIP_HAS_REV1_XDN()
__insn_mtspr(SPR_UDN_SP_FREEZE, 0);
#endif
}
-/* Restart a UDN switch after draining. */
-static void restart_udn_switch(void *ignored)
+void reset_network_state(void)
{
- reset_network_state();
-
- /* Disable firewall interrupts. */
- __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, 0);
- disable_firewall_interrupts();
+ reset_xdn_network_state(&hardwall_types[HARDWALL_UDN]);
+#ifndef __tilepro__
+ reset_xdn_network_state(&hardwall_types[HARDWALL_IDN]);
+#endif
}
-/* Build a struct cpumask containing all valid tiles in bounding rectangle. */
-static void fill_mask(struct hardwall_info *r, struct cpumask *result)
+/* Restart an XDN switch after draining. */
+static void restart_xdn_switch(void *arg)
{
- int x, y, cpu;
+ struct hardwall_type *hwt = arg;
- cpumask_clear(result);
+#if CHIP_HAS_REV1_XDN()
+ /* One last drain step to avoid races with injection and draining. */
+ empty_xdn_demuxes(hwt);
+#endif
- cpu = r->ulhc_y * smp_width + r->ulhc_x;
- for (y = 0; y < r->height; ++y, cpu += smp_width - r->width) {
- for (x = 0; x < r->width; ++x, ++cpu)
- cpu_online_set(cpu, result);
- }
+ reset_xdn_network_state(hwt);
+
+ /* Disable firewall interrupts. */
+ disable_firewall_interrupts(hwt);
}
/* Last reference to a hardwall is gone, so clear the network. */
-static void hardwall_destroy(struct hardwall_info *rect)
+static void hardwall_destroy(struct hardwall_info *info)
{
struct task_struct *task;
+ struct hardwall_type *hwt;
unsigned long flags;
- struct cpumask mask;
- /* Make sure this file actually represents a rectangle. */
- if (rect == NULL)
+ /* Make sure this file actually represents a hardwall. */
+ if (info == NULL)
return;
/*
@@ -644,39 +859,53 @@ static void hardwall_destroy(struct hardwall_info *rect)
* deactivate any remaining tasks before freeing the
* hardwall_info object itself.
*/
- spin_lock_irqsave(&hardwall_lock, flags);
- list_for_each_entry(task, &rect->task_head, thread.hardwall_list)
- _hardwall_deactivate(task);
- spin_unlock_irqrestore(&hardwall_lock, flags);
-
- /* Drain the UDN. */
- printk(KERN_DEBUG "Clearing hardwall rectangle %dx%d %d,%d\n",
- rect->width, rect->height, rect->ulhc_x, rect->ulhc_y);
- fill_mask(rect, &mask);
- on_each_cpu_mask(&mask, stop_udn_switch, NULL, 1);
- on_each_cpu_mask(&mask, drain_udn_switch, NULL, 1);
+ hwt = info->type;
+ info->teardown_in_progress = 1;
+ spin_lock_irqsave(&hwt->lock, flags);
+ list_for_each_entry(task, &info->task_head,
+ thread.hardwall[hwt->index].list)
+ _hardwall_deactivate(hwt, task);
+ spin_unlock_irqrestore(&hwt->lock, flags);
+
+ if (hwt->is_xdn) {
+ /* Configure the switches for draining the user network. */
+ printk(KERN_DEBUG
+ "Clearing %s hardwall rectangle %dx%d %d,%d\n",
+ hwt->name, info->width, info->height,
+ info->ulhc_x, info->ulhc_y);
+ on_each_cpu_mask(&info->cpumask, stop_xdn_switch, hwt, 1);
+
+ /* Drain the network. */
+#if CHIP_HAS_REV1_XDN()
+ atomic_set(&info->xdn_pending_count,
+ cpumask_weight(&info->cpumask));
+ on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 0);
+#else
+ on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 1);
+#endif
- /* Restart switch and disable firewall. */
- on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
+ /* Restart switch and disable firewall. */
+ on_each_cpu_mask(&info->cpumask, restart_xdn_switch, hwt, 1);
+ }
/* Remove the /proc/tile/hardwall entry. */
- hardwall_remove_proc(rect);
-
- /* Now free the rectangle from the list. */
- spin_lock_irqsave(&hardwall_lock, flags);
- BUG_ON(!list_empty(&rect->task_head));
- list_del(&rect->list);
- spin_unlock_irqrestore(&hardwall_lock, flags);
- kfree(rect);
+ hardwall_remove_proc(info);
+
+ /* Now free the hardwall from the list. */
+ spin_lock_irqsave(&hwt->lock, flags);
+ BUG_ON(!list_empty(&info->task_head));
+ list_del(&info->list);
+ spin_unlock_irqrestore(&hwt->lock, flags);
+ kfree(info);
}
static int hardwall_proc_show(struct seq_file *sf, void *v)
{
- struct hardwall_info *rect = sf->private;
+ struct hardwall_info *info = sf->private;
char buf[256];
- int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask);
+ int rc = cpulist_scnprintf(buf, sizeof(buf), &info->cpumask);
buf[rc++] = '\n';
seq_write(sf, buf, rc);
return 0;
@@ -695,31 +924,45 @@ static const struct file_operations hardwall_proc_fops = {
.release = single_release,
};
-static void hardwall_add_proc(struct hardwall_info *rect)
+static void hardwall_add_proc(struct hardwall_info *info)
{
char buf[64];
- snprintf(buf, sizeof(buf), "%d", rect->id);
- proc_create_data(buf, 0444, hardwall_proc_dir,
- &hardwall_proc_fops, rect);
+ snprintf(buf, sizeof(buf), "%d", info->id);
+ proc_create_data(buf, 0444, info->type->proc_dir,
+ &hardwall_proc_fops, info);
}
-static void hardwall_remove_proc(struct hardwall_info *rect)
+static void hardwall_remove_proc(struct hardwall_info *info)
{
char buf[64];
- snprintf(buf, sizeof(buf), "%d", rect->id);
- remove_proc_entry(buf, hardwall_proc_dir);
+ snprintf(buf, sizeof(buf), "%d", info->id);
+ remove_proc_entry(buf, info->type->proc_dir);
}
int proc_pid_hardwall(struct task_struct *task, char *buffer)
{
- struct hardwall_info *rect = task->thread.hardwall;
- return rect ? sprintf(buffer, "%d\n", rect->id) : 0;
+ int i;
+ int n = 0;
+ for (i = 0; i < HARDWALL_TYPES; ++i) {
+ struct hardwall_info *info = task->thread.hardwall[i].info;
+ if (info)
+ n += sprintf(&buffer[n], "%s: %d\n",
+ info->type->name, info->id);
+ }
+ return n;
}
void proc_tile_hardwall_init(struct proc_dir_entry *root)
{
- if (!udn_disabled)
- hardwall_proc_dir = proc_mkdir("hardwall", root);
+ int i;
+ for (i = 0; i < HARDWALL_TYPES; ++i) {
+ struct hardwall_type *hwt = &hardwall_types[i];
+ if (hwt->disabled)
+ continue;
+ if (hardwall_proc_dir == NULL)
+ hardwall_proc_dir = proc_mkdir("hardwall", root);
+ hwt->proc_dir = proc_mkdir(hwt->name, hardwall_proc_dir);
+ }
}
@@ -729,34 +972,45 @@ void proc_tile_hardwall_init(struct proc_dir_entry *root)
static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
{
- struct hardwall_info *rect = file->private_data;
+ struct hardwall_info *info = file->private_data;
+ int minor = iminor(file->f_mapping->host);
+ struct hardwall_type* hwt;
if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE)
return -EINVAL;
+ BUILD_BUG_ON(HARDWALL_TYPES != _HARDWALL_TYPES);
+ BUILD_BUG_ON(HARDWALL_TYPES !=
+ sizeof(hardwall_types)/sizeof(hardwall_types[0]));
+
+ if (minor < 0 || minor >= HARDWALL_TYPES)
+ return -EINVAL;
+ hwt = &hardwall_types[minor];
+ WARN_ON(info && hwt != info->type);
+
switch (_IOC_NR(a)) {
case _HARDWALL_CREATE:
- if (udn_disabled)
+ if (hwt->disabled)
return -ENOSYS;
- if (rect != NULL)
+ if (info != NULL)
return -EALREADY;
- rect = hardwall_create(_IOC_SIZE(a),
- (const unsigned char __user *)b);
- if (IS_ERR(rect))
- return PTR_ERR(rect);
- file->private_data = rect;
+ info = hardwall_create(hwt, _IOC_SIZE(a),
+ (const unsigned char __user *)b);
+ if (IS_ERR(info))
+ return PTR_ERR(info);
+ file->private_data = info;
return 0;
case _HARDWALL_ACTIVATE:
- return hardwall_activate(rect);
+ return hardwall_activate(info);
case _HARDWALL_DEACTIVATE:
- if (current->thread.hardwall != rect)
+ if (current->thread.hardwall[hwt->index].info != info)
return -EINVAL;
- return hardwall_deactivate(current);
+ return hardwall_deactivate(hwt, current);
case _HARDWALL_GET_ID:
- return rect ? rect->id : -EINVAL;
+ return info ? info->id : -EINVAL;
default:
return -EINVAL;
@@ -775,26 +1029,28 @@ static long hardwall_compat_ioctl(struct file *file,
/* The user process closed the file; revoke access to user networks. */
static int hardwall_flush(struct file *file, fl_owner_t owner)
{
- struct hardwall_info *rect = file->private_data;
+ struct hardwall_info *info = file->private_data;
struct task_struct *task, *tmp;
unsigned long flags;
- if (rect) {
+ if (info) {
/*
* NOTE: if multiple threads are activated on this hardwall
* file, the other threads will continue having access to the
- * UDN until they are context-switched out and back in again.
+ * user network until they are context-switched out and back
+ * in again.
*
* NOTE: A NULL files pointer means the task is being torn
* down, so in that case we also deactivate it.
*/
- spin_lock_irqsave(&hardwall_lock, flags);
- list_for_each_entry_safe(task, tmp, &rect->task_head,
- thread.hardwall_list) {
+ struct hardwall_type *hwt = info->type;
+ spin_lock_irqsave(&hwt->lock, flags);
+ list_for_each_entry_safe(task, tmp, &info->task_head,
+ thread.hardwall[hwt->index].list) {
if (task->files == owner || task->files == NULL)
- _hardwall_deactivate(task);
+ _hardwall_deactivate(hwt, task);
}
- spin_unlock_irqrestore(&hardwall_lock, flags);
+ spin_unlock_irqrestore(&hwt->lock, flags);
}
return 0;
@@ -824,11 +1080,11 @@ static int __init dev_hardwall_init(void)
int rc;
dev_t dev;
- rc = alloc_chrdev_region(&dev, 0, 1, "hardwall");
+ rc = alloc_chrdev_region(&dev, 0, HARDWALL_TYPES, "hardwall");
if (rc < 0)
return rc;
cdev_init(&hardwall_dev, &dev_hardwall_fops);
- rc = cdev_add(&hardwall_dev, dev, 1);
+ rc = cdev_add(&hardwall_dev, dev, HARDWALL_TYPES);
if (rc < 0)
return rc;
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
index 1a39b7c1c87e..f71bfeeaf1a9 100644
--- a/arch/tile/kernel/head_32.S
+++ b/arch/tile/kernel/head_32.S
@@ -69,7 +69,7 @@ ENTRY(_start)
}
{
moveli lr, lo16(1f)
- move r5, zero
+ moveli r5, CTX_PAGE_FLAG
}
{
auli lr, lr, ha16(1f)
@@ -141,11 +141,11 @@ ENTRY(empty_zero_page)
.macro PTE va, cpa, bits1, no_org=0
.ifeq \no_org
- .org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE
+ .org swapper_pg_dir + PGD_INDEX(\va) * HV_PTE_SIZE
.endif
.word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
(HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
- .word (\bits1) | (HV_CPA_TO_PFN(\cpa) << (HV_PTE_INDEX_PFN - 32))
+ .word (\bits1) | (HV_CPA_TO_PTFN(\cpa) << (HV_PTE_INDEX_PTFN - 32))
.endm
__PAGE_ALIGNED_DATA
@@ -166,7 +166,7 @@ ENTRY(swapper_pg_dir)
/* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \
(1 << (HV_PTE_INDEX_EXECUTABLE - 32))
- .org swapper_pg_dir + HV_L1_SIZE
+ .org swapper_pg_dir + PGDIR_SIZE
END(swapper_pg_dir)
/*
diff --git a/arch/tile/kernel/head_64.S b/arch/tile/kernel/head_64.S
index 6bc3a932fe45..f9a2734f7b82 100644
--- a/arch/tile/kernel/head_64.S
+++ b/arch/tile/kernel/head_64.S
@@ -114,7 +114,7 @@ ENTRY(_start)
shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
}
{
- move r3, zero
+ moveli r3, CTX_PAGE_FLAG
j hv_install_context
}
1:
@@ -210,19 +210,19 @@ ENTRY(empty_zero_page)
.macro PTE cpa, bits1
.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
- (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
+ (\bits1) | (HV_CPA_TO_PTFN(\cpa) << HV_PTE_INDEX_PTFN)
.endm
__PAGE_ALIGNED_DATA
.align PAGE_SIZE
ENTRY(swapper_pg_dir)
- .org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
+ .org swapper_pg_dir + PGD_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
.Lsv_data_pmd:
.quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
- .org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
+ .org swapper_pg_dir + PGD_INDEX(MEM_SV_START) * HV_PTE_SIZE
.Lsv_code_pmd:
.quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
- .org swapper_pg_dir + HV_L0_SIZE
+ .org swapper_pg_dir + SIZEOF_PGD
END(swapper_pg_dir)
.align HV_PAGE_TABLE_ALIGN
@@ -233,11 +233,11 @@ ENTRY(temp_data_pmd)
* permissions later.
*/
.set addr, 0
- .rept HV_L1_ENTRIES
+ .rept PTRS_PER_PMD
PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
- .set addr, addr + HV_PAGE_SIZE_LARGE
+ .set addr, addr + HPAGE_SIZE
.endr
- .org temp_data_pmd + HV_L1_SIZE
+ .org temp_data_pmd + SIZEOF_PMD
END(temp_data_pmd)
.align HV_PAGE_TABLE_ALIGN
@@ -248,11 +248,11 @@ ENTRY(temp_code_pmd)
* permissions later.
*/
.set addr, 0
- .rept HV_L1_ENTRIES
+ .rept PTRS_PER_PMD
PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
- .set addr, addr + HV_PAGE_SIZE_LARGE
+ .set addr, addr + HPAGE_SIZE
.endr
- .org temp_code_pmd + HV_L1_SIZE
+ .org temp_code_pmd + SIZEOF_PMD
END(temp_code_pmd)
/*
diff --git a/arch/tile/kernel/hvglue.lds b/arch/tile/kernel/hvglue.lds
index 2b7cd0a659a9..d44c5a67a1ed 100644
--- a/arch/tile/kernel/hvglue.lds
+++ b/arch/tile/kernel/hvglue.lds
@@ -55,4 +55,5 @@ hv_store_mapping = TEXT_OFFSET + 0x106a0;
hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
hv_flush_all = TEXT_OFFSET + 0x106e0;
hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
-hv_glue_internals = TEXT_OFFSET + 0x10720;
+hv_set_pte_super_shift = TEXT_OFFSET + 0x10720;
+hv_glue_internals = TEXT_OFFSET + 0x10740;
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 30ae76e50c44..7c06d597ffd0 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -220,7 +220,9 @@ intvec_\vecname:
* This routine saves just the first four registers, plus the
* stack context so we can do proper backtracing right away,
* and defers to handle_interrupt to save the rest.
- * The backtracer needs pc, ex1, lr, sp, r52, and faultnum.
+ * The backtracer needs pc, ex1, lr, sp, r52, and faultnum,
+ * and needs sp set to its final location at the bottom of
+ * the stack frame.
*/
addli r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP)
wh64 r0 /* cache line 7 */
@@ -450,23 +452,6 @@ intvec_\vecname:
push_reg r5, r52
st r52, r4
- /* Load tp with our per-cpu offset. */
-#ifdef CONFIG_SMP
- {
- mfspr r20, SPR_SYSTEM_SAVE_K_0
- moveli r21, hw2_last(__per_cpu_offset)
- }
- {
- shl16insli r21, r21, hw1(__per_cpu_offset)
- bfextu r20, r20, 0, LOG2_THREAD_SIZE-1
- }
- shl16insli r21, r21, hw0(__per_cpu_offset)
- shl3add r20, r20, r21
- ld tp, r20
-#else
- move tp, zero
-#endif
-
/*
* If we will be returning to the kernel, we will need to
* reset the interrupt masks to the state they had before.
@@ -489,6 +474,44 @@ intvec_\vecname:
.endif
st r21, r32
+ /*
+ * we've captured enough state to the stack (including in
+ * particular our EX_CONTEXT state) that we can now release
+ * the interrupt critical section and replace it with our
+ * standard "interrupts disabled" mask value. This allows
+ * synchronous interrupts (and profile interrupts) to punch
+ * through from this point onwards.
+ *
+ * It's important that no code before this point touch memory
+ * other than our own stack (to keep the invariant that this
+ * is all that gets touched under ICS), and that no code after
+ * this point reference any interrupt-specific SPR, in particular
+ * the EX_CONTEXT_K_ values.
+ */
+ .ifc \function,handle_nmi
+ IRQ_DISABLE_ALL(r20)
+ .else
+ IRQ_DISABLE(r20, r21)
+ .endif
+ mtspr INTERRUPT_CRITICAL_SECTION, zero
+
+ /* Load tp with our per-cpu offset. */
+#ifdef CONFIG_SMP
+ {
+ mfspr r20, SPR_SYSTEM_SAVE_K_0
+ moveli r21, hw2_last(__per_cpu_offset)
+ }
+ {
+ shl16insli r21, r21, hw1(__per_cpu_offset)
+ bfextu r20, r20, 0, LOG2_THREAD_SIZE-1
+ }
+ shl16insli r21, r21, hw0(__per_cpu_offset)
+ shl3add r20, r20, r21
+ ld tp, r20
+#else
+ move tp, zero
+#endif
+
#ifdef __COLLECT_LINKER_FEEDBACK__
/*
* Notify the feedback routines that we were in the
@@ -513,21 +536,6 @@ intvec_\vecname:
#endif
/*
- * we've captured enough state to the stack (including in
- * particular our EX_CONTEXT state) that we can now release
- * the interrupt critical section and replace it with our
- * standard "interrupts disabled" mask value. This allows
- * synchronous interrupts (and profile interrupts) to punch
- * through from this point onwards.
- */
- .ifc \function,handle_nmi
- IRQ_DISABLE_ALL(r20)
- .else
- IRQ_DISABLE(r20, r21)
- .endif
- mtspr INTERRUPT_CRITICAL_SECTION, zero
-
- /*
* Prepare the first 256 stack bytes to be rapidly accessible
* without having to fetch the background data.
*/
@@ -736,9 +744,10 @@ STD_ENTRY(interrupt_return)
beqzt r30, .Lrestore_regs
j 3f
2: TRACE_IRQS_ON
+ IRQ_ENABLE_LOAD(r20, r21)
movei r0, 1
mtspr INTERRUPT_CRITICAL_SECTION, r0
- IRQ_ENABLE(r20, r21)
+ IRQ_ENABLE_APPLY(r20, r21)
beqzt r30, .Lrestore_regs
3:
@@ -755,7 +764,6 @@ STD_ENTRY(interrupt_return)
* that will save some cycles if this turns out to be a syscall.
*/
.Lrestore_regs:
- FEEDBACK_REENTER(interrupt_return) /* called from elsewhere */
/*
* Rotate so we have one high bit and one low bit to test.
@@ -1249,7 +1257,7 @@ STD_ENTRY(fill_ra_stack)
int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
- int_hand INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr
+ int_hand INT_IDN_FIREWALL, IDN_FIREWALL, do_hardwall_trap
int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
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 6255f2eab112..f0b54a934712 100644
--- a/arch/tile/kernel/machine_kexec.c
+++ b/arch/tile/kernel/machine_kexec.c
@@ -31,6 +31,8 @@
#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <asm/checksum.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
#include <hv/hypervisor.h>
@@ -222,11 +224,22 @@ struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order)
return alloc_pages_node(0, gfp_mask, order);
}
+/*
+ * Address range in which pa=va mapping is set in setup_quasi_va_is_pa().
+ * For tilepro, PAGE_OFFSET is used since this is the largest possbile value
+ * for tilepro, while for tilegx, we limit it to entire middle level page
+ * table which we assume has been allocated and is undoubtedly large enough.
+ */
+#ifndef __tilegx__
+#define QUASI_VA_IS_PA_ADDR_RANGE PAGE_OFFSET
+#else
+#define QUASI_VA_IS_PA_ADDR_RANGE PGDIR_SIZE
+#endif
+
static void setup_quasi_va_is_pa(void)
{
- HV_PTE *pgtable;
HV_PTE pte;
- int i;
+ unsigned long i;
/*
* Flush our TLB to prevent conflicts between the previous contents
@@ -234,16 +247,22 @@ static void setup_quasi_va_is_pa(void)
*/
local_flush_tlb_all();
- /* setup VA is PA, at least up to PAGE_OFFSET */
-
- pgtable = (HV_PTE *)current->mm->pgd;
+ /*
+ * setup VA is PA, at least up to QUASI_VA_IS_PA_ADDR_RANGE.
+ * Note here we assume that level-1 page table is defined by
+ * HPAGE_SIZE.
+ */
pte = hv_pte(_PAGE_KERNEL | _PAGE_HUGE_PAGE);
pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
-
- for (i = 0; i < pgd_index(PAGE_OFFSET); i++) {
+ for (i = 0; i < (QUASI_VA_IS_PA_ADDR_RANGE >> HPAGE_SHIFT); i++) {
+ unsigned long vaddr = i << HPAGE_SHIFT;
+ pgd_t *pgd = pgd_offset(current->mm, vaddr);
+ pud_t *pud = pud_offset(pgd, vaddr);
+ pte_t *ptep = (pte_t *) pmd_offset(pud, vaddr);
unsigned long pfn = i << (HPAGE_SHIFT - PAGE_SHIFT);
+
if (pfn_valid(pfn))
- __set_pte(&pgtable[i], pfn_pte(pfn, pte));
+ __set_pte(ptep, pfn_pte(pfn, pte));
}
}
@@ -251,6 +270,7 @@ static void setup_quasi_va_is_pa(void)
void machine_kexec(struct kimage *image)
{
void *reboot_code_buffer;
+ pte_t *ptep;
void (*rnk)(unsigned long, void *, unsigned long)
__noreturn;
@@ -266,8 +286,10 @@ void machine_kexec(struct kimage *image)
*/
homecache_change_page_home(image->control_code_page, 0,
smp_processor_id());
- reboot_code_buffer = vmap(&image->control_code_page, 1, 0,
- __pgprot(_PAGE_KERNEL | _PAGE_EXECUTABLE));
+ reboot_code_buffer = page_address(image->control_code_page);
+ BUG_ON(reboot_code_buffer == NULL);
+ ptep = virt_to_pte(NULL, (unsigned long)reboot_code_buffer);
+ __set_pte(ptep, pte_mkexec(*ptep));
memcpy(reboot_code_buffer, relocate_new_kernel,
relocate_new_kernel_size);
__flush_icache_range(
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
index 98d476920106..001cbfa10ac6 100644
--- a/arch/tile/kernel/module.c
+++ b/arch/tile/kernel/module.c
@@ -159,7 +159,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
switch (ELF_R_TYPE(rel[i].r_info)) {
-#define MUNGE(func) (*location = ((*location & ~func(-1)) | func(value)))
+#ifdef __LITTLE_ENDIAN
+# define MUNGE(func) \
+ (*location = ((*location & ~func(-1)) | func(value)))
+#else
+/*
+ * Instructions are always little-endian, so when we read them as data,
+ * we have to swap them around before and after modifying them.
+ */
+# define MUNGE(func) \
+ (*location = swab64((swab64(*location) & ~func(-1)) | func(value)))
+#endif
#ifndef __tilegx__
case R_TILE_32:
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c
index 446a7f52cc11..dafc447b5125 100644
--- a/arch/tile/kernel/proc.c
+++ b/arch/tile/kernel/proc.c
@@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/hardirq.h>
+#include <linux/hugetlb.h>
#include <linux/mman.h>
#include <asm/unaligned.h>
#include <asm/pgtable.h>
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
index f572c19c4082..ba1023d8a021 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)
* Calling deactivate here just frees up the data structures.
* If the task we're freeing held the last reference to a
* hardwall fd, it would have been released prior to this point
- * anyway via exit_files(), and "hardwall" would be NULL by now.
+ * anyway via exit_files(), and the hardwall_task.info pointers
+ * would be NULL by now.
*/
- if (info->task->thread.hardwall)
- hardwall_deactivate(info->task);
+ hardwall_deactivate_all(info->task);
#endif
if (step_state) {
@@ -245,7 +245,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
#ifdef CONFIG_HARDWALL
/* New thread does not own any networks. */
- p->thread.hardwall = NULL;
+ memset(&p->thread.hardwall[0], 0,
+ sizeof(struct hardwall_task) * HARDWALL_TYPES);
#endif
@@ -515,12 +516,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
#ifdef CONFIG_HARDWALL
/* Enable or disable access to the network registers appropriately. */
- if (prev->thread.hardwall != NULL) {
- if (next->thread.hardwall == NULL)
- restrict_network_mpls();
- } else if (next->thread.hardwall != NULL) {
- grant_network_mpls();
- }
+ hardwall_switch_tasks(prev, next);
#endif
/*
diff --git a/arch/tile/kernel/relocate_kernel.S b/arch/tile/kernel/relocate_kernel_32.S
index 010b418515f8..010b418515f8 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 000000000000..1c09a4f5a4ea
--- /dev/null
+++ b/arch/tile/kernel/relocate_kernel_64.S
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * copy new kernel into place and then call hv_reexec
+ *
+ */
+
+#include <linux/linkage.h>
+#include <arch/chip.h>
+#include <asm/page.h>
+#include <hv/hypervisor.h>
+
+#undef RELOCATE_NEW_KERNEL_VERBOSE
+
+STD_ENTRY(relocate_new_kernel)
+
+ move r30, r0 /* page list */
+ move r31, r1 /* address of page we are on */
+ move r32, r2 /* start address of new kernel */
+
+ shrui r1, r1, PAGE_SHIFT
+ addi r1, r1, 1
+ shli sp, r1, PAGE_SHIFT
+ addi sp, sp, -8
+ /* we now have a stack (whether we need one or not) */
+
+ moveli r40, hw2_last(hv_console_putc)
+ shl16insli r40, r40, hw1(hv_console_putc)
+ shl16insli r40, r40, hw0(hv_console_putc)
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'r'
+ jalr r40
+
+ moveli r0, '_'
+ jalr r40
+
+ moveli r0, 'n'
+ jalr r40
+
+ moveli r0, '_'
+ jalr r40
+
+ moveli r0, 'k'
+ jalr r40
+
+ moveli r0, '\n'
+ jalr r40
+#endif
+
+ /*
+ * Throughout this code r30 is pointer to the element of page
+ * list we are working on.
+ *
+ * Normally we get to the next element of the page list by
+ * incrementing r30 by eight. The exception is if the element
+ * on the page list is an IND_INDIRECTION in which case we use
+ * the element with the low bits masked off as the new value
+ * of r30.
+ *
+ * To get this started, we need the value passed to us (which
+ * will always be an IND_INDIRECTION) in memory somewhere with
+ * r30 pointing at it. To do that, we push the value passed
+ * to us on the stack and make r30 point to it.
+ */
+
+ st sp, r30
+ move r30, sp
+ addi sp, sp, -16
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ /*
+ * On TILE-GX, we need to flush all tiles' caches, since we may
+ * have been doing hash-for-home caching there. Note that we
+ * must do this _after_ we're completely done modifying any memory
+ * other than our output buffer (which we know is locally cached).
+ * We want the caches to be fully clean when we do the reexec,
+ * because the hypervisor is going to do this flush again at that
+ * point, and we don't want that second flush to overwrite any memory.
+ */
+ {
+ move r0, zero /* cache_pa */
+ moveli r1, hw2_last(HV_FLUSH_EVICT_L2)
+ }
+ {
+ shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)
+ movei r2, -1 /* cache_cpumask; -1 means all client tiles */
+ }
+ {
+ shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2) /* cache_control */
+ move r3, zero /* tlb_va */
+ }
+ {
+ move r4, zero /* tlb_length */
+ move r5, zero /* tlb_pgsize */
+ }
+ {
+ move r6, zero /* tlb_cpumask */
+ move r7, zero /* asids */
+ }
+ {
+ moveli r20, hw2_last(hv_flush_remote)
+ move r8, zero /* asidcount */
+ }
+ shl16insli r20, r20, hw1(hv_flush_remote)
+ shl16insli r20, r20, hw0(hv_flush_remote)
+
+ jalr r20
+#endif
+
+ /* r33 is destination pointer, default to zero */
+
+ moveli r33, 0
+
+.Lloop: ld r10, r30
+
+ andi r9, r10, 0xf /* low 4 bits tell us what type it is */
+ xor r10, r10, r9 /* r10 is now value with low 4 bits stripped */
+
+ cmpeqi r0, r9, 0x1 /* IND_DESTINATION */
+ beqzt r0, .Ltry2
+
+ move r33, r10
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'd'
+ jalr r40
+#endif
+
+ addi r30, r30, 8
+ j .Lloop
+
+.Ltry2:
+ cmpeqi r0, r9, 0x2 /* IND_INDIRECTION */
+ beqzt r0, .Ltry4
+
+ move r30, r10
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'i'
+ jalr r40
+#endif
+
+ j .Lloop
+
+.Ltry4:
+ cmpeqi r0, r9, 0x4 /* IND_DONE */
+ beqzt r0, .Ltry8
+
+ mf
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'D'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+#endif
+
+ move r0, r32
+
+ moveli r41, hw2_last(hv_reexec)
+ shl16insli r41, r41, hw1(hv_reexec)
+ shl16insli r41, r41, hw0(hv_reexec)
+
+ jalr r41
+
+ /* we should not get here */
+
+ moveli r0, '?'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+
+ j .Lhalt
+
+.Ltry8: cmpeqi r0, r9, 0x8 /* IND_SOURCE */
+ beqz r0, .Lerr /* unknown type */
+
+ /* copy page at r10 to page at r33 */
+
+ move r11, r33
+
+ moveli r0, hw2_last(PAGE_SIZE)
+ shl16insli r0, r0, hw1(PAGE_SIZE)
+ shl16insli r0, r0, hw0(PAGE_SIZE)
+ add r33, r33, r0
+
+ /* copy word at r10 to word at r11 until r11 equals r33 */
+
+ /* We know page size must be multiple of 8, so we can unroll
+ * 8 times safely without any edge case checking.
+ *
+ * Issue a flush of the destination every 8 words to avoid
+ * incoherence when starting the new kernel. (Now this is
+ * just good paranoia because the hv_reexec call will also
+ * take care of this.)
+ */
+
+1:
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0; addi r11, r11, 8 }
+ { ld r0, r10; addi r10, r10, 8 }
+ { st r11, r0 }
+ { flush r11 ; addi r11, r11, 8 }
+
+ cmpeq r0, r33, r11
+ beqzt r0, 1b
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 's'
+ jalr r40
+#endif
+
+ addi r30, r30, 8
+ j .Lloop
+
+
+.Lerr: moveli r0, 'e'
+ jalr r40
+ moveli r0, 'r'
+ jalr r40
+ moveli r0, 'r'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+.Lhalt:
+ moveli r41, hw2_last(hv_halt)
+ shl16insli r41, r41, hw1(hv_halt)
+ shl16insli r41, r41, hw0(hv_halt)
+
+ jalr r41
+ STD_ENDPROC(relocate_new_kernel)
+
+ .section .rodata,"a"
+
+ .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+ .long .Lend_relocate_new_kernel - relocate_new_kernel
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index 98d80eb49ddb..6098ccc59be2 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -28,6 +28,7 @@
#include <linux/highmem.h>
#include <linux/smp.h>
#include <linux/timex.h>
+#include <linux/hugetlb.h>
#include <asm/setup.h>
#include <asm/sections.h>
#include <asm/cacheflush.h>
@@ -49,9 +50,6 @@ char chip_model[64] __write_once;
struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data);
-/* We only create bootmem data on node 0. */
-static bootmem_data_t __initdata node0_bdata;
-
/* Information on the NUMA nodes that we compute early */
unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
@@ -534,37 +532,96 @@ static void __init setup_memory(void)
#endif
}
-static void __init setup_bootmem_allocator(void)
+/*
+ * On 32-bit machines, we only put bootmem on the low controller,
+ * since PAs > 4GB can't be used in bootmem. In principle one could
+ * imagine, e.g., multiple 1 GB controllers all of which could support
+ * bootmem, but in practice using controllers this small isn't a
+ * particularly interesting scenario, so we just keep it simple and
+ * use only the first controller for bootmem on 32-bit machines.
+ */
+static inline int node_has_bootmem(int nid)
{
- unsigned long bootmap_size, first_alloc_pfn, last_alloc_pfn;
+#ifdef CONFIG_64BIT
+ return 1;
+#else
+ return nid == 0;
+#endif
+}
- /* Provide a node 0 bdata. */
- NODE_DATA(0)->bdata = &node0_bdata;
+static inline unsigned long alloc_bootmem_pfn(int nid,
+ unsigned long size,
+ unsigned long goal)
+{
+ void *kva = __alloc_bootmem_node(NODE_DATA(nid), size,
+ PAGE_SIZE, goal);
+ unsigned long pfn = kaddr_to_pfn(kva);
+ BUG_ON(goal && PFN_PHYS(pfn) != goal);
+ return pfn;
+}
-#ifdef CONFIG_PCI
- /* Don't let boot memory alias the PCI region. */
- last_alloc_pfn = min(max_low_pfn, pci_reserve_start_pfn);
+static void __init setup_bootmem_allocator_node(int i)
+{
+ unsigned long start, end, mapsize, mapstart;
+
+ if (node_has_bootmem(i)) {
+ NODE_DATA(i)->bdata = &bootmem_node_data[i];
+ } else {
+ /* Share controller zero's bdata for now. */
+ NODE_DATA(i)->bdata = &bootmem_node_data[0];
+ return;
+ }
+
+ /* Skip up to after the bss in node 0. */
+ start = (i == 0) ? min_low_pfn : node_start_pfn[i];
+
+ /* Only lowmem, if we're a HIGHMEM build. */
+#ifdef CONFIG_HIGHMEM
+ end = node_lowmem_end_pfn[i];
#else
- last_alloc_pfn = max_low_pfn;
+ end = node_end_pfn[i];
#endif
- /*
- * Initialize the boot-time allocator (with low memory only):
- * The first argument says where to put the bitmap, and the
- * second says where the end of allocatable memory is.
- */
- bootmap_size = init_bootmem(min_low_pfn, last_alloc_pfn);
+ /* No memory here. */
+ if (end == start)
+ return;
+
+ /* Figure out where the bootmem bitmap is located. */
+ mapsize = bootmem_bootmap_pages(end - start);
+ if (i == 0) {
+ /* Use some space right before the heap on node 0. */
+ mapstart = start;
+ start += mapsize;
+ } else {
+ /* Allocate bitmap on node 0 to avoid page table issues. */
+ mapstart = alloc_bootmem_pfn(0, PFN_PHYS(mapsize), 0);
+ }
+ /* Initialize a node. */
+ init_bootmem_node(NODE_DATA(i), mapstart, start, end);
+
+ /* Free all the space back into the allocator. */
+ free_bootmem(PFN_PHYS(start), PFN_PHYS(end - start));
+
+#if defined(CONFIG_PCI)
/*
- * Let the bootmem allocator use all the space we've given it
- * except for its own bitmap.
+ * Throw away any memory aliased by the PCI region. FIXME: this
+ * is a temporary hack to work around bug 10502, and needs to be
+ * fixed properly.
*/
- first_alloc_pfn = min_low_pfn + PFN_UP(bootmap_size);
- if (first_alloc_pfn >= last_alloc_pfn)
- early_panic("Not enough memory on controller 0 for bootmem\n");
+ if (pci_reserve_start_pfn < end && pci_reserve_end_pfn > start)
+ reserve_bootmem(PFN_PHYS(pci_reserve_start_pfn),
+ PFN_PHYS(pci_reserve_end_pfn -
+ pci_reserve_start_pfn),
+ BOOTMEM_EXCLUSIVE);
+#endif
+}
- free_bootmem(PFN_PHYS(first_alloc_pfn),
- PFN_PHYS(last_alloc_pfn - first_alloc_pfn));
+static void __init setup_bootmem_allocator(void)
+{
+ int i;
+ for (i = 0; i < MAX_NUMNODES; ++i)
+ setup_bootmem_allocator_node(i);
#ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end)
@@ -595,14 +652,6 @@ static int __init percpu_size(void)
return size;
}
-static inline unsigned long alloc_bootmem_pfn(int size, unsigned long goal)
-{
- void *kva = __alloc_bootmem(size, PAGE_SIZE, goal);
- unsigned long pfn = kaddr_to_pfn(kva);
- BUG_ON(goal && PFN_PHYS(pfn) != goal);
- return pfn;
-}
-
static void __init zone_sizes_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = { 0 };
@@ -640,21 +689,22 @@ static void __init zone_sizes_init(void)
* though, there'll be no lowmem, so we just alloc_bootmem
* the memmap. There will be no percpu memory either.
*/
- if (__pfn_to_highbits(start) == 0) {
- /* In low PAs, allocate via bootmem. */
+ if (i != 0 && cpu_isset(i, isolnodes)) {
+ node_memmap_pfn[i] =
+ alloc_bootmem_pfn(0, memmap_size, 0);
+ BUG_ON(node_percpu[i] != 0);
+ } else if (node_has_bootmem(start)) {
unsigned long goal = 0;
node_memmap_pfn[i] =
- alloc_bootmem_pfn(memmap_size, goal);
+ alloc_bootmem_pfn(i, memmap_size, 0);
if (kdata_huge)
goal = PFN_PHYS(lowmem_end) - node_percpu[i];
if (node_percpu[i])
node_percpu_pfn[i] =
- alloc_bootmem_pfn(node_percpu[i], goal);
- } else if (cpu_isset(i, isolnodes)) {
- node_memmap_pfn[i] = alloc_bootmem_pfn(memmap_size, 0);
- BUG_ON(node_percpu[i] != 0);
+ alloc_bootmem_pfn(i, node_percpu[i],
+ goal);
} else {
- /* In high PAs, just reserve some pages. */
+ /* In non-bootmem zones, just reserve some pages. */
node_memmap_pfn[i] = node_free_pfn[i];
node_free_pfn[i] += PFN_UP(memmap_size);
if (!kdata_huge) {
@@ -678,16 +728,9 @@ static void __init zone_sizes_init(void)
zones_size[ZONE_NORMAL] = end - start;
#endif
- /*
- * Everyone shares node 0's bootmem allocator, but
- * we use alloc_remap(), above, to put the actual
- * struct page array on the individual controllers,
- * which is most of the data that we actually care about.
- * We can't place bootmem allocators on the other
- * controllers since the bootmem allocator can only
- * operate on 32-bit physical addresses.
- */
- NODE_DATA(i)->bdata = NODE_DATA(0)->bdata;
+ /* Take zone metadata from controller 0 if we're isolnode. */
+ if (node_isset(i, isolnodes))
+ NODE_DATA(i)->bdata = &bootmem_node_data[0];
free_area_init_node(i, zones_size, start, NULL);
printk(KERN_DEBUG " Normal zone: %ld per-cpu pages\n",
@@ -870,6 +913,22 @@ subsys_initcall(topology_init);
#endif /* CONFIG_NUMA */
+/*
+ * Initialize hugepage support on this cpu. We do this on all cores
+ * early in boot: before argument parsing for the boot cpu, and after
+ * argument parsing but before the init functions run on the secondaries.
+ * So the values we set up here in the hypervisor may be overridden on
+ * the boot cpu as arguments are parsed.
+ */
+static __cpuinit void init_super_pages(void)
+{
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+ int i;
+ for (i = 0; i < HUGE_SHIFT_ENTRIES; ++i)
+ hv_set_pte_super_shift(i, huge_shift[i]);
+#endif
+}
+
/**
* setup_cpu() - Do all necessary per-cpu, tile-specific initialization.
* @boot: Is this the boot cpu?
@@ -924,6 +983,8 @@ void __cpuinit setup_cpu(int boot)
/* Reset the network state on this cpu. */
reset_network_state();
#endif
+
+ init_super_pages();
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -1412,13 +1473,13 @@ void __init setup_per_cpu_areas(void)
for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
/* Update the vmalloc mapping and page home. */
- pte_t *ptep =
- virt_to_pte(NULL, (unsigned long)ptr + i);
+ unsigned long addr = (unsigned long)ptr + i;
+ pte_t *ptep = virt_to_pte(NULL, addr);
pte_t pte = *ptep;
BUG_ON(pfn != pte_pfn(pte));
pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
pte = set_remote_cache_cpu(pte, cpu);
- set_pte(ptep, pte);
+ set_pte_at(&init_mm, addr, ptep, pte);
/* Update the lowmem mapping for consistency. */
lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
@@ -1431,7 +1492,7 @@ void __init setup_per_cpu_areas(void)
BUG_ON(pte_huge(*ptep));
}
BUG_ON(pfn != pte_pfn(*ptep));
- set_pte(ptep, pte);
+ set_pte_at(&init_mm, lowmem_va, ptep, pte);
}
}
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 89529c9f0605..27742e87e255 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(
return (tilepro_bundle_bits) 0;
}
-#ifndef __LITTLE_ENDIAN
-# error We assume little-endian representation with copy_xx_user size 2 here
-#endif
/* Handle unaligned load/store */
if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
unsigned short val_16;
@@ -195,8 +192,19 @@ static tile_bundle_bits rewrite_load_store_unaligned(
state->update = 1;
}
} else {
+ unsigned short val_16;
val = (val_reg == TREG_ZERO) ? 0 : regs->regs[val_reg];
- err = copy_to_user(addr, &val, size);
+ switch (size) {
+ case 2:
+ val_16 = val;
+ err = copy_to_user(addr, &val_16, sizeof(val_16));
+ break;
+ case 4:
+ err = copy_to_user(addr, &val, sizeof(val));
+ break;
+ default:
+ BUG();
+ }
}
if (err) {
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index 91da0f721958..cbc73a8b8fe1 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -203,7 +203,7 @@ void __init ipi_init(void)
if (hv_get_ipi_pte(tile, KERNEL_PL, &pte) != 0)
panic("Failed to initialize IPI for cpu %d\n", cpu);
- offset = hv_pte_get_pfn(pte) << PAGE_SHIFT;
+ offset = PFN_PHYS(pte_pfn(pte));
ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte);
}
#endif
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
index cb44ba7ccd2d..b08095b402d6 100644
--- a/arch/tile/kernel/sys.c
+++ b/arch/tile/kernel/sys.c
@@ -32,11 +32,17 @@
#include <asm/syscalls.h>
#include <asm/pgtable.h>
#include <asm/homecache.h>
+#include <asm/cachectl.h>
#include <arch/chip.h>
-SYSCALL_DEFINE0(flush_cache)
+SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len,
+ unsigned long, flags)
{
- homecache_evict(cpumask_of(smp_processor_id()));
+ if (flags & DCACHE)
+ homecache_evict(cpumask_of(smp_processor_id()));
+ if (flags & ICACHE)
+ flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(current->mm),
+ 0, 0, 0, NULL, NULL, 0);
return 0;
}
diff --git a/arch/tile/kernel/sysfs.c b/arch/tile/kernel/sysfs.c
index 71ae728e9d0b..e25b0a89c18f 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)
HV_CONF_ATTR(mezz_serial, HV_CONFSTR_MEZZ_SERIAL_NUM)
HV_CONF_ATTR(mezz_revision, HV_CONFSTR_MEZZ_REV)
HV_CONF_ATTR(mezz_description, HV_CONFSTR_MEZZ_DESC)
+HV_CONF_ATTR(cpumod_part, HV_CONFSTR_CPUMOD_PART_NUM)
+HV_CONF_ATTR(cpumod_serial, HV_CONFSTR_CPUMOD_SERIAL_NUM)
+HV_CONF_ATTR(cpumod_revision, HV_CONFSTR_CPUMOD_REV)
+HV_CONF_ATTR(cpumod_description,HV_CONFSTR_CPUMOD_DESC)
HV_CONF_ATTR(switch_control, HV_CONFSTR_SWITCH_CONTROL)
static struct attribute *board_attrs[] = {
@@ -104,6 +108,10 @@ static struct attribute *board_attrs[] = {
&dev_attr_mezz_serial.attr,
&dev_attr_mezz_revision.attr,
&dev_attr_mezz_description.attr,
+ &dev_attr_cpumod_part.attr,
+ &dev_attr_cpumod_serial.attr,
+ &dev_attr_cpumod_revision.attr,
+ &dev_attr_cpumod_description.attr,
&dev_attr_switch_control.attr,
NULL
};
diff --git a/arch/tile/kernel/tlb.c b/arch/tile/kernel/tlb.c
index a5f241c24cac..3fd54d5bbd4c 100644
--- a/arch/tile/kernel/tlb.c
+++ b/arch/tile/kernel/tlb.c
@@ -15,6 +15,7 @@
#include <linux/cpumask.h>
#include <linux/module.h>
+#include <linux/hugetlb.h>
#include <asm/tlbflush.h>
#include <asm/homecache.h>
#include <hv/hypervisor.h>
@@ -49,25 +50,25 @@ void flush_tlb_current_task(void)
flush_tlb_mm(current->mm);
}
-void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm,
+void flush_tlb_page_mm(struct vm_area_struct *vma, struct mm_struct *mm,
unsigned long va)
{
- unsigned long size = hv_page_size(vma);
+ unsigned long size = vma_kernel_pagesize(vma);
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
flush_remote(0, cache, mm_cpumask(mm),
va, size, size, mm_cpumask(mm), NULL, 0);
}
-void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{
flush_tlb_page_mm(vma, vma->vm_mm, va);
}
EXPORT_SYMBOL(flush_tlb_page);
-void flush_tlb_range(const struct vm_area_struct *vma,
+void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- unsigned long size = hv_page_size(vma);
+ unsigned long size = vma_kernel_pagesize(vma);
struct mm_struct *mm = vma->vm_mm;
int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
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 73cff814ac57..5b19a23c8908 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)
return 1;
}
+static const char *const int_name[] = {
+ [INT_MEM_ERROR] = "Memory error",
+ [INT_ILL] = "Illegal instruction",
+ [INT_GPV] = "General protection violation",
+ [INT_UDN_ACCESS] = "UDN access",
+ [INT_IDN_ACCESS] = "IDN access",
+#if CHIP_HAS_SN()
+ [INT_SN_ACCESS] = "SN access",
+#endif
+ [INT_SWINT_3] = "Software interrupt 3",
+ [INT_SWINT_2] = "Software interrupt 2",
+ [INT_SWINT_0] = "Software interrupt 0",
+ [INT_UNALIGN_DATA] = "Unaligned data",
+ [INT_DOUBLE_FAULT] = "Double fault",
+#ifdef __tilegx__
+ [INT_ILL_TRANS] = "Illegal virtual address",
+#endif
+};
+
void __kprobes do_trap(struct pt_regs *regs, int fault_num,
unsigned long reason)
{
@@ -211,10 +230,17 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
* current process and hope for the best.
*/
if (!user_mode(regs)) {
+ const char *name;
if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */
return;
- pr_alert("Kernel took bad trap %d at PC %#lx\n",
- fault_num, regs->pc);
+ if (fault_num >= 0 &&
+ fault_num < sizeof(int_name)/sizeof(int_name[0]) &&
+ int_name[fault_num] != NULL)
+ name = int_name[fault_num];
+ else
+ name = "Unknown interrupt";
+ pr_alert("Kernel took bad trap %d (%s) at PC %#lx\n",
+ fault_num, name, regs->pc);
if (fault_num == INT_GPV)
pr_alert("GPV_REASON is %#lx\n", reason);
show_regs(regs);
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
index 771b251b409d..f5cada70c3c8 100644
--- a/arch/tile/lib/atomic_32.c
+++ b/arch/tile/lib/atomic_32.c
@@ -18,7 +18,6 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/atomic.h>
-#include <asm/futex.h>
#include <arch/chip.h>
/* See <asm/atomic_32.h> */
@@ -50,7 +49,7 @@ int atomic_locks[PAGE_SIZE / sizeof(int)] __page_aligned_bss;
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
-static inline int *__atomic_hashed_lock(volatile void *v)
+int *__atomic_hashed_lock(volatile void *v)
{
/* NOTE: this code must match "sys_cmpxchg" in kernel/intvec_32.S */
#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
@@ -191,47 +190,6 @@ u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
EXPORT_SYMBOL(_atomic64_cmpxchg);
-static inline int *__futex_setup(int __user *v)
-{
- /*
- * Issue a prefetch to the counter to bring it into cache.
- * As for __atomic_setup, but we can't do a read into the L1
- * since it might fault; instead we do a prefetch into the L2.
- */
- __insn_prefetch(v);
- return __atomic_hashed_lock((int __force *)v);
-}
-
-struct __get_user futex_set(u32 __user *v, int i)
-{
- return __atomic_xchg((int __force *)v, __futex_setup(v), i);
-}
-
-struct __get_user futex_add(u32 __user *v, int n)
-{
- return __atomic_xchg_add((int __force *)v, __futex_setup(v), n);
-}
-
-struct __get_user futex_or(u32 __user *v, int n)
-{
- return __atomic_or((int __force *)v, __futex_setup(v), n);
-}
-
-struct __get_user futex_andn(u32 __user *v, int n)
-{
- return __atomic_andn((int __force *)v, __futex_setup(v), n);
-}
-
-struct __get_user futex_xor(u32 __user *v, int n)
-{
- return __atomic_xor((int __force *)v, __futex_setup(v), n);
-}
-
-struct __get_user futex_cmpxchg(u32 __user *v, int o, int n)
-{
- return __atomic_cmpxchg((int __force *)v, __futex_setup(v), o, n);
-}
-
/*
* If any of the atomic or futex routines hit a bad address (not in
* the page tables at kernel PL) this routine is called. The futex
@@ -323,7 +281,4 @@ void __init __init_atomic_per_cpu(void)
BUILD_BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
-
- /* The futex code makes this assumption, so we validate it here. */
- BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int));
}
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
index 2a81d32de0da..dd5f0a33fdaf 100644
--- a/arch/tile/lib/exports.c
+++ b/arch/tile/lib/exports.c
@@ -18,14 +18,6 @@
/* arch/tile/lib/usercopy.S */
#include <linux/uaccess.h>
-EXPORT_SYMBOL(__get_user_1);
-EXPORT_SYMBOL(__get_user_2);
-EXPORT_SYMBOL(__get_user_4);
-EXPORT_SYMBOL(__get_user_8);
-EXPORT_SYMBOL(__put_user_1);
-EXPORT_SYMBOL(__put_user_2);
-EXPORT_SYMBOL(__put_user_4);
-EXPORT_SYMBOL(__put_user_8);
EXPORT_SYMBOL(strnlen_user_asm);
EXPORT_SYMBOL(strncpy_from_user_asm);
EXPORT_SYMBOL(clear_user_asm);
diff --git a/arch/tile/lib/memchr_64.c b/arch/tile/lib/memchr_64.c
index 84fdc8d8e735..6f867dbf7c56 100644
--- a/arch/tile/lib/memchr_64.c
+++ b/arch/tile/lib/memchr_64.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
+#include "string-endian.h"
void *memchr(const void *s, int c, size_t n)
{
@@ -39,11 +40,8 @@ void *memchr(const void *s, int c, size_t n)
/* Read the first word, but munge it so that bytes before the array
* will not match goal.
- *
- * Note that this shift count expression works because we know
- * shift counts are taken mod 64.
*/
- before_mask = (1ULL << (s_int << 3)) - 1;
+ before_mask = MASK(s_int);
v = (*p | before_mask) ^ (goal & before_mask);
/* Compute the address of the last byte. */
@@ -65,7 +63,7 @@ void *memchr(const void *s, int c, size_t n)
/* We found a match, but it might be in a byte past the end
* of the array.
*/
- ret = ((char *)p) + (__insn_ctz(bits) >> 3);
+ ret = ((char *)p) + (CFZ(bits) >> 3);
return (ret <= last_byte_ptr) ? ret : NULL;
}
EXPORT_SYMBOL(memchr);
diff --git a/arch/tile/lib/memcpy_64.c b/arch/tile/lib/memcpy_64.c
index 3fab9a6a2bbe..c79b8e7c6828 100644
--- a/arch/tile/lib/memcpy_64.c
+++ b/arch/tile/lib/memcpy_64.c
@@ -15,7 +15,6 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
-#define __memcpy memcpy
/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
/* Must be 8 bytes in size. */
@@ -188,6 +187,7 @@ int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
/* n != 0 if we get here. Write out any trailing bytes. */
dst1 = (char *)dst8;
+#ifndef __BIG_ENDIAN__
if (n & 4) {
ST4((uint32_t *)dst1, final);
dst1 += 4;
@@ -202,11 +202,30 @@ int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
}
if (n)
ST1((uint8_t *)dst1, final);
+#else
+ if (n & 4) {
+ ST4((uint32_t *)dst1, final >> 32);
+ dst1 += 4;
+ }
+ else
+ {
+ final >>= 32;
+ }
+ if (n & 2) {
+ ST2((uint16_t *)dst1, final >> 16);
+ dst1 += 2;
+ }
+ else
+ {
+ final >>= 16;
+ }
+ if (n & 1)
+ ST1((uint8_t *)dst1, final >> 8);
+#endif
return RETVAL;
}
-
#ifdef USERCOPY_FUNC
#undef ST1
#undef ST2
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c
index b2fe15e01075..3bc4b4e40d93 100644
--- a/arch/tile/lib/memcpy_tile64.c
+++ b/arch/tile/lib/memcpy_tile64.c
@@ -160,7 +160,7 @@ retry_source:
break;
if (get_remote_cache_cpu(src_pte) == smp_processor_id())
break;
- src_page = pfn_to_page(hv_pte_get_pfn(src_pte));
+ src_page = pfn_to_page(pte_pfn(src_pte));
get_page(src_page);
if (pte_val(src_pte) != pte_val(*src_ptep)) {
put_page(src_page);
@@ -168,7 +168,7 @@ retry_source:
}
if (pte_huge(src_pte)) {
/* Adjust the PTE to correspond to a small page */
- int pfn = hv_pte_get_pfn(src_pte);
+ int pfn = pte_pfn(src_pte);
pfn += (((unsigned long)source & (HPAGE_SIZE-1))
>> PAGE_SHIFT);
src_pte = pfn_pte(pfn, src_pte);
@@ -188,7 +188,7 @@ retry_dest:
put_page(src_page);
break;
}
- dst_page = pfn_to_page(hv_pte_get_pfn(dst_pte));
+ dst_page = pfn_to_page(pte_pfn(dst_pte));
if (dst_page == src_page) {
/*
* Source and dest are on the same page; this
@@ -206,7 +206,7 @@ retry_dest:
}
if (pte_huge(dst_pte)) {
/* Adjust the PTE to correspond to a small page */
- int pfn = hv_pte_get_pfn(dst_pte);
+ int pfn = pte_pfn(dst_pte);
pfn += (((unsigned long)dest & (HPAGE_SIZE-1))
>> PAGE_SHIFT);
dst_pte = pfn_pte(pfn, dst_pte);
diff --git a/arch/tile/lib/strchr_64.c b/arch/tile/lib/strchr_64.c
index 617a9273aaa8..f39f9dc422b0 100644
--- a/arch/tile/lib/strchr_64.c
+++ b/arch/tile/lib/strchr_64.c
@@ -15,8 +15,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
-
-#undef strchr
+#include "string-endian.h"
char *strchr(const char *s, int c)
{
@@ -33,13 +32,9 @@ char *strchr(const char *s, int c)
* match neither zero nor goal (we make sure the high bit of each
* byte is 1, and the low 7 bits are all the opposite of the goal
* byte).
- *
- * Note that this shift count expression works because we know shift
- * counts are taken mod 64.
*/
- const uint64_t before_mask = (1ULL << (s_int << 3)) - 1;
- uint64_t v = (*p | before_mask) ^
- (goal & __insn_v1shrsi(before_mask, 1));
+ const uint64_t before_mask = MASK(s_int);
+ uint64_t v = (*p | before_mask) ^ (goal & __insn_v1shrui(before_mask, 1));
uint64_t zero_matches, goal_matches;
while (1) {
@@ -55,8 +50,8 @@ char *strchr(const char *s, int c)
v = *++p;
}
- z = __insn_ctz(zero_matches);
- g = __insn_ctz(goal_matches);
+ z = CFZ(zero_matches);
+ g = CFZ(goal_matches);
/* If we found c before '\0' we got a match. Note that if c == '\0'
* 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 000000000000..c0eed7ce69c3
--- /dev/null
+++ b/arch/tile/lib/string-endian.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Provide a mask based on the pointer alignment that
+ * sets up non-zero bytes before the beginning of the string.
+ * The MASK expression works because shift counts are taken mod 64.
+ * Also, specify how to count "first" and "last" bits
+ * when the bits have been read as a word.
+ */
+
+#include <asm/byteorder.h>
+
+#ifdef __LITTLE_ENDIAN
+#define MASK(x) (__insn_shl(1ULL, (x << 3)) - 1)
+#define NULMASK(x) ((2ULL << x) - 1)
+#define CFZ(x) __insn_ctz(x)
+#define REVCZ(x) __insn_clz(x)
+#else
+#define MASK(x) (__insn_shl(-2LL, ((-x << 3) - 1)))
+#define NULMASK(x) (-2LL << (63 - x))
+#define CFZ(x) __insn_clz(x)
+#define REVCZ(x) __insn_ctz(x)
+#endif
diff --git a/arch/tile/lib/strlen_64.c b/arch/tile/lib/strlen_64.c
index 1c92d46202a8..9583fc3361fa 100644
--- a/arch/tile/lib/strlen_64.c
+++ b/arch/tile/lib/strlen_64.c
@@ -15,8 +15,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/module.h>
-
-#undef strlen
+#include "string-endian.h"
size_t strlen(const char *s)
{
@@ -24,15 +23,13 @@ size_t strlen(const char *s)
const uintptr_t s_int = (uintptr_t) s;
const uint64_t *p = (const uint64_t *)(s_int & -8);
- /* Read the first word, but force bytes before the string to be nonzero.
- * This expression works because we know shift counts are taken mod 64.
- */
- uint64_t v = *p | ((1ULL << (s_int << 3)) - 1);
+ /* Read and MASK the first word. */
+ uint64_t v = *p | MASK(s_int);
uint64_t bits;
while ((bits = __insn_v1cmpeqi(v, 0)) == 0)
v = *++p;
- return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
+ return ((const char *)p) + (CFZ(bits) >> 3) - s;
}
EXPORT_SYMBOL(strlen);
diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S
index 979f76d83746..b62d002af009 100644
--- a/arch/tile/lib/usercopy_32.S
+++ b/arch/tile/lib/usercopy_32.S
@@ -19,82 +19,6 @@
/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
- .pushsection .fixup,"ax"
-
-get_user_fault:
- { move r0, zero; move r1, zero }
- { movei r2, -EFAULT; jrp lr }
- ENDPROC(get_user_fault)
-
-put_user_fault:
- { movei r0, -EFAULT; jrp lr }
- ENDPROC(put_user_fault)
-
- .popsection
-
-/*
- * __get_user_N functions take a pointer in r0, and return 0 in r2
- * on success, with the value in r0; or else -EFAULT in r2.
- */
-#define __get_user_N(bytes, LOAD) \
- STD_ENTRY(__get_user_##bytes); \
-1: { LOAD r0, r0; move r1, zero; move r2, zero }; \
- jrp lr; \
- STD_ENDPROC(__get_user_##bytes); \
- .pushsection __ex_table,"a"; \
- .word 1b, get_user_fault; \
- .popsection
-
-__get_user_N(1, lb_u)
-__get_user_N(2, lh_u)
-__get_user_N(4, lw)
-
-/*
- * __get_user_8 takes a pointer in r0, and returns 0 in r2
- * on success, with the value in r0/r1; or else -EFAULT in r2.
- */
- STD_ENTRY(__get_user_8);
-1: { lw r0, r0; addi r1, r0, 4 };
-2: { lw r1, r1; move r2, zero };
- jrp lr;
- STD_ENDPROC(__get_user_8);
- .pushsection __ex_table,"a";
- .word 1b, get_user_fault;
- .word 2b, get_user_fault;
- .popsection
-
-/*
- * __put_user_N functions take a value in r0 and a pointer in r1,
- * and return 0 in r0 on success or -EFAULT on failure.
- */
-#define __put_user_N(bytes, STORE) \
- STD_ENTRY(__put_user_##bytes); \
-1: { STORE r1, r0; move r0, zero }; \
- jrp lr; \
- STD_ENDPROC(__put_user_##bytes); \
- .pushsection __ex_table,"a"; \
- .word 1b, put_user_fault; \
- .popsection
-
-__put_user_N(1, sb)
-__put_user_N(2, sh)
-__put_user_N(4, sw)
-
-/*
- * __put_user_8 takes a value in r0/r1 and a pointer in r2,
- * and returns 0 in r0 on success or -EFAULT on failure.
- */
-STD_ENTRY(__put_user_8)
-1: { sw r2, r0; addi r2, r2, 4 }
-2: { sw r2, r1; move r0, zero }
- jrp lr
- STD_ENDPROC(__put_user_8)
- .pushsection __ex_table,"a"
- .word 1b, put_user_fault
- .word 2b, put_user_fault
- .popsection
-
-
/*
* strnlen_user_asm takes the pointer in r0, and the length bound in r1.
* 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 2ff44f87b78e..adb2dbbc70cd 100644
--- a/arch/tile/lib/usercopy_64.S
+++ b/arch/tile/lib/usercopy_64.S
@@ -19,55 +19,6 @@
/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
- .pushsection .fixup,"ax"
-
-get_user_fault:
- { movei r1, -EFAULT; move r0, zero }
- jrp lr
- ENDPROC(get_user_fault)
-
-put_user_fault:
- { movei r0, -EFAULT; jrp lr }
- ENDPROC(put_user_fault)
-
- .popsection
-
-/*
- * __get_user_N functions take a pointer in r0, and return 0 in r1
- * on success, with the value in r0; or else -EFAULT in r1.
- */
-#define __get_user_N(bytes, LOAD) \
- STD_ENTRY(__get_user_##bytes); \
-1: { LOAD r0, r0; move r1, zero }; \
- jrp lr; \
- STD_ENDPROC(__get_user_##bytes); \
- .pushsection __ex_table,"a"; \
- .quad 1b, get_user_fault; \
- .popsection
-
-__get_user_N(1, ld1u)
-__get_user_N(2, ld2u)
-__get_user_N(4, ld4u)
-__get_user_N(8, ld)
-
-/*
- * __put_user_N functions take a value in r0 and a pointer in r1,
- * and return 0 in r0 on success or -EFAULT on failure.
- */
-#define __put_user_N(bytes, STORE) \
- STD_ENTRY(__put_user_##bytes); \
-1: { STORE r1, r0; move r0, zero }; \
- jrp lr; \
- STD_ENDPROC(__put_user_##bytes); \
- .pushsection __ex_table,"a"; \
- .quad 1b, put_user_fault; \
- .popsection
-
-__put_user_N(1, st1)
-__put_user_N(2, st2)
-__put_user_N(4, st4)
-__put_user_N(8, st)
-
/*
* strnlen_user_asm takes the pointer in r0, and the length bound in r1.
* 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 22e58f51ed23..84ce7abbf5af 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -187,7 +187,7 @@ static pgd_t *get_current_pgd(void)
HV_Context ctx = hv_inquire_context();
unsigned long pgd_pfn = ctx.page_table >> PAGE_SHIFT;
struct page *pgd_page = pfn_to_page(pgd_pfn);
- BUG_ON(PageHighMem(pgd_page)); /* oops, HIGHPTE? */
+ BUG_ON(PageHighMem(pgd_page));
return (pgd_t *) __va(ctx.page_table);
}
@@ -273,11 +273,15 @@ static int handle_page_fault(struct pt_regs *regs,
int si_code;
int is_kernel_mode;
pgd_t *pgd;
+ unsigned int flags;
/* on TILE, protection faults are always writes */
if (!is_page_fault)
write = 1;
+ flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ (write ? FAULT_FLAG_WRITE : 0));
+
is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL);
tsk = validate_current();
@@ -382,6 +386,8 @@ static int handle_page_fault(struct pt_regs *regs,
vma = NULL; /* happy compiler */
goto bad_area_nosemaphore;
}
+
+retry:
down_read(&mm->mmap_sem);
}
@@ -429,7 +435,11 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(mm, vma, address, write);
+ fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return 0;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -437,10 +447,22 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+ /*
+ * No need to up_read(&mm->mmap_sem) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+ goto retry;
+ }
+ }
#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
/*
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
index 499f73770b05..dbcbdf7b8aa8 100644
--- a/arch/tile/mm/homecache.c
+++ b/arch/tile/mm/homecache.c
@@ -30,6 +30,7 @@
#include <linux/cache.h>
#include <linux/smp.h>
#include <linux/module.h>
+#include <linux/hugetlb.h>
#include <asm/page.h>
#include <asm/sections.h>
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
index 42cfcba4e1ef..812e2d037972 100644
--- a/arch/tile/mm/hugetlbpage.c
+++ b/arch/tile/mm/hugetlbpage.c
@@ -27,85 +27,161 @@
#include <linux/mman.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+
+/*
+ * Provide an additional huge page size (in addition to the regular default
+ * huge page size) if no "hugepagesz" arguments are specified.
+ * Note that it must be smaller than the default huge page size so
+ * that it's possible to allocate them on demand from the buddy allocator.
+ * You can change this to 64K (on a 16K build), 256K, 1M, or 4M,
+ * or not define it at all.
+ */
+#define ADDITIONAL_HUGE_SIZE (1024 * 1024UL)
+
+/* "Extra" page-size multipliers, one per level of the page table. */
+int huge_shift[HUGE_SHIFT_ENTRIES] = {
+#ifdef ADDITIONAL_HUGE_SIZE
+#define ADDITIONAL_HUGE_SHIFT __builtin_ctzl(ADDITIONAL_HUGE_SIZE / PAGE_SIZE)
+ [HUGE_SHIFT_PAGE] = ADDITIONAL_HUGE_SHIFT
+#endif
+};
+
+/*
+ * This routine is a hybrid of pte_alloc_map() and pte_alloc_kernel().
+ * It assumes that L2 PTEs are never in HIGHMEM (we don't support that).
+ * It locks the user pagetable, and bumps up the mm->nr_ptes field,
+ * but otherwise allocate the page table using the kernel versions.
+ */
+static pte_t *pte_alloc_hugetlb(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long address)
+{
+ pte_t *new;
+
+ if (pmd_none(*pmd)) {
+ new = pte_alloc_one_kernel(mm, address);
+ if (!new)
+ return NULL;
+
+ smp_wmb(); /* See comment in __pte_alloc */
+
+ spin_lock(&mm->page_table_lock);
+ if (likely(pmd_none(*pmd))) { /* Has another populated it ? */
+ mm->nr_ptes++;
+ pmd_populate_kernel(mm, pmd, new);
+ new = NULL;
+ } else
+ VM_BUG_ON(pmd_trans_splitting(*pmd));
+ spin_unlock(&mm->page_table_lock);
+ if (new)
+ pte_free_kernel(mm, new);
+ }
+
+ return pte_offset_kernel(pmd, address);
+}
+#endif
pte_t *huge_pte_alloc(struct mm_struct *mm,
unsigned long addr, unsigned long sz)
{
pgd_t *pgd;
pud_t *pud;
- pte_t *pte = NULL;
- /* We do not yet support multiple huge page sizes. */
- BUG_ON(sz != PMD_SIZE);
+ addr &= -sz; /* Mask off any low bits in the address. */
pgd = pgd_offset(mm, addr);
pud = pud_alloc(mm, pgd, addr);
- if (pud)
- pte = (pte_t *) pmd_alloc(mm, pud, addr);
- BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
- return pte;
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+ if (sz >= PGDIR_SIZE) {
+ BUG_ON(sz != PGDIR_SIZE &&
+ sz != PGDIR_SIZE << huge_shift[HUGE_SHIFT_PGDIR]);
+ return (pte_t *)pud;
+ } else {
+ pmd_t *pmd = pmd_alloc(mm, pud, addr);
+ if (sz >= PMD_SIZE) {
+ BUG_ON(sz != PMD_SIZE &&
+ sz != (PMD_SIZE << huge_shift[HUGE_SHIFT_PMD]));
+ return (pte_t *)pmd;
+ }
+ else {
+ if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE])
+ panic("Unexpected page size %#lx\n", sz);
+ return pte_alloc_hugetlb(mm, pmd, addr);
+ }
+ }
+#else
+ BUG_ON(sz != PMD_SIZE);
+ return (pte_t *) pmd_alloc(mm, pud, addr);
+#endif
}
-pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+static pte_t *get_pte(pte_t *base, int index, int level)
{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd = NULL;
-
- pgd = pgd_offset(mm, addr);
- if (pgd_present(*pgd)) {
- pud = pud_offset(pgd, addr);
- if (pud_present(*pud))
- pmd = pmd_offset(pud, addr);
+ pte_t *ptep = base + index;
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+ if (!pte_present(*ptep) && huge_shift[level] != 0) {
+ unsigned long mask = -1UL << huge_shift[level];
+ pte_t *super_ptep = base + (index & mask);
+ pte_t pte = *super_ptep;
+ if (pte_present(pte) && pte_super(pte))
+ ptep = super_ptep;
}
- return (pte_t *) pmd;
+#endif
+ return ptep;
}
-#ifdef HUGETLB_TEST
-struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
- int write)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
{
- unsigned long start = address;
- int length = 1;
- int nr;
- struct page *page;
- struct vm_area_struct *vma;
-
- vma = find_vma(mm, addr);
- if (!vma || !is_vm_hugetlb_page(vma))
- return ERR_PTR(-EINVAL);
-
- pte = huge_pte_offset(mm, address);
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+ pte_t *pte;
+#endif
- /* hugetlb should be locked, and hence, prefaulted */
- WARN_ON(!pte || pte_none(*pte));
+ /* Get the top-level page table entry. */
+ pgd = (pgd_t *)get_pte((pte_t *)mm->pgd, pgd_index(addr), 0);
+ if (!pgd_present(*pgd))
+ return NULL;
- page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+ /* We don't have four levels. */
+ pud = pud_offset(pgd, addr);
+#ifndef __PAGETABLE_PUD_FOLDED
+# error support fourth page table level
+#endif
- WARN_ON(!PageHead(page));
+ /* Check for an L0 huge PTE, if we have three levels. */
+#ifndef __PAGETABLE_PMD_FOLDED
+ if (pud_huge(*pud))
+ return (pte_t *)pud;
- return page;
-}
-
-int pmd_huge(pmd_t pmd)
-{
- return 0;
-}
+ pmd = (pmd_t *)get_pte((pte_t *)pud_page_vaddr(*pud),
+ pmd_index(addr), 1);
+ if (!pmd_present(*pmd))
+ return NULL;
+#else
+ pmd = pmd_offset(pud, addr);
+#endif
-int pud_huge(pud_t pud)
-{
- return 0;
-}
+ /* Check for an L1 huge PTE. */
+ if (pmd_huge(*pmd))
+ return (pte_t *)pmd;
+
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+ /* Check for an L2 huge PTE. */
+ pte = get_pte((pte_t *)pmd_page_vaddr(*pmd), pte_index(addr), 2);
+ if (!pte_present(*pte))
+ return NULL;
+ if (pte_super(*pte))
+ return pte;
+#endif
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
- pmd_t *pmd, int write)
-{
return NULL;
}
-#else
-
struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
int write)
{
@@ -149,8 +225,6 @@ int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
return 0;
}
-#endif
-
#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
unsigned long addr, unsigned long len,
@@ -322,21 +396,102 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
return hugetlb_get_unmapped_area_topdown(file, addr, len,
pgoff, flags);
}
+#endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
-static __init int setup_hugepagesz(char *opt)
+#ifdef CONFIG_HUGETLB_SUPER_PAGES
+static __init int __setup_hugepagesz(unsigned long ps)
{
- unsigned long ps = memparse(opt, &opt);
- if (ps == PMD_SIZE) {
- hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
- } else if (ps == PUD_SIZE) {
- hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
+ int log_ps = __builtin_ctzl(ps);
+ int level, base_shift;
+
+ if ((1UL << log_ps) != ps || (log_ps & 1) != 0) {
+ pr_warn("Not enabling %ld byte huge pages;"
+ " must be a power of four.\n", ps);
+ return -EINVAL;
+ }
+
+ if (ps > 64*1024*1024*1024UL) {
+ pr_warn("Not enabling %ld MB huge pages;"
+ " largest legal value is 64 GB .\n", ps >> 20);
+ return -EINVAL;
+ } else if (ps >= PUD_SIZE) {
+ static long hv_jpage_size;
+ if (hv_jpage_size == 0)
+ hv_jpage_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO);
+ if (hv_jpage_size != PUD_SIZE) {
+ pr_warn("Not enabling >= %ld MB huge pages:"
+ " hypervisor reports size %ld\n",
+ PUD_SIZE >> 20, hv_jpage_size);
+ return -EINVAL;
+ }
+ level = 0;
+ base_shift = PUD_SHIFT;
+ } else if (ps >= PMD_SIZE) {
+ level = 1;
+ base_shift = PMD_SHIFT;
+ } else if (ps > PAGE_SIZE) {
+ level = 2;
+ base_shift = PAGE_SHIFT;
} else {
- pr_err("hugepagesz: Unsupported page size %lu M\n",
- ps >> 20);
- return 0;
+ pr_err("hugepagesz: huge page size %ld too small\n", ps);
+ return -EINVAL;
}
- return 1;
+
+ if (log_ps != base_shift) {
+ int shift_val = log_ps - base_shift;
+ if (huge_shift[level] != 0) {
+ int old_shift = base_shift + huge_shift[level];
+ pr_warn("Not enabling %ld MB huge pages;"
+ " already have size %ld MB.\n",
+ ps >> 20, (1UL << old_shift) >> 20);
+ return -EINVAL;
+ }
+ if (hv_set_pte_super_shift(level, shift_val) != 0) {
+ pr_warn("Not enabling %ld MB huge pages;"
+ " no hypervisor support.\n", ps >> 20);
+ return -EINVAL;
+ }
+ printk(KERN_DEBUG "Enabled %ld MB huge pages\n", ps >> 20);
+ huge_shift[level] = shift_val;
+ }
+
+ hugetlb_add_hstate(log_ps - PAGE_SHIFT);
+
+ return 0;
+}
+
+static bool saw_hugepagesz;
+
+static __init int setup_hugepagesz(char *opt)
+{
+ if (!saw_hugepagesz) {
+ saw_hugepagesz = true;
+ memset(huge_shift, 0, sizeof(huge_shift));
+ }
+ return __setup_hugepagesz(memparse(opt, NULL));
}
__setup("hugepagesz=", setup_hugepagesz);
-#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
+#ifdef ADDITIONAL_HUGE_SIZE
+/*
+ * Provide an additional huge page size if no "hugepagesz" args are given.
+ * In that case, all the cores have properly set up their hv super_shift
+ * already, but we need to notify the hugetlb code to enable the
+ * new huge page size from the Linux point of view.
+ */
+static __init int add_default_hugepagesz(void)
+{
+ if (!saw_hugepagesz) {
+ BUILD_BUG_ON(ADDITIONAL_HUGE_SIZE >= PMD_SIZE ||
+ ADDITIONAL_HUGE_SIZE <= PAGE_SIZE);
+ BUILD_BUG_ON((PAGE_SIZE << ADDITIONAL_HUGE_SHIFT) !=
+ ADDITIONAL_HUGE_SIZE);
+ BUILD_BUG_ON(ADDITIONAL_HUGE_SHIFT & 1);
+ hugetlb_add_hstate(ADDITIONAL_HUGE_SHIFT);
+ }
+ return 0;
+}
+arch_initcall(add_default_hugepagesz);
+#endif
+
+#endif /* CONFIG_HUGETLB_SUPER_PAGES */
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
index 6a9d20ddc34f..630dd2ce2afe 100644
--- a/arch/tile/mm/init.c
+++ b/arch/tile/mm/init.c
@@ -82,7 +82,7 @@ static int num_l2_ptes[MAX_NUMNODES];
static void init_prealloc_ptes(int node, int pages)
{
- BUG_ON(pages & (HV_L2_ENTRIES-1));
+ BUG_ON(pages & (PTRS_PER_PTE - 1));
if (pages) {
num_l2_ptes[node] = pages;
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)
#ifdef __tilegx__
-#if HV_L1_SIZE != HV_L2_SIZE
-# error Rework assumption that L1 and L2 page tables are same size.
-#endif
-
-/* Since pmd_t arrays and pte_t arrays are the same size, just use casts. */
static inline pmd_t *alloc_pmd(void)
{
- return (pmd_t *)alloc_pte();
+ return __alloc_bootmem(L1_KERNEL_PGTABLE_SIZE, HV_PAGE_TABLE_ALIGN, 0);
}
static inline void assign_pmd(pud_t *pud, pmd_t *pmd)
@@ -444,6 +439,7 @@ static pgd_t pgtables[PTRS_PER_PGD]
*/
static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
{
+ unsigned long long irqmask;
unsigned long address, pfn;
pmd_t *pmd;
pte_t *pte;
@@ -633,10 +629,13 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
* - install pgtables[] as the real page table
* - flush the TLB so the new page table takes effect
*/
+ irqmask = interrupt_mask_save_mask();
+ interrupt_mask_set_mask(-1ULL);
rc = flush_and_install_context(__pa(pgtables),
init_pgprot((unsigned long)pgtables),
__get_cpu_var(current_asid),
cpumask_bits(my_cpu_mask));
+ interrupt_mask_restore_mask(irqmask);
BUG_ON(rc != 0);
/* 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)
#endif /* CONFIG_HIGHMEM */
+#ifndef CONFIG_64BIT
static void __init init_free_pfn_range(unsigned long start, unsigned long end)
{
unsigned long pfn;
@@ -771,6 +771,7 @@ static void __init set_non_bootmem_pages_init(void)
init_free_pfn_range(start, end);
}
}
+#endif
/*
* paging_init() sets up the page tables - note that all of lowmem is
@@ -807,7 +808,7 @@ void __init paging_init(void)
* changing init_mm once we get up and running, and there's no
* need for e.g. vmalloc_sync_all().
*/
- BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END));
+ BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END - 1));
pud = pud_offset(pgd_base + pgd_index(VMALLOC_START), VMALLOC_START);
assign_pmd(pud, alloc_pmd());
#endif
@@ -859,8 +860,10 @@ void __init mem_init(void)
/* this will put all bootmem onto the freelists */
totalram_pages += free_all_bootmem();
+#ifndef CONFIG_64BIT
/* count all remaining LOWMEM and give all HIGHMEM to page allocator */
set_non_bootmem_pages_init();
+#endif
codesize = (unsigned long)&_etext - (unsigned long)&_text;
datasize = (unsigned long)&_end - (unsigned long)&_sdata;
diff --git a/arch/tile/mm/migrate.h b/arch/tile/mm/migrate.h
index cd45a0837fa6..91683d97917e 100644
--- a/arch/tile/mm/migrate.h
+++ b/arch/tile/mm/migrate.h
@@ -24,6 +24,9 @@
/*
* This function is used as a helper when setting up the initial
* page table (swapper_pg_dir).
+ *
+ * You must mask ALL interrupts prior to invoking this code, since
+ * you can't legally touch the stack during the cache flush.
*/
extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
HV_ASID asid,
@@ -39,6 +42,9 @@ extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
*
* Note that any non-NULL pointers must not point to the page that
* is handled by the stack_pte itself.
+ *
+ * You must mask ALL interrupts prior to invoking this code, since
+ * you can't legally touch the stack during the cache flush.
*/
extern int homecache_migrate_stack_and_flush(pte_t stack_pte, unsigned long va,
size_t length, pte_t *stack_ptep,
diff --git a/arch/tile/mm/migrate_32.S b/arch/tile/mm/migrate_32.S
index ac01a7cdf77f..5305814bf187 100644
--- a/arch/tile/mm/migrate_32.S
+++ b/arch/tile/mm/migrate_32.S
@@ -40,8 +40,7 @@
#define FRAME_R32 16
#define FRAME_R33 20
#define FRAME_R34 24
-#define FRAME_R35 28
-#define FRAME_SIZE 32
+#define FRAME_SIZE 28
@@ -66,12 +65,11 @@
#define r_my_cpumask r5
/* Locals (callee-save); must not be more than FRAME_xxx above. */
-#define r_save_ics r30
-#define r_context_lo r31
-#define r_context_hi r32
-#define r_access_lo r33
-#define r_access_hi r34
-#define r_asid r35
+#define r_context_lo r30
+#define r_context_hi r31
+#define r_access_lo r32
+#define r_access_hi r33
+#define r_asid r34
STD_ENTRY(flush_and_install_context)
/*
@@ -104,11 +102,7 @@ STD_ENTRY(flush_and_install_context)
sw r_tmp, r33
addi r_tmp, sp, FRAME_R34
}
- {
- sw r_tmp, r34
- addi r_tmp, sp, FRAME_R35
- }
- sw r_tmp, r35
+ sw r_tmp, r34
/* Move some arguments to callee-save registers. */
{
@@ -121,13 +115,6 @@ STD_ENTRY(flush_and_install_context)
}
move r_asid, r_asid_in
- /* Disable interrupts, since we can't use our stack. */
- {
- mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
- movei r_tmp, 1
- }
- mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
-
/* First, flush our L2 cache. */
{
move r0, zero /* cache_pa */
@@ -163,7 +150,7 @@ STD_ENTRY(flush_and_install_context)
}
{
move r4, r_asid
- movei r5, HV_CTX_DIRECTIO
+ moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
}
jal hv_install_context
bnz r0, .Ldone
@@ -175,9 +162,6 @@ STD_ENTRY(flush_and_install_context)
}
.Ldone:
- /* Reset interrupts back how they were before. */
- mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
-
/* Restore the callee-saved registers and return. */
addli lr, sp, FRAME_SIZE
{
@@ -202,10 +186,6 @@ STD_ENTRY(flush_and_install_context)
}
{
lw r34, r_tmp
- addli r_tmp, sp, FRAME_R35
- }
- {
- lw r35, r_tmp
addi sp, sp, FRAME_SIZE
}
jrp lr
diff --git a/arch/tile/mm/migrate_64.S b/arch/tile/mm/migrate_64.S
index e76fea688beb..1d15b10833d1 100644
--- a/arch/tile/mm/migrate_64.S
+++ b/arch/tile/mm/migrate_64.S
@@ -38,8 +38,7 @@
#define FRAME_R30 16
#define FRAME_R31 24
#define FRAME_R32 32
-#define FRAME_R33 40
-#define FRAME_SIZE 48
+#define FRAME_SIZE 40
@@ -60,10 +59,9 @@
#define r_my_cpumask r3
/* Locals (callee-save); must not be more than FRAME_xxx above. */
-#define r_save_ics r30
-#define r_context r31
-#define r_access r32
-#define r_asid r33
+#define r_context r30
+#define r_access r31
+#define r_asid r32
/*
* Caller-save locals and frame constants are the same as
@@ -93,11 +91,7 @@ STD_ENTRY(flush_and_install_context)
st r_tmp, r31
addi r_tmp, sp, FRAME_R32
}
- {
- st r_tmp, r32
- addi r_tmp, sp, FRAME_R33
- }
- st r_tmp, r33
+ st r_tmp, r32
/* Move some arguments to callee-save registers. */
{
@@ -106,13 +100,6 @@ STD_ENTRY(flush_and_install_context)
}
move r_asid, r_asid_in
- /* Disable interrupts, since we can't use our stack. */
- {
- mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
- movei r_tmp, 1
- }
- mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
-
/* First, flush our L2 cache. */
{
move r0, zero /* cache_pa */
@@ -147,7 +134,7 @@ STD_ENTRY(flush_and_install_context)
}
{
move r2, r_asid
- movei r3, HV_CTX_DIRECTIO
+ moveli r3, HV_CTX_DIRECTIO | CTX_PAGE_FLAG
}
jal hv_install_context
bnez r0, 1f
@@ -158,10 +145,7 @@ STD_ENTRY(flush_and_install_context)
jal hv_flush_all
}
-1: /* Reset interrupts back how they were before. */
- mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
-
- /* Restore the callee-saved registers and return. */
+1: /* Restore the callee-saved registers and return. */
addli lr, sp, FRAME_SIZE
{
ld lr, lr
@@ -177,10 +161,6 @@ STD_ENTRY(flush_and_install_context)
}
{
ld r32, r_tmp
- addli r_tmp, sp, FRAME_R33
- }
- {
- ld r33, r_tmp
addi sp, sp, FRAME_SIZE
}
jrp lr
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
index 2410aa899b3e..345edfed9fcd 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)
set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
}
-#if defined(CONFIG_HIGHPTE)
-pte_t *_pte_offset_map(pmd_t *dir, unsigned long address)
-{
- pte_t *pte = kmap_atomic(pmd_page(*dir)) +
- (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
- return &pte[pte_index(address)];
-}
-#endif
-
/**
* shatter_huge_page() - ensure a given address is mapped by a small page.
*
@@ -289,33 +280,26 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
#define L2_USER_PGTABLE_PAGES (1 << L2_USER_PGTABLE_ORDER)
-struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+struct page *pgtable_alloc_one(struct mm_struct *mm, unsigned long address,
+ int order)
{
gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO;
struct page *p;
-#if L2_USER_PGTABLE_ORDER > 0
int i;
-#endif
-
-#ifdef CONFIG_HIGHPTE
- flags |= __GFP_HIGHMEM;
-#endif
p = alloc_pages(flags, L2_USER_PGTABLE_ORDER);
if (p == NULL)
return NULL;
-#if L2_USER_PGTABLE_ORDER > 0
/*
* Make every page have a page_count() of one, not just the first.
* We don't use __GFP_COMP since it doesn't look like it works
* correctly with tlb_remove_page().
*/
- for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) {
+ for (i = 1; i < order; ++i) {
init_page_count(p+i);
inc_zone_page_state(p+i, NR_PAGETABLE);
}
-#endif
pgtable_page_ctor(p);
return p;
@@ -326,28 +310,28 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
* process). We have to correct whatever pte_alloc_one() did before
* returning the pages to the allocator.
*/
-void pte_free(struct mm_struct *mm, struct page *p)
+void pgtable_free(struct mm_struct *mm, struct page *p, int order)
{
int i;
pgtable_page_dtor(p);
__free_page(p);
- for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) {
+ for (i = 1; i < order; ++i) {
__free_page(p+i);
dec_zone_page_state(p+i, NR_PAGETABLE);
}
}
-void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
- unsigned long address)
+void __pgtable_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address, int order)
{
int i;
pgtable_page_dtor(pte);
tlb_remove_page(tlb, pte);
- for (i = 1; i < L2_USER_PGTABLE_PAGES; ++i) {
+ for (i = 1; i < order; ++i) {
tlb_remove_page(tlb, pte + i);
dec_zone_page_state(pte + i, NR_PAGETABLE);
}
@@ -490,7 +474,7 @@ void set_pte(pte_t *ptep, pte_t pte)
/* Can this mm load a PTE with cached_priority set? */
static inline int mm_is_priority_cached(struct mm_struct *mm)
{
- return mm->context.priority_cached;
+ return mm->context.priority_cached != 0;
}
/*
@@ -500,8 +484,8 @@ static inline int mm_is_priority_cached(struct mm_struct *mm)
void start_mm_caching(struct mm_struct *mm)
{
if (!mm_is_priority_cached(mm)) {
- mm->context.priority_cached = -1U;
- hv_set_caching(-1U);
+ mm->context.priority_cached = -1UL;
+ hv_set_caching(-1UL);
}
}
@@ -516,7 +500,7 @@ void start_mm_caching(struct mm_struct *mm)
* Presumably we'll come back later and have more luck and clear
* the value then; for now we'll just keep the cache marked for priority.
*/
-static unsigned int update_priority_cached(struct mm_struct *mm)
+static unsigned long update_priority_cached(struct mm_struct *mm)
{
if (mm->context.priority_cached && down_write_trylock(&mm->mmap_sem)) {
struct vm_area_struct *vm;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 66cc380bebf0..d700811785ea 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -32,6 +32,7 @@ config X86
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARCH_WANT_FRAME_POINTERS
select HAVE_DMA_ATTRS
+ select HAVE_DMA_CONTIGUOUS if !SWIOTLB
select HAVE_KRETPROBES
select HAVE_OPTPROBES
select HAVE_FTRACE_MCOUNT_RECORD
@@ -92,6 +93,8 @@ config X86
select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
select GENERIC_TIME_VSYSCALL if X86_64
select KTIME_SCALAR if X86_32
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
config INSTRUCTION_DECODER
def_bool (KPROBES || PERF_EVENTS || UPROBES)
diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h
new file mode 100644
index 000000000000..c09241659971
--- /dev/null
+++ b/arch/x86/include/asm/dma-contiguous.h
@@ -0,0 +1,13 @@
+#ifndef ASMX86_DMA_CONTIGUOUS_H
+#define ASMX86_DMA_CONTIGUOUS_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm-generic/dma-contiguous.h>
+
+static inline void
+dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
+
+#endif
+#endif
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 61c0bd25845a..f7b4c7903e7e 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -13,6 +13,7 @@
#include <asm/io.h>
#include <asm/swiotlb.h>
#include <asm-generic/dma-coherent.h>
+#include <linux/dma-contiguous.h>
#ifdef CONFIG_ISA
# 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,
dma_addr_t *dma_addr, gfp_t flag,
struct dma_attrs *attrs);
+extern void dma_generic_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_addr,
+ struct dma_attrs *attrs);
+
#ifdef CONFIG_X86_DMA_REMAP /* Platform code defines bridge-specific code */
extern bool dma_capable(struct device *dev, dma_addr_t addr, size_t size);
extern dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 851fe0dc13bc..04cd6882308e 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -32,6 +32,7 @@
#define segment_eq(a, b) ((a).seg == (b).seg)
+#define user_addr_max() (current_thread_info()->addr_limit.seg)
#define __addr_ok(addr) \
((unsigned long __force)(addr) < \
(current_thread_info()->addr_limit.seg))
@@ -565,6 +566,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
extern __must_check long
strncpy_from_user(char *dst, const char __user *src, long count);
+extern __must_check long strlen_user(const char __user *str);
+extern __must_check long strnlen_user(const char __user *str, long n);
+
/*
* movsl can be slow when source and dest are not both 8-byte aligned
*/
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 8084bc73b18c..576e39bca6ad 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,
return n;
}
-/**
- * strlen_user: - Get the size of a string in user space.
- * @str: The string to measure.
- *
- * Context: User context only. This function may sleep.
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- *
- * If there is a limit on the length of a valid string, you may wish to
- * consider using strnlen_user() instead.
- */
-#define strlen_user(str) strnlen_user(str, LONG_MAX)
-
-long strnlen_user(const char __user *str, long n);
unsigned long __must_check clear_user(void __user *mem, unsigned long len);
unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
index fcd4b6f3ef02..8e796fbbf9c6 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)
}
}
-__must_check long strnlen_user(const char __user *str, long n);
-__must_check long __strnlen_user(const char __user *str, long n);
-__must_check long strlen_user(const char __user *str);
__must_check unsigned long clear_user(void __user *mem, unsigned long len);
__must_check unsigned long __clear_user(void __user *mem, unsigned long len);
diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h
index ae03facfadd6..5b238981542a 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 @@
* bit count instruction, that might be better than the multiply
* and shift, for example.
*/
+struct word_at_a_time {
+ const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
#ifdef CONFIG_64BIT
@@ -37,10 +42,31 @@ static inline long count_masked_bytes(long mask)
#endif
-/* Return the high bit set in the first byte that is a zero */
-static inline unsigned long has_zero(unsigned long a)
+/* Return nonzero if it has a zero */
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
+{
+ unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
+ *bits = mask;
+ return mask;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
+{
+ return bits;
+}
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+ bits = (bits - 1) & ~bits;
+ return bits >> 7;
+}
+
+/* The mask we created is directly usable as a bytemask */
+#define zero_bytemask(mask) (mask)
+
+static inline unsigned long find_zero(unsigned long mask)
{
- return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80);
+ return count_masked_bytes(mask);
}
/*
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c
index 507ea58688e2..cd8b166a1735 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)
struct mce m;
/* Only corrected MC is reported */
- if (!corrected)
+ if (!corrected || !(mem_err->validation_bits &
+ CPER_MEM_VALID_PHYSICAL_ADDRESS))
return;
mce_setup(&m);
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 0c82091b1652..413c2ced887c 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 {
SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
USER
),
+ MCESEV(
+ KEEP, "HT thread notices Action required: instruction fetch error",
+ SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
+ MCGMASK(MCG_STATUS_EIPV, 0)
+ ),
+ MCESEV(
+ AR, "Action required: instruction fetch error",
+ SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
+ USER
+ ),
#endif
MCESEV(
PANIC, "Action required: unknown MCACOD",
@@ -165,15 +175,19 @@ static struct severity {
};
/*
- * If the EIPV bit is set, it means the saved IP is the
- * instruction which caused the MCE.
+ * If mcgstatus indicated that ip/cs on the stack were
+ * no good, then "m->cs" will be zero and we will have
+ * to assume the worst case (IN_KERNEL) as we actually
+ * have no idea what we were executing when the machine
+ * check hit.
+ * If we do have a good "m->cs" (or a faked one in the
+ * case we were executing in VM86 mode) we can use it to
+ * distinguish an exception taken in user from from one
+ * taken in the kernel.
*/
static int error_context(struct mce *m)
{
- if (m->mcgstatus & MCG_STATUS_EIPV)
- return (m->ip && (m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
- /* Unknown, assume kernel */
- return IN_KERNEL;
+ return ((m->cs & 3) == 3) ? IN_USER : IN_KERNEL;
}
int 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 2afcbd253e1d..b772dd6ad450 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)
if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) {
m->ip = regs->ip;
m->cs = regs->cs;
+
+ /*
+ * When in VM86 mode make the cs look like ring 3
+ * always. This is a lie, but it's better than passing
+ * the additional vm86 bit around everywhere.
+ */
+ if (v8086_mode(regs))
+ m->cs |= 3;
}
/* Use accurate RIP reporting if available. */
if (rip_msr)
@@ -641,16 +649,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
* Do a quick check if any of the events requires a panic.
* This decides if we keep the events around or clear them.
*/
-static int mce_no_way_out(struct mce *m, char **msg)
+static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp)
{
- int i;
+ int i, ret = 0;
for (i = 0; i < banks; i++) {
m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
+ if (m->status & MCI_STATUS_VAL)
+ __set_bit(i, validp);
if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
- return 1;
+ ret = 1;
}
- return 0;
+ return ret;
}
/*
@@ -1013,6 +1023,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
*/
int kill_it = 0;
DECLARE_BITMAP(toclear, MAX_NR_BANKS);
+ DECLARE_BITMAP(valid_banks, MAX_NR_BANKS);
char *msg = "Unknown";
atomic_inc(&mce_entry);
@@ -1027,7 +1038,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
final = &__get_cpu_var(mces_seen);
*final = m;
- no_way_out = mce_no_way_out(&m, &msg);
+ memset(valid_banks, 0, sizeof(valid_banks));
+ no_way_out = mce_no_way_out(&m, &msg, valid_banks);
barrier();
@@ -1047,6 +1059,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
order = mce_start(&no_way_out);
for (i = 0; i < banks; i++) {
__clear_bit(i, toclear);
+ if (!test_bit(i, valid_banks))
+ continue;
if (!mce_banks[i].ctl)
continue;
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 3003250ac51d..62c9457ccd2f 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,
struct dma_attrs *attrs)
{
unsigned long dma_mask;
- struct page *page;
+ struct page *page = NULL;
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
dma_addr_t addr;
dma_mask = dma_alloc_coherent_mask(dev, flag);
flag |= __GFP_ZERO;
again:
- page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
+ if (!(flag & GFP_ATOMIC))
+ page = dma_alloc_from_contiguous(dev, count, get_order(size));
+ if (!page)
+ page = alloc_pages_node(dev_to_node(dev), flag, get_order(size));
if (!page)
return NULL;
@@ -127,6 +131,16 @@ again:
return page_address(page);
}
+void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_addr, struct dma_attrs *attrs)
+{
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct page *page = virt_to_page(vaddr);
+
+ if (!dma_release_from_contiguous(dev, page, count))
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+
/*
* See <Documentation/x86/x86_64/boot-options.txt> for the iommu kernel
* parameter documentation.
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index f96050685b46..871be4a84c7d 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,
return nents;
}
-static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_addr, struct dma_attrs *attrs)
-{
- free_pages((unsigned long)vaddr, get_order(size));
-}
-
static void nommu_sync_single_for_device(struct device *dev,
dma_addr_t addr, size_t size,
enum dma_data_direction dir)
@@ -97,7 +91,7 @@ static void nommu_sync_sg_for_device(struct device *dev,
struct dma_map_ops nommu_dma_ops = {
.alloc = dma_generic_alloc_coherent,
- .free = nommu_free_coherent,
+ .free = dma_generic_free_coherent,
.map_sg = nommu_map_sg,
.map_page = nommu_map_page,
.sync_single_for_device = nommu_sync_single_for_device,
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 366c688d619e..f2afee6a19c1 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -49,6 +49,7 @@
#include <asm/pci-direct.h>
#include <linux/init_ohci1394_dma.h>
#include <linux/kvm_para.h>
+#include <linux/dma-contiguous.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -925,6 +926,7 @@ void __init setup_arch(char **cmdline_p)
}
#endif
memblock.current_limit = get_max_mapped();
+ dma_contiguous_reserve(0);
/*
* NOTE: On x86-32, only from this point on, fixmaps are ready for use.
diff --git a/arch/x86/lib/usercopy.c b/arch/x86/lib/usercopy.c
index 2e4e4b02c37a..f61ee67ec00f 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)
return len;
}
EXPORT_SYMBOL_GPL(copy_from_user_nmi);
-
-/*
- * Do a strncpy, return length of string without final '\0'.
- * 'count' is the user-supplied count (return 'count' if we
- * hit it), 'max' is the address space maximum (and we return
- * -EFAULT if we hit it).
- */
-static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
-{
- long res = 0;
-
- /*
- * Truncate 'max' to the user-specified limit, so that
- * we only have one limit we need to check in the loop
- */
- if (max > count)
- max = count;
-
- while (max >= sizeof(unsigned long)) {
- unsigned long c, mask;
-
- /* Fall back to byte-at-a-time if we get a page fault */
- if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
- break;
- mask = has_zero(c);
- if (mask) {
- mask = (mask - 1) & ~mask;
- mask >>= 7;
- *(unsigned long *)(dst+res) = c & mask;
- return res + count_masked_bytes(mask);
- }
- *(unsigned long *)(dst+res) = c;
- res += sizeof(unsigned long);
- max -= sizeof(unsigned long);
- }
-
- while (max) {
- char c;
-
- if (unlikely(__get_user(c,src+res)))
- return -EFAULT;
- dst[res] = c;
- if (!c)
- return res;
- res++;
- max--;
- }
-
- /*
- * Uhhuh. We hit 'max'. But was that the user-specified maximum
- * too? If so, that's ok - we got as much as the user asked for.
- */
- if (res >= count)
- return res;
-
- /*
- * Nope: we hit the address space limit, and we still had more
- * characters the caller would have wanted. That's an EFAULT.
- */
- return -EFAULT;
-}
-
-/**
- * strncpy_from_user: - Copy a NUL terminated string from userspace.
- * @dst: Destination address, in kernel space. This buffer must be at
- * least @count bytes long.
- * @src: Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- unsigned long max_addr, src_addr;
-
- if (unlikely(count <= 0))
- return 0;
-
- max_addr = current_thread_info()->addr_limit.seg;
- src_addr = (unsigned long)src;
- if (likely(src_addr < max_addr)) {
- unsigned long max = max_addr - src_addr;
- return do_strncpy_from_user(dst, src, count, max);
- }
- return -EFAULT;
-}
-EXPORT_SYMBOL(strncpy_from_user);
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 883b216c60b2..1781b2f950e2 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)
}
EXPORT_SYMBOL(__clear_user);
-/**
- * strnlen_user: - Get the size of a string in user space.
- * @s: The string to measure.
- * @n: The maximum valid length
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
- */
-long strnlen_user(const char __user *s, long n)
-{
- unsigned long mask = -__addr_ok(s);
- unsigned long res, tmp;
-
- might_fault();
-
- __asm__ __volatile__(
- " testl %0, %0\n"
- " jz 3f\n"
- " andl %0,%%ecx\n"
- "0: repne; scasb\n"
- " setne %%al\n"
- " subl %%ecx,%0\n"
- " addl %0,%%eax\n"
- "1:\n"
- ".section .fixup,\"ax\"\n"
- "2: xorl %%eax,%%eax\n"
- " jmp 1b\n"
- "3: movb $1,%%al\n"
- " jmp 1b\n"
- ".previous\n"
- _ASM_EXTABLE(0b,2b)
- :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
- :"0" (n), "1" (s), "2" (0), "3" (mask)
- :"cc");
- return res & mask;
-}
-EXPORT_SYMBOL(strnlen_user);
-
#ifdef CONFIG_X86_INTEL_USERCOPY
static unsigned long
__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 0d0326f388c0..e5b130bc2d0e 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)
}
EXPORT_SYMBOL(clear_user);
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 on exception, a value greater than N if too long
- */
-
-long __strnlen_user(const char __user *s, long n)
-{
- long res = 0;
- char c;
-
- while (1) {
- if (res>n)
- return n+1;
- if (__get_user(c, s))
- return 0;
- if (!c)
- return res+1;
- res++;
- s++;
- }
-}
-EXPORT_SYMBOL(__strnlen_user);
-
-long strnlen_user(const char __user *s, long n)
-{
- if (!access_ok(VERIFY_READ, s, 1))
- return 0;
- return __strnlen_user(s, n);
-}
-EXPORT_SYMBOL(strnlen_user);
-
-long strlen_user(const char __user *s)
-{
- long res = 0;
- char c;
-
- for (;;) {
- if (get_user(c, s))
- return 0;
- if (!c)
- return res+1;
- res++;
- s++;
- }
-}
-EXPORT_SYMBOL(strlen_user);
-
unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
{
if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {