aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-01-11 23:11:43 -0500
committerPaul Mundt <lethal@linux-sh.org>2012-01-11 23:11:43 -0500
commitb1bdd255661369cb6eb90b6e181169b5e6d0f9b6 (patch)
tree17d15f3a6dc5bdd6205070dbef0e339421b13d25 /arch
parent9d14070f656addddce3d63fd483de46930b51850 (diff)
parentc1537b4863da620f12f5b42ece61bf65314148ed (diff)
Merge branch 'sh/nommu' into sh-latest
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig5
-rw-r--r--arch/alpha/kernel/pci-noop.c12
-rw-r--r--arch/alpha/kernel/pci.c26
-rw-r--r--arch/arm/Kconfig9
-rw-r--r--arch/arm/Kconfig.debug45
-rw-r--r--arch/arm/boot/dts/at91sam9g20.dtsi7
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi7
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts5
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts137
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts182
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi397
-rw-r--r--arch/arm/boot/dts/highbank.dts12
-rw-r--r--arch/arm/boot/dts/imx51-babbage.dts17
-rw-r--r--arch/arm/boot/dts/imx51.dtsi20
-rw-r--r--arch/arm/boot/dts/imx53-ard.dts18
-rw-r--r--arch/arm/boot/dts/imx53-evk.dts17
-rw-r--r--arch/arm/boot/dts/imx53-qsb.dts18
-rw-r--r--arch/arm/boot/dts/imx53-smd.dts19
-rw-r--r--arch/arm/boot/dts/imx53.dtsi34
-rw-r--r--arch/arm/boot/dts/imx6q-arm2.dts (renamed from arch/arm/boot/dts/imx6q-sabreauto.dts)12
-rw-r--r--arch/arm/boot/dts/imx6q-sabrelite.dts49
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi34
-rw-r--r--arch/arm/boot/dts/omap2.dtsi67
-rw-r--r--arch/arm/boot/dts/omap3.dtsi31
-rw-r--r--arch/arm/boot/dts/omap4.dtsi28
-rw-r--r--arch/arm/boot/dts/tegra-cardhu.dts36
-rw-r--r--arch/arm/boot/dts/tegra-harmony.dts29
-rw-r--r--arch/arm/boot/dts/tegra-paz00.dts77
-rw-r--r--arch/arm/boot/dts/tegra-seaboard.dts74
-rw-r--r--arch/arm/boot/dts/tegra-trimslice.dts65
-rw-r--r--arch/arm/boot/dts/tegra-ventana.dts45
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi71
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi127
-rw-r--r--arch/arm/boot/dts/usb_a9g20.dts5
-rw-r--r--arch/arm/configs/imx_v4_v5_defconfig1
-rw-r--r--arch/arm/configs/omap1_defconfig1
-rw-r--r--arch/arm/configs/pcontrol_g20_defconfig175
-rw-r--r--arch/arm/configs/tegra_defconfig9
-rw-r--r--arch/arm/include/asm/io.h2
-rw-r--r--arch/arm/mach-at91/Kconfig24
-rw-r--r--arch/arm/mach-at91/at91cap9.c40
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c49
-rw-r--r--arch/arm/mach-at91/at91rm9200.c24
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c48
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c8
-rw-r--r--arch/arm/mach-at91/at91sam9260.c36
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c55
-rw-r--r--arch/arm/mach-at91/at91sam9261.c32
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c33
-rw-r--r--arch/arm/mach-at91/at91sam9263.c45
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c59
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c38
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c44
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c69
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c36
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c43
-rw-r--r--arch/arm/mach-at91/board-1arm.c4
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c10
-rw-r--r--arch/arm/mach-at91/board-cam60.c8
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c21
-rw-r--r--arch/arm/mach-at91/board-carmeva.c9
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c14
-rw-r--r--arch/arm/mach-at91/board-cpuat91.c7
-rw-r--r--arch/arm/mach-at91/board-csb337.c7
-rw-r--r--arch/arm/mach-at91/board-csb637.c4
-rw-r--r--arch/arm/mach-at91/board-dt.c3
-rw-r--r--arch/arm/mach-at91/board-eb9200.c11
-rw-r--r--arch/arm/mach-at91/board-ecbat91.c7
-rw-r--r--arch/arm/mach-at91/board-eco920.c7
-rw-r--r--arch/arm/mach-at91/board-flexibity.c5
-rw-r--r--arch/arm/mach-at91/board-foxg20.c9
-rw-r--r--arch/arm/mach-at91/board-gsia18s.c7
-rw-r--r--arch/arm/mach-at91/board-kafa.c4
-rw-r--r--arch/arm/mach-at91/board-kb9202.c8
-rw-r--r--arch/arm/mach-at91/board-neocore926.c9
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c8
-rw-r--r--arch/arm/mach-at91/board-picotux200.c5
-rw-r--r--arch/arm/mach-at91/board-qil-a9260.c18
-rw-r--r--arch/arm/mach-at91/board-rm9200dk.c13
-rw-r--r--arch/arm/mach-at91/board-rm9200ek.c5
-rw-r--r--arch/arm/mach-at91/board-rsi-ews.c4
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c12
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c16
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c13
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c12
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c13
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c8
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c9
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c10
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c16
-rw-r--r--arch/arm/mach-at91/board-usb-a926x.c14
-rw-r--r--arch/arm/mach-at91/board-yl-9200.c9
-rw-r--r--arch/arm/mach-at91/generic.h7
-rw-r--r--arch/arm/mach-at91/gpio.c85
-rw-r--r--arch/arm/mach-at91/include/mach/at91_aic.h48
-rw-r--r--arch/arm/mach-at91/include/mach/at91_dbgu.h2
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pit.h8
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rtc.h24
-rw-r--r--arch/arm/mach-at91/include/mach/at91_shdwc.h16
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9.h27
-rw-r--r--arch/arm/mach-at91/include/mach/at91rm9200.h14
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9260.h23
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9261.h20
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9263.h33
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_smc.h17
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9g45.h30
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9rl.h29
-rw-r--r--arch/arm/mach-at91/include/mach/at91x40.h1
-rw-r--r--arch/arm/mach-at91/include/mach/board.h42
-rw-r--r--arch/arm/mach-at91/include/mach/debug-macro.S10
-rw-r--r--arch/arm/mach-at91/include/mach/entry-macro.S11
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h336
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h12
-rw-r--r--arch/arm/mach-at91/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-at91/include/mach/timex.h65
-rw-r--r--arch/arm/mach-at91/include/mach/uncompress.h6
-rw-r--r--arch/arm/mach-at91/irq.c38
-rw-r--r--arch/arm/mach-at91/pm.c11
-rw-r--r--arch/arm/mach-at91/sam9_smc.c62
-rw-r--r--arch/arm/mach-at91/sam9_smc.h3
-rw-r--r--arch/arm/mach-at91/setup.c26
-rw-r--r--arch/arm/mach-at91/soc.h1
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c2
-rw-r--r--arch/arm/mach-davinci/clock.c13
-rw-r--r--arch/arm/mach-davinci/clock.h10
-rw-r--r--arch/arm/mach-davinci/dm644x.c4
-rw-r--r--arch/arm/mach-davinci/include/mach/dm646x.h53
-rw-r--r--arch/arm/mach-dove/addr-map.c121
-rw-r--r--arch/arm/mach-dove/common.c16
-rw-r--r--arch/arm/mach-dove/common.h1
-rw-r--r--arch/arm/mach-dove/pcie.c4
-rw-r--r--arch/arm/mach-exynos/Kconfig36
-rw-r--r--arch/arm/mach-exynos/Makefile8
-rw-r--r--arch/arm/mach-exynos/clock.c302
-rw-r--r--arch/arm/mach-exynos/common.c53
-rw-r--r--arch/arm/mach-exynos/dev-ohci.c52
-rw-r--r--arch/arm/mach-exynos/dma.c229
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h11
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h8
-rw-r--r--arch/arm/mach-exynos/include/mach/ohci.h21
-rw-r--r--arch/arm/mach-exynos/include/mach/spi-clocks.h16
-rw-r--r--arch/arm/mach-exynos/mach-exynos4-dt.c85
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c9
-rw-r--r--arch/arm/mach-exynos/mach-origen.c13
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c17
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c10
-rw-r--r--arch/arm/mach-exynos/pm.c24
-rw-r--r--arch/arm/mach-exynos/setup-sdhci.c22
-rw-r--r--arch/arm/mach-exynos/setup-spi.c72
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c15
-rw-r--r--arch/arm/mach-imx/Kconfig2
-rw-r--r--arch/arm/mach-imx/Makefile6
-rw-r--r--arch/arm/mach-imx/Makefile.boot3
-rw-r--r--arch/arm/mach-imx/head-v7.S17
-rw-r--r--arch/arm/mach-imx/mach-apf9328.c10
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c24
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c2
-rw-r--r--arch/arm/mach-imx/pm-imx6q.c2
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c137
-rw-r--r--arch/arm/mach-kirkwood/common.c19
-rw-r--r--arch/arm/mach-kirkwood/common.h1
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h1
-rw-r--r--arch/arm/mach-kirkwood/mpp.c1
-rw-r--r--arch/arm/mach-kirkwood/mpp.h1
-rw-r--r--arch/arm/mach-kirkwood/pcie.c4
-rw-r--r--arch/arm/mach-mmp/aspenite.c5
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c1
-rw-r--r--arch/arm/mach-mmp/brownstone.c1
-rw-r--r--arch/arm/mach-mmp/flint.c5
-rw-r--r--arch/arm/mach-mmp/gplugd.c1
-rw-r--r--arch/arm/mach-mmp/include/mach/gpio-pxa.h3
-rw-r--r--arch/arm/mach-mmp/include/mach/gpio.h7
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h2
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h2
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h2
-rw-r--r--arch/arm/mach-mmp/mmp2.c39
-rw-r--r--arch/arm/mach-mmp/pxa168.c40
-rw-r--r--arch/arm/mach-mmp/pxa910.c40
-rw-r--r--arch/arm/mach-mmp/tavorevb.c6
-rw-r--r--arch/arm/mach-mmp/teton_bga.c3
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c8
-rw-r--r--arch/arm/mach-msm/Kconfig35
-rw-r--r--arch/arm/mach-msm/include/mach/debug-macro.S51
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x00.h12
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x30.h12
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8960.h5
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x50.h12
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x60.h5
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h12
-rw-r--r--arch/arm/mach-msm/include/mach/uncompress.h39
-rw-r--r--arch/arm/mach-msm/io.c15
-rw-r--r--arch/arm/mach-msm/platsmp.c2
-rw-r--r--arch/arm/mach-msm/timer.c347
-rw-r--r--arch/arm/mach-mv78xx0/addr-map.c102
-rw-r--r--arch/arm/mach-mv78xx0/common.c22
-rw-r--r--arch/arm/mach-mv78xx0/common.h1
-rw-r--r--arch/arm/mach-mv78xx0/mpp.c1
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c4
-rw-r--r--arch/arm/mach-mx5/mm.c19
-rw-r--r--arch/arm/mach-mx5/system.c3
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c10
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c48
-rw-r--r--arch/arm/mach-mxs/clock.c33
-rw-r--r--arch/arm/mach-mxs/devices-mx28.h3
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-saif.c5
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h1
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h4
-rw-r--r--arch/arm/mach-mxs/include/mach/digctl.h21
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c20
-rw-r--r--arch/arm/mach-mxs/system.c2
-rw-r--r--arch/arm/mach-mxs/timer.c2
-rw-r--r--arch/arm/mach-omap1/Kconfig64
-rw-r--r--arch/arm/mach-omap1/clock.c14
-rw-r--r--arch/arm/mach-omap1/clock.h3
-rw-r--r--arch/arm/mach-omap1/clock_data.c19
-rw-r--r--arch/arm/mach-omap1/opp.h1
-rw-r--r--arch/arm/mach-omap1/opp_data.c63
-rw-r--r--arch/arm/mach-omap2/Kconfig37
-rw-r--r--arch/arm/mach-omap2/Makefile20
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c100
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c75
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c22
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c82
-rw-r--r--arch/arm/mach-omap2/board-generic.c1
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c8
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c68
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c46
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c43
-rw-r--r--arch/arm/mach-omap2/clock.c2
-rw-r--r--arch/arm/mach-omap2/clock.h2
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c43
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c19
-rw-r--r--arch/arm/mach-omap2/common.c48
-rw-r--r--arch/arm/mach-omap2/common.h87
-rw-r--r--arch/arm/mach-omap2/control.h8
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c21
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c245
-rw-r--r--arch/arm/mach-omap2/devices.c29
-rw-r--r--arch/arm/mach-omap2/hsmmc.c59
-rw-r--r--arch/arm/mach-omap2/hsmmc.h1
-rw-r--r--arch/arm/mach-omap2/id.c52
-rw-r--r--arch/arm/mach-omap2/include/mach/barriers.h31
-rw-r--r--arch/arm/mach-omap2/include/mach/debug-macro.S12
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-secure.h57
-rw-r--r--arch/arm/mach-omap2/include/mach/omap-wakeupgen.h39
-rw-r--r--arch/arm/mach-omap2/io.c47
-rw-r--r--arch/arm/mach-omap2/irq.c2
-rw-r--r--arch/arm/mach-omap2/mux.c89
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S5
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c14
-rw-r--r--arch/arm/mach-omap2/omap-mpuss-lowpower.c398
-rw-r--r--arch/arm/mach-omap2/omap-secure.c81
-rw-r--r--arch/arm/mach-omap2/omap-smc.S (renamed from arch/arm/mach-omap2/omap44xx-smc.S)23
-rw-r--r--arch/arm/mach-omap2/omap-smp.c45
-rw-r--r--arch/arm/mach-omap2/omap-wakeupgen.c389
-rw-r--r--arch/arm/mach-omap2/omap4-common.c94
-rw-r--r--arch/arm/mach-omap2/omap4-sar-layout.h50
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c223
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c388
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c217
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c35
-rw-r--r--arch/arm/mach-omap2/opp2xxx.h2
-rw-r--r--arch/arm/mach-omap2/pm.h1
-rw-r--r--arch/arm/mach-omap2/pm24xx.c20
-rw-r--r--arch/arm/mach-omap2/pm34xx.c158
-rw-r--r--arch/arm/mach-omap2/pm44xx.c153
-rw-r--r--arch/arm/mach-omap2/prcm-common.h77
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c97
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h9
-rw-r--r--arch/arm/mach-omap2/prm44xx.c116
-rw-r--r--arch/arm/mach-omap2/prm44xx.h8
-rw-r--r--arch/arm/mach-omap2/prm_common.c320
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.c25
-rw-r--r--arch/arm/mach-omap2/serial.c907
-rw-r--r--arch/arm/mach-omap2/sleep44xx.S379
-rw-r--r--arch/arm/mach-omap2/usb-host.c100
-rw-r--r--arch/arm/mach-omap2/usb-musb.c3
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c40
-rw-r--r--arch/arm/mach-orion5x/addr-map.c146
-rw-r--r--arch/arm/mach-orion5x/common.c23
-rw-r--r--arch/arm/mach-orion5x/common.h3
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h2
-rw-r--r--arch/arm/mach-orion5x/mpp.c1
-rw-r--r--arch/arm/mach-orion5x/pci.c5
-rw-r--r--arch/arm/mach-picoxcell/Makefile1
-rw-r--r--arch/arm/mach-picoxcell/common.c52
-rw-r--r--arch/arm/mach-picoxcell/common.h1
-rw-r--r--arch/arm/mach-picoxcell/include/mach/irqs.h9
-rw-r--r--arch/arm/mach-picoxcell/include/mach/memory.h1
-rw-r--r--arch/arm/mach-picoxcell/io.c32
-rw-r--r--arch/arm/mach-pxa/am200epd.c4
-rw-r--r--arch/arm/mach-pxa/am300epd.c4
-rw-r--r--arch/arm/mach-pxa/balloon3.c3
-rw-r--r--arch/arm/mach-pxa/capc7117.c12
-rw-r--r--arch/arm/mach-pxa/cm-x270.c4
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c4
-rw-r--r--arch/arm/mach-pxa/cm-x300.c6
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c6
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c4
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c4
-rw-r--r--arch/arm/mach-pxa/corgi.c2
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c21
-rw-r--r--arch/arm/mach-pxa/devices.c50
-rw-r--r--arch/arm/mach-pxa/devices.h1
-rw-r--r--arch/arm/mach-pxa/em-x270.c6
-rw-r--r--arch/arm/mach-pxa/eseries.c4
-rw-r--r--arch/arm/mach-pxa/hx4700.c18
-rw-r--r--arch/arm/mach-pxa/icontrol.c8
-rw-r--r--arch/arm/mach-pxa/idp.c4
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h6
-rw-r--r--arch/arm/mach-pxa/include/mach/corgi.h26
-rw-r--r--arch/arm/mach-pxa/include/mach/csb726.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio-pxa.h133
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio.h20
-rw-r--r--arch/arm/mach-pxa/include/mach/gumstix.h20
-rw-r--r--arch/arm/mach-pxa/include/mach/hx4700.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/idp.h16
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/littleton.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/palmld.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtc.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtx.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm027.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm990_baseboard.h14
-rw-r--r--arch/arm/mach-pxa/include/mach/poodle.h26
-rw-r--r--arch/arm/mach-pxa/include/mach/spitz.h40
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h54
-rw-r--r--arch/arm/mach-pxa/include/mach/trizeps4.h16
-rw-r--r--arch/arm/mach-pxa/irq.c61
-rw-r--r--arch/arm/mach-pxa/littleton.c6
-rw-r--r--arch/arm/mach-pxa/lpd270.c4
-rw-r--r--arch/arm/mach-pxa/lubbock.c4
-rw-r--r--arch/arm/mach-pxa/magician.c8
-rw-r--r--arch/arm/mach-pxa/mainstone.c4
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c6
-rw-r--r--arch/arm/mach-pxa/mioa701.c37
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c4
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c6
-rw-r--r--arch/arm/mach-pxa/poodle.c6
-rw-r--r--arch/arm/mach-pxa/pxa25x.c7
-rw-r--r--arch/arm/mach-pxa/pxa27x.c7
-rw-r--r--arch/arm/mach-pxa/pxa300.c1
-rw-r--r--arch/arm/mach-pxa/pxa320.c1
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c9
-rw-r--r--arch/arm/mach-pxa/pxa95x.c6
-rw-r--r--arch/arm/mach-pxa/raumfeld.c8
-rw-r--r--arch/arm/mach-pxa/saar.c6
-rw-r--r--arch/arm/mach-pxa/saarb.c2
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c24
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c11
-rw-r--r--arch/arm/mach-pxa/stargate2.c26
-rw-r--r--arch/arm/mach-pxa/tavorevb.c4
-rw-r--r--arch/arm/mach-pxa/tavorevb3.c2
-rw-r--r--arch/arm/mach-pxa/tosa.c4
-rw-r--r--arch/arm/mach-pxa/viper.c12
-rw-r--r--arch/arm/mach-pxa/vpac270.c10
-rw-r--r--arch/arm/mach-pxa/z2.c2
-rw-r--r--arch/arm/mach-pxa/zeus.c20
-rw-r--r--arch/arm/mach-pxa/zylonite.c4
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c24
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c6
-rw-r--r--arch/arm/mach-s3c2412/clock.c7
-rw-r--r--arch/arm/mach-s3c2416/Makefile1
-rw-r--r--arch/arm/mach-s3c2416/clock.c68
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c1
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci.c24
-rw-r--r--arch/arm/mach-s3c2440/clock.c44
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c22
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c22
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c18
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c24
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c18
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c19
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig14
-rw-r--r--arch/arm/mach-s3c64xx/Makefile2
-rw-r--r--arch/arm/mach-s3c64xx/clock.c243
-rw-r--r--arch/arm/mach-s3c64xx/dev-spi.c180
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/crag6410.h6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio.h2
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h2
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410-module.c56
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c39
-rw-r--r--arch/arm/mach-s3c64xx/pm.c13
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci.c24
-rw-r--r--arch/arm/mach-s3c64xx/setup-spi.c45
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig31
-rw-r--r--arch/arm/mach-s5p64x0/Makefile3
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c165
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c153
-rw-r--r--arch/arm/mach-s5p64x0/common.c40
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c224
-rw-r--r--arch/arm/mach-s5p64x0/dma.c227
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c25
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c26
-rw-r--r--arch/arm/mach-s5p64x0/setup-sdhci-gpio.c104
-rw-r--r--arch/arm/mach-s5p64x0/setup-spi.c55
-rw-r--r--arch/arm/mach-s5pc100/Kconfig5
-rw-r--r--arch/arm/mach-s5pc100/Makefile3
-rw-r--r--arch/arm/mach-s5pc100/clock.c287
-rw-r--r--arch/arm/mach-s5pc100/dev-spi.c227
-rw-r--r--arch/arm/mach-s5pc100/dma.c247
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci.c23
-rw-r--r--arch/arm/mach-s5pc100/setup-spi.c65
-rw-r--r--arch/arm/mach-s5pv210/Kconfig5
-rw-r--r--arch/arm/mach-s5pv210/Makefile3
-rw-r--r--arch/arm/mach-s5pv210/clock.c324
-rw-r--r--arch/arm/mach-s5pv210/common.c19
-rw-r--r--arch/arm/mach-s5pv210/dev-spi.c175
-rw-r--r--arch/arm/mach-s5pv210/dma.c241
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h2
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c3
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c6
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c10
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci.c22
-rw-r--r--arch/arm/mach-s5pv210/setup-spi.c51
-rw-r--r--arch/arm/mach-sa1100/clock.c91
-rw-r--r--arch/arm/mach-sa1100/generic.c20
-rw-r--r--arch/arm/mach-tegra/Kconfig31
-rw-r--r--arch/arm/mach-tegra/Makefile36
-rw-r--r--arch/arm/mach-tegra/Makefile.boot3
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c (renamed from arch/arm/mach-tegra/board-dt.c)62
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c63
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c9
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c23
-rw-r--r--arch/arm/mach-tegra/board-harmony.c2
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c25
-rw-r--r--arch/arm/mach-tegra/board-paz00.c29
-rw-r--r--arch/arm/mach-tegra/board-paz00.h3
-rw-r--r--arch/arm/mach-tegra/board-pinmux.c104
-rw-r--r--arch/arm/mach-tegra/board-pinmux.h38
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c122
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c6
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c27
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c2
-rw-r--r--arch/arm/mach-tegra/board.h5
-rw-r--r--arch/arm/mach-tegra/clock.c25
-rw-r--r--arch/arm/mach-tegra/clock.h4
-rw-r--r--arch/arm/mach-tegra/common.c55
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/kbc.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-tegra20.h (renamed from arch/arm/mach-tegra/include/mach/pinmux-t2.h)6
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-tegra30.h320
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h88
-rw-r--r--arch/arm/mach-tegra/irq.c14
-rw-r--r--arch/arm/mach-tegra/pcie.c1
-rw-r--r--arch/arm/mach-tegra/pinmux-tegra20-tables.c (renamed from arch/arm/mach-tegra/pinmux-t2-tables.c)24
-rw-r--r--arch/arm/mach-tegra/pinmux-tegra30-tables.c376
-rw-r--r--arch/arm/mach-tegra/pinmux.c153
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c19
-rw-r--r--arch/arm/mach-tegra/timer.c18
-rw-r--r--arch/arm/mach-u300/Kconfig4
-rw-r--r--arch/arm/mach-u300/core.c14
-rw-r--r--arch/arm/mach-u300/include/mach/gpio-u300.h115
-rw-r--r--arch/arm/mach-u300/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-u300/include/mach/memory.h19
-rw-r--r--arch/arm/mach-u300/mmc.c2
-rw-r--r--arch/arm/mach-u300/u300-gpio.h114
-rw-r--r--arch/arm/mach-u300/u300.c2
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c88
-rw-r--r--arch/arm/mach-ux500/board-mop500.c2
-rw-r--r--arch/arm/mach-ux500/board-mop500.h63
-rw-r--r--arch/arm/mach-ux500/clock.c207
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c41
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c30
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c10
-rw-r--r--arch/arm/mach-ux500/id.c6
-rw-r--r--arch/arm/mach-ux500/include/mach/db5500-regs.h4
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h20
-rw-r--r--arch/arm/mach-ux500/include/mach/devices.h2
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h10
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h24
-rw-r--r--arch/arm/mm/iomap.c21
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx25.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h2
-rw-r--r--arch/arm/plat-mxc/tzic.c40
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/common.c3
-rw-r--r--arch/arm/plat-omap/dma.c22
-rw-r--r--arch/arm/plat-omap/include/plat/am33xx.h25
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h1
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h4
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h56
-rw-r--r--arch/arm/plat-omap/include/plat/hardware.h3
-rw-r--r--arch/arm/plat-omap/include/plat/io.h12
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h31
-rw-r--r--arch/arm/plat-omap/include/plat/iovmm.h12
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h2
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap-secure.h13
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h37
-rw-r--r--arch/arm/plat-omap/include/plat/omap34xx.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h6
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h25
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h6
-rw-r--r--arch/arm/plat-omap/include/plat/ti81xx.h (renamed from arch/arm/plat-omap/include/plat/ti816x.h)18
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h11
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h35
-rw-r--r--arch/arm/plat-omap/sram.c17
-rw-r--r--arch/arm/plat-orion/Makefile2
-rw-r--r--arch/arm/plat-orion/addr-map.c174
-rw-r--r--arch/arm/plat-orion/common.c43
-rw-r--r--arch/arm/plat-orion/include/plat/addr-map.h53
-rw-r--r--arch/arm/plat-orion/include/plat/audio.h3
-rw-r--r--arch/arm/plat-orion/include/plat/common.h17
-rw-r--r--arch/arm/plat-orion/include/plat/ehci-orion.h1
-rw-r--r--arch/arm/plat-orion/include/plat/mv_xor.h6
-rw-r--r--arch/arm/plat-orion/include/plat/mvsdio.h1
-rw-r--r--arch/arm/plat-orion/include/plat/pcie.h3
-rw-r--r--arch/arm/plat-orion/pcie.c6
-rw-r--r--arch/arm/plat-pxa/include/plat/gpio-pxa.h44
-rw-r--r--arch/arm/plat-pxa/include/plat/gpio.h30
-rw-r--r--arch/arm/plat-s3c24xx/dma.c3
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c39
-rw-r--r--arch/arm/plat-samsung/Kconfig24
-rw-r--r--arch/arm/plat-samsung/devs.c128
-rw-r--r--arch/arm/plat-samsung/dma-ops.c15
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h9
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/irqs.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad.h27
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h45
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h24
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h75
-rw-r--r--arch/arm/plat-samsung/include/plat/udc.h15
-rw-r--r--arch/avr32/boards/atngw100/setup.c2
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c2
-rw-r--r--arch/avr32/boards/favr-32/setup.c2
-rw-r--r--arch/avr32/boards/hammerhead/setup.c2
-rw-r--r--arch/avr32/boards/merisc/setup.c2
-rw-r--r--arch/avr32/boards/mimc200/setup.c2
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c8
-rw-r--r--arch/avr32/mach-at32ap/include/mach/board.h7
-rw-r--r--arch/blackfin/configs/BF518F-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-AD7160-EVAL_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-EZKIT-V2_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF561-ACVILON_defconfig2
-rw-r--r--arch/blackfin/configs/BF561-EZKIT-SMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BlackStamp_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF533_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF537E_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF537U_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig2
-rw-r--r--arch/blackfin/configs/DNP5370_defconfig2
-rw-r--r--arch/blackfin/configs/H8606_defconfig2
-rw-r--r--arch/blackfin/configs/IP0X_defconfig2
-rw-r--r--arch/blackfin/configs/PNAV-10_defconfig2
-rw-r--r--arch/blackfin/configs/SRV1_defconfig2
-rw-r--r--arch/blackfin/configs/TCM-BF518_defconfig2
-rw-r--r--arch/blackfin/configs/TCM-BF537_defconfig2
-rw-r--r--arch/blackfin/include/asm/bfin_serial.h3
-rw-r--r--arch/blackfin/include/asm/cpu.h3
-rw-r--r--arch/blackfin/include/asm/smp.h5
-rw-r--r--arch/blackfin/kernel/setup.c16
-rw-r--r--arch/blackfin/kernel/time-ts.c8
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c10
-rw-r--r--arch/blackfin/mach-bf518/boards/tcm-bf518.c4
-rw-r--r--arch/blackfin/mach-bf527/boards/ad7160eval.c4
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c4
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c4
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf527/boards/tll6527m.c4
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c6
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c4
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c6
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c4
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c179
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/dnp5370.c4
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c78
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c6
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c6
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c6
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c73
-rw-r--r--arch/blackfin/mach-bf561/boards/acvilon.c4
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c6
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c101
-rw-r--r--arch/blackfin/mach-bf561/include/mach/pll.h4
-rw-r--r--arch/blackfin/mach-bf561/smp.c5
-rw-r--r--arch/blackfin/mach-common/smp.c61
-rw-r--r--arch/c6x/Kconfig174
-rw-r--r--arch/c6x/Makefile60
-rw-r--r--arch/c6x/boot/Makefile30
-rw-r--r--arch/c6x/boot/dts/dsk6455.dts62
-rw-r--r--arch/c6x/boot/dts/evmc6457.dts48
-rw-r--r--arch/c6x/boot/dts/evmc6472.dts73
-rw-r--r--arch/c6x/boot/dts/evmc6474.dts58
-rw-r--r--arch/c6x/boot/dts/tms320c6455.dtsi96
-rw-r--r--arch/c6x/boot/dts/tms320c6457.dtsi68
-rw-r--r--arch/c6x/boot/dts/tms320c6472.dtsi134
-rw-r--r--arch/c6x/boot/dts/tms320c6474.dtsi89
-rw-r--r--arch/c6x/boot/linked_dtb.S2
-rw-r--r--arch/c6x/configs/dsk6455_defconfig44
-rw-r--r--arch/c6x/configs/evmc6457_defconfig41
-rw-r--r--arch/c6x/configs/evmc6472_defconfig42
-rw-r--r--arch/c6x/configs/evmc6474_defconfig42
-rw-r--r--arch/c6x/include/asm/Kbuild54
-rw-r--r--arch/c6x/include/asm/asm-offsets.h1
-rw-r--r--arch/c6x/include/asm/bitops.h105
-rw-r--r--arch/c6x/include/asm/byteorder.h12
-rw-r--r--arch/c6x/include/asm/cache.h90
-rw-r--r--arch/c6x/include/asm/cacheflush.h65
-rw-r--r--arch/c6x/include/asm/checksum.h34
-rw-r--r--arch/c6x/include/asm/clkdev.h22
-rw-r--r--arch/c6x/include/asm/clock.h148
-rw-r--r--arch/c6x/include/asm/delay.h67
-rw-r--r--arch/c6x/include/asm/dma-mapping.h91
-rw-r--r--arch/c6x/include/asm/dscr.h34
-rw-r--r--arch/c6x/include/asm/elf.h113
-rw-r--r--arch/c6x/include/asm/ftrace.h6
-rw-r--r--arch/c6x/include/asm/hardirq.h20
-rw-r--r--arch/c6x/include/asm/irq.h302
-rw-r--r--arch/c6x/include/asm/irqflags.h72
-rw-r--r--arch/c6x/include/asm/linkage.h30
-rw-r--r--arch/c6x/include/asm/megamod-pic.h9
-rw-r--r--arch/c6x/include/asm/mmu.h18
-rw-r--r--arch/c6x/include/asm/module.h33
-rw-r--r--arch/c6x/include/asm/mutex.h6
-rw-r--r--arch/c6x/include/asm/page.h11
-rw-r--r--arch/c6x/include/asm/pgtable.h81
-rw-r--r--arch/c6x/include/asm/processor.h132
-rw-r--r--arch/c6x/include/asm/procinfo.h28
-rw-r--r--arch/c6x/include/asm/prom.h1
-rw-r--r--arch/c6x/include/asm/ptrace.h174
-rw-r--r--arch/c6x/include/asm/sections.h12
-rw-r--r--arch/c6x/include/asm/setup.h32
-rw-r--r--arch/c6x/include/asm/sigcontext.h80
-rw-r--r--arch/c6x/include/asm/signal.h17
-rw-r--r--arch/c6x/include/asm/soc.h35
-rw-r--r--arch/c6x/include/asm/string.h21
-rw-r--r--arch/c6x/include/asm/swab.h54
-rw-r--r--arch/c6x/include/asm/syscall.h123
-rw-r--r--arch/c6x/include/asm/syscalls.h55
-rw-r--r--arch/c6x/include/asm/system.h168
-rw-r--r--arch/c6x/include/asm/thread_info.h121
-rw-r--r--arch/c6x/include/asm/timer64.h6
-rw-r--r--arch/c6x/include/asm/timex.h33
-rw-r--r--arch/c6x/include/asm/tlb.h8
-rw-r--r--arch/c6x/include/asm/traps.h36
-rw-r--r--arch/c6x/include/asm/uaccess.h107
-rw-r--r--arch/c6x/include/asm/unaligned.h170
-rw-r--r--arch/c6x/include/asm/unistd.h26
-rw-r--r--arch/c6x/kernel/Makefile12
-rw-r--r--arch/c6x/kernel/asm-offsets.c123
-rw-r--r--arch/c6x/kernel/c6x_ksyms.c66
-rw-r--r--arch/c6x/kernel/devicetree.c53
-rw-r--r--arch/c6x/kernel/dma.c153
-rw-r--r--arch/c6x/kernel/entry.S803
-rw-r--r--arch/c6x/kernel/head.S84
-rw-r--r--arch/c6x/kernel/irq.c728
-rw-r--r--arch/c6x/kernel/module.c123
-rw-r--r--arch/c6x/kernel/process.c265
-rw-r--r--arch/c6x/kernel/ptrace.c187
-rw-r--r--arch/c6x/kernel/setup.c510
-rw-r--r--arch/c6x/kernel/signal.c377
-rw-r--r--arch/c6x/kernel/soc.c91
-rw-r--r--arch/c6x/kernel/switch_to.S74
-rw-r--r--arch/c6x/kernel/sys_c6x.c74
-rw-r--r--arch/c6x/kernel/time.c65
-rw-r--r--arch/c6x/kernel/traps.c423
-rw-r--r--arch/c6x/kernel/vectors.S81
-rw-r--r--arch/c6x/kernel/vmlinux.lds.S162
-rw-r--r--arch/c6x/lib/Makefile7
-rw-r--r--arch/c6x/lib/checksum.c36
-rw-r--r--arch/c6x/lib/csum_64plus.S419
-rw-r--r--arch/c6x/lib/divi.S53
-rw-r--r--arch/c6x/lib/divremi.S46
-rw-r--r--arch/c6x/lib/divremu.S87
-rw-r--r--arch/c6x/lib/divu.S98
-rw-r--r--arch/c6x/lib/llshl.S37
-rw-r--r--arch/c6x/lib/llshr.S38
-rw-r--r--arch/c6x/lib/llshru.S38
-rw-r--r--arch/c6x/lib/memcpy_64plus.S46
-rw-r--r--arch/c6x/lib/mpyll.S49
-rw-r--r--arch/c6x/lib/negll.S31
-rw-r--r--arch/c6x/lib/pop_rts.S32
-rw-r--r--arch/c6x/lib/push_rts.S31
-rw-r--r--arch/c6x/lib/remi.S64
-rw-r--r--arch/c6x/lib/remu.S82
-rw-r--r--arch/c6x/lib/strasgi.S89
-rw-r--r--arch/c6x/lib/strasgi_64plus.S39
-rw-r--r--arch/c6x/mm/Makefile5
-rw-r--r--arch/c6x/mm/dma-coherent.c143
-rw-r--r--arch/c6x/mm/init.c113
-rw-r--r--arch/c6x/platforms/Kconfig16
-rw-r--r--arch/c6x/platforms/Makefile12
-rw-r--r--arch/c6x/platforms/cache.c445
-rw-r--r--arch/c6x/platforms/dscr.c598
-rw-r--r--arch/c6x/platforms/emif.c87
-rw-r--r--arch/c6x/platforms/megamod-pic.c349
-rw-r--r--arch/c6x/platforms/platform.c17
-rw-r--r--arch/c6x/platforms/pll.c444
-rw-r--r--arch/c6x/platforms/plldata.c404
-rw-r--r--arch/c6x/platforms/timer64.c244
-rw-r--r--arch/cris/Kconfig5
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c7
-rw-r--r--arch/frv/Kconfig1
-rw-r--r--arch/frv/include/asm/io.h2
-rw-r--r--arch/frv/mb93090-mb00/Makefile2
-rw-r--r--arch/frv/mb93090-mb00/pci-iomap.c29
-rw-r--r--arch/hexagon/Kconfig4
-rw-r--r--arch/ia64/Kconfig5
-rw-r--r--arch/ia64/include/asm/iommu.h2
-rw-r--r--arch/ia64/include/asm/xen/interface.h2
-rw-r--r--arch/ia64/kernel/pci-dma.c1
-rw-r--r--arch/ia64/kvm/kvm-ia64.c12
-rw-r--r--arch/m68k/Kconfig4
-rw-r--r--arch/microblaze/Kconfig1
-rw-r--r--arch/microblaze/include/asm/irq.h11
-rw-r--r--arch/microblaze/include/asm/page.h11
-rw-r--r--arch/microblaze/include/asm/setup.h6
-rw-r--r--arch/microblaze/include/asm/unistd.h5
-rw-r--r--arch/microblaze/kernel/early_printk.c4
-rw-r--r--arch/microblaze/kernel/entry.S2
-rw-r--r--arch/microblaze/kernel/intc.c52
-rw-r--r--arch/microblaze/kernel/irq.c11
-rw-r--r--arch/microblaze/kernel/module.c2
-rw-r--r--arch/microblaze/kernel/setup.c18
-rw-r--r--arch/microblaze/kernel/syscall_table.S3
-rw-r--r--arch/microblaze/kernel/timer.c21
-rw-r--r--arch/microblaze/lib/Makefile1
-rw-r--r--arch/microblaze/lib/cmpdi2.c26
-rw-r--r--arch/microblaze/pci/iomap.c19
-rw-r--r--arch/microblaze/pci/pci-common.c4
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c3
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h11
-rw-r--r--arch/mips/lib/iomap-pci.c26
-rw-r--r--arch/mn10300/Kconfig1
-rw-r--r--arch/mn10300/include/asm/io.h17
-rw-r--r--arch/mn10300/unit-asb2305/Makefile2
-rw-r--r--arch/mn10300/unit-asb2305/pci-iomap.c31
-rw-r--r--arch/openrisc/Kconfig3
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/lib/iomap.c23
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/include/asm/kvm.h4
-rw-r--r--arch/powerpc/kernel/iomap.c19
-rw-r--r--arch/powerpc/kernel/legacy_serial.c3
-rw-r--r--arch/powerpc/kvm/book3s.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv_builtin.c2
-rw-r--r--arch/powerpc/platforms/Kconfig3
-rw-r--r--arch/s390/Kbuild13
-rw-r--r--arch/s390/Kconfig11
-rw-r--r--arch/s390/Makefile1
-rw-r--r--arch/s390/boot/Makefile2
-rw-r--r--arch/s390/include/asm/kdebug.h2
-rw-r--r--arch/s390/include/asm/lowcore.h142
-rw-r--r--arch/s390/include/asm/percpu.h44
-rw-r--r--arch/s390/include/asm/pgtable.h23
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/ptrace.h3
-rw-r--r--arch/s390/include/asm/qdio.h5
-rw-r--r--arch/s390/include/asm/sigp.h1
-rw-r--r--arch/s390/include/asm/smp.h1
-rw-r--r--arch/s390/include/asm/sparsemem.h4
-rw-r--r--arch/s390/include/asm/syscall.h2
-rw-r--r--arch/s390/include/asm/system.h2
-rw-r--r--arch/s390/include/asm/topology.h40
-rw-r--r--arch/s390/include/asm/unistd.h1
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/asm-offsets.c8
-rw-r--r--arch/s390/kernel/base.S16
-rw-r--r--arch/s390/kernel/compat_linux.c3
-rw-r--r--arch/s390/kernel/compat_signal.c12
-rw-r--r--arch/s390/kernel/dis.c9
-rw-r--r--arch/s390/kernel/early.c20
-rw-r--r--arch/s390/kernel/entry.S1103
-rw-r--r--arch/s390/kernel/entry.h10
-rw-r--r--arch/s390/kernel/entry64.S976
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/mem_detect.c122
-rw-r--r--arch/s390/kernel/reipl64.S4
-rw-r--r--arch/s390/kernel/setup.c69
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c173
-rw-r--r--arch/s390/kernel/sys_s390.c76
-rw-r--r--arch/s390/kernel/topology.c275
-rw-r--r--arch/s390/kernel/traps.c170
-rw-r--r--arch/s390/mm/fault.c107
-rw-r--r--arch/s390/mm/init.c16
-rw-r--r--arch/s390/mm/pgtable.c14
-rw-r--r--arch/score/Kconfig4
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh/drivers/pci/pci.c23
-rw-r--r--arch/sh/mm/cache-sh2a.c123
-rw-r--r--arch/sparc/Kconfig4
-rw-r--r--arch/sparc/include/asm/atomic_32.h104
-rw-r--r--arch/sparc/include/asm/io_32.h2
-rw-r--r--arch/sparc/include/asm/io_64.h2
-rw-r--r--arch/sparc/include/asm/page_32.h10
-rw-r--r--arch/sparc/include/asm/pgtsun4.h171
-rw-r--r--arch/sparc/include/asm/signal.h3
-rw-r--r--arch/sparc/include/asm/thread_info_32.h2
-rw-r--r--arch/sparc/lib/atomic_32.S55
-rw-r--r--arch/sparc/lib/iomap.c23
-rw-r--r--arch/sparc/lib/ksyms.c6
-rw-r--r--arch/tile/Kconfig1
-rw-r--r--arch/tile/include/asm/io.h3
-rw-r--r--arch/tile/include/asm/pci.h2
-rw-r--r--arch/tile/kernel/pci.c21
-rw-r--r--arch/unicore32/Kconfig4
-rw-r--r--arch/unicore32/include/asm/io.h8
-rw-r--r--arch/unicore32/kernel/puv3-nb0916.c4
-rw-r--r--arch/unicore32/kernel/setup.c2
-rw-r--r--arch/unicore32/kernel/signal.c15
-rw-r--r--arch/unicore32/kernel/time.c2
-rw-r--r--arch/x86/Kconfig5
-rw-r--r--arch/x86/include/asm/cpufeature.h3
-rw-r--r--arch/x86/include/asm/iommu.h1
-rw-r--r--arch/x86/include/asm/kvm_emulate.h2
-rw-r--r--arch/x86/include/asm/kvm_host.h90
-rw-r--r--arch/x86/include/asm/mrst.h2
-rw-r--r--arch/x86/include/asm/percpu.h28
-rw-r--r--arch/x86/kernel/early_printk.c2
-rw-r--r--arch/x86/kernel/kvm.c181
-rw-r--r--arch/x86/kernel/pci-dma.c11
-rw-r--r--arch/x86/kernel/signal.c6
-rw-r--r--arch/x86/kvm/Kconfig3
-rw-r--r--arch/x86/kvm/Makefile2
-rw-r--r--arch/x86/kvm/cpuid.c670
-rw-r--r--arch/x86/kvm/cpuid.h46
-rw-r--r--arch/x86/kvm/emulate.c436
-rw-r--r--arch/x86/kvm/i8254.c10
-rw-r--r--arch/x86/kvm/i8259.c24
-rw-r--r--arch/x86/kvm/lapic.c3
-rw-r--r--arch/x86/kvm/lapic.h1
-rw-r--r--arch/x86/kvm/mmu.c545
-rw-r--r--arch/x86/kvm/mmu_audit.c29
-rw-r--r--arch/x86/kvm/mmutrace.h19
-rw-r--r--arch/x86/kvm/paging_tmpl.h86
-rw-r--r--arch/x86/kvm/pmu.c533
-rw-r--r--arch/x86/kvm/svm.c15
-rw-r--r--arch/x86/kvm/timer.c26
-rw-r--r--arch/x86/kvm/vmx.c45
-rw-r--r--arch/x86/kvm/x86.c1001
-rw-r--r--arch/x86/kvm/x86.h5
-rw-r--r--arch/x86/platform/mrst/early_printk_mrst.c16
-rw-r--r--arch/x86/xen/Kconfig4
-rw-r--r--arch/x86/xen/grant-table.c44
-rw-r--r--arch/x86/xen/mmu.c2
872 files changed, 30562 insertions, 12282 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 3d74801a401..56a4df952fb 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -70,10 +70,6 @@ config GENERIC_ISA_DMA
70 bool 70 bool
71 default y 71 default y
72 72
73config GENERIC_IOMAP
74 bool
75 default n
76
77source "init/Kconfig" 73source "init/Kconfig"
78source "kernel/Kconfig.freezer" 74source "kernel/Kconfig.freezer"
79 75
@@ -319,6 +315,7 @@ config ISA_DMA_API
319config PCI 315config PCI
320 bool 316 bool
321 depends on !ALPHA_JENSEN 317 depends on !ALPHA_JENSEN
318 select GENERIC_PCI_IOMAP
322 default y 319 default y
323 help 320 help
324 Find out whether you have a PCI motherboard. PCI is the name of a 321 Find out whether you have a PCI motherboard. PCI is the name of a
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 246100ef07c..04eea4894ef 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -185,15 +185,3 @@ struct dma_map_ops alpha_noop_ops = {
185 185
186struct dma_map_ops *dma_ops = &alpha_noop_ops; 186struct dma_map_ops *dma_ops = &alpha_noop_ops;
187EXPORT_SYMBOL(dma_ops); 187EXPORT_SYMBOL(dma_ops);
188
189void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
190{
191 return NULL;
192}
193
194void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
195{
196}
197
198EXPORT_SYMBOL(pci_iomap);
199EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index c9ab94ee1ca..f3cae275d3f 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -508,30 +508,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
508 return -EOPNOTSUPP; 508 return -EOPNOTSUPP;
509} 509}
510 510
511/* Create an __iomem token from a PCI BAR. Copied from lib/iomap.c with 511/* Destroy an __iomem token. Not copied from lib/iomap.c. */
512 no changes, since we don't want the other things in that object file. */
513
514void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
515{
516 resource_size_t start = pci_resource_start(dev, bar);
517 resource_size_t len = pci_resource_len(dev, bar);
518 unsigned long flags = pci_resource_flags(dev, bar);
519
520 if (!len || !start)
521 return NULL;
522 if (maxlen && len > maxlen)
523 len = maxlen;
524 if (flags & IORESOURCE_IO)
525 return ioport_map(start, len);
526 if (flags & IORESOURCE_MEM) {
527 /* Not checking IORESOURCE_CACHEABLE because alpha does
528 not distinguish between ioremap and ioremap_nocache. */
529 return ioremap(start, len);
530 }
531 return NULL;
532}
533
534/* Destroy that token. Not copied from lib/iomap.c. */
535 512
536void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 513void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
537{ 514{
@@ -539,7 +516,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
539 iounmap(addr); 516 iounmap(addr);
540} 517}
541 518
542EXPORT_SYMBOL(pci_iomap);
543EXPORT_SYMBOL(pci_iounmap); 519EXPORT_SYMBOL(pci_iounmap);
544 520
545/* FIXME: Some boxes have multiple ISA bridges! */ 521/* FIXME: Some boxes have multiple ISA bridges! */
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f72e1707d46..24626b0419e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -16,6 +16,7 @@ config ARM
16 select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) 16 select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
17 select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) 17 select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
18 select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL) 18 select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
19 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
19 select HAVE_GENERIC_DMA_COHERENT 20 select HAVE_GENERIC_DMA_COHERENT
20 select HAVE_KERNEL_GZIP 21 select HAVE_KERNEL_GZIP
21 select HAVE_KERNEL_LZO 22 select HAVE_KERNEL_LZO
@@ -30,6 +31,7 @@ config ARM
30 select HAVE_SPARSE_IRQ 31 select HAVE_SPARSE_IRQ
31 select GENERIC_IRQ_SHOW 32 select GENERIC_IRQ_SHOW
32 select CPU_PM if (SUSPEND || CPU_IDLE) 33 select CPU_PM if (SUSPEND || CPU_IDLE)
34 select GENERIC_PCI_IOMAP
33 help 35 help
34 The ARM series is a line of low-power-consumption RISC chip designs 36 The ARM series is a line of low-power-consumption RISC chip designs
35 licensed by ARM Ltd and targeted at embedded applications and 37 licensed by ARM Ltd and targeted at embedded applications and
@@ -447,6 +449,7 @@ config ARCH_MXS
447 select ARCH_REQUIRE_GPIOLIB 449 select ARCH_REQUIRE_GPIOLIB
448 select CLKDEV_LOOKUP 450 select CLKDEV_LOOKUP
449 select CLKSRC_MMIO 451 select CLKSRC_MMIO
452 select HAVE_CLK_PREPARE
450 help 453 help
451 Support for Freescale MXS-based family of processors 454 Support for Freescale MXS-based family of processors
452 455
@@ -597,6 +600,7 @@ config ARCH_MMP
597 select ARCH_REQUIRE_GPIOLIB 600 select ARCH_REQUIRE_GPIOLIB
598 select CLKDEV_LOOKUP 601 select CLKDEV_LOOKUP
599 select GENERIC_CLOCKEVENTS 602 select GENERIC_CLOCKEVENTS
603 select GPIO_PXA
600 select HAVE_SCHED_CLOCK 604 select HAVE_SCHED_CLOCK
601 select TICK_ONESHOT 605 select TICK_ONESHOT
602 select PLAT_PXA 606 select PLAT_PXA
@@ -658,6 +662,7 @@ config ARCH_PICOXCELL
658 select HAVE_SCHED_CLOCK 662 select HAVE_SCHED_CLOCK
659 select HAVE_TCM 663 select HAVE_TCM
660 select NO_IOPORT 664 select NO_IOPORT
665 select SPARSE_IRQ
661 select USE_OF 666 select USE_OF
662 help 667 help
663 This enables support for systems based on the Picochip picoXcell 668 This enables support for systems based on the Picochip picoXcell
@@ -681,6 +686,7 @@ config ARCH_PXA
681 select CLKSRC_MMIO 686 select CLKSRC_MMIO
682 select ARCH_REQUIRE_GPIOLIB 687 select ARCH_REQUIRE_GPIOLIB
683 select GENERIC_CLOCKEVENTS 688 select GENERIC_CLOCKEVENTS
689 select GPIO_PXA
684 select HAVE_SCHED_CLOCK 690 select HAVE_SCHED_CLOCK
685 select TICK_ONESHOT 691 select TICK_ONESHOT
686 select PLAT_PXA 692 select PLAT_PXA
@@ -748,7 +754,7 @@ config ARCH_SA1100
748 select ARCH_HAS_CPUFREQ 754 select ARCH_HAS_CPUFREQ
749 select CPU_FREQ 755 select CPU_FREQ
750 select GENERIC_CLOCKEVENTS 756 select GENERIC_CLOCKEVENTS
751 select HAVE_CLK 757 select CLKDEV_LOOKUP
752 select HAVE_SCHED_CLOCK 758 select HAVE_SCHED_CLOCK
753 select TICK_ONESHOT 759 select TICK_ONESHOT
754 select ARCH_REQUIRE_GPIOLIB 760 select ARCH_REQUIRE_GPIOLIB
@@ -892,7 +898,6 @@ config ARCH_U300
892 select HAVE_MACH_CLKDEV 898 select HAVE_MACH_CLKDEV
893 select GENERIC_GPIO 899 select GENERIC_GPIO
894 select ARCH_REQUIRE_GPIOLIB 900 select ARCH_REQUIRE_GPIOLIB
895 select NEED_MACH_MEMORY_H
896 help 901 help
897 Support for ST-Ericsson U300 series mobile platforms. 902 Support for ST-Ericsson U300 series mobile platforms.
898 903
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index c5213e78606..e0d236d7ff7 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -100,6 +100,14 @@ choice
100 Note that the system will appear to hang during boot if there 100 Note that the system will appear to hang during boot if there
101 is nothing connected to read from the DCC. 101 is nothing connected to read from the DCC.
102 102
103 config AT91_DEBUG_LL_DBGU0
104 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
105 depends on HAVE_AT91_DBGU0
106
107 config AT91_DEBUG_LL_DBGU1
108 bool "Kernel low-level debugging on 9263, 9g45 and cap9"
109 depends on HAVE_AT91_DBGU1
110
103 config DEBUG_FOOTBRIDGE_COM1 111 config DEBUG_FOOTBRIDGE_COM1
104 bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1" 112 bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
105 depends on FOOTBRIDGE 113 depends on FOOTBRIDGE
@@ -247,6 +255,43 @@ choice
247 their output to the standard serial port on the RealView 255 their output to the standard serial port on the RealView
248 PB1176 platform. 256 PB1176 platform.
249 257
258 config DEBUG_MSM_UART1
259 bool "Kernel low-level debugging messages via MSM UART1"
260 depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
261 help
262 Say Y here if you want the debug print routines to direct
263 their output to the first serial port on MSM devices.
264
265 config DEBUG_MSM_UART2
266 bool "Kernel low-level debugging messages via MSM UART2"
267 depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
268 help
269 Say Y here if you want the debug print routines to direct
270 their output to the second serial port on MSM devices.
271
272 config DEBUG_MSM_UART3
273 bool "Kernel low-level debugging messages via MSM UART3"
274 depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
275 help
276 Say Y here if you want the debug print routines to direct
277 their output to the third serial port on MSM devices.
278
279 config DEBUG_MSM8660_UART
280 bool "Kernel low-level debugging messages via MSM 8660 UART"
281 depends on ARCH_MSM8X60
282 select MSM_HAS_DEBUG_UART_HS
283 help
284 Say Y here if you want the debug print routines to direct
285 their output to the serial port on MSM 8660 devices.
286
287 config DEBUG_MSM8960_UART
288 bool "Kernel low-level debugging messages via MSM 8960 UART"
289 depends on ARCH_MSM8960
290 select MSM_HAS_DEBUG_UART_HS
291 help
292 Say Y here if you want the debug print routines to direct
293 their output to the serial port on MSM 8960 devices.
294
250endchoice 295endchoice
251 296
252config EARLY_PRINTK 297config EARLY_PRINTK
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index aeef04269cf..07603b8c950 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -114,6 +114,13 @@
114 atmel,use-dma-tx; 114 atmel,use-dma-tx;
115 status = "disabled"; 115 status = "disabled";
116 }; 116 };
117
118 macb0: ethernet@fffc4000 {
119 compatible = "cdns,at32ap7000-macb", "cdns,macb";
120 reg = <0xfffc4000 0x100>;
121 interrupts = <21>;
122 status = "disabled";
123 };
117 }; 124 };
118 }; 125 };
119}; 126};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index db6a45202f2..fffa005300a 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -101,6 +101,13 @@
101 atmel,use-dma-tx; 101 atmel,use-dma-tx;
102 status = "disabled"; 102 status = "disabled";
103 }; 103 };
104
105 macb0: ethernet@fffbc000 {
106 compatible = "cdns,at32ap7000-macb", "cdns,macb";
107 reg = <0xfffbc000 0x100>;
108 interrupts = <25>;
109 status = "disabled";
110 };
104 }; 111 };
105 }; 112 };
106}; 113};
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index 85b34f59cd8..a387e7704ce 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -30,6 +30,11 @@
30 usart1: serial@fff90000 { 30 usart1: serial@fff90000 {
31 status = "okay"; 31 status = "okay";
32 }; 32 };
33
34 macb0: ethernet@fffbc000 {
35 phy-mode = "rmii";
36 status = "okay";
37 };
33 }; 38 };
34 }; 39 };
35}; 40};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
new file mode 100644
index 00000000000..b8c476384ee
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -0,0 +1,137 @@
1/*
2 * Samsung's Exynos4210 based Origen board device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Device tree source file for Insignal's Origen board which is based on
10 * Samsung's Exynos4210 SoC.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17/dts-v1/;
18/include/ "exynos4210.dtsi"
19
20/ {
21 model = "Insignal Origen evaluation board based on Exynos4210";
22 compatible = "insignal,origen", "samsung,exynos4210";
23
24 memory {
25 reg = <0x40000000 0x40000000>;
26 };
27
28 chosen {
29 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
30 };
31
32 sdhci@12530000 {
33 samsung,sdhci-bus-width = <4>;
34 linux,mmc_cap_4_bit_data;
35 samsung,sdhci-cd-internal;
36 gpio-cd = <&gpk2 2 2 3 3>;
37 gpios = <&gpk2 0 2 0 3>,
38 <&gpk2 1 2 0 3>,
39 <&gpk2 3 2 3 3>,
40 <&gpk2 4 2 3 3>,
41 <&gpk2 5 2 3 3>,
42 <&gpk2 6 2 3 3>;
43 };
44
45 sdhci@12510000 {
46 samsung,sdhci-bus-width = <4>;
47 linux,mmc_cap_4_bit_data;
48 samsung,sdhci-cd-internal;
49 gpio-cd = <&gpk0 2 2 3 3>;
50 gpios = <&gpk0 0 2 0 3>,
51 <&gpk0 1 2 0 3>,
52 <&gpk0 3 2 3 3>,
53 <&gpk0 4 2 3 3>,
54 <&gpk0 5 2 3 3>,
55 <&gpk0 6 2 3 3>;
56 };
57
58 gpio_keys {
59 compatible = "gpio-keys";
60 #address-cells = <1>;
61 #size-cells = <0>;
62
63 up {
64 label = "Up";
65 gpios = <&gpx2 0 0 0 2>;
66 linux,code = <103>;
67 };
68
69 down {
70 label = "Down";
71 gpios = <&gpx2 1 0 0 2>;
72 linux,code = <108>;
73 };
74
75 back {
76 label = "Back";
77 gpios = <&gpx1 7 0 0 2>;
78 linux,code = <158>;
79 };
80
81 home {
82 label = "Home";
83 gpios = <&gpx1 6 0 0 2>;
84 linux,code = <102>;
85 };
86
87 menu {
88 label = "Menu";
89 gpios = <&gpx1 5 0 0 2>;
90 linux,code = <139>;
91 };
92 };
93
94 keypad@100A0000 {
95 status = "disabled";
96 };
97
98 sdhci@12520000 {
99 status = "disabled";
100 };
101
102 sdhci@12540000 {
103 status = "disabled";
104 };
105
106 i2c@13860000 {
107 status = "disabled";
108 };
109
110 i2c@13870000 {
111 status = "disabled";
112 };
113
114 i2c@13880000 {
115 status = "disabled";
116 };
117
118 i2c@13890000 {
119 status = "disabled";
120 };
121
122 i2c@138A0000 {
123 status = "disabled";
124 };
125
126 i2c@138B0000 {
127 status = "disabled";
128 };
129
130 i2c@138C0000 {
131 status = "disabled";
132 };
133
134 i2c@138D0000 {
135 status = "disabled";
136 };
137};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
new file mode 100644
index 00000000000..27afc8e535c
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -0,0 +1,182 @@
1/*
2 * Samsung's Exynos4210 based SMDKV310 board device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Device tree source file for Samsung's SMDKV310 board which is based on
10 * Samsung's Exynos4210 SoC.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17/dts-v1/;
18/include/ "exynos4210.dtsi"
19
20/ {
21 model = "Samsung smdkv310 evaluation board based on Exynos4210";
22 compatible = "samsung,smdkv310", "samsung,exynos4210";
23
24 memory {
25 reg = <0x40000000 0x80000000>;
26 };
27
28 chosen {
29 bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
30 };
31
32 sdhci@12530000 {
33 samsung,sdhci-bus-width = <4>;
34 linux,mmc_cap_4_bit_data;
35 samsung,sdhci-cd-internal;
36 gpio-cd = <&gpk2 2 2 3 3>;
37 gpios = <&gpk2 0 2 0 3>,
38 <&gpk2 1 2 0 3>,
39 <&gpk2 3 2 3 3>,
40 <&gpk2 4 2 3 3>,
41 <&gpk2 5 2 3 3>,
42 <&gpk2 6 2 3 3>;
43 };
44
45 keypad@100A0000 {
46 samsung,keypad-num-rows = <2>;
47 samsung,keypad-num-columns = <8>;
48 linux,keypad-no-autorepeat;
49 linux,keypad-wakeup;
50
51 row-gpios = <&gpx2 0 3 3 0>,
52 <&gpx2 1 3 3 0>;
53
54 col-gpios = <&gpx1 0 3 0 0>,
55 <&gpx1 1 3 0 0>,
56 <&gpx1 2 3 0 0>,
57 <&gpx1 3 3 0 0>,
58 <&gpx1 4 3 0 0>,
59 <&gpx1 5 3 0 0>,
60 <&gpx1 6 3 0 0>,
61 <&gpx1 7 3 0 0>;
62
63 key_1 {
64 keypad,row = <0>;
65 keypad,column = <3>;
66 linux,code = <2>;
67 };
68
69 key_2 {
70 keypad,row = <0>;
71 keypad,column = <4>;
72 linux,code = <3>;
73 };
74
75 key_3 {
76 keypad,row = <0>;
77 keypad,column = <5>;
78 linux,code = <4>;
79 };
80
81 key_4 {
82 keypad,row = <0>;
83 keypad,column = <6>;
84 linux,code = <5>;
85 };
86
87 key_5 {
88 keypad,row = <0>;
89 keypad,column = <7>;
90 linux,code = <6>;
91 };
92
93 key_a {
94 keypad,row = <1>;
95 keypad,column = <3>;
96 linux,code = <30>;
97 };
98
99 key_b {
100 keypad,row = <1>;
101 keypad,column = <4>;
102 linux,code = <48>;
103 };
104
105 key_c {
106 keypad,row = <1>;
107 keypad,column = <5>;
108 linux,code = <46>;
109 };
110
111 key_d {
112 keypad,row = <1>;
113 keypad,column = <6>;
114 linux,code = <32>;
115 };
116
117 key_e {
118 keypad,row = <1>;
119 keypad,column = <7>;
120 linux,code = <18>;
121 };
122 };
123
124 i2c@13860000 {
125 #address-cells = <1>;
126 #size-cells = <0>;
127 samsung,i2c-sda-delay = <100>;
128 samsung,i2c-max-bus-freq = <20000>;
129 gpios = <&gpd1 0 2 3 0>,
130 <&gpd1 1 2 3 0>;
131
132 eeprom@50 {
133 compatible = "samsung,24ad0xd1";
134 reg = <0x50>;
135 };
136
137 eeprom@52 {
138 compatible = "samsung,24ad0xd1";
139 reg = <0x52>;
140 };
141 };
142
143 sdhci@12510000 {
144 status = "disabled";
145 };
146
147 sdhci@12520000 {
148 status = "disabled";
149 };
150
151 sdhci@12540000 {
152 status = "disabled";
153 };
154
155 i2c@13870000 {
156 status = "disabled";
157 };
158
159 i2c@13880000 {
160 status = "disabled";
161 };
162
163 i2c@13890000 {
164 status = "disabled";
165 };
166
167 i2c@138A0000 {
168 status = "disabled";
169 };
170
171 i2c@138B0000 {
172 status = "disabled";
173 };
174
175 i2c@138C0000 {
176 status = "disabled";
177 };
178
179 i2c@138D0000 {
180 status = "disabled";
181 };
182};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
new file mode 100644
index 00000000000..63d7578856c
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -0,0 +1,397 @@
1/*
2 * Samsung's Exynos4210 SoC device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
10 * based board files can include this file and provide values for board specfic
11 * bindings.
12 *
13 * Note: This file does not include device nodes for all the controllers in
14 * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
15 * nodes can be added to this file.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20*/
21
22/include/ "skeleton.dtsi"
23
24/ {
25 compatible = "samsung,exynos4210";
26 interrupt-parent = <&gic>;
27
28 gic:interrupt-controller@10490000 {
29 compatible = "arm,cortex-a9-gic";
30 #interrupt-cells = <3>;
31 interrupt-controller;
32 reg = <0x10490000 0x1000>, <0x10480000 0x100>;
33 };
34
35 watchdog@10060000 {
36 compatible = "samsung,s3c2410-wdt";
37 reg = <0x10060000 0x100>;
38 interrupts = <0 43 0>;
39 };
40
41 rtc@10070000 {
42 compatible = "samsung,s3c6410-rtc";
43 reg = <0x10070000 0x100>;
44 interrupts = <0 44 0>, <0 45 0>;
45 };
46
47 keypad@100A0000 {
48 compatible = "samsung,s5pv210-keypad";
49 reg = <0x100A0000 0x100>;
50 interrupts = <0 109 0>;
51 };
52
53 sdhci@12510000 {
54 compatible = "samsung,exynos4210-sdhci";
55 reg = <0x12510000 0x100>;
56 interrupts = <0 73 0>;
57 };
58
59 sdhci@12520000 {
60 compatible = "samsung,exynos4210-sdhci";
61 reg = <0x12520000 0x100>;
62 interrupts = <0 74 0>;
63 };
64
65 sdhci@12530000 {
66 compatible = "samsung,exynos4210-sdhci";
67 reg = <0x12530000 0x100>;
68 interrupts = <0 75 0>;
69 };
70
71 sdhci@12540000 {
72 compatible = "samsung,exynos4210-sdhci";
73 reg = <0x12540000 0x100>;
74 interrupts = <0 76 0>;
75 };
76
77 serial@13800000 {
78 compatible = "samsung,exynos4210-uart";
79 reg = <0x13800000 0x100>;
80 interrupts = <0 52 0>;
81 };
82
83 serial@13810000 {
84 compatible = "samsung,exynos4210-uart";
85 reg = <0x13810000 0x100>;
86 interrupts = <0 53 0>;
87 };
88
89 serial@13820000 {
90 compatible = "samsung,exynos4210-uart";
91 reg = <0x13820000 0x100>;
92 interrupts = <0 54 0>;
93 };
94
95 serial@13830000 {
96 compatible = "samsung,exynos4210-uart";
97 reg = <0x13830000 0x100>;
98 interrupts = <0 55 0>;
99 };
100
101 i2c@13860000 {
102 compatible = "samsung,s3c2440-i2c";
103 reg = <0x13860000 0x100>;
104 interrupts = <0 58 0>;
105 };
106
107 i2c@13870000 {
108 compatible = "samsung,s3c2440-i2c";
109 reg = <0x13870000 0x100>;
110 interrupts = <0 59 0>;
111 };
112
113 i2c@13880000 {
114 compatible = "samsung,s3c2440-i2c";
115 reg = <0x13880000 0x100>;
116 interrupts = <0 60 0>;
117 };
118
119 i2c@13890000 {
120 compatible = "samsung,s3c2440-i2c";
121 reg = <0x13890000 0x100>;
122 interrupts = <0 61 0>;
123 };
124
125 i2c@138A0000 {
126 compatible = "samsung,s3c2440-i2c";
127 reg = <0x138A0000 0x100>;
128 interrupts = <0 62 0>;
129 };
130
131 i2c@138B0000 {
132 compatible = "samsung,s3c2440-i2c";
133 reg = <0x138B0000 0x100>;
134 interrupts = <0 63 0>;
135 };
136
137 i2c@138C0000 {
138 compatible = "samsung,s3c2440-i2c";
139 reg = <0x138C0000 0x100>;
140 interrupts = <0 64 0>;
141 };
142
143 i2c@138D0000 {
144 compatible = "samsung,s3c2440-i2c";
145 reg = <0x138D0000 0x100>;
146 interrupts = <0 65 0>;
147 };
148
149 amba {
150 #address-cells = <1>;
151 #size-cells = <1>;
152 compatible = "arm,amba-bus";
153 interrupt-parent = <&gic>;
154 ranges;
155
156 pdma0: pdma@12680000 {
157 compatible = "arm,pl330", "arm,primecell";
158 reg = <0x12680000 0x1000>;
159 interrupts = <0 35 0>;
160 };
161
162 pdma1: pdma@12690000 {
163 compatible = "arm,pl330", "arm,primecell";
164 reg = <0x12690000 0x1000>;
165 interrupts = <0 36 0>;
166 };
167 };
168
169 gpio-controllers {
170 #address-cells = <1>;
171 #size-cells = <1>;
172 gpio-controller;
173 ranges;
174
175 gpa0: gpio-controller@11400000 {
176 compatible = "samsung,exynos4-gpio";
177 reg = <0x11400000 0x20>;
178 #gpio-cells = <4>;
179 };
180
181 gpa1: gpio-controller@11400020 {
182 compatible = "samsung,exynos4-gpio";
183 reg = <0x11400020 0x20>;
184 #gpio-cells = <4>;
185 };
186
187 gpb: gpio-controller@11400040 {
188 compatible = "samsung,exynos4-gpio";
189 reg = <0x11400040 0x20>;
190 #gpio-cells = <4>;
191 };
192
193 gpc0: gpio-controller@11400060 {
194 compatible = "samsung,exynos4-gpio";
195 reg = <0x11400060 0x20>;
196 #gpio-cells = <4>;
197 };
198
199 gpc1: gpio-controller@11400080 {
200 compatible = "samsung,exynos4-gpio";
201 reg = <0x11400080 0x20>;
202 #gpio-cells = <4>;
203 };
204
205 gpd0: gpio-controller@114000A0 {
206 compatible = "samsung,exynos4-gpio";
207 reg = <0x114000A0 0x20>;
208 #gpio-cells = <4>;
209 };
210
211 gpd1: gpio-controller@114000C0 {
212 compatible = "samsung,exynos4-gpio";
213 reg = <0x114000C0 0x20>;
214 #gpio-cells = <4>;
215 };
216
217 gpe0: gpio-controller@114000E0 {
218 compatible = "samsung,exynos4-gpio";
219 reg = <0x114000E0 0x20>;
220 #gpio-cells = <4>;
221 };
222
223 gpe1: gpio-controller@11400100 {
224 compatible = "samsung,exynos4-gpio";
225 reg = <0x11400100 0x20>;
226 #gpio-cells = <4>;
227 };
228
229 gpe2: gpio-controller@11400120 {
230 compatible = "samsung,exynos4-gpio";
231 reg = <0x11400120 0x20>;
232 #gpio-cells = <4>;
233 };
234
235 gpe3: gpio-controller@11400140 {
236 compatible = "samsung,exynos4-gpio";
237 reg = <0x11400140 0x20>;
238 #gpio-cells = <4>;
239 };
240
241 gpe4: gpio-controller@11400160 {
242 compatible = "samsung,exynos4-gpio";
243 reg = <0x11400160 0x20>;
244 #gpio-cells = <4>;
245 };
246
247 gpf0: gpio-controller@11400180 {
248 compatible = "samsung,exynos4-gpio";
249 reg = <0x11400180 0x20>;
250 #gpio-cells = <4>;
251 };
252
253 gpf1: gpio-controller@114001A0 {
254 compatible = "samsung,exynos4-gpio";
255 reg = <0x114001A0 0x20>;
256 #gpio-cells = <4>;
257 };
258
259 gpf2: gpio-controller@114001C0 {
260 compatible = "samsung,exynos4-gpio";
261 reg = <0x114001C0 0x20>;
262 #gpio-cells = <4>;
263 };
264
265 gpf3: gpio-controller@114001E0 {
266 compatible = "samsung,exynos4-gpio";
267 reg = <0x114001E0 0x20>;
268 #gpio-cells = <4>;
269 };
270
271 gpj0: gpio-controller@11000000 {
272 compatible = "samsung,exynos4-gpio";
273 reg = <0x11000000 0x20>;
274 #gpio-cells = <4>;
275 };
276
277 gpj1: gpio-controller@11000020 {
278 compatible = "samsung,exynos4-gpio";
279 reg = <0x11000020 0x20>;
280 #gpio-cells = <4>;
281 };
282
283 gpk0: gpio-controller@11000040 {
284 compatible = "samsung,exynos4-gpio";
285 reg = <0x11000040 0x20>;
286 #gpio-cells = <4>;
287 };
288
289 gpk1: gpio-controller@11000060 {
290 compatible = "samsung,exynos4-gpio";
291 reg = <0x11000060 0x20>;
292 #gpio-cells = <4>;
293 };
294
295 gpk2: gpio-controller@11000080 {
296 compatible = "samsung,exynos4-gpio";
297 reg = <0x11000080 0x20>;
298 #gpio-cells = <4>;
299 };
300
301 gpk3: gpio-controller@110000A0 {
302 compatible = "samsung,exynos4-gpio";
303 reg = <0x110000A0 0x20>;
304 #gpio-cells = <4>;
305 };
306
307 gpl0: gpio-controller@110000C0 {
308 compatible = "samsung,exynos4-gpio";
309 reg = <0x110000C0 0x20>;
310 #gpio-cells = <4>;
311 };
312
313 gpl1: gpio-controller@110000E0 {
314 compatible = "samsung,exynos4-gpio";
315 reg = <0x110000E0 0x20>;
316 #gpio-cells = <4>;
317 };
318
319 gpl2: gpio-controller@11000100 {
320 compatible = "samsung,exynos4-gpio";
321 reg = <0x11000100 0x20>;
322 #gpio-cells = <4>;
323 };
324
325 gpy0: gpio-controller@11000120 {
326 compatible = "samsung,exynos4-gpio";
327 reg = <0x11000120 0x20>;
328 #gpio-cells = <4>;
329 };
330
331 gpy1: gpio-controller@11000140 {
332 compatible = "samsung,exynos4-gpio";
333 reg = <0x11000140 0x20>;
334 #gpio-cells = <4>;
335 };
336
337 gpy2: gpio-controller@11000160 {
338 compatible = "samsung,exynos4-gpio";
339 reg = <0x11000160 0x20>;
340 #gpio-cells = <4>;
341 };
342
343 gpy3: gpio-controller@11000180 {
344 compatible = "samsung,exynos4-gpio";
345 reg = <0x11000180 0x20>;
346 #gpio-cells = <4>;
347 };
348
349 gpy4: gpio-controller@110001A0 {
350 compatible = "samsung,exynos4-gpio";
351 reg = <0x110001A0 0x20>;
352 #gpio-cells = <4>;
353 };
354
355 gpy5: gpio-controller@110001C0 {
356 compatible = "samsung,exynos4-gpio";
357 reg = <0x110001C0 0x20>;
358 #gpio-cells = <4>;
359 };
360
361 gpy6: gpio-controller@110001E0 {
362 compatible = "samsung,exynos4-gpio";
363 reg = <0x110001E0 0x20>;
364 #gpio-cells = <4>;
365 };
366
367 gpx0: gpio-controller@11000C00 {
368 compatible = "samsung,exynos4-gpio";
369 reg = <0x11000C00 0x20>;
370 #gpio-cells = <4>;
371 };
372
373 gpx1: gpio-controller@11000C20 {
374 compatible = "samsung,exynos4-gpio";
375 reg = <0x11000C20 0x20>;
376 #gpio-cells = <4>;
377 };
378
379 gpx2: gpio-controller@11000C40 {
380 compatible = "samsung,exynos4-gpio";
381 reg = <0x11000C40 0x20>;
382 #gpio-cells = <4>;
383 };
384
385 gpx3: gpio-controller@11000C60 {
386 compatible = "samsung,exynos4-gpio";
387 reg = <0x11000C60 0x20>;
388 #gpio-cells = <4>;
389 };
390
391 gpz: gpio-controller@03860000 {
392 compatible = "samsung,exynos4-gpio";
393 reg = <0x03860000 0x20>;
394 #gpio-cells = <4>;
395 };
396 };
397};
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index aeb1a7578fa..305635bd45c 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -194,5 +194,17 @@
194 reg = <0xfff3d000 0x1000>; 194 reg = <0xfff3d000 0x1000>;
195 interrupts = <0 92 4>; 195 interrupts = <0 92 4>;
196 }; 196 };
197
198 ethernet@fff50000 {
199 compatible = "calxeda,hb-xgmac";
200 reg = <0xfff50000 0x1000>;
201 interrupts = <0 77 4 0 78 4 0 79 4>;
202 };
203
204 ethernet@fff51000 {
205 compatible = "calxeda,hb-xgmac";
206 reg = <0xfff51000 0x1000>;
207 interrupts = <0 80 4 0 81 4 0 82 4>;
208 };
197 }; 209 };
198}; 210};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index f8766af1121..564cb8c19f1 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -35,20 +35,19 @@
35 }; 35 };
36 36
37 esdhc@70008000 { /* ESDHC2 */ 37 esdhc@70008000 { /* ESDHC2 */
38 cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */ 38 cd-gpios = <&gpio1 6 0>;
39 wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */ 39 wp-gpios = <&gpio1 5 0>;
40 status = "okay"; 40 status = "okay";
41 }; 41 };
42 42
43 uart2: uart@7000c000 { /* UART3 */ 43 uart3: uart@7000c000 {
44 fsl,uart-has-rtscts; 44 fsl,uart-has-rtscts;
45 status = "okay"; 45 status = "okay";
46 }; 46 };
47 47
48 ecspi@70010000 { /* ECSPI1 */ 48 ecspi@70010000 { /* ECSPI1 */
49 fsl,spi-num-chipselects = <2>; 49 fsl,spi-num-chipselects = <2>;
50 cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ 50 cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
51 <&gpio3 25 0>; /* GPIO4_25 */
52 status = "okay"; 51 status = "okay";
53 52
54 pmic: mc13892@0 { 53 pmic: mc13892@0 {
@@ -57,7 +56,7 @@
57 compatible = "fsl,mc13892"; 56 compatible = "fsl,mc13892";
58 spi-max-frequency = <6000000>; 57 spi-max-frequency = <6000000>;
59 reg = <0>; 58 reg = <0>;
60 mc13xxx-irq-gpios = <&gpio0 8 0>; /* GPIO1_8 */ 59 mc13xxx-irq-gpios = <&gpio1 8 0>;
61 fsl,mc13xxx-uses-regulator; 60 fsl,mc13xxx-uses-regulator;
62 }; 61 };
63 62
@@ -91,12 +90,12 @@
91 reg = <0x73fa8000 0x4000>; 90 reg = <0x73fa8000 0x4000>;
92 }; 91 };
93 92
94 uart0: uart@73fbc000 { 93 uart1: uart@73fbc000 {
95 fsl,uart-has-rtscts; 94 fsl,uart-has-rtscts;
96 status = "okay"; 95 status = "okay";
97 }; 96 };
98 97
99 uart1: uart@73fc0000 { 98 uart2: uart@73fc0000 {
100 status = "okay"; 99 status = "okay";
101 }; 100 };
102 }; 101 };
@@ -127,7 +126,7 @@
127 126
128 power { 127 power {
129 label = "Power Button"; 128 label = "Power Button";
130 gpios = <&gpio1 21 0>; 129 gpios = <&gpio2 21 0>;
131 linux,code = <116>; /* KEY_POWER */ 130 linux,code = <116>; /* KEY_POWER */
132 gpio-key,wakeup; 131 gpio-key,wakeup;
133 }; 132 };
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 327ab8e3a4c..6663986fe1c 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -14,9 +14,9 @@
14 14
15/ { 15/ {
16 aliases { 16 aliases {
17 serial0 = &uart0; 17 serial0 = &uart1;
18 serial1 = &uart1; 18 serial1 = &uart2;
19 serial2 = &uart2; 19 serial2 = &uart3;
20 }; 20 };
21 21
22 tzic: tz-interrupt-controller@e0000000 { 22 tzic: tz-interrupt-controller@e0000000 {
@@ -86,7 +86,7 @@
86 status = "disabled"; 86 status = "disabled";
87 }; 87 };
88 88
89 uart2: uart@7000c000 { /* UART3 */ 89 uart3: uart@7000c000 {
90 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 90 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
91 reg = <0x7000c000 0x4000>; 91 reg = <0x7000c000 0x4000>;
92 interrupts = <33>; 92 interrupts = <33>;
@@ -117,7 +117,7 @@
117 }; 117 };
118 }; 118 };
119 119
120 gpio0: gpio@73f84000 { /* GPIO1 */ 120 gpio1: gpio@73f84000 {
121 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; 121 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
122 reg = <0x73f84000 0x4000>; 122 reg = <0x73f84000 0x4000>;
123 interrupts = <50 51>; 123 interrupts = <50 51>;
@@ -127,7 +127,7 @@
127 #interrupt-cells = <1>; 127 #interrupt-cells = <1>;
128 }; 128 };
129 129
130 gpio1: gpio@73f88000 { /* GPIO2 */ 130 gpio2: gpio@73f88000 {
131 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; 131 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
132 reg = <0x73f88000 0x4000>; 132 reg = <0x73f88000 0x4000>;
133 interrupts = <52 53>; 133 interrupts = <52 53>;
@@ -137,7 +137,7 @@
137 #interrupt-cells = <1>; 137 #interrupt-cells = <1>;
138 }; 138 };
139 139
140 gpio2: gpio@73f8c000 { /* GPIO3 */ 140 gpio3: gpio@73f8c000 {
141 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; 141 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
142 reg = <0x73f8c000 0x4000>; 142 reg = <0x73f8c000 0x4000>;
143 interrupts = <54 55>; 143 interrupts = <54 55>;
@@ -147,7 +147,7 @@
147 #interrupt-cells = <1>; 147 #interrupt-cells = <1>;
148 }; 148 };
149 149
150 gpio3: gpio@73f90000 { /* GPIO4 */ 150 gpio4: gpio@73f90000 {
151 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio"; 151 compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
152 reg = <0x73f90000 0x4000>; 152 reg = <0x73f90000 0x4000>;
153 interrupts = <56 57>; 153 interrupts = <56 57>;
@@ -171,14 +171,14 @@
171 status = "disabled"; 171 status = "disabled";
172 }; 172 };
173 173
174 uart0: uart@73fbc000 { 174 uart1: uart@73fbc000 {
175 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 175 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
176 reg = <0x73fbc000 0x4000>; 176 reg = <0x73fbc000 0x4000>;
177 interrupts = <31>; 177 interrupts = <31>;
178 status = "disabled"; 178 status = "disabled";
179 }; 179 };
180 180
181 uart1: uart@73fc0000 { 181 uart2: uart@73fc0000 {
182 compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 182 compatible = "fsl,imx51-uart", "fsl,imx21-uart";
183 reg = <0x73fc0000 0x4000>; 183 reg = <0x73fc0000 0x4000>;
184 interrupts = <32>; 184 interrupts = <32>;
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
index 2ab7f80a0a3..2dccce46ed8 100644
--- a/arch/arm/boot/dts/imx53-ard.dts
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -29,8 +29,8 @@
29 aips@50000000 { /* AIPS1 */ 29 aips@50000000 { /* AIPS1 */
30 spba@50000000 { 30 spba@50000000 {
31 esdhc@50004000 { /* ESDHC1 */ 31 esdhc@50004000 { /* ESDHC1 */
32 cd-gpios = <&gpio0 1 0>; /* GPIO1_1 */ 32 cd-gpios = <&gpio1 1 0>;
33 wp-gpios = <&gpio0 9 0>; /* GPIO1_9 */ 33 wp-gpios = <&gpio1 9 0>;
34 status = "okay"; 34 status = "okay";
35 }; 35 };
36 }; 36 };
@@ -44,7 +44,7 @@
44 reg = <0x53fa8000 0x4000>; 44 reg = <0x53fa8000 0x4000>;
45 }; 45 };
46 46
47 uart0: uart@53fbc000 { /* UART1 */ 47 uart1: uart@53fbc000 {
48 status = "okay"; 48 status = "okay";
49 }; 49 };
50 }; 50 };
@@ -67,7 +67,7 @@
67 compatible = "smsc,lan9220", "smsc,lan9115"; 67 compatible = "smsc,lan9220", "smsc,lan9115";
68 reg = <0xf4000000 0x2000000>; 68 reg = <0xf4000000 0x2000000>;
69 phy-mode = "mii"; 69 phy-mode = "mii";
70 interrupt-parent = <&gpio1>; 70 interrupt-parent = <&gpio2>;
71 interrupts = <31>; 71 interrupts = <31>;
72 reg-io-width = <4>; 72 reg-io-width = <4>;
73 smsc,irq-push-pull; 73 smsc,irq-push-pull;
@@ -79,34 +79,34 @@
79 79
80 home { 80 home {
81 label = "Home"; 81 label = "Home";
82 gpios = <&gpio4 10 0>; /* GPIO5_10 */ 82 gpios = <&gpio5 10 0>;
83 linux,code = <102>; /* KEY_HOME */ 83 linux,code = <102>; /* KEY_HOME */
84 gpio-key,wakeup; 84 gpio-key,wakeup;
85 }; 85 };
86 86
87 back { 87 back {
88 label = "Back"; 88 label = "Back";
89 gpios = <&gpio4 11 0>; /* GPIO5_11 */ 89 gpios = <&gpio5 11 0>;
90 linux,code = <158>; /* KEY_BACK */ 90 linux,code = <158>; /* KEY_BACK */
91 gpio-key,wakeup; 91 gpio-key,wakeup;
92 }; 92 };
93 93
94 program { 94 program {
95 label = "Program"; 95 label = "Program";
96 gpios = <&gpio4 12 0>; /* GPIO5_12 */ 96 gpios = <&gpio5 12 0>;
97 linux,code = <362>; /* KEY_PROGRAM */ 97 linux,code = <362>; /* KEY_PROGRAM */
98 gpio-key,wakeup; 98 gpio-key,wakeup;
99 }; 99 };
100 100
101 volume-up { 101 volume-up {
102 label = "Volume Up"; 102 label = "Volume Up";
103 gpios = <&gpio4 13 0>; /* GPIO5_13 */ 103 gpios = <&gpio5 13 0>;
104 linux,code = <115>; /* KEY_VOLUMEUP */ 104 linux,code = <115>; /* KEY_VOLUMEUP */
105 }; 105 };
106 106
107 volume-down { 107 volume-down {
108 label = "Volume Down"; 108 label = "Volume Down";
109 gpios = <&gpio3 0 0>; /* GPIO4_0 */ 109 gpios = <&gpio4 0 0>;
110 linux,code = <114>; /* KEY_VOLUMEDOWN */ 110 linux,code = <114>; /* KEY_VOLUMEDOWN */
111 }; 111 };
112 }; 112 };
diff --git a/arch/arm/boot/dts/imx53-evk.dts b/arch/arm/boot/dts/imx53-evk.dts
index 3f3a88185ff..5bac4aa4800 100644
--- a/arch/arm/boot/dts/imx53-evk.dts
+++ b/arch/arm/boot/dts/imx53-evk.dts
@@ -29,15 +29,14 @@
29 aips@50000000 { /* AIPS1 */ 29 aips@50000000 { /* AIPS1 */
30 spba@50000000 { 30 spba@50000000 {
31 esdhc@50004000 { /* ESDHC1 */ 31 esdhc@50004000 { /* ESDHC1 */
32 cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */ 32 cd-gpios = <&gpio3 13 0>;
33 wp-gpios = <&gpio2 14 0>; /* GPIO3_14 */ 33 wp-gpios = <&gpio3 14 0>;
34 status = "okay"; 34 status = "okay";
35 }; 35 };
36 36
37 ecspi@50010000 { /* ECSPI1 */ 37 ecspi@50010000 { /* ECSPI1 */
38 fsl,spi-num-chipselects = <2>; 38 fsl,spi-num-chipselects = <2>;
39 cs-gpios = <&gpio1 30 0>, /* GPIO2_30 */ 39 cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
40 <&gpio2 19 0>; /* GPIO3_19 */
41 status = "okay"; 40 status = "okay";
42 41
43 flash: at45db321d@1 { 42 flash: at45db321d@1 {
@@ -61,8 +60,8 @@
61 }; 60 };
62 61
63 esdhc@50020000 { /* ESDHC3 */ 62 esdhc@50020000 { /* ESDHC3 */
64 cd-gpios = <&gpio2 11 0>; /* GPIO3_11 */ 63 cd-gpios = <&gpio3 11 0>;
65 wp-gpios = <&gpio2 12 0>; /* GPIO3_12 */ 64 wp-gpios = <&gpio3 12 0>;
66 status = "okay"; 65 status = "okay";
67 }; 66 };
68 }; 67 };
@@ -76,7 +75,7 @@
76 reg = <0x53fa8000 0x4000>; 75 reg = <0x53fa8000 0x4000>;
77 }; 76 };
78 77
79 uart0: uart@53fbc000 { /* UART1 */ 78 uart1: uart@53fbc000 {
80 status = "okay"; 79 status = "okay";
81 }; 80 };
82 }; 81 };
@@ -102,7 +101,7 @@
102 101
103 fec@63fec000 { 102 fec@63fec000 {
104 phy-mode = "rmii"; 103 phy-mode = "rmii";
105 phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */ 104 phy-reset-gpios = <&gpio7 6 0>;
106 status = "okay"; 105 status = "okay";
107 }; 106 };
108 }; 107 };
@@ -113,7 +112,7 @@
113 112
114 green { 113 green {
115 label = "Heartbeat"; 114 label = "Heartbeat";
116 gpios = <&gpio6 7 0>; /* GPIO7_7 */ 115 gpios = <&gpio7 7 0>;
117 linux,default-trigger = "heartbeat"; 116 linux,default-trigger = "heartbeat";
118 }; 117 };
119 }; 118 };
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
index ae6de6d0c3f..5c57c8672c3 100644
--- a/arch/arm/boot/dts/imx53-qsb.dts
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -29,13 +29,13 @@
29 aips@50000000 { /* AIPS1 */ 29 aips@50000000 { /* AIPS1 */
30 spba@50000000 { 30 spba@50000000 {
31 esdhc@50004000 { /* ESDHC1 */ 31 esdhc@50004000 { /* ESDHC1 */
32 cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */ 32 cd-gpios = <&gpio3 13 0>;
33 status = "okay"; 33 status = "okay";
34 }; 34 };
35 35
36 esdhc@50020000 { /* ESDHC3 */ 36 esdhc@50020000 { /* ESDHC3 */
37 cd-gpios = <&gpio2 11 0>; /* GPIO3_11 */ 37 cd-gpios = <&gpio3 11 0>;
38 wp-gpios = <&gpio2 12 0>; /* GPIO3_12 */ 38 wp-gpios = <&gpio3 12 0>;
39 status = "okay"; 39 status = "okay";
40 }; 40 };
41 }; 41 };
@@ -49,7 +49,7 @@
49 reg = <0x53fa8000 0x4000>; 49 reg = <0x53fa8000 0x4000>;
50 }; 50 };
51 51
52 uart0: uart@53fbc000 { /* UART1 */ 52 uart1: uart@53fbc000 {
53 status = "okay"; 53 status = "okay";
54 }; 54 };
55 }; 55 };
@@ -84,7 +84,7 @@
84 84
85 fec@63fec000 { 85 fec@63fec000 {
86 phy-mode = "rmii"; 86 phy-mode = "rmii";
87 phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */ 87 phy-reset-gpios = <&gpio7 6 0>;
88 status = "okay"; 88 status = "okay";
89 }; 89 };
90 }; 90 };
@@ -95,20 +95,20 @@
95 95
96 power { 96 power {
97 label = "Power Button"; 97 label = "Power Button";
98 gpios = <&gpio0 8 0>; /* GPIO1_8 */ 98 gpios = <&gpio1 8 0>;
99 linux,code = <116>; /* KEY_POWER */ 99 linux,code = <116>; /* KEY_POWER */
100 gpio-key,wakeup; 100 gpio-key,wakeup;
101 }; 101 };
102 102
103 volume-up { 103 volume-up {
104 label = "Volume Up"; 104 label = "Volume Up";
105 gpios = <&gpio1 14 0>; /* GPIO2_14 */ 105 gpios = <&gpio2 14 0>;
106 linux,code = <115>; /* KEY_VOLUMEUP */ 106 linux,code = <115>; /* KEY_VOLUMEUP */
107 }; 107 };
108 108
109 volume-down { 109 volume-down {
110 label = "Volume Down"; 110 label = "Volume Down";
111 gpios = <&gpio1 15 0>; /* GPIO2_15 */ 111 gpios = <&gpio2 15 0>;
112 linux,code = <114>; /* KEY_VOLUMEDOWN */ 112 linux,code = <114>; /* KEY_VOLUMEDOWN */
113 }; 113 };
114 }; 114 };
@@ -118,7 +118,7 @@
118 118
119 user { 119 user {
120 label = "Heartbeat"; 120 label = "Heartbeat";
121 gpios = <&gpio6 7 0>; /* GPIO7_7 */ 121 gpios = <&gpio7 7 0>;
122 linux,default-trigger = "heartbeat"; 122 linux,default-trigger = "heartbeat";
123 }; 123 };
124 }; 124 };
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index b1c062eea71..c7ee86c2dfb 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -29,8 +29,8 @@
29 aips@50000000 { /* AIPS1 */ 29 aips@50000000 { /* AIPS1 */
30 spba@50000000 { 30 spba@50000000 {
31 esdhc@50004000 { /* ESDHC1 */ 31 esdhc@50004000 { /* ESDHC1 */
32 cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */ 32 cd-gpios = <&gpio3 13 0>;
33 wp-gpios = <&gpio3 11 0>; /* GPIO4_11 */ 33 wp-gpios = <&gpio4 11 0>;
34 status = "okay"; 34 status = "okay";
35 }; 35 };
36 36
@@ -39,15 +39,14 @@
39 status = "okay"; 39 status = "okay";
40 }; 40 };
41 41
42 uart2: uart@5000c000 { /* UART3 */ 42 uart3: uart@5000c000 {
43 fsl,uart-has-rtscts; 43 fsl,uart-has-rtscts;
44 status = "okay"; 44 status = "okay";
45 }; 45 };
46 46
47 ecspi@50010000 { /* ECSPI1 */ 47 ecspi@50010000 { /* ECSPI1 */
48 fsl,spi-num-chipselects = <2>; 48 fsl,spi-num-chipselects = <2>;
49 cs-gpios = <&gpio1 30 0>, /* GPIO2_30 */ 49 cs-gpios = <&gpio2 30 0>, <&gpio3 19 0>;
50 <&gpio2 19 0>; /* GPIO3_19 */
51 status = "okay"; 50 status = "okay";
52 51
53 zigbee: mc1323@0 { 52 zigbee: mc1323@0 {
@@ -91,11 +90,11 @@
91 reg = <0x53fa8000 0x4000>; 90 reg = <0x53fa8000 0x4000>;
92 }; 91 };
93 92
94 uart0: uart@53fbc000 { /* UART1 */ 93 uart1: uart@53fbc000 {
95 status = "okay"; 94 status = "okay";
96 }; 95 };
97 96
98 uart1: uart@53fc0000 { /* UART2 */ 97 uart2: uart@53fc0000 {
99 status = "okay"; 98 status = "okay";
100 }; 99 };
101 }; 100 };
@@ -145,7 +144,7 @@
145 144
146 fec@63fec000 { 145 fec@63fec000 {
147 phy-mode = "rmii"; 146 phy-mode = "rmii";
148 phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */ 147 phy-reset-gpios = <&gpio7 6 0>;
149 status = "okay"; 148 status = "okay";
150 }; 149 };
151 }; 150 };
@@ -156,13 +155,13 @@
156 155
157 volume-up { 156 volume-up {
158 label = "Volume Up"; 157 label = "Volume Up";
159 gpios = <&gpio1 14 0>; /* GPIO2_14 */ 158 gpios = <&gpio2 14 0>;
160 linux,code = <115>; /* KEY_VOLUMEUP */ 159 linux,code = <115>; /* KEY_VOLUMEUP */
161 }; 160 };
162 161
163 volume-down { 162 volume-down {
164 label = "Volume Down"; 163 label = "Volume Down";
165 gpios = <&gpio1 15 0>; /* GPIO2_15 */ 164 gpios = <&gpio2 15 0>;
166 linux,code = <114>; /* KEY_VOLUMEDOWN */ 165 linux,code = <114>; /* KEY_VOLUMEDOWN */
167 }; 166 };
168 }; 167 };
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 099cd84ee37..5dd91b942c9 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -14,11 +14,11 @@
14 14
15/ { 15/ {
16 aliases { 16 aliases {
17 serial0 = &uart0; 17 serial0 = &uart1;
18 serial1 = &uart1; 18 serial1 = &uart2;
19 serial2 = &uart2; 19 serial2 = &uart3;
20 serial3 = &uart3; 20 serial3 = &uart4;
21 serial4 = &uart4; 21 serial4 = &uart5;
22 }; 22 };
23 23
24 tzic: tz-interrupt-controller@0fffc000 { 24 tzic: tz-interrupt-controller@0fffc000 {
@@ -88,7 +88,7 @@
88 status = "disabled"; 88 status = "disabled";
89 }; 89 };
90 90
91 uart2: uart@5000c000 { /* UART3 */ 91 uart3: uart@5000c000 {
92 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 92 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
93 reg = <0x5000c000 0x4000>; 93 reg = <0x5000c000 0x4000>;
94 interrupts = <33>; 94 interrupts = <33>;
@@ -119,7 +119,7 @@
119 }; 119 };
120 }; 120 };
121 121
122 gpio0: gpio@53f84000 { /* GPIO1 */ 122 gpio1: gpio@53f84000 {
123 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 123 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
124 reg = <0x53f84000 0x4000>; 124 reg = <0x53f84000 0x4000>;
125 interrupts = <50 51>; 125 interrupts = <50 51>;
@@ -129,7 +129,7 @@
129 #interrupt-cells = <1>; 129 #interrupt-cells = <1>;
130 }; 130 };
131 131
132 gpio1: gpio@53f88000 { /* GPIO2 */ 132 gpio2: gpio@53f88000 {
133 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 133 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
134 reg = <0x53f88000 0x4000>; 134 reg = <0x53f88000 0x4000>;
135 interrupts = <52 53>; 135 interrupts = <52 53>;
@@ -139,7 +139,7 @@
139 #interrupt-cells = <1>; 139 #interrupt-cells = <1>;
140 }; 140 };
141 141
142 gpio2: gpio@53f8c000 { /* GPIO3 */ 142 gpio3: gpio@53f8c000 {
143 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 143 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
144 reg = <0x53f8c000 0x4000>; 144 reg = <0x53f8c000 0x4000>;
145 interrupts = <54 55>; 145 interrupts = <54 55>;
@@ -149,7 +149,7 @@
149 #interrupt-cells = <1>; 149 #interrupt-cells = <1>;
150 }; 150 };
151 151
152 gpio3: gpio@53f90000 { /* GPIO4 */ 152 gpio4: gpio@53f90000 {
153 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 153 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
154 reg = <0x53f90000 0x4000>; 154 reg = <0x53f90000 0x4000>;
155 interrupts = <56 57>; 155 interrupts = <56 57>;
@@ -173,21 +173,21 @@
173 status = "disabled"; 173 status = "disabled";
174 }; 174 };
175 175
176 uart0: uart@53fbc000 { /* UART1 */ 176 uart1: uart@53fbc000 {
177 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 177 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
178 reg = <0x53fbc000 0x4000>; 178 reg = <0x53fbc000 0x4000>;
179 interrupts = <31>; 179 interrupts = <31>;
180 status = "disabled"; 180 status = "disabled";
181 }; 181 };
182 182
183 uart1: uart@53fc0000 { /* UART2 */ 183 uart2: uart@53fc0000 {
184 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 184 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
185 reg = <0x53fc0000 0x4000>; 185 reg = <0x53fc0000 0x4000>;
186 interrupts = <32>; 186 interrupts = <32>;
187 status = "disabled"; 187 status = "disabled";
188 }; 188 };
189 189
190 gpio4: gpio@53fdc000 { /* GPIO5 */ 190 gpio5: gpio@53fdc000 {
191 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 191 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
192 reg = <0x53fdc000 0x4000>; 192 reg = <0x53fdc000 0x4000>;
193 interrupts = <103 104>; 193 interrupts = <103 104>;
@@ -197,7 +197,7 @@
197 #interrupt-cells = <1>; 197 #interrupt-cells = <1>;
198 }; 198 };
199 199
200 gpio5: gpio@53fe0000 { /* GPIO6 */ 200 gpio6: gpio@53fe0000 {
201 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 201 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
202 reg = <0x53fe0000 0x4000>; 202 reg = <0x53fe0000 0x4000>;
203 interrupts = <105 106>; 203 interrupts = <105 106>;
@@ -207,7 +207,7 @@
207 #interrupt-cells = <1>; 207 #interrupt-cells = <1>;
208 }; 208 };
209 209
210 gpio6: gpio@53fe4000 { /* GPIO7 */ 210 gpio7: gpio@53fe4000 {
211 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio"; 211 compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
212 reg = <0x53fe4000 0x4000>; 212 reg = <0x53fe4000 0x4000>;
213 interrupts = <107 108>; 213 interrupts = <107 108>;
@@ -226,7 +226,7 @@
226 status = "disabled"; 226 status = "disabled";
227 }; 227 };
228 228
229 uart3: uart@53ff0000 { /* UART4 */ 229 uart4: uart@53ff0000 {
230 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 230 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
231 reg = <0x53ff0000 0x4000>; 231 reg = <0x53ff0000 0x4000>;
232 interrupts = <13>; 232 interrupts = <13>;
@@ -241,7 +241,7 @@
241 reg = <0x60000000 0x10000000>; 241 reg = <0x60000000 0x10000000>;
242 ranges; 242 ranges;
243 243
244 uart4: uart@63f90000 { /* UART5 */ 244 uart5: uart@63f90000 {
245 compatible = "fsl,imx53-uart", "fsl,imx21-uart"; 245 compatible = "fsl,imx53-uart", "fsl,imx21-uart";
246 reg = <0x63f90000 0x4000>; 246 reg = <0x63f90000 0x4000>;
247 interrupts = <86>; 247 interrupts = <86>;
diff --git a/arch/arm/boot/dts/imx6q-sabreauto.dts b/arch/arm/boot/dts/imx6q-arm2.dts
index 072974e443f..c3977e0478b 100644
--- a/arch/arm/boot/dts/imx6q-sabreauto.dts
+++ b/arch/arm/boot/dts/imx6q-arm2.dts
@@ -14,8 +14,8 @@
14/include/ "imx6q.dtsi" 14/include/ "imx6q.dtsi"
15 15
16/ { 16/ {
17 model = "Freescale i.MX6 Quad SABRE Automotive Board"; 17 model = "Freescale i.MX6 Quad Armadillo2 Board";
18 compatible = "fsl,imx6q-sabreauto", "fsl,imx6q"; 18 compatible = "fsl,imx6q-arm2", "fsl,imx6q";
19 19
20 chosen { 20 chosen {
21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait"; 21 bootargs = "console=ttymxc0,115200 root=/dev/mmcblk3p3 rootwait";
@@ -34,8 +34,8 @@
34 }; 34 };
35 35
36 usdhc@02198000 { /* uSDHC3 */ 36 usdhc@02198000 { /* uSDHC3 */
37 cd-gpios = <&gpio5 11 0>; /* GPIO6_11 */ 37 cd-gpios = <&gpio6 11 0>;
38 wp-gpios = <&gpio5 14 0>; /* GPIO6_14 */ 38 wp-gpios = <&gpio6 14 0>;
39 status = "okay"; 39 status = "okay";
40 }; 40 };
41 41
@@ -44,7 +44,7 @@
44 status = "okay"; 44 status = "okay";
45 }; 45 };
46 46
47 uart3: uart@021f0000 { /* UART4 */ 47 uart4: uart@021f0000 {
48 status = "okay"; 48 status = "okay";
49 }; 49 };
50 }; 50 };
@@ -55,7 +55,7 @@
55 55
56 debug-led { 56 debug-led {
57 label = "Heartbeat"; 57 label = "Heartbeat";
58 gpios = <&gpio2 25 0>; /* GPIO3_25 */ 58 gpios = <&gpio3 25 0>;
59 linux,default-trigger = "heartbeat"; 59 linux,default-trigger = "heartbeat";
60 }; 60 };
61 }; 61 };
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts
new file mode 100644
index 00000000000..08d920de728
--- /dev/null
+++ b/arch/arm/boot/dts/imx6q-sabrelite.dts
@@ -0,0 +1,49 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13/dts-v1/;
14/include/ "imx6q.dtsi"
15
16/ {
17 model = "Freescale i.MX6 Quad SABRE Lite Board";
18 compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
19
20 memory {
21 reg = <0x10000000 0x40000000>;
22 };
23
24 soc {
25 aips-bus@02100000 { /* AIPS2 */
26 enet@02188000 {
27 phy-mode = "rgmii";
28 phy-reset-gpios = <&gpio3 23 0>;
29 status = "okay";
30 };
31
32 usdhc@02198000 { /* uSDHC3 */
33 cd-gpios = <&gpio7 0 0>;
34 wp-gpios = <&gpio7 1 0>;
35 status = "okay";
36 };
37
38 usdhc@0219c000 { /* uSDHC4 */
39 cd-gpios = <&gpio2 6 0>;
40 wp-gpios = <&gpio2 7 0>;
41 status = "okay";
42 };
43
44 uart2: uart@021e8000 {
45 status = "okay";
46 };
47 };
48 };
49};
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 7dda599558c..263e8f3664b 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -14,11 +14,11 @@
14 14
15/ { 15/ {
16 aliases { 16 aliases {
17 serial0 = &uart0; 17 serial0 = &uart1;
18 serial1 = &uart1; 18 serial1 = &uart2;
19 serial2 = &uart2; 19 serial2 = &uart3;
20 serial3 = &uart3; 20 serial3 = &uart4;
21 serial4 = &uart4; 21 serial4 = &uart5;
22 }; 22 };
23 23
24 cpus { 24 cpus {
@@ -165,7 +165,7 @@
165 status = "disabled"; 165 status = "disabled";
166 }; 166 };
167 167
168 uart0: uart@02020000 { /* UART1 */ 168 uart1: uart@02020000 {
169 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 169 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
170 reg = <0x02020000 0x4000>; 170 reg = <0x02020000 0x4000>;
171 interrupts = <0 26 0x04>; 171 interrupts = <0 26 0x04>;
@@ -247,7 +247,7 @@
247 interrupts = <0 55 0x04>; 247 interrupts = <0 55 0x04>;
248 }; 248 };
249 249
250 gpio0: gpio@0209c000 { /* GPIO1 */ 250 gpio1: gpio@0209c000 {
251 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 251 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
252 reg = <0x0209c000 0x4000>; 252 reg = <0x0209c000 0x4000>;
253 interrupts = <0 66 0x04 0 67 0x04>; 253 interrupts = <0 66 0x04 0 67 0x04>;
@@ -257,7 +257,7 @@
257 #interrupt-cells = <1>; 257 #interrupt-cells = <1>;
258 }; 258 };
259 259
260 gpio1: gpio@020a0000 { /* GPIO2 */ 260 gpio2: gpio@020a0000 {
261 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 261 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
262 reg = <0x020a0000 0x4000>; 262 reg = <0x020a0000 0x4000>;
263 interrupts = <0 68 0x04 0 69 0x04>; 263 interrupts = <0 68 0x04 0 69 0x04>;
@@ -267,7 +267,7 @@
267 #interrupt-cells = <1>; 267 #interrupt-cells = <1>;
268 }; 268 };
269 269
270 gpio2: gpio@020a4000 { /* GPIO3 */ 270 gpio3: gpio@020a4000 {
271 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 271 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
272 reg = <0x020a4000 0x4000>; 272 reg = <0x020a4000 0x4000>;
273 interrupts = <0 70 0x04 0 71 0x04>; 273 interrupts = <0 70 0x04 0 71 0x04>;
@@ -277,7 +277,7 @@
277 #interrupt-cells = <1>; 277 #interrupt-cells = <1>;
278 }; 278 };
279 279
280 gpio3: gpio@020a8000 { /* GPIO4 */ 280 gpio4: gpio@020a8000 {
281 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 281 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
282 reg = <0x020a8000 0x4000>; 282 reg = <0x020a8000 0x4000>;
283 interrupts = <0 72 0x04 0 73 0x04>; 283 interrupts = <0 72 0x04 0 73 0x04>;
@@ -287,7 +287,7 @@
287 #interrupt-cells = <1>; 287 #interrupt-cells = <1>;
288 }; 288 };
289 289
290 gpio4: gpio@020ac000 { /* GPIO5 */ 290 gpio5: gpio@020ac000 {
291 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 291 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
292 reg = <0x020ac000 0x4000>; 292 reg = <0x020ac000 0x4000>;
293 interrupts = <0 74 0x04 0 75 0x04>; 293 interrupts = <0 74 0x04 0 75 0x04>;
@@ -297,7 +297,7 @@
297 #interrupt-cells = <1>; 297 #interrupt-cells = <1>;
298 }; 298 };
299 299
300 gpio5: gpio@020b0000 { /* GPIO6 */ 300 gpio6: gpio@020b0000 {
301 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 301 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
302 reg = <0x020b0000 0x4000>; 302 reg = <0x020b0000 0x4000>;
303 interrupts = <0 76 0x04 0 77 0x04>; 303 interrupts = <0 76 0x04 0 77 0x04>;
@@ -307,7 +307,7 @@
307 #interrupt-cells = <1>; 307 #interrupt-cells = <1>;
308 }; 308 };
309 309
310 gpio6: gpio@020b4000 { /* GPIO7 */ 310 gpio7: gpio@020b4000 {
311 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio"; 311 compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
312 reg = <0x020b4000 0x4000>; 312 reg = <0x020b4000 0x4000>;
313 interrupts = <0 78 0x04 0 79 0x04>; 313 interrupts = <0 78 0x04 0 79 0x04>;
@@ -543,28 +543,28 @@
543 interrupts = <0 18 0x04>; 543 interrupts = <0 18 0x04>;
544 }; 544 };
545 545
546 uart1: uart@021e8000 { /* UART2 */ 546 uart2: uart@021e8000 {
547 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 547 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
548 reg = <0x021e8000 0x4000>; 548 reg = <0x021e8000 0x4000>;
549 interrupts = <0 27 0x04>; 549 interrupts = <0 27 0x04>;
550 status = "disabled"; 550 status = "disabled";
551 }; 551 };
552 552
553 uart2: uart@021ec000 { /* UART3 */ 553 uart3: uart@021ec000 {
554 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 554 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
555 reg = <0x021ec000 0x4000>; 555 reg = <0x021ec000 0x4000>;
556 interrupts = <0 28 0x04>; 556 interrupts = <0 28 0x04>;
557 status = "disabled"; 557 status = "disabled";
558 }; 558 };
559 559
560 uart3: uart@021f0000 { /* UART4 */ 560 uart4: uart@021f0000 {
561 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 561 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
562 reg = <0x021f0000 0x4000>; 562 reg = <0x021f0000 0x4000>;
563 interrupts = <0 29 0x04>; 563 interrupts = <0 29 0x04>;
564 status = "disabled"; 564 status = "disabled";
565 }; 565 };
566 566
567 uart4: uart@021f4000 { /* UART5 */ 567 uart5: uart@021f4000 {
568 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 568 compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
569 reg = <0x021f4000 0x4000>; 569 reg = <0x021f4000 0x4000>;
570 interrupts = <0 30 0x04>; 570 interrupts = <0 30 0x04>;
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
new file mode 100644
index 00000000000..f2ab4ea7cc0
--- /dev/null
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -0,0 +1,67 @@
1/*
2 * Device Tree Source for OMAP2 SoC
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11/include/ "skeleton.dtsi"
12
13/ {
14 compatible = "ti,omap2430", "ti,omap2420", "ti,omap2";
15
16 aliases {
17 serial0 = &uart1;
18 serial1 = &uart2;
19 serial2 = &uart3;
20 };
21
22 cpus {
23 cpu@0 {
24 compatible = "arm,arm1136jf-s";
25 };
26 };
27
28 soc {
29 compatible = "ti,omap-infra";
30 mpu {
31 compatible = "ti,omap2-mpu";
32 ti,hwmods = "mpu";
33 };
34 };
35
36 ocp {
37 compatible = "simple-bus";
38 #address-cells = <1>;
39 #size-cells = <1>;
40 ranges;
41 ti,hwmods = "l3_main";
42
43 intc: interrupt-controller@1 {
44 compatible = "ti,omap2-intc";
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 };
48
49 uart1: serial@4806a000 {
50 compatible = "ti,omap2-uart";
51 ti,hwmods = "uart1";
52 clock-frequency = <48000000>;
53 };
54
55 uart2: serial@4806c000 {
56 compatible = "ti,omap2-uart";
57 ti,hwmods = "uart2";
58 clock-frequency = <48000000>;
59 };
60
61 uart3: serial@4806e000 {
62 compatible = "ti,omap2-uart";
63 ti,hwmods = "uart3";
64 clock-frequency = <48000000>;
65 };
66 };
67};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index d202bb5ec7e..216c3317461 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -13,6 +13,13 @@
13/ { 13/ {
14 compatible = "ti,omap3430", "ti,omap3"; 14 compatible = "ti,omap3430", "ti,omap3";
15 15
16 aliases {
17 serial0 = &uart1;
18 serial1 = &uart2;
19 serial2 = &uart3;
20 serial3 = &uart4;
21 };
22
16 cpus { 23 cpus {
17 cpu@0 { 24 cpu@0 {
18 compatible = "arm,cortex-a8"; 25 compatible = "arm,cortex-a8";
@@ -59,5 +66,29 @@
59 interrupt-controller; 66 interrupt-controller;
60 #interrupt-cells = <1>; 67 #interrupt-cells = <1>;
61 }; 68 };
69
70 uart1: serial@0x4806a000 {
71 compatible = "ti,omap3-uart";
72 ti,hwmods = "uart1";
73 clock-frequency = <48000000>;
74 };
75
76 uart2: serial@0x4806c000 {
77 compatible = "ti,omap3-uart";
78 ti,hwmods = "uart2";
79 clock-frequency = <48000000>;
80 };
81
82 uart3: serial@0x49020000 {
83 compatible = "ti,omap3-uart";
84 ti,hwmods = "uart3";
85 clock-frequency = <48000000>;
86 };
87
88 uart4: serial@0x49042000 {
89 compatible = "ti,omap3-uart";
90 ti,hwmods = "uart4";
91 clock-frequency = <48000000>;
92 };
62 }; 93 };
63}; 94};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 4c61c829043..e8fe75fac7c 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -21,6 +21,10 @@
21 interrupt-parent = <&gic>; 21 interrupt-parent = <&gic>;
22 22
23 aliases { 23 aliases {
24 serial0 = &uart1;
25 serial1 = &uart2;
26 serial2 = &uart3;
27 serial3 = &uart4;
24 }; 28 };
25 29
26 cpus { 30 cpus {
@@ -99,5 +103,29 @@
99 reg = <0x48241000 0x1000>, 103 reg = <0x48241000 0x1000>,
100 <0x48240100 0x0100>; 104 <0x48240100 0x0100>;
101 }; 105 };
106
107 uart1: serial@0x4806a000 {
108 compatible = "ti,omap4-uart";
109 ti,hwmods = "uart1";
110 clock-frequency = <48000000>;
111 };
112
113 uart2: serial@0x4806c000 {
114 compatible = "ti,omap4-uart";
115 ti,hwmods = "uart2";
116 clock-frequency = <48000000>;
117 };
118
119 uart3: serial@0x48020000 {
120 compatible = "ti,omap4-uart";
121 ti,hwmods = "uart3";
122 clock-frequency = <48000000>;
123 };
124
125 uart4: serial@0x4806e000 {
126 compatible = "ti,omap4-uart";
127 ti,hwmods = "uart4";
128 clock-frequency = <48000000>;
129 };
102 }; 130 };
103}; 131};
diff --git a/arch/arm/boot/dts/tegra-cardhu.dts b/arch/arm/boot/dts/tegra-cardhu.dts
new file mode 100644
index 00000000000..70c41fc897d
--- /dev/null
+++ b/arch/arm/boot/dts/tegra-cardhu.dts
@@ -0,0 +1,36 @@
1/dts-v1/;
2
3/include/ "tegra30.dtsi"
4
5/ {
6 model = "NVIDIA Tegra30 Cardhu evaluation board";
7 compatible = "nvidia,cardhu", "nvidia,tegra30";
8
9 memory {
10 reg = < 0x80000000 0x40000000 >;
11 };
12
13 serial@70006000 {
14 clock-frequency = < 408000000 >;
15 };
16
17 i2c@7000c000 {
18 clock-frequency = <100000>;
19 };
20
21 i2c@7000c400 {
22 clock-frequency = <100000>;
23 };
24
25 i2c@7000c500 {
26 clock-frequency = <100000>;
27 };
28
29 i2c@7000c700 {
30 clock-frequency = <100000>;
31 };
32
33 i2c@7000d000 {
34 clock-frequency = <100000>;
35 };
36};
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index 0e225b86b65..80afa1b70b8 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -1,16 +1,11 @@
1/dts-v1/; 1/dts-v1/;
2 2
3/memreserve/ 0x1c000000 0x04000000;
4/include/ "tegra20.dtsi" 3/include/ "tegra20.dtsi"
5 4
6/ { 5/ {
7 model = "NVIDIA Tegra2 Harmony evaluation board"; 6 model = "NVIDIA Tegra2 Harmony evaluation board";
8 compatible = "nvidia,harmony", "nvidia,tegra20"; 7 compatible = "nvidia,harmony", "nvidia,tegra20";
9 8
10 chosen {
11 bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
12 };
13
14 memory@0 { 9 memory@0 {
15 reg = < 0x00000000 0x40000000 >; 10 reg = < 0x00000000 0x40000000 >;
16 }; 11 };
@@ -52,16 +47,40 @@
52 ext-mic-en-gpios = <&gpio 185 0>; 47 ext-mic-en-gpios = <&gpio 185 0>;
53 }; 48 };
54 49
50 serial@70006000 {
51 status = "disable";
52 };
53
54 serial@70006040 {
55 status = "disable";
56 };
57
58 serial@70006200 {
59 status = "disable";
60 };
61
55 serial@70006300 { 62 serial@70006300 {
56 clock-frequency = < 216000000 >; 63 clock-frequency = < 216000000 >;
57 }; 64 };
58 65
66 serial@70006400 {
67 status = "disable";
68 };
69
70 sdhci@c8000000 {
71 status = "disable";
72 };
73
59 sdhci@c8000200 { 74 sdhci@c8000200 {
60 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 75 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
61 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 76 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
62 power-gpios = <&gpio 155 0>; /* gpio PT3 */ 77 power-gpios = <&gpio 155 0>; /* gpio PT3 */
63 }; 78 };
64 79
80 sdhci@c8000400 {
81 status = "disable";
82 };
83
65 sdhci@c8000600 { 84 sdhci@c8000600 {
66 cd-gpios = <&gpio 58 0>; /* gpio PH2 */ 85 cd-gpios = <&gpio 58 0>; /* gpio PH2 */
67 wp-gpios = <&gpio 59 0>; /* gpio PH3 */ 86 wp-gpios = <&gpio 59 0>; /* gpio PH3 */
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
new file mode 100644
index 00000000000..1a1d7023b69
--- /dev/null
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -0,0 +1,77 @@
1/dts-v1/;
2
3/include/ "tegra20.dtsi"
4
5/ {
6 model = "Toshiba AC100 / Dynabook AZ";
7 compatible = "compal,paz00", "nvidia,tegra20";
8
9 memory@0 {
10 reg = <0x00000000 0x20000000>;
11 };
12
13 i2c@7000c000 {
14 clock-frequency = <400000>;
15 };
16
17 i2c@7000c400 {
18 clock-frequency = <400000>;
19 };
20
21 i2c@7000c500 {
22 status = "disable";
23 };
24
25 nvec@7000c500 {
26 #address-cells = <1>;
27 #size-cells = <0>;
28 compatible = "nvidia,nvec";
29 reg = <0x7000C500 0x100>;
30 interrupts = <0 92 0x04>;
31 clock-frequency = <80000>;
32 request-gpios = <&gpio 170 0>;
33 slave-addr = <138>;
34 };
35
36 i2c@7000d000 {
37 clock-frequency = <400000>;
38 };
39
40 serial@70006000 {
41 clock-frequency = <216000000>;
42 };
43
44 serial@70006040 {
45 status = "disable";
46 };
47
48 serial@70006200 {
49 status = "disable";
50 };
51
52 serial@70006300 {
53 clock-frequency = <216000000>;
54 };
55
56 serial@70006400 {
57 status = "disable";
58 };
59
60 sdhci@c8000000 {
61 cd-gpios = <&gpio 173 0>; /* gpio PV5 */
62 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
63 power-gpios = <&gpio 155 0>; /* gpio PT3 */
64 };
65
66 sdhci@c8000200 {
67 status = "disable";
68 };
69
70 sdhci@c8000400 {
71 status = "disable";
72 };
73
74 sdhci@c8000600 {
75 support-8bit;
76 };
77};
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index a72299b8e66..b55a02e34ba 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -1,25 +1,65 @@
1/dts-v1/; 1/dts-v1/;
2 2
3/memreserve/ 0x1c000000 0x04000000;
4/include/ "tegra20.dtsi" 3/include/ "tegra20.dtsi"
5 4
6/ { 5/ {
7 model = "NVIDIA Seaboard"; 6 model = "NVIDIA Seaboard";
8 compatible = "nvidia,seaboard", "nvidia,tegra20"; 7 compatible = "nvidia,seaboard", "nvidia,tegra20";
9 8
10 chosen {
11 bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait";
12 };
13
14 memory { 9 memory {
15 device_type = "memory"; 10 device_type = "memory";
16 reg = < 0x00000000 0x40000000 >; 11 reg = < 0x00000000 0x40000000 >;
17 }; 12 };
18 13
14 i2c@7000c000 {
15 clock-frequency = <400000>;
16 };
17
18 i2c@7000c400 {
19 clock-frequency = <400000>;
20 };
21
22 i2c@7000c500 {
23 clock-frequency = <400000>;
24 };
25
26 i2c@7000d000 {
27 clock-frequency = <400000>;
28
29 adt7461@4c {
30 compatible = "adt7461";
31 reg = <0x4c>;
32 };
33 };
34
35 serial@70006000 {
36 status = "disable";
37 };
38
39 serial@70006040 {
40 status = "disable";
41 };
42
43 serial@70006200 {
44 status = "disable";
45 };
46
19 serial@70006300 { 47 serial@70006300 {
20 clock-frequency = < 216000000 >; 48 clock-frequency = < 216000000 >;
21 }; 49 };
22 50
51 serial@70006400 {
52 status = "disable";
53 };
54
55 sdhci@c8000000 {
56 status = "disable";
57 };
58
59 sdhci@c8000200 {
60 status = "disable";
61 };
62
23 sdhci@c8000400 { 63 sdhci@c8000400 {
24 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 64 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
25 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 65 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
@@ -29,4 +69,28 @@
29 sdhci@c8000600 { 69 sdhci@c8000600 {
30 support-8bit; 70 support-8bit;
31 }; 71 };
72
73 usb@c5000000 {
74 nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
75 };
76
77 gpio-keys {
78 compatible = "gpio-keys";
79
80 power {
81 label = "Power";
82 gpios = <&gpio 170 1>; /* gpio PV2, active low */
83 linux,code = <116>; /* KEY_POWER */
84 gpio-key,wakeup;
85 };
86
87 lid {
88 label = "Lid";
89 gpios = <&gpio 23 0>; /* gpio PC7 */
90 linux,input-type = <5>; /* EV_SW */
91 linux,code = <0>; /* SW_LID */
92 debounce-interval = <1>;
93 gpio-key,wakeup;
94 };
95 };
32}; 96};
diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
new file mode 100644
index 00000000000..3b3ee7db99f
--- /dev/null
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -0,0 +1,65 @@
1/dts-v1/;
2
3/include/ "tegra20.dtsi"
4
5/ {
6 model = "Compulab TrimSlice board";
7 compatible = "compulab,trimslice", "nvidia,tegra20";
8
9 memory@0 {
10 reg = < 0x00000000 0x40000000 >;
11 };
12
13 i2c@7000c000 {
14 clock-frequency = <400000>;
15 };
16
17 i2c@7000c400 {
18 clock-frequency = <400000>;
19 };
20
21 i2c@7000c500 {
22 clock-frequency = <400000>;
23 };
24
25 i2c@7000d000 {
26 status = "disable";
27 };
28
29 serial@70006000 {
30 clock-frequency = < 216000000 >;
31 };
32
33 serial@70006040 {
34 status = "disable";
35 };
36
37 serial@70006200 {
38 status = "disable";
39 };
40
41 serial@70006300 {
42 status = "disable";
43 };
44
45 serial@70006400 {
46 status = "disable";
47 };
48
49 sdhci@c8000000 {
50 status = "disable";
51 };
52
53 sdhci@c8000200 {
54 status = "disable";
55 };
56
57 sdhci@c8000400 {
58 status = "disable";
59 };
60
61 sdhci@c8000600 {
62 cd-gpios = <&gpio 121 0>;
63 wp-gpios = <&gpio 122 0>;
64 };
65};
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
index 3f9abd6b696..c7d3b87f29d 100644
--- a/arch/arm/boot/dts/tegra-ventana.dts
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -1,24 +1,59 @@
1/dts-v1/; 1/dts-v1/;
2 2
3/memreserve/ 0x1c000000 0x04000000;
4/include/ "tegra20.dtsi" 3/include/ "tegra20.dtsi"
5 4
6/ { 5/ {
7 model = "NVIDIA Tegra2 Ventana evaluation board"; 6 model = "NVIDIA Tegra2 Ventana evaluation board";
8 compatible = "nvidia,ventana", "nvidia,tegra20"; 7 compatible = "nvidia,ventana", "nvidia,tegra20";
9 8
10 chosen {
11 bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init";
12 };
13
14 memory { 9 memory {
15 reg = < 0x00000000 0x40000000 >; 10 reg = < 0x00000000 0x40000000 >;
16 }; 11 };
17 12
13 i2c@7000c000 {
14 clock-frequency = <400000>;
15 };
16
17 i2c@7000c400 {
18 clock-frequency = <400000>;
19 };
20
21 i2c@7000c500 {
22 clock-frequency = <400000>;
23 };
24
25 i2c@7000d000 {
26 clock-frequency = <400000>;
27 };
28
29 serial@70006000 {
30 status = "disable";
31 };
32
33 serial@70006040 {
34 status = "disable";
35 };
36
37 serial@70006200 {
38 status = "disable";
39 };
40
18 serial@70006300 { 41 serial@70006300 {
19 clock-frequency = < 216000000 >; 42 clock-frequency = < 216000000 >;
20 }; 43 };
21 44
45 serial@70006400 {
46 status = "disable";
47 };
48
49 sdhci@c8000000 {
50 status = "disable";
51 };
52
53 sdhci@c8000200 {
54 status = "disable";
55 };
56
22 sdhci@c8000400 { 57 sdhci@c8000400 {
23 cd-gpios = <&gpio 69 0>; /* gpio PI5 */ 58 cd-gpios = <&gpio 69 0>; /* gpio PI5 */
24 wp-gpios = <&gpio 57 0>; /* gpio PH1 */ 59 wp-gpios = <&gpio 57 0>; /* gpio PH1 */
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 65d7e6a333e..3da7afd4532 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -5,9 +5,9 @@
5 interrupt-parent = <&intc>; 5 interrupt-parent = <&intc>;
6 6
7 intc: interrupt-controller@50041000 { 7 intc: interrupt-controller@50041000 {
8 compatible = "nvidia,tegra20-gic"; 8 compatible = "arm,cortex-a9-gic";
9 interrupt-controller; 9 interrupt-controller;
10 #interrupt-cells = <1>; 10 #interrupt-cells = <3>;
11 reg = < 0x50041000 0x1000 >, 11 reg = < 0x50041000 0x1000 >,
12 < 0x50040100 0x0100 >; 12 < 0x50040100 0x0100 >;
13 }; 13 };
@@ -17,7 +17,7 @@
17 #size-cells = <0>; 17 #size-cells = <0>;
18 compatible = "nvidia,tegra20-i2c"; 18 compatible = "nvidia,tegra20-i2c";
19 reg = <0x7000C000 0x100>; 19 reg = <0x7000C000 0x100>;
20 interrupts = < 70 >; 20 interrupts = < 0 38 0x04 >;
21 }; 21 };
22 22
23 i2c@7000c400 { 23 i2c@7000c400 {
@@ -25,7 +25,7 @@
25 #size-cells = <0>; 25 #size-cells = <0>;
26 compatible = "nvidia,tegra20-i2c"; 26 compatible = "nvidia,tegra20-i2c";
27 reg = <0x7000C400 0x100>; 27 reg = <0x7000C400 0x100>;
28 interrupts = < 116 >; 28 interrupts = < 0 84 0x04 >;
29 }; 29 };
30 30
31 i2c@7000c500 { 31 i2c@7000c500 {
@@ -33,38 +33,32 @@
33 #size-cells = <0>; 33 #size-cells = <0>;
34 compatible = "nvidia,tegra20-i2c"; 34 compatible = "nvidia,tegra20-i2c";
35 reg = <0x7000C500 0x100>; 35 reg = <0x7000C500 0x100>;
36 interrupts = < 124 >; 36 interrupts = < 0 92 0x04 >;
37 }; 37 };
38 38
39 i2c@7000d000 { 39 i2c@7000d000 {
40 #address-cells = <1>; 40 #address-cells = <1>;
41 #size-cells = <0>; 41 #size-cells = <0>;
42 compatible = "nvidia,tegra20-i2c"; 42 compatible = "nvidia,tegra20-i2c-dvc";
43 reg = <0x7000D000 0x200>; 43 reg = <0x7000D000 0x200>;
44 interrupts = < 85 >; 44 interrupts = < 0 53 0x04 >;
45 }; 45 };
46 46
47 i2s@70002800 { 47 i2s@70002800 {
48 #address-cells = <1>;
49 #size-cells = <0>;
50 compatible = "nvidia,tegra20-i2s"; 48 compatible = "nvidia,tegra20-i2s";
51 reg = <0x70002800 0x200>; 49 reg = <0x70002800 0x200>;
52 interrupts = < 45 >; 50 interrupts = < 0 13 0x04 >;
53 dma-channel = < 2 >; 51 dma-channel = < 2 >;
54 }; 52 };
55 53
56 i2s@70002a00 { 54 i2s@70002a00 {
57 #address-cells = <1>;
58 #size-cells = <0>;
59 compatible = "nvidia,tegra20-i2s"; 55 compatible = "nvidia,tegra20-i2s";
60 reg = <0x70002a00 0x200>; 56 reg = <0x70002a00 0x200>;
61 interrupts = < 35 >; 57 interrupts = < 0 3 0x04 >;
62 dma-channel = < 1 >; 58 dma-channel = < 1 >;
63 }; 59 };
64 60
65 das@70000c00 { 61 das@70000c00 {
66 #address-cells = <1>;
67 #size-cells = <0>;
68 compatible = "nvidia,tegra20-das"; 62 compatible = "nvidia,tegra20-das";
69 reg = <0x70000c00 0x80>; 63 reg = <0x70000c00 0x80>;
70 }; 64 };
@@ -72,7 +66,13 @@
72 gpio: gpio@6000d000 { 66 gpio: gpio@6000d000 {
73 compatible = "nvidia,tegra20-gpio"; 67 compatible = "nvidia,tegra20-gpio";
74 reg = < 0x6000d000 0x1000 >; 68 reg = < 0x6000d000 0x1000 >;
75 interrupts = < 64 65 66 67 87 119 121 >; 69 interrupts = < 0 32 0x04
70 0 33 0x04
71 0 34 0x04
72 0 35 0x04
73 0 55 0x04
74 0 87 0x04
75 0 89 0x04 >;
76 #gpio-cells = <2>; 76 #gpio-cells = <2>;
77 gpio-controller; 77 gpio-controller;
78 }; 78 };
@@ -89,59 +89,80 @@
89 compatible = "nvidia,tegra20-uart"; 89 compatible = "nvidia,tegra20-uart";
90 reg = <0x70006000 0x40>; 90 reg = <0x70006000 0x40>;
91 reg-shift = <2>; 91 reg-shift = <2>;
92 interrupts = < 68 >; 92 interrupts = < 0 36 0x04 >;
93 }; 93 };
94 94
95 serial@70006040 { 95 serial@70006040 {
96 compatible = "nvidia,tegra20-uart"; 96 compatible = "nvidia,tegra20-uart";
97 reg = <0x70006040 0x40>; 97 reg = <0x70006040 0x40>;
98 reg-shift = <2>; 98 reg-shift = <2>;
99 interrupts = < 69 >; 99 interrupts = < 0 37 0x04 >;
100 }; 100 };
101 101
102 serial@70006200 { 102 serial@70006200 {
103 compatible = "nvidia,tegra20-uart"; 103 compatible = "nvidia,tegra20-uart";
104 reg = <0x70006200 0x100>; 104 reg = <0x70006200 0x100>;
105 reg-shift = <2>; 105 reg-shift = <2>;
106 interrupts = < 78 >; 106 interrupts = < 0 46 0x04 >;
107 }; 107 };
108 108
109 serial@70006300 { 109 serial@70006300 {
110 compatible = "nvidia,tegra20-uart"; 110 compatible = "nvidia,tegra20-uart";
111 reg = <0x70006300 0x100>; 111 reg = <0x70006300 0x100>;
112 reg-shift = <2>; 112 reg-shift = <2>;
113 interrupts = < 122 >; 113 interrupts = < 0 90 0x04 >;
114 }; 114 };
115 115
116 serial@70006400 { 116 serial@70006400 {
117 compatible = "nvidia,tegra20-uart"; 117 compatible = "nvidia,tegra20-uart";
118 reg = <0x70006400 0x100>; 118 reg = <0x70006400 0x100>;
119 reg-shift = <2>; 119 reg-shift = <2>;
120 interrupts = < 123 >; 120 interrupts = < 0 91 0x04 >;
121 }; 121 };
122 122
123 sdhci@c8000000 { 123 sdhci@c8000000 {
124 compatible = "nvidia,tegra20-sdhci"; 124 compatible = "nvidia,tegra20-sdhci";
125 reg = <0xc8000000 0x200>; 125 reg = <0xc8000000 0x200>;
126 interrupts = < 46 >; 126 interrupts = < 0 14 0x04 >;
127 }; 127 };
128 128
129 sdhci@c8000200 { 129 sdhci@c8000200 {
130 compatible = "nvidia,tegra20-sdhci"; 130 compatible = "nvidia,tegra20-sdhci";
131 reg = <0xc8000200 0x200>; 131 reg = <0xc8000200 0x200>;
132 interrupts = < 47 >; 132 interrupts = < 0 15 0x04 >;
133 }; 133 };
134 134
135 sdhci@c8000400 { 135 sdhci@c8000400 {
136 compatible = "nvidia,tegra20-sdhci"; 136 compatible = "nvidia,tegra20-sdhci";
137 reg = <0xc8000400 0x200>; 137 reg = <0xc8000400 0x200>;
138 interrupts = < 51 >; 138 interrupts = < 0 19 0x04 >;
139 }; 139 };
140 140
141 sdhci@c8000600 { 141 sdhci@c8000600 {
142 compatible = "nvidia,tegra20-sdhci"; 142 compatible = "nvidia,tegra20-sdhci";
143 reg = <0xc8000600 0x200>; 143 reg = <0xc8000600 0x200>;
144 interrupts = < 63 >; 144 interrupts = < 0 31 0x04 >;
145 };
146
147 usb@c5000000 {
148 compatible = "nvidia,tegra20-ehci", "usb-ehci";
149 reg = <0xc5000000 0x4000>;
150 interrupts = < 0 20 0x04 >;
151 phy_type = "utmi";
152 };
153
154 usb@c5004000 {
155 compatible = "nvidia,tegra20-ehci", "usb-ehci";
156 reg = <0xc5004000 0x4000>;
157 interrupts = < 0 21 0x04 >;
158 phy_type = "ulpi";
159 };
160
161 usb@c5008000 {
162 compatible = "nvidia,tegra20-ehci", "usb-ehci";
163 reg = <0xc5008000 0x4000>;
164 interrupts = < 0 97 0x04 >;
165 phy_type = "utmi";
145 }; 166 };
146}; 167};
147 168
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
new file mode 100644
index 00000000000..ee7db9892e0
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -0,0 +1,127 @@
1/include/ "skeleton.dtsi"
2
3/ {
4 compatible = "nvidia,tegra30";
5 interrupt-parent = <&intc>;
6
7 intc: interrupt-controller@50041000 {
8 compatible = "arm,cortex-a9-gic";
9 interrupt-controller;
10 #interrupt-cells = <3>;
11 reg = < 0x50041000 0x1000 >,
12 < 0x50040100 0x0100 >;
13 };
14
15 i2c@7000c000 {
16 #address-cells = <1>;
17 #size-cells = <0>;
18 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
19 reg = <0x7000C000 0x100>;
20 interrupts = < 0 38 0x04 >;
21 };
22
23 i2c@7000c400 {
24 #address-cells = <1>;
25 #size-cells = <0>;
26 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
27 reg = <0x7000C400 0x100>;
28 interrupts = < 0 84 0x04 >;
29 };
30
31 i2c@7000c500 {
32 #address-cells = <1>;
33 #size-cells = <0>;
34 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
35 reg = <0x7000C500 0x100>;
36 interrupts = < 0 92 0x04 >;
37 };
38
39 i2c@7000c700 {
40 #address-cells = <1>;
41 #size-cells = <0>;
42 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
43 reg = <0x7000c700 0x100>;
44 interrupts = < 0 120 0x04 >;
45 };
46
47 i2c@7000d000 {
48 #address-cells = <1>;
49 #size-cells = <0>;
50 compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
51 reg = <0x7000D000 0x100>;
52 interrupts = < 0 53 0x04 >;
53 };
54
55 gpio: gpio@6000d000 {
56 compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
57 reg = < 0x6000d000 0x1000 >;
58 interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >;
59 #gpio-cells = <2>;
60 gpio-controller;
61 };
62
63 serial@70006000 {
64 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
65 reg = <0x70006000 0x40>;
66 reg-shift = <2>;
67 interrupts = < 0 36 0x04 >;
68 };
69
70 serial@70006040 {
71 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
72 reg = <0x70006040 0x40>;
73 reg-shift = <2>;
74 interrupts = < 0 37 0x04 >;
75 };
76
77 serial@70006200 {
78 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
79 reg = <0x70006200 0x100>;
80 reg-shift = <2>;
81 interrupts = < 0 46 0x04 >;
82 };
83
84 serial@70006300 {
85 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
86 reg = <0x70006300 0x100>;
87 reg-shift = <2>;
88 interrupts = < 0 90 0x04 >;
89 };
90
91 serial@70006400 {
92 compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
93 reg = <0x70006400 0x100>;
94 reg-shift = <2>;
95 interrupts = < 0 91 0x04 >;
96 };
97
98 sdhci@78000000 {
99 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
100 reg = <0x78000000 0x200>;
101 interrupts = < 0 14 0x04 >;
102 };
103
104 sdhci@78000200 {
105 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
106 reg = <0x78000200 0x200>;
107 interrupts = < 0 15 0x04 >;
108 };
109
110 sdhci@78000400 {
111 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
112 reg = <0x78000400 0x200>;
113 interrupts = < 0 19 0x04 >;
114 };
115
116 sdhci@78000600 {
117 compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
118 reg = <0x78000600 0x200>;
119 interrupts = < 0 31 0x04 >;
120 };
121
122 pinmux: pinmux@70000000 {
123 compatible = "nvidia,tegra30-pinmux";
124 reg = < 0x70000868 0xd0 /* Pad control registers */
125 0x70003000 0x3e0 >; /* Mux registers */
126 };
127};
diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts
index d66e2c00ac3..f04b535477f 100644
--- a/arch/arm/boot/dts/usb_a9g20.dts
+++ b/arch/arm/boot/dts/usb_a9g20.dts
@@ -25,6 +25,11 @@
25 dbgu: serial@fffff200 { 25 dbgu: serial@fffff200 {
26 status = "okay"; 26 status = "okay";
27 }; 27 };
28
29 macb0: ethernet@fffc4000 {
30 phy-mode = "rmii";
31 status = "okay";
32 };
28 }; 33 };
29 }; 34 };
30}; 35};
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index cf497ce41df..a22e9307906 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -68,7 +68,6 @@ CONFIG_MTD_CFI=y
68CONFIG_MTD_CFI_ADV_OPTIONS=y 68CONFIG_MTD_CFI_ADV_OPTIONS=y
69CONFIG_MTD_CFI_GEOMETRY=y 69CONFIG_MTD_CFI_GEOMETRY=y
70# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set 70# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
71# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
72# CONFIG_MTD_CFI_I2 is not set 71# CONFIG_MTD_CFI_I2 is not set
73CONFIG_MTD_CFI_INTELEXT=y 72CONFIG_MTD_CFI_INTELEXT=y
74CONFIG_MTD_PHYSMAP=y 73CONFIG_MTD_PHYSMAP=y
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 945a34f2a34..dde2a1af7b3 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -48,7 +48,6 @@ CONFIG_MACH_SX1=y
48CONFIG_MACH_NOKIA770=y 48CONFIG_MACH_NOKIA770=y
49CONFIG_MACH_AMS_DELTA=y 49CONFIG_MACH_AMS_DELTA=y
50CONFIG_MACH_OMAP_GENERIC=y 50CONFIG_MACH_OMAP_GENERIC=y
51CONFIG_OMAP_ARM_182MHZ=y
52# CONFIG_ARM_THUMB is not set 51# CONFIG_ARM_THUMB is not set
53CONFIG_PCCARD=y 52CONFIG_PCCARD=y
54CONFIG_OMAP_CF=y 53CONFIG_OMAP_CF=y
diff --git a/arch/arm/configs/pcontrol_g20_defconfig b/arch/arm/configs/pcontrol_g20_defconfig
deleted file mode 100644
index c75c9fcede5..00000000000
--- a/arch/arm/configs/pcontrol_g20_defconfig
+++ /dev/null
@@ -1,175 +0,0 @@
1CONFIG_EXPERIMENTAL=y
2CONFIG_CROSS_COMPILE="/opt/arm-2010q1/bin/arm-none-linux-gnueabi-"
3# CONFIG_LOCALVERSION_AUTO is not set
4# CONFIG_SWAP is not set
5CONFIG_SYSVIPC=y
6CONFIG_POSIX_MQUEUE=y
7CONFIG_TREE_PREEMPT_RCU=y
8CONFIG_IKCONFIG=y
9CONFIG_IKCONFIG_PROC=y
10CONFIG_LOG_BUF_SHIFT=14
11CONFIG_NAMESPACES=y
12CONFIG_BLK_DEV_INITRD=y
13CONFIG_EXPERT=y
14# CONFIG_SYSCTL_SYSCALL is not set
15# CONFIG_KALLSYMS is not set
16# CONFIG_VM_EVENT_COUNTERS is not set
17# CONFIG_COMPAT_BRK is not set
18CONFIG_SLAB=y
19CONFIG_MODULES=y
20CONFIG_MODULE_UNLOAD=y
21# CONFIG_LBDAF is not set
22# CONFIG_BLK_DEV_BSG is not set
23CONFIG_DEFAULT_DEADLINE=y
24CONFIG_ARCH_AT91=y
25CONFIG_ARCH_AT91SAM9G20=y
26CONFIG_MACH_PCONTROL_G20=y
27CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
28CONFIG_NO_HZ=y
29CONFIG_HIGH_RES_TIMERS=y
30CONFIG_PREEMPT=y
31CONFIG_AEABI=y
32# CONFIG_OABI_COMPAT is not set
33CONFIG_ZBOOT_ROM_TEXT=0x0
34CONFIG_ZBOOT_ROM_BSS=0x0
35CONFIG_CMDLINE="console=ttyS0,115200 mem=128M mtdparts=atmel_nand:128k(bootstrap)ro,256k(uboot)ro,128k(env1)ro,128k(env2)ro,2M(linux),-(root) root=/dev/mmcblk0p1 rootwait rw"
36CONFIG_VFP=y
37CONFIG_BINFMT_MISC=y
38CONFIG_NET=y
39CONFIG_PACKET=y
40CONFIG_UNIX=y
41CONFIG_INET=y
42# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
43# CONFIG_INET_XFRM_MODE_TUNNEL is not set
44# CONFIG_INET_XFRM_MODE_BEET is not set
45# CONFIG_INET_LRO is not set
46# CONFIG_IPV6 is not set
47CONFIG_VLAN_8021Q=y
48# CONFIG_WIRELESS is not set
49CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
50# CONFIG_FW_LOADER is not set
51CONFIG_MTD=y
52CONFIG_MTD_PARTITIONS=y
53CONFIG_MTD_CMDLINE_PARTS=y
54CONFIG_MTD_CHAR=y
55CONFIG_MTD_BLOCK=y
56CONFIG_MTD_COMPLEX_MAPPINGS=y
57CONFIG_MTD_PHRAM=m
58CONFIG_MTD_NAND=y
59CONFIG_MTD_NAND_ATMEL=y
60CONFIG_BLK_DEV_LOOP=y
61CONFIG_BLK_DEV_RAM=y
62CONFIG_BLK_DEV_RAM_SIZE=8192
63CONFIG_ATMEL_TCLIB=y
64CONFIG_EEPROM_AT24=m
65CONFIG_SCSI=m
66# CONFIG_SCSI_PROC_FS is not set
67CONFIG_BLK_DEV_SD=m
68CONFIG_SCSI_MULTI_LUN=y
69# CONFIG_SCSI_LOWLEVEL is not set
70CONFIG_NETDEVICES=y
71CONFIG_MACVLAN=m
72CONFIG_TUN=m
73CONFIG_SMSC_PHY=m
74CONFIG_BROADCOM_PHY=m
75CONFIG_NET_ETHERNET=y
76CONFIG_MII=y
77CONFIG_MACB=y
78CONFIG_SMSC911X=m
79# CONFIG_NETDEV_1000 is not set
80# CONFIG_NETDEV_10000 is not set
81# CONFIG_WLAN is not set
82CONFIG_PPP=m
83CONFIG_PPP_ASYNC=m
84CONFIG_PPP_DEFLATE=m
85CONFIG_PPP_MPPE=m
86CONFIG_INPUT_POLLDEV=y
87CONFIG_INPUT_SPARSEKMAP=y
88# CONFIG_INPUT_MOUSEDEV is not set
89CONFIG_INPUT_EVDEV=m
90CONFIG_INPUT_EVBUG=m
91# CONFIG_KEYBOARD_ATKBD is not set
92CONFIG_KEYBOARD_GPIO=m
93CONFIG_KEYBOARD_MATRIX=m
94# CONFIG_INPUT_MOUSE is not set
95CONFIG_INPUT_TOUCHSCREEN=y
96CONFIG_INPUT_MISC=y
97CONFIG_INPUT_UINPUT=m
98CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
99# CONFIG_SERIO is not set
100# CONFIG_DEVKMEM is not set
101CONFIG_SERIAL_ATMEL=y
102CONFIG_SERIAL_ATMEL_CONSOLE=y
103CONFIG_SERIAL_MAX3100=m
104# CONFIG_LEGACY_PTYS is not set
105# CONFIG_HW_RANDOM is not set
106CONFIG_R3964=m
107CONFIG_I2C=m
108CONFIG_I2C_CHARDEV=m
109# CONFIG_I2C_HELPER_AUTO is not set
110CONFIG_I2C_GPIO=m
111CONFIG_SPI=y
112CONFIG_SPI_ATMEL=m
113CONFIG_SPI_SPIDEV=m
114CONFIG_GPIO_SYSFS=y
115CONFIG_W1=m
116CONFIG_W1_MASTER_GPIO=m
117CONFIG_W1_SLAVE_DS2431=m
118# CONFIG_HWMON is not set
119CONFIG_WATCHDOG=y
120CONFIG_AT91SAM9X_WATCHDOG=y
121# CONFIG_MFD_SUPPORT is not set
122# CONFIG_HID_SUPPORT is not set
123CONFIG_USB=y
124# CONFIG_USB_DEVICE_CLASS is not set
125CONFIG_USB_OHCI_HCD=y
126CONFIG_USB_STORAGE=m
127CONFIG_USB_LIBUSUAL=y
128CONFIG_USB_SERIAL=m
129CONFIG_USB_SERIAL_GENERIC=y
130CONFIG_USB_SERIAL_FTDI_SIO=m
131CONFIG_USB_SERIAL_PL2303=m
132CONFIG_USB_GADGET=y
133CONFIG_USB_ZERO=m
134CONFIG_USB_ETH=m
135CONFIG_USB_FILE_STORAGE=m
136CONFIG_USB_G_SERIAL=m
137CONFIG_USB_G_HID=m
138CONFIG_MMC=y
139CONFIG_MMC_UNSAFE_RESUME=y
140CONFIG_MMC_ATMELMCI=y
141CONFIG_NEW_LEDS=y
142CONFIG_LEDS_CLASS=y
143CONFIG_LEDS_GPIO=y
144CONFIG_LEDS_TRIGGERS=y
145CONFIG_LEDS_TRIGGER_TIMER=y
146CONFIG_LEDS_TRIGGER_HEARTBEAT=y
147CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
148CONFIG_RTC_CLASS=y
149CONFIG_RTC_DRV_AT91SAM9=y
150CONFIG_AUXDISPLAY=y
151CONFIG_UIO=y
152CONFIG_UIO_PDRV=y
153CONFIG_STAGING=y
154# CONFIG_STAGING_EXCLUDE_BUILD is not set
155CONFIG_IIO=y
156CONFIG_EXT2_FS=y
157CONFIG_EXT3_FS=y
158# CONFIG_EXT3_FS_XATTR is not set
159CONFIG_VFAT_FS=y
160CONFIG_TMPFS=y
161CONFIG_JFFS2_FS=y
162CONFIG_NFS_FS=y
163CONFIG_NFS_V3=y
164CONFIG_NFS_V4=y
165CONFIG_PARTITION_ADVANCED=y
166CONFIG_NLS_CODEPAGE_437=y
167CONFIG_NLS_CODEPAGE_850=y
168CONFIG_NLS_ISO8859_1=y
169CONFIG_NLS_ISO8859_15=y
170CONFIG_NLS_UTF8=y
171# CONFIG_RCU_CPU_STALL_DETECTOR is not set
172CONFIG_CRYPTO=y
173CONFIG_CRYPTO_ANSI_CPRNG=y
174# CONFIG_CRYPTO_HW is not set
175CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 195729760ae..fd5d3041d71 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -9,9 +9,8 @@ CONFIG_RESOURCE_COUNTERS=y
9CONFIG_CGROUP_SCHED=y 9CONFIG_CGROUP_SCHED=y
10CONFIG_RT_GROUP_SCHED=y 10CONFIG_RT_GROUP_SCHED=y
11CONFIG_BLK_DEV_INITRD=y 11CONFIG_BLK_DEV_INITRD=y
12CONFIG_EMBEDDED=y
13# CONFIG_SYSCTL_SYSCALL is not set
14# CONFIG_ELF_CORE is not set 12# CONFIG_ELF_CORE is not set
13CONFIG_EMBEDDED=y
15CONFIG_SLAB=y 14CONFIG_SLAB=y
16CONFIG_MODULES=y 15CONFIG_MODULES=y
17CONFIG_MODULE_UNLOAD=y 16CONFIG_MODULE_UNLOAD=y
@@ -20,6 +19,8 @@ CONFIG_MODULE_FORCE_UNLOAD=y
20# CONFIG_IOSCHED_DEADLINE is not set 19# CONFIG_IOSCHED_DEADLINE is not set
21# CONFIG_IOSCHED_CFQ is not set 20# CONFIG_IOSCHED_CFQ is not set
22CONFIG_ARCH_TEGRA=y 21CONFIG_ARCH_TEGRA=y
22CONFIG_ARCH_TEGRA_2x_SOC=y
23CONFIG_ARCH_TEGRA_3x_SOC=y
23CONFIG_MACH_HARMONY=y 24CONFIG_MACH_HARMONY=y
24CONFIG_MACH_KAEN=y 25CONFIG_MACH_KAEN=y
25CONFIG_MACH_PAZ00=y 26CONFIG_MACH_PAZ00=y
@@ -78,14 +79,12 @@ CONFIG_BLK_DEV_SD=y
78# CONFIG_SCSI_LOWLEVEL is not set 79# CONFIG_SCSI_LOWLEVEL is not set
79CONFIG_NETDEVICES=y 80CONFIG_NETDEVICES=y
80CONFIG_DUMMY=y 81CONFIG_DUMMY=y
81CONFIG_NET_ETHERNET=y
82CONFIG_R8169=y 82CONFIG_R8169=y
83# CONFIG_NETDEV_10000 is not set
84# CONFIG_WLAN is not set
85CONFIG_USB_PEGASUS=y 83CONFIG_USB_PEGASUS=y
86CONFIG_USB_USBNET=y 84CONFIG_USB_USBNET=y
87CONFIG_USB_NET_SMSC75XX=y 85CONFIG_USB_NET_SMSC75XX=y
88CONFIG_USB_NET_SMSC95XX=y 86CONFIG_USB_NET_SMSC95XX=y
87# CONFIG_WLAN is not set
89# CONFIG_INPUT is not set 88# CONFIG_INPUT is not set
90# CONFIG_SERIO is not set 89# CONFIG_SERIO is not set
91# CONFIG_VT is not set 90# CONFIG_VT is not set
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 065d100fa63..9275828feb3 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -27,6 +27,7 @@
27#include <asm/byteorder.h> 27#include <asm/byteorder.h>
28#include <asm/memory.h> 28#include <asm/memory.h>
29#include <asm/system.h> 29#include <asm/system.h>
30#include <asm-generic/pci_iomap.h>
30 31
31/* 32/*
32 * ISA I/O bus memory addresses are 1:1 with the physical address. 33 * ISA I/O bus memory addresses are 1:1 with the physical address.
@@ -306,7 +307,6 @@ extern void ioport_unmap(void __iomem *addr);
306 307
307struct pci_dev; 308struct pci_dev;
308 309
309extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
310extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); 310extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
311 311
312/* 312/*
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index d111c3e9924..4f991f29528 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -3,6 +3,12 @@ if ARCH_AT91
3config HAVE_AT91_DATAFLASH_CARD 3config HAVE_AT91_DATAFLASH_CARD
4 bool 4 bool
5 5
6config HAVE_AT91_DBGU0
7 bool
8
9config HAVE_AT91_DBGU1
10 bool
11
6config HAVE_AT91_USART3 12config HAVE_AT91_USART3
7 bool 13 bool
8 14
@@ -21,12 +27,14 @@ config ARCH_AT91RM9200
21 bool "AT91RM9200" 27 bool "AT91RM9200"
22 select CPU_ARM920T 28 select CPU_ARM920T
23 select GENERIC_CLOCKEVENTS 29 select GENERIC_CLOCKEVENTS
30 select HAVE_AT91_DBGU0
24 select HAVE_AT91_USART3 31 select HAVE_AT91_USART3
25 32
26config ARCH_AT91SAM9260 33config ARCH_AT91SAM9260
27 bool "AT91SAM9260 or AT91SAM9XE" 34 bool "AT91SAM9260 or AT91SAM9XE"
28 select CPU_ARM926T 35 select CPU_ARM926T
29 select GENERIC_CLOCKEVENTS 36 select GENERIC_CLOCKEVENTS
37 select HAVE_AT91_DBGU0
30 select HAVE_AT91_USART3 38 select HAVE_AT91_USART3
31 select HAVE_AT91_USART4 39 select HAVE_AT91_USART4
32 select HAVE_AT91_USART5 40 select HAVE_AT91_USART5
@@ -37,11 +45,13 @@ config ARCH_AT91SAM9261
37 select CPU_ARM926T 45 select CPU_ARM926T
38 select GENERIC_CLOCKEVENTS 46 select GENERIC_CLOCKEVENTS
39 select HAVE_FB_ATMEL 47 select HAVE_FB_ATMEL
48 select HAVE_AT91_DBGU0
40 49
41config ARCH_AT91SAM9G10 50config ARCH_AT91SAM9G10
42 bool "AT91SAM9G10" 51 bool "AT91SAM9G10"
43 select CPU_ARM926T 52 select CPU_ARM926T
44 select GENERIC_CLOCKEVENTS 53 select GENERIC_CLOCKEVENTS
54 select HAVE_AT91_DBGU0
45 select HAVE_FB_ATMEL 55 select HAVE_FB_ATMEL
46 56
47config ARCH_AT91SAM9263 57config ARCH_AT91SAM9263
@@ -50,6 +60,7 @@ config ARCH_AT91SAM9263
50 select GENERIC_CLOCKEVENTS 60 select GENERIC_CLOCKEVENTS
51 select HAVE_FB_ATMEL 61 select HAVE_FB_ATMEL
52 select HAVE_NET_MACB 62 select HAVE_NET_MACB
63 select HAVE_AT91_DBGU1
53 64
54config ARCH_AT91SAM9RL 65config ARCH_AT91SAM9RL
55 bool "AT91SAM9RL" 66 bool "AT91SAM9RL"
@@ -57,11 +68,13 @@ config ARCH_AT91SAM9RL
57 select GENERIC_CLOCKEVENTS 68 select GENERIC_CLOCKEVENTS
58 select HAVE_AT91_USART3 69 select HAVE_AT91_USART3
59 select HAVE_FB_ATMEL 70 select HAVE_FB_ATMEL
71 select HAVE_AT91_DBGU0
60 72
61config ARCH_AT91SAM9G20 73config ARCH_AT91SAM9G20
62 bool "AT91SAM9G20" 74 bool "AT91SAM9G20"
63 select CPU_ARM926T 75 select CPU_ARM926T
64 select GENERIC_CLOCKEVENTS 76 select GENERIC_CLOCKEVENTS
77 select HAVE_AT91_DBGU0
65 select HAVE_AT91_USART3 78 select HAVE_AT91_USART3
66 select HAVE_AT91_USART4 79 select HAVE_AT91_USART4
67 select HAVE_AT91_USART5 80 select HAVE_AT91_USART5
@@ -74,6 +87,7 @@ config ARCH_AT91SAM9G45
74 select HAVE_AT91_USART3 87 select HAVE_AT91_USART3
75 select HAVE_FB_ATMEL 88 select HAVE_FB_ATMEL
76 select HAVE_NET_MACB 89 select HAVE_NET_MACB
90 select HAVE_AT91_DBGU1
77 91
78config ARCH_AT91CAP9 92config ARCH_AT91CAP9
79 bool "AT91CAP9" 93 bool "AT91CAP9"
@@ -81,6 +95,7 @@ config ARCH_AT91CAP9
81 select GENERIC_CLOCKEVENTS 95 select GENERIC_CLOCKEVENTS
82 select HAVE_FB_ATMEL 96 select HAVE_FB_ATMEL
83 select HAVE_NET_MACB 97 select HAVE_NET_MACB
98 select HAVE_AT91_DBGU1
84 99
85config ARCH_AT91X40 100config ARCH_AT91X40
86 bool "AT91x40" 101 bool "AT91x40"
@@ -510,8 +525,13 @@ config AT91_TIMER_HZ
510choice 525choice
511 prompt "Select a UART for early kernel messages" 526 prompt "Select a UART for early kernel messages"
512 527
513config AT91_EARLY_DBGU 528config AT91_EARLY_DBGU0
514 bool "DBGU" 529 bool "DBGU on rm9200, 9260/9g20, 9261/9g10 and 9rl"
530 depends on HAVE_AT91_DBGU0
531
532config AT91_EARLY_DBGU1
533 bool "DBGU on 9263, 9g45 and cap9"
534 depends on HAVE_AT91_DBGU1
515 535
516config AT91_EARLY_USART0 536config AT91_EARLY_USART0
517 bool "USART0" 537 bool "USART0"
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index 29373397d2d..edb879ac04c 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/pm.h>
17 16
18#include <asm/irq.h> 17#include <asm/irq.h>
19#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
@@ -23,11 +22,11 @@
23#include <mach/at91cap9.h> 22#include <mach/at91cap9.h>
24#include <mach/at91_pmc.h> 23#include <mach/at91_pmc.h>
25#include <mach/at91_rstc.h> 24#include <mach/at91_rstc.h>
26#include <mach/at91_shdwc.h>
27 25
28#include "soc.h" 26#include "soc.h"
29#include "generic.h" 27#include "generic.h"
30#include "clock.h" 28#include "clock.h"
29#include "sam9_smc.h"
31 30
32/* -------------------------------------------------------------------- 31/* --------------------------------------------------------------------
33 * Clocks 32 * Clocks
@@ -137,7 +136,7 @@ static struct clk pwm_clk = {
137 .type = CLK_TYPE_PERIPHERAL, 136 .type = CLK_TYPE_PERIPHERAL,
138}; 137};
139static struct clk macb_clk = { 138static struct clk macb_clk = {
140 .name = "macb_clk", 139 .name = "pclk",
141 .pmc_mask = 1 << AT91CAP9_ID_EMAC, 140 .pmc_mask = 1 << AT91CAP9_ID_EMAC,
142 .type = CLK_TYPE_PERIPHERAL, 141 .type = CLK_TYPE_PERIPHERAL,
143}; 142};
@@ -210,6 +209,8 @@ static struct clk *periph_clocks[] __initdata = {
210}; 209};
211 210
212static struct clk_lookup periph_clocks_lookups[] = { 211static struct clk_lookup periph_clocks_lookups[] = {
212 /* One additional fake clock for macb_hclk */
213 CLKDEV_CON_ID("hclk", &macb_clk),
213 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), 214 CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
214 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), 215 CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
215 CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), 216 CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
@@ -221,6 +222,10 @@ static struct clk_lookup periph_clocks_lookups[] = {
221 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), 222 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
222 /* fake hclk clock */ 223 /* fake hclk clock */
223 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), 224 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
225 CLKDEV_CON_ID("pioA", &pioABCD_clk),
226 CLKDEV_CON_ID("pioB", &pioABCD_clk),
227 CLKDEV_CON_ID("pioC", &pioABCD_clk),
228 CLKDEV_CON_ID("pioD", &pioABCD_clk),
224}; 229};
225 230
226static struct clk_lookup usart_clocks_lookups[] = { 231static struct clk_lookup usart_clocks_lookups[] = {
@@ -293,23 +298,19 @@ void __init at91cap9_set_console_clock(int id)
293 * GPIO 298 * GPIO
294 * -------------------------------------------------------------------- */ 299 * -------------------------------------------------------------------- */
295 300
296static struct at91_gpio_bank at91cap9_gpio[] = { 301static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
297 { 302 {
298 .id = AT91CAP9_ID_PIOABCD, 303 .id = AT91CAP9_ID_PIOABCD,
299 .offset = AT91_PIOA, 304 .regbase = AT91CAP9_BASE_PIOA,
300 .clock = &pioABCD_clk,
301 }, { 305 }, {
302 .id = AT91CAP9_ID_PIOABCD, 306 .id = AT91CAP9_ID_PIOABCD,
303 .offset = AT91_PIOB, 307 .regbase = AT91CAP9_BASE_PIOB,
304 .clock = &pioABCD_clk,
305 }, { 308 }, {
306 .id = AT91CAP9_ID_PIOABCD, 309 .id = AT91CAP9_ID_PIOABCD,
307 .offset = AT91_PIOC, 310 .regbase = AT91CAP9_BASE_PIOC,
308 .clock = &pioABCD_clk,
309 }, { 311 }, {
310 .id = AT91CAP9_ID_PIOABCD, 312 .id = AT91CAP9_ID_PIOABCD,
311 .offset = AT91_PIOD, 313 .regbase = AT91CAP9_BASE_PIOD,
312 .clock = &pioABCD_clk,
313 } 314 }
314}; 315};
315 316
@@ -318,12 +319,6 @@ static void at91cap9_restart(char mode, const char *cmd)
318 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 319 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
319} 320}
320 321
321static void at91cap9_poweroff(void)
322{
323 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
324}
325
326
327/* -------------------------------------------------------------------- 322/* --------------------------------------------------------------------
328 * AT91CAP9 processor initialization 323 * AT91CAP9 processor initialization
329 * -------------------------------------------------------------------- */ 324 * -------------------------------------------------------------------- */
@@ -333,10 +328,16 @@ static void __init at91cap9_map_io(void)
333 at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); 328 at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE);
334} 329}
335 330
331static void __init at91cap9_ioremap_registers(void)
332{
333 at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
334 at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
335 at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
336}
337
336static void __init at91cap9_initialize(void) 338static void __init at91cap9_initialize(void)
337{ 339{
338 arm_pm_restart = at91cap9_restart; 340 arm_pm_restart = at91cap9_restart;
339 pm_power_off = at91cap9_poweroff;
340 at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); 341 at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
341 342
342 /* Register GPIO subsystem */ 343 /* Register GPIO subsystem */
@@ -394,6 +395,7 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
394struct at91_init_soc __initdata at91cap9_soc = { 395struct at91_init_soc __initdata at91cap9_soc = {
395 .map_io = at91cap9_map_io, 396 .map_io = at91cap9_map_io,
396 .default_irq_priority = at91cap9_default_irq_priority, 397 .default_irq_priority = at91cap9_default_irq_priority,
398 .ioremap_registers = at91cap9_ioremap_registers,
397 .register_clocks = at91cap9_register_clocks, 399 .register_clocks = at91cap9_register_clocks,
398 .init = at91cap9_initialize, 400 .init = at91cap9_initialize,
399}; 401};
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index adad70db70e..d298fb7cb21 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -76,7 +76,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
76 76
77 /* Enable VBus control for UHP ports */ 77 /* Enable VBus control for UHP ports */
78 for (i = 0; i < data->ports; i++) { 78 for (i = 0; i < data->ports; i++) {
79 if (data->vbus_pin[i]) 79 if (gpio_is_valid(data->vbus_pin[i]))
80 at91_set_gpio_output(data->vbus_pin[i], 0); 80 at91_set_gpio_output(data->vbus_pin[i], 0);
81 } 81 }
82 82
@@ -179,7 +179,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data)
179 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); 179 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
180 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); 180 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
181 181
182 if (data && data->vbus_pin > 0) { 182 if (data && gpio_is_valid(data->vbus_pin)) {
183 at91_set_gpio_input(data->vbus_pin, 0); 183 at91_set_gpio_input(data->vbus_pin, 0);
184 at91_set_deglitch(data->vbus_pin, 1); 184 at91_set_deglitch(data->vbus_pin, 1);
185 usba_udc_data.pdata.vbus_pin = data->vbus_pin; 185 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
@@ -200,7 +200,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {}
200 200
201#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 201#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
202static u64 eth_dmamask = DMA_BIT_MASK(32); 202static u64 eth_dmamask = DMA_BIT_MASK(32);
203static struct at91_eth_data eth_data; 203static struct macb_platform_data eth_data;
204 204
205static struct resource eth_resources[] = { 205static struct resource eth_resources[] = {
206 [0] = { 206 [0] = {
@@ -227,12 +227,12 @@ static struct platform_device at91cap9_eth_device = {
227 .num_resources = ARRAY_SIZE(eth_resources), 227 .num_resources = ARRAY_SIZE(eth_resources),
228}; 228};
229 229
230void __init at91_add_device_eth(struct at91_eth_data *data) 230void __init at91_add_device_eth(struct macb_platform_data *data)
231{ 231{
232 if (!data) 232 if (!data)
233 return; 233 return;
234 234
235 if (data->phy_irq_pin) { 235 if (gpio_is_valid(data->phy_irq_pin)) {
236 at91_set_gpio_input(data->phy_irq_pin, 0); 236 at91_set_gpio_input(data->phy_irq_pin, 0);
237 at91_set_deglitch(data->phy_irq_pin, 1); 237 at91_set_deglitch(data->phy_irq_pin, 1);
238 } 238 }
@@ -264,7 +264,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
264 platform_device_register(&at91cap9_eth_device); 264 platform_device_register(&at91cap9_eth_device);
265} 265}
266#else 266#else
267void __init at91_add_device_eth(struct at91_eth_data *data) {} 267void __init at91_add_device_eth(struct macb_platform_data *data) {}
268#endif 268#endif
269 269
270 270
@@ -332,13 +332,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
332 return; 332 return;
333 333
334 /* input/irq */ 334 /* input/irq */
335 if (data->det_pin) { 335 if (gpio_is_valid(data->det_pin)) {
336 at91_set_gpio_input(data->det_pin, 1); 336 at91_set_gpio_input(data->det_pin, 1);
337 at91_set_deglitch(data->det_pin, 1); 337 at91_set_deglitch(data->det_pin, 1);
338 } 338 }
339 if (data->wp_pin) 339 if (gpio_is_valid(data->wp_pin))
340 at91_set_gpio_input(data->wp_pin, 1); 340 at91_set_gpio_input(data->wp_pin, 1);
341 if (data->vcc_pin) 341 if (gpio_is_valid(data->vcc_pin))
342 at91_set_gpio_output(data->vcc_pin, 0); 342 at91_set_gpio_output(data->vcc_pin, 0);
343 343
344 if (mmc_id == 0) { /* MCI0 */ 344 if (mmc_id == 0) { /* MCI0 */
@@ -398,8 +398,8 @@ static struct resource nand_resources[] = {
398 .flags = IORESOURCE_MEM, 398 .flags = IORESOURCE_MEM,
399 }, 399 },
400 [1] = { 400 [1] = {
401 .start = AT91_BASE_SYS + AT91_ECC, 401 .start = AT91CAP9_BASE_ECC,
402 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, 402 .end = AT91CAP9_BASE_ECC + SZ_512 - 1,
403 .flags = IORESOURCE_MEM, 403 .flags = IORESOURCE_MEM,
404 } 404 }
405}; 405};
@@ -425,15 +425,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
425 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); 425 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
426 426
427 /* enable pin */ 427 /* enable pin */
428 if (data->enable_pin) 428 if (gpio_is_valid(data->enable_pin))
429 at91_set_gpio_output(data->enable_pin, 1); 429 at91_set_gpio_output(data->enable_pin, 1);
430 430
431 /* ready/busy pin */ 431 /* ready/busy pin */
432 if (data->rdy_pin) 432 if (gpio_is_valid(data->rdy_pin))
433 at91_set_gpio_input(data->rdy_pin, 1); 433 at91_set_gpio_input(data->rdy_pin, 1);
434 434
435 /* card detect pin */ 435 /* card detect pin */
436 if (data->det_pin) 436 if (gpio_is_valid(data->det_pin))
437 at91_set_gpio_input(data->det_pin, 1); 437 at91_set_gpio_input(data->det_pin, 1);
438 438
439 nand_data = *data; 439 nand_data = *data;
@@ -670,8 +670,8 @@ static void __init at91_add_device_tc(void) { }
670 670
671static struct resource rtt_resources[] = { 671static struct resource rtt_resources[] = {
672 { 672 {
673 .start = AT91_BASE_SYS + AT91_RTT, 673 .start = AT91CAP9_BASE_RTT,
674 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, 674 .end = AT91CAP9_BASE_RTT + SZ_16 - 1,
675 .flags = IORESOURCE_MEM, 675 .flags = IORESOURCE_MEM,
676 } 676 }
677}; 677};
@@ -694,10 +694,19 @@ static void __init at91_add_device_rtt(void)
694 * -------------------------------------------------------------------- */ 694 * -------------------------------------------------------------------- */
695 695
696#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 696#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
697static struct resource wdt_resources[] = {
698 {
699 .start = AT91CAP9_BASE_WDT,
700 .end = AT91CAP9_BASE_WDT + SZ_16 - 1,
701 .flags = IORESOURCE_MEM,
702 }
703};
704
697static struct platform_device at91cap9_wdt_device = { 705static struct platform_device at91cap9_wdt_device = {
698 .name = "at91_wdt", 706 .name = "at91_wdt",
699 .id = -1, 707 .id = -1,
700 .num_resources = 0, 708 .resource = wdt_resources,
709 .num_resources = ARRAY_SIZE(wdt_resources),
701}; 710};
702 711
703static void __init at91_add_device_watchdog(void) 712static void __init at91_add_device_watchdog(void)
@@ -807,7 +816,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
807 at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */ 816 at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
808 817
809 /* reset */ 818 /* reset */
810 if (data->reset_pin) 819 if (gpio_is_valid(data->reset_pin))
811 at91_set_gpio_output(data->reset_pin, 0); 820 at91_set_gpio_output(data->reset_pin, 0);
812 821
813 ac97_data = *data; 822 ac97_data = *data;
@@ -1021,8 +1030,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1021#if defined(CONFIG_SERIAL_ATMEL) 1030#if defined(CONFIG_SERIAL_ATMEL)
1022static struct resource dbgu_resources[] = { 1031static struct resource dbgu_resources[] = {
1023 [0] = { 1032 [0] = {
1024 .start = AT91_BASE_SYS + AT91_DBGU, 1033 .start = AT91CAP9_BASE_DBGU,
1025 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 1034 .end = AT91CAP9_BASE_DBGU + SZ_512 - 1,
1026 .flags = IORESOURCE_MEM, 1035 .flags = IORESOURCE_MEM,
1027 }, 1036 },
1028 [1] = { 1037 [1] = {
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 430a9fdc3db..99c3174e24a 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -23,6 +23,7 @@
23#include "soc.h" 23#include "soc.h"
24#include "generic.h" 24#include "generic.h"
25#include "clock.h" 25#include "clock.h"
26#include "sam9_smc.h"
26 27
27static struct map_desc at91rm9200_io_desc[] __initdata = { 28static struct map_desc at91rm9200_io_desc[] __initdata = {
28 { 29 {
@@ -195,6 +196,10 @@ static struct clk_lookup periph_clocks_lookups[] = {
195 CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), 196 CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
196 /* fake hclk clock */ 197 /* fake hclk clock */
197 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), 198 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
199 CLKDEV_CON_ID("pioA", &pioA_clk),
200 CLKDEV_CON_ID("pioB", &pioB_clk),
201 CLKDEV_CON_ID("pioC", &pioC_clk),
202 CLKDEV_CON_ID("pioD", &pioD_clk),
198}; 203};
199 204
200static struct clk_lookup usart_clocks_lookups[] = { 205static struct clk_lookup usart_clocks_lookups[] = {
@@ -268,23 +273,19 @@ void __init at91rm9200_set_console_clock(int id)
268 * GPIO 273 * GPIO
269 * -------------------------------------------------------------------- */ 274 * -------------------------------------------------------------------- */
270 275
271static struct at91_gpio_bank at91rm9200_gpio[] = { 276static struct at91_gpio_bank at91rm9200_gpio[] __initdata = {
272 { 277 {
273 .id = AT91RM9200_ID_PIOA, 278 .id = AT91RM9200_ID_PIOA,
274 .offset = AT91_PIOA, 279 .regbase = AT91RM9200_BASE_PIOA,
275 .clock = &pioA_clk,
276 }, { 280 }, {
277 .id = AT91RM9200_ID_PIOB, 281 .id = AT91RM9200_ID_PIOB,
278 .offset = AT91_PIOB, 282 .regbase = AT91RM9200_BASE_PIOB,
279 .clock = &pioB_clk,
280 }, { 283 }, {
281 .id = AT91RM9200_ID_PIOC, 284 .id = AT91RM9200_ID_PIOC,
282 .offset = AT91_PIOC, 285 .regbase = AT91RM9200_BASE_PIOC,
283 .clock = &pioC_clk,
284 }, { 286 }, {
285 .id = AT91RM9200_ID_PIOD, 287 .id = AT91RM9200_ID_PIOD,
286 .offset = AT91_PIOD, 288 .regbase = AT91RM9200_BASE_PIOD,
287 .clock = &pioD_clk,
288 } 289 }
289}; 290};
290 291
@@ -307,6 +308,10 @@ static void __init at91rm9200_map_io(void)
307 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); 308 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
308} 309}
309 310
311static void __init at91rm9200_ioremap_registers(void)
312{
313}
314
310static void __init at91rm9200_initialize(void) 315static void __init at91rm9200_initialize(void)
311{ 316{
312 arm_pm_restart = at91rm9200_restart; 317 arm_pm_restart = at91rm9200_restart;
@@ -366,6 +371,7 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
366struct at91_init_soc __initdata at91rm9200_soc = { 371struct at91_init_soc __initdata at91rm9200_soc = {
367 .map_io = at91rm9200_map_io, 372 .map_io = at91rm9200_map_io,
368 .default_irq_priority = at91rm9200_default_irq_priority, 373 .default_irq_priority = at91rm9200_default_irq_priority,
374 .ioremap_registers = at91rm9200_ioremap_registers,
369 .register_clocks = at91rm9200_register_clocks, 375 .register_clocks = at91rm9200_register_clocks,
370 .init = at91rm9200_initialize, 376 .init = at91rm9200_initialize,
371}; 377};
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index ad930688358..18bacec2b09 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -114,11 +114,11 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
114 if (!data) 114 if (!data)
115 return; 115 return;
116 116
117 if (data->vbus_pin) { 117 if (gpio_is_valid(data->vbus_pin)) {
118 at91_set_gpio_input(data->vbus_pin, 0); 118 at91_set_gpio_input(data->vbus_pin, 0);
119 at91_set_deglitch(data->vbus_pin, 1); 119 at91_set_deglitch(data->vbus_pin, 1);
120 } 120 }
121 if (data->pullup_pin) 121 if (gpio_is_valid(data->pullup_pin))
122 at91_set_gpio_output(data->pullup_pin, 0); 122 at91_set_gpio_output(data->pullup_pin, 0);
123 123
124 udc_data = *data; 124 udc_data = *data;
@@ -135,7 +135,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
135 135
136#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) 136#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE)
137static u64 eth_dmamask = DMA_BIT_MASK(32); 137static u64 eth_dmamask = DMA_BIT_MASK(32);
138static struct at91_eth_data eth_data; 138static struct macb_platform_data eth_data;
139 139
140static struct resource eth_resources[] = { 140static struct resource eth_resources[] = {
141 [0] = { 141 [0] = {
@@ -162,12 +162,12 @@ static struct platform_device at91rm9200_eth_device = {
162 .num_resources = ARRAY_SIZE(eth_resources), 162 .num_resources = ARRAY_SIZE(eth_resources),
163}; 163};
164 164
165void __init at91_add_device_eth(struct at91_eth_data *data) 165void __init at91_add_device_eth(struct macb_platform_data *data)
166{ 166{
167 if (!data) 167 if (!data)
168 return; 168 return;
169 169
170 if (data->phy_irq_pin) { 170 if (gpio_is_valid(data->phy_irq_pin)) {
171 at91_set_gpio_input(data->phy_irq_pin, 0); 171 at91_set_gpio_input(data->phy_irq_pin, 0);
172 at91_set_deglitch(data->phy_irq_pin, 1); 172 at91_set_deglitch(data->phy_irq_pin, 1);
173 } 173 }
@@ -199,7 +199,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
199 platform_device_register(&at91rm9200_eth_device); 199 platform_device_register(&at91rm9200_eth_device);
200} 200}
201#else 201#else
202void __init at91_add_device_eth(struct at91_eth_data *data) {} 202void __init at91_add_device_eth(struct macb_platform_data *data) {}
203#endif 203#endif
204 204
205 205
@@ -260,7 +260,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
260 ); 260 );
261 261
262 /* input/irq */ 262 /* input/irq */
263 if (data->irq_pin) { 263 if (gpio_is_valid(data->irq_pin)) {
264 at91_set_gpio_input(data->irq_pin, 1); 264 at91_set_gpio_input(data->irq_pin, 1);
265 at91_set_deglitch(data->irq_pin, 1); 265 at91_set_deglitch(data->irq_pin, 1);
266 } 266 }
@@ -268,7 +268,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
268 at91_set_deglitch(data->det_pin, 1); 268 at91_set_deglitch(data->det_pin, 1);
269 269
270 /* outputs, initially off */ 270 /* outputs, initially off */
271 if (data->vcc_pin) 271 if (gpio_is_valid(data->vcc_pin))
272 at91_set_gpio_output(data->vcc_pin, 0); 272 at91_set_gpio_output(data->vcc_pin, 0);
273 at91_set_gpio_output(data->rst_pin, 0); 273 at91_set_gpio_output(data->rst_pin, 0);
274 274
@@ -328,13 +328,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
328 return; 328 return;
329 329
330 /* input/irq */ 330 /* input/irq */
331 if (data->det_pin) { 331 if (gpio_is_valid(data->det_pin)) {
332 at91_set_gpio_input(data->det_pin, 1); 332 at91_set_gpio_input(data->det_pin, 1);
333 at91_set_deglitch(data->det_pin, 1); 333 at91_set_deglitch(data->det_pin, 1);
334 } 334 }
335 if (data->wp_pin) 335 if (gpio_is_valid(data->wp_pin))
336 at91_set_gpio_input(data->wp_pin, 1); 336 at91_set_gpio_input(data->wp_pin, 1);
337 if (data->vcc_pin) 337 if (gpio_is_valid(data->vcc_pin))
338 at91_set_gpio_output(data->vcc_pin, 0); 338 at91_set_gpio_output(data->vcc_pin, 0);
339 339
340 /* CLK */ 340 /* CLK */
@@ -419,15 +419,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
419 ); 419 );
420 420
421 /* enable pin */ 421 /* enable pin */
422 if (data->enable_pin) 422 if (gpio_is_valid(data->enable_pin))
423 at91_set_gpio_output(data->enable_pin, 1); 423 at91_set_gpio_output(data->enable_pin, 1);
424 424
425 /* ready/busy pin */ 425 /* ready/busy pin */
426 if (data->rdy_pin) 426 if (gpio_is_valid(data->rdy_pin))
427 at91_set_gpio_input(data->rdy_pin, 1); 427 at91_set_gpio_input(data->rdy_pin, 1);
428 428
429 /* card detect pin */ 429 /* card detect pin */
430 if (data->det_pin) 430 if (gpio_is_valid(data->det_pin))
431 at91_set_gpio_input(data->det_pin, 1); 431 at91_set_gpio_input(data->det_pin, 1);
432 432
433 at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ 433 at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */
@@ -665,10 +665,24 @@ static void __init at91_add_device_tc(void) { }
665 * -------------------------------------------------------------------- */ 665 * -------------------------------------------------------------------- */
666 666
667#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) 667#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
668static struct resource rtc_resources[] = {
669 [0] = {
670 .start = AT91RM9200_BASE_RTC,
671 .end = AT91RM9200_BASE_RTC + SZ_256 - 1,
672 .flags = IORESOURCE_MEM,
673 },
674 [1] = {
675 .start = AT91_ID_SYS,
676 .end = AT91_ID_SYS,
677 .flags = IORESOURCE_IRQ,
678 },
679};
680
668static struct platform_device at91rm9200_rtc_device = { 681static struct platform_device at91rm9200_rtc_device = {
669 .name = "at91_rtc", 682 .name = "at91_rtc",
670 .id = -1, 683 .id = -1,
671 .num_resources = 0, 684 .resource = rtc_resources,
685 .num_resources = ARRAY_SIZE(rtc_resources),
672}; 686};
673 687
674static void __init at91_add_device_rtc(void) 688static void __init at91_add_device_rtc(void)
@@ -877,8 +891,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
877#if defined(CONFIG_SERIAL_ATMEL) 891#if defined(CONFIG_SERIAL_ATMEL)
878static struct resource dbgu_resources[] = { 892static struct resource dbgu_resources[] = {
879 [0] = { 893 [0] = {
880 .start = AT91_BASE_SYS + AT91_DBGU, 894 .start = AT91RM9200_BASE_DBGU,
881 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 895 .end = AT91RM9200_BASE_DBGU + SZ_512 - 1,
882 .flags = IORESOURCE_MEM, 896 .flags = IORESOURCE_MEM,
883 }, 897 },
884 [1] = { 898 [1] = {
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index 1dd69c85dfe..a028cdf8f97 100644
--- a/arch/arm/mach-at91/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -32,6 +32,8 @@ static unsigned long last_crtr;
32static u32 irqmask; 32static u32 irqmask;
33static struct clock_event_device clkevt; 33static struct clock_event_device clkevt;
34 34
35#define RM9200_TIMER_LATCH ((AT91_SLOW_CLOCK + HZ/2) / HZ)
36
35/* 37/*
36 * The ST_CRTR is updated asynchronously to the master clock ... but 38 * The ST_CRTR is updated asynchronously to the master clock ... but
37 * the updates as seen by the CPU don't seem to be strictly monotonic. 39 * the updates as seen by the CPU don't seem to be strictly monotonic.
@@ -74,8 +76,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
74 if (sr & AT91_ST_PITS) { 76 if (sr & AT91_ST_PITS) {
75 u32 crtr = read_CRTR(); 77 u32 crtr = read_CRTR();
76 78
77 while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) { 79 while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
78 last_crtr += LATCH; 80 last_crtr += RM9200_TIMER_LATCH;
79 clkevt.event_handler(&clkevt); 81 clkevt.event_handler(&clkevt);
80 } 82 }
81 return IRQ_HANDLED; 83 return IRQ_HANDLED;
@@ -116,7 +118,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
116 case CLOCK_EVT_MODE_PERIODIC: 118 case CLOCK_EVT_MODE_PERIODIC:
117 /* PIT for periodic irqs; fixed rate of 1/HZ */ 119 /* PIT for periodic irqs; fixed rate of 1/HZ */
118 irqmask = AT91_ST_PITS; 120 irqmask = AT91_ST_PITS;
119 at91_sys_write(AT91_ST_PIMR, LATCH); 121 at91_sys_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
120 break; 122 break;
121 case CLOCK_EVT_MODE_ONESHOT: 123 case CLOCK_EVT_MODE_ONESHOT:
122 /* ALM for oneshot irqs, set by next_event() 124 /* ALM for oneshot irqs, set by next_event()
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index e76cd49ebc9..5e46e4a9643 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pm.h>
15 14
16#include <asm/irq.h> 15#include <asm/irq.h>
17#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
@@ -21,11 +20,11 @@
21#include <mach/at91sam9260.h> 20#include <mach/at91sam9260.h>
22#include <mach/at91_pmc.h> 21#include <mach/at91_pmc.h>
23#include <mach/at91_rstc.h> 22#include <mach/at91_rstc.h>
24#include <mach/at91_shdwc.h>
25 23
26#include "soc.h" 24#include "soc.h"
27#include "generic.h" 25#include "generic.h"
28#include "clock.h" 26#include "clock.h"
27#include "sam9_smc.h"
29 28
30/* -------------------------------------------------------------------- 29/* --------------------------------------------------------------------
31 * Clocks 30 * Clocks
@@ -120,7 +119,7 @@ static struct clk ohci_clk = {
120 .type = CLK_TYPE_PERIPHERAL, 119 .type = CLK_TYPE_PERIPHERAL,
121}; 120};
122static struct clk macb_clk = { 121static struct clk macb_clk = {
123 .name = "macb_clk", 122 .name = "pclk",
124 .pmc_mask = 1 << AT91SAM9260_ID_EMAC, 123 .pmc_mask = 1 << AT91SAM9260_ID_EMAC,
125 .type = CLK_TYPE_PERIPHERAL, 124 .type = CLK_TYPE_PERIPHERAL,
126}; 125};
@@ -190,6 +189,8 @@ static struct clk *periph_clocks[] __initdata = {
190}; 189};
191 190
192static struct clk_lookup periph_clocks_lookups[] = { 191static struct clk_lookup periph_clocks_lookups[] = {
192 /* One additional fake clock for macb_hclk */
193 CLKDEV_CON_ID("hclk", &macb_clk),
193 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), 194 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
194 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), 195 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
195 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), 196 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
@@ -209,6 +210,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
209 CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), 210 CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk),
210 /* fake hclk clock */ 211 /* fake hclk clock */
211 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), 212 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
213 CLKDEV_CON_ID("pioA", &pioA_clk),
214 CLKDEV_CON_ID("pioB", &pioB_clk),
215 CLKDEV_CON_ID("pioC", &pioC_clk),
212}; 216};
213 217
214static struct clk_lookup usart_clocks_lookups[] = { 218static struct clk_lookup usart_clocks_lookups[] = {
@@ -270,28 +274,19 @@ void __init at91sam9260_set_console_clock(int id)
270 * GPIO 274 * GPIO
271 * -------------------------------------------------------------------- */ 275 * -------------------------------------------------------------------- */
272 276
273static struct at91_gpio_bank at91sam9260_gpio[] = { 277static struct at91_gpio_bank at91sam9260_gpio[] __initdata = {
274 { 278 {
275 .id = AT91SAM9260_ID_PIOA, 279 .id = AT91SAM9260_ID_PIOA,
276 .offset = AT91_PIOA, 280 .regbase = AT91SAM9260_BASE_PIOA,
277 .clock = &pioA_clk,
278 }, { 281 }, {
279 .id = AT91SAM9260_ID_PIOB, 282 .id = AT91SAM9260_ID_PIOB,
280 .offset = AT91_PIOB, 283 .regbase = AT91SAM9260_BASE_PIOB,
281 .clock = &pioB_clk,
282 }, { 284 }, {
283 .id = AT91SAM9260_ID_PIOC, 285 .id = AT91SAM9260_ID_PIOC,
284 .offset = AT91_PIOC, 286 .regbase = AT91SAM9260_BASE_PIOC,
285 .clock = &pioC_clk,
286 } 287 }
287}; 288};
288 289
289static void at91sam9260_poweroff(void)
290{
291 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
292}
293
294
295/* -------------------------------------------------------------------- 290/* --------------------------------------------------------------------
296 * AT91SAM9260 processor initialization 291 * AT91SAM9260 processor initialization
297 * -------------------------------------------------------------------- */ 292 * -------------------------------------------------------------------- */
@@ -325,10 +320,16 @@ static void __init at91sam9260_map_io(void)
325 } 320 }
326} 321}
327 322
323static void __init at91sam9260_ioremap_registers(void)
324{
325 at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC);
326 at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT);
327 at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
328}
329
328static void __init at91sam9260_initialize(void) 330static void __init at91sam9260_initialize(void)
329{ 331{
330 arm_pm_restart = at91sam9_alt_restart; 332 arm_pm_restart = at91sam9_alt_restart;
331 pm_power_off = at91sam9260_poweroff;
332 at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) 333 at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
333 | (1 << AT91SAM9260_ID_IRQ2); 334 | (1 << AT91SAM9260_ID_IRQ2);
334 335
@@ -381,6 +382,7 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
381struct at91_init_soc __initdata at91sam9260_soc = { 382struct at91_init_soc __initdata at91sam9260_soc = {
382 .map_io = at91sam9260_map_io, 383 .map_io = at91sam9260_map_io,
383 .default_irq_priority = at91sam9260_default_irq_priority, 384 .default_irq_priority = at91sam9260_default_irq_priority,
385 .ioremap_registers = at91sam9260_ioremap_registers,
384 .register_clocks = at91sam9260_register_clocks, 386 .register_clocks = at91sam9260_register_clocks,
385 .init = at91sam9260_initialize, 387 .init = at91sam9260_initialize,
386}; 388};
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 629fa977497..642ccb6d26b 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -115,7 +115,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
115 if (!data) 115 if (!data)
116 return; 116 return;
117 117
118 if (data->vbus_pin) { 118 if (gpio_is_valid(data->vbus_pin)) {
119 at91_set_gpio_input(data->vbus_pin, 0); 119 at91_set_gpio_input(data->vbus_pin, 0);
120 at91_set_deglitch(data->vbus_pin, 1); 120 at91_set_deglitch(data->vbus_pin, 1);
121 } 121 }
@@ -136,7 +136,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
136 136
137#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 137#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
138static u64 eth_dmamask = DMA_BIT_MASK(32); 138static u64 eth_dmamask = DMA_BIT_MASK(32);
139static struct at91_eth_data eth_data; 139static struct macb_platform_data eth_data;
140 140
141static struct resource eth_resources[] = { 141static struct resource eth_resources[] = {
142 [0] = { 142 [0] = {
@@ -163,12 +163,12 @@ static struct platform_device at91sam9260_eth_device = {
163 .num_resources = ARRAY_SIZE(eth_resources), 163 .num_resources = ARRAY_SIZE(eth_resources),
164}; 164};
165 165
166void __init at91_add_device_eth(struct at91_eth_data *data) 166void __init at91_add_device_eth(struct macb_platform_data *data)
167{ 167{
168 if (!data) 168 if (!data)
169 return; 169 return;
170 170
171 if (data->phy_irq_pin) { 171 if (gpio_is_valid(data->phy_irq_pin)) {
172 at91_set_gpio_input(data->phy_irq_pin, 0); 172 at91_set_gpio_input(data->phy_irq_pin, 0);
173 at91_set_deglitch(data->phy_irq_pin, 1); 173 at91_set_deglitch(data->phy_irq_pin, 1);
174 } 174 }
@@ -200,7 +200,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
200 platform_device_register(&at91sam9260_eth_device); 200 platform_device_register(&at91sam9260_eth_device);
201} 201}
202#else 202#else
203void __init at91_add_device_eth(struct at91_eth_data *data) {} 203void __init at91_add_device_eth(struct macb_platform_data *data) {}
204#endif 204#endif
205 205
206 206
@@ -243,13 +243,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
243 return; 243 return;
244 244
245 /* input/irq */ 245 /* input/irq */
246 if (data->det_pin) { 246 if (gpio_is_valid(data->det_pin)) {
247 at91_set_gpio_input(data->det_pin, 1); 247 at91_set_gpio_input(data->det_pin, 1);
248 at91_set_deglitch(data->det_pin, 1); 248 at91_set_deglitch(data->det_pin, 1);
249 } 249 }
250 if (data->wp_pin) 250 if (gpio_is_valid(data->wp_pin))
251 at91_set_gpio_input(data->wp_pin, 1); 251 at91_set_gpio_input(data->wp_pin, 1);
252 if (data->vcc_pin) 252 if (gpio_is_valid(data->vcc_pin))
253 at91_set_gpio_output(data->vcc_pin, 0); 253 at91_set_gpio_output(data->vcc_pin, 0);
254 254
255 /* CLK */ 255 /* CLK */
@@ -330,11 +330,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
330 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) { 330 for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
331 if (data->slot[i].bus_width) { 331 if (data->slot[i].bus_width) {
332 /* input/irq */ 332 /* input/irq */
333 if (data->slot[i].detect_pin) { 333 if (gpio_is_valid(data->slot[i].detect_pin)) {
334 at91_set_gpio_input(data->slot[i].detect_pin, 1); 334 at91_set_gpio_input(data->slot[i].detect_pin, 1);
335 at91_set_deglitch(data->slot[i].detect_pin, 1); 335 at91_set_deglitch(data->slot[i].detect_pin, 1);
336 } 336 }
337 if (data->slot[i].wp_pin) 337 if (gpio_is_valid(data->slot[i].wp_pin))
338 at91_set_gpio_input(data->slot[i].wp_pin, 1); 338 at91_set_gpio_input(data->slot[i].wp_pin, 1);
339 339
340 switch (i) { 340 switch (i) {
@@ -399,8 +399,8 @@ static struct resource nand_resources[] = {
399 .flags = IORESOURCE_MEM, 399 .flags = IORESOURCE_MEM,
400 }, 400 },
401 [1] = { 401 [1] = {
402 .start = AT91_BASE_SYS + AT91_ECC, 402 .start = AT91SAM9260_BASE_ECC,
403 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, 403 .end = AT91SAM9260_BASE_ECC + SZ_512 - 1,
404 .flags = IORESOURCE_MEM, 404 .flags = IORESOURCE_MEM,
405 } 405 }
406}; 406};
@@ -426,15 +426,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
426 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); 426 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
427 427
428 /* enable pin */ 428 /* enable pin */
429 if (data->enable_pin) 429 if (gpio_is_valid(data->enable_pin))
430 at91_set_gpio_output(data->enable_pin, 1); 430 at91_set_gpio_output(data->enable_pin, 1);
431 431
432 /* ready/busy pin */ 432 /* ready/busy pin */
433 if (data->rdy_pin) 433 if (gpio_is_valid(data->rdy_pin))
434 at91_set_gpio_input(data->rdy_pin, 1); 434 at91_set_gpio_input(data->rdy_pin, 1);
435 435
436 /* card detect pin */ 436 /* card detect pin */
437 if (data->det_pin) 437 if (gpio_is_valid(data->det_pin))
438 at91_set_gpio_input(data->det_pin, 1); 438 at91_set_gpio_input(data->det_pin, 1);
439 439
440 nand_data = *data; 440 nand_data = *data;
@@ -714,8 +714,8 @@ static void __init at91_add_device_tc(void) { }
714 714
715static struct resource rtt_resources[] = { 715static struct resource rtt_resources[] = {
716 { 716 {
717 .start = AT91_BASE_SYS + AT91_RTT, 717 .start = AT91SAM9260_BASE_RTT,
718 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, 718 .end = AT91SAM9260_BASE_RTT + SZ_16 - 1,
719 .flags = IORESOURCE_MEM, 719 .flags = IORESOURCE_MEM,
720 } 720 }
721}; 721};
@@ -738,10 +738,19 @@ static void __init at91_add_device_rtt(void)
738 * -------------------------------------------------------------------- */ 738 * -------------------------------------------------------------------- */
739 739
740#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 740#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
741static struct resource wdt_resources[] = {
742 {
743 .start = AT91SAM9260_BASE_WDT,
744 .end = AT91SAM9260_BASE_WDT + SZ_16 - 1,
745 .flags = IORESOURCE_MEM,
746 }
747};
748
741static struct platform_device at91sam9260_wdt_device = { 749static struct platform_device at91sam9260_wdt_device = {
742 .name = "at91_wdt", 750 .name = "at91_wdt",
743 .id = -1, 751 .id = -1,
744 .num_resources = 0, 752 .resource = wdt_resources,
753 .num_resources = ARRAY_SIZE(wdt_resources),
745}; 754};
746 755
747static void __init at91_add_device_watchdog(void) 756static void __init at91_add_device_watchdog(void)
@@ -837,8 +846,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
837#if defined(CONFIG_SERIAL_ATMEL) 846#if defined(CONFIG_SERIAL_ATMEL)
838static struct resource dbgu_resources[] = { 847static struct resource dbgu_resources[] = {
839 [0] = { 848 [0] = {
840 .start = AT91_BASE_SYS + AT91_DBGU, 849 .start = AT91SAM9260_BASE_DBGU,
841 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 850 .end = AT91SAM9260_BASE_DBGU + SZ_512 - 1,
842 .flags = IORESOURCE_MEM, 851 .flags = IORESOURCE_MEM,
843 }, 852 },
844 [1] = { 853 [1] = {
@@ -1281,17 +1290,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
1281 1290
1282 at91_sys_write(AT91_MATRIX_EBICSA, csa); 1291 at91_sys_write(AT91_MATRIX_EBICSA, csa);
1283 1292
1284 if (data->rst_pin) { 1293 if (gpio_is_valid(data->rst_pin)) {
1285 at91_set_multi_drive(data->rst_pin, 0); 1294 at91_set_multi_drive(data->rst_pin, 0);
1286 at91_set_gpio_output(data->rst_pin, 1); 1295 at91_set_gpio_output(data->rst_pin, 1);
1287 } 1296 }
1288 1297
1289 if (data->irq_pin) { 1298 if (gpio_is_valid(data->irq_pin)) {
1290 at91_set_gpio_input(data->irq_pin, 0); 1299 at91_set_gpio_input(data->irq_pin, 0);
1291 at91_set_deglitch(data->irq_pin, 1); 1300 at91_set_deglitch(data->irq_pin, 1);
1292 } 1301 }
1293 1302
1294 if (data->det_pin) { 1303 if (gpio_is_valid(data->det_pin)) {
1295 at91_set_gpio_input(data->det_pin, 0); 1304 at91_set_gpio_input(data->det_pin, 0);
1296 at91_set_deglitch(data->det_pin, 1); 1305 at91_set_deglitch(data->det_pin, 1);
1297 } 1306 }
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 19ac7c0729a..b85b9ea6017 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pm.h>
15 14
16#include <asm/irq.h> 15#include <asm/irq.h>
17#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
@@ -20,11 +19,11 @@
20#include <mach/at91sam9261.h> 19#include <mach/at91sam9261.h>
21#include <mach/at91_pmc.h> 20#include <mach/at91_pmc.h>
22#include <mach/at91_rstc.h> 21#include <mach/at91_rstc.h>
23#include <mach/at91_shdwc.h>
24 22
25#include "soc.h" 23#include "soc.h"
26#include "generic.h" 24#include "generic.h"
27#include "clock.h" 25#include "clock.h"
26#include "sam9_smc.h"
28 27
29/* -------------------------------------------------------------------- 28/* --------------------------------------------------------------------
30 * Clocks 29 * Clocks
@@ -176,6 +175,9 @@ static struct clk_lookup periph_clocks_lookups[] = {
176 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), 175 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
177 CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), 176 CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
178 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), 177 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
178 CLKDEV_CON_ID("pioA", &pioA_clk),
179 CLKDEV_CON_ID("pioB", &pioB_clk),
180 CLKDEV_CON_ID("pioC", &pioC_clk),
179}; 181};
180 182
181static struct clk_lookup usart_clocks_lookups[] = { 183static struct clk_lookup usart_clocks_lookups[] = {
@@ -251,28 +253,19 @@ void __init at91sam9261_set_console_clock(int id)
251 * GPIO 253 * GPIO
252 * -------------------------------------------------------------------- */ 254 * -------------------------------------------------------------------- */
253 255
254static struct at91_gpio_bank at91sam9261_gpio[] = { 256static struct at91_gpio_bank at91sam9261_gpio[] __initdata = {
255 { 257 {
256 .id = AT91SAM9261_ID_PIOA, 258 .id = AT91SAM9261_ID_PIOA,
257 .offset = AT91_PIOA, 259 .regbase = AT91SAM9261_BASE_PIOA,
258 .clock = &pioA_clk,
259 }, { 260 }, {
260 .id = AT91SAM9261_ID_PIOB, 261 .id = AT91SAM9261_ID_PIOB,
261 .offset = AT91_PIOB, 262 .regbase = AT91SAM9261_BASE_PIOB,
262 .clock = &pioB_clk,
263 }, { 263 }, {
264 .id = AT91SAM9261_ID_PIOC, 264 .id = AT91SAM9261_ID_PIOC,
265 .offset = AT91_PIOC, 265 .regbase = AT91SAM9261_BASE_PIOC,
266 .clock = &pioC_clk,
267 } 266 }
268}; 267};
269 268
270static void at91sam9261_poweroff(void)
271{
272 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
273}
274
275
276/* -------------------------------------------------------------------- 269/* --------------------------------------------------------------------
277 * AT91SAM9261 processor initialization 270 * AT91SAM9261 processor initialization
278 * -------------------------------------------------------------------- */ 271 * -------------------------------------------------------------------- */
@@ -285,10 +278,16 @@ static void __init at91sam9261_map_io(void)
285 at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE); 278 at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE);
286} 279}
287 280
281static void __init at91sam9261_ioremap_registers(void)
282{
283 at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC);
284 at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT);
285 at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
286}
287
288static void __init at91sam9261_initialize(void) 288static void __init at91sam9261_initialize(void)
289{ 289{
290 arm_pm_restart = at91sam9_alt_restart; 290 arm_pm_restart = at91sam9_alt_restart;
291 pm_power_off = at91sam9261_poweroff;
292 at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) 291 at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
293 | (1 << AT91SAM9261_ID_IRQ2); 292 | (1 << AT91SAM9261_ID_IRQ2);
294 293
@@ -341,6 +340,7 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
341struct at91_init_soc __initdata at91sam9261_soc = { 340struct at91_init_soc __initdata at91sam9261_soc = {
342 .map_io = at91sam9261_map_io, 341 .map_io = at91sam9261_map_io,
343 .default_irq_priority = at91sam9261_default_irq_priority, 342 .default_irq_priority = at91sam9261_default_irq_priority,
343 .ioremap_registers = at91sam9261_ioremap_registers,
344 .register_clocks = at91sam9261_register_clocks, 344 .register_clocks = at91sam9261_register_clocks,
345 .init = at91sam9261_initialize, 345 .init = at91sam9261_initialize,
346}; 346};
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index a178b58b0b9..fc59cbdb0e3 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -118,7 +118,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
118 if (!data) 118 if (!data)
119 return; 119 return;
120 120
121 if (data->vbus_pin) { 121 if (gpio_is_valid(data->vbus_pin)) {
122 at91_set_gpio_input(data->vbus_pin, 0); 122 at91_set_gpio_input(data->vbus_pin, 0);
123 at91_set_deglitch(data->vbus_pin, 1); 123 at91_set_deglitch(data->vbus_pin, 1);
124 } 124 }
@@ -171,13 +171,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
171 return; 171 return;
172 172
173 /* input/irq */ 173 /* input/irq */
174 if (data->det_pin) { 174 if (gpio_is_valid(data->det_pin)) {
175 at91_set_gpio_input(data->det_pin, 1); 175 at91_set_gpio_input(data->det_pin, 1);
176 at91_set_deglitch(data->det_pin, 1); 176 at91_set_deglitch(data->det_pin, 1);
177 } 177 }
178 if (data->wp_pin) 178 if (gpio_is_valid(data->wp_pin))
179 at91_set_gpio_input(data->wp_pin, 1); 179 at91_set_gpio_input(data->wp_pin, 1);
180 if (data->vcc_pin) 180 if (gpio_is_valid(data->vcc_pin))
181 at91_set_gpio_output(data->vcc_pin, 0); 181 at91_set_gpio_output(data->vcc_pin, 0);
182 182
183 /* CLK */ 183 /* CLK */
@@ -240,15 +240,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
240 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); 240 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
241 241
242 /* enable pin */ 242 /* enable pin */
243 if (data->enable_pin) 243 if (gpio_is_valid(data->enable_pin))
244 at91_set_gpio_output(data->enable_pin, 1); 244 at91_set_gpio_output(data->enable_pin, 1);
245 245
246 /* ready/busy pin */ 246 /* ready/busy pin */
247 if (data->rdy_pin) 247 if (gpio_is_valid(data->rdy_pin))
248 at91_set_gpio_input(data->rdy_pin, 1); 248 at91_set_gpio_input(data->rdy_pin, 1);
249 249
250 /* card detect pin */ 250 /* card detect pin */
251 if (data->det_pin) 251 if (gpio_is_valid(data->det_pin))
252 at91_set_gpio_input(data->det_pin, 1); 252 at91_set_gpio_input(data->det_pin, 1);
253 253
254 at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ 254 at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */
@@ -600,8 +600,8 @@ static void __init at91_add_device_tc(void) { }
600 600
601static struct resource rtt_resources[] = { 601static struct resource rtt_resources[] = {
602 { 602 {
603 .start = AT91_BASE_SYS + AT91_RTT, 603 .start = AT91SAM9261_BASE_RTT,
604 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, 604 .end = AT91SAM9261_BASE_RTT + SZ_16 - 1,
605 .flags = IORESOURCE_MEM, 605 .flags = IORESOURCE_MEM,
606 } 606 }
607}; 607};
@@ -624,10 +624,19 @@ static void __init at91_add_device_rtt(void)
624 * -------------------------------------------------------------------- */ 624 * -------------------------------------------------------------------- */
625 625
626#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 626#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
627static struct resource wdt_resources[] = {
628 {
629 .start = AT91SAM9261_BASE_WDT,
630 .end = AT91SAM9261_BASE_WDT + SZ_16 - 1,
631 .flags = IORESOURCE_MEM,
632 }
633};
634
627static struct platform_device at91sam9261_wdt_device = { 635static struct platform_device at91sam9261_wdt_device = {
628 .name = "at91_wdt", 636 .name = "at91_wdt",
629 .id = -1, 637 .id = -1,
630 .num_resources = 0, 638 .resource = wdt_resources,
639 .num_resources = ARRAY_SIZE(wdt_resources),
631}; 640};
632 641
633static void __init at91_add_device_watchdog(void) 642static void __init at91_add_device_watchdog(void)
@@ -816,8 +825,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
816#if defined(CONFIG_SERIAL_ATMEL) 825#if defined(CONFIG_SERIAL_ATMEL)
817static struct resource dbgu_resources[] = { 826static struct resource dbgu_resources[] = {
818 [0] = { 827 [0] = {
819 .start = AT91_BASE_SYS + AT91_DBGU, 828 .start = AT91SAM9261_BASE_DBGU,
820 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 829 .end = AT91SAM9261_BASE_DBGU + SZ_512 - 1,
821 .flags = IORESOURCE_MEM, 830 .flags = IORESOURCE_MEM,
822 }, 831 },
823 [1] = { 832 [1] = {
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 50d01631003..79e3669b111 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pm.h>
15 14
16#include <asm/irq.h> 15#include <asm/irq.h>
17#include <asm/mach/arch.h> 16#include <asm/mach/arch.h>
@@ -19,11 +18,11 @@
19#include <mach/at91sam9263.h> 18#include <mach/at91sam9263.h>
20#include <mach/at91_pmc.h> 19#include <mach/at91_pmc.h>
21#include <mach/at91_rstc.h> 20#include <mach/at91_rstc.h>
22#include <mach/at91_shdwc.h>
23 21
24#include "soc.h" 22#include "soc.h"
25#include "generic.h" 23#include "generic.h"
26#include "clock.h" 24#include "clock.h"
25#include "sam9_smc.h"
27 26
28/* -------------------------------------------------------------------- 27/* --------------------------------------------------------------------
29 * Clocks 28 * Clocks
@@ -118,7 +117,7 @@ static struct clk pwm_clk = {
118 .type = CLK_TYPE_PERIPHERAL, 117 .type = CLK_TYPE_PERIPHERAL,
119}; 118};
120static struct clk macb_clk = { 119static struct clk macb_clk = {
121 .name = "macb_clk", 120 .name = "pclk",
122 .pmc_mask = 1 << AT91SAM9263_ID_EMAC, 121 .pmc_mask = 1 << AT91SAM9263_ID_EMAC,
123 .type = CLK_TYPE_PERIPHERAL, 122 .type = CLK_TYPE_PERIPHERAL,
124}; 123};
@@ -182,6 +181,8 @@ static struct clk *periph_clocks[] __initdata = {
182}; 181};
183 182
184static struct clk_lookup periph_clocks_lookups[] = { 183static struct clk_lookup periph_clocks_lookups[] = {
184 /* One additional fake clock for macb_hclk */
185 CLKDEV_CON_ID("hclk", &macb_clk),
185 CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), 186 CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
186 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), 187 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
187 CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), 188 CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
@@ -191,6 +192,11 @@ static struct clk_lookup periph_clocks_lookups[] = {
191 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), 192 CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
192 /* fake hclk clock */ 193 /* fake hclk clock */
193 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), 194 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
195 CLKDEV_CON_ID("pioA", &pioA_clk),
196 CLKDEV_CON_ID("pioB", &pioB_clk),
197 CLKDEV_CON_ID("pioC", &pioCDE_clk),
198 CLKDEV_CON_ID("pioD", &pioCDE_clk),
199 CLKDEV_CON_ID("pioE", &pioCDE_clk),
194}; 200};
195 201
196static struct clk_lookup usart_clocks_lookups[] = { 202static struct clk_lookup usart_clocks_lookups[] = {
@@ -263,36 +269,25 @@ void __init at91sam9263_set_console_clock(int id)
263 * GPIO 269 * GPIO
264 * -------------------------------------------------------------------- */ 270 * -------------------------------------------------------------------- */
265 271
266static struct at91_gpio_bank at91sam9263_gpio[] = { 272static struct at91_gpio_bank at91sam9263_gpio[] __initdata = {
267 { 273 {
268 .id = AT91SAM9263_ID_PIOA, 274 .id = AT91SAM9263_ID_PIOA,
269 .offset = AT91_PIOA, 275 .regbase = AT91SAM9263_BASE_PIOA,
270 .clock = &pioA_clk,
271 }, { 276 }, {
272 .id = AT91SAM9263_ID_PIOB, 277 .id = AT91SAM9263_ID_PIOB,
273 .offset = AT91_PIOB, 278 .regbase = AT91SAM9263_BASE_PIOB,
274 .clock = &pioB_clk,
275 }, { 279 }, {
276 .id = AT91SAM9263_ID_PIOCDE, 280 .id = AT91SAM9263_ID_PIOCDE,
277 .offset = AT91_PIOC, 281 .regbase = AT91SAM9263_BASE_PIOC,
278 .clock = &pioCDE_clk,
279 }, { 282 }, {
280 .id = AT91SAM9263_ID_PIOCDE, 283 .id = AT91SAM9263_ID_PIOCDE,
281 .offset = AT91_PIOD, 284 .regbase = AT91SAM9263_BASE_PIOD,
282 .clock = &pioCDE_clk,
283 }, { 285 }, {
284 .id = AT91SAM9263_ID_PIOCDE, 286 .id = AT91SAM9263_ID_PIOCDE,
285 .offset = AT91_PIOE, 287 .regbase = AT91SAM9263_BASE_PIOE,
286 .clock = &pioCDE_clk,
287 } 288 }
288}; 289};
289 290
290static void at91sam9263_poweroff(void)
291{
292 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
293}
294
295
296/* -------------------------------------------------------------------- 291/* --------------------------------------------------------------------
297 * AT91SAM9263 processor initialization 292 * AT91SAM9263 processor initialization
298 * -------------------------------------------------------------------- */ 293 * -------------------------------------------------------------------- */
@@ -303,10 +298,17 @@ static void __init at91sam9263_map_io(void)
303 at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE); 298 at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE);
304} 299}
305 300
301static void __init at91sam9263_ioremap_registers(void)
302{
303 at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC);
304 at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT);
305 at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0);
306 at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
307}
308
306static void __init at91sam9263_initialize(void) 309static void __init at91sam9263_initialize(void)
307{ 310{
308 arm_pm_restart = at91sam9_alt_restart; 311 arm_pm_restart = at91sam9_alt_restart;
309 pm_power_off = at91sam9263_poweroff;
310 at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1); 312 at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
311 313
312 /* Register GPIO subsystem */ 314 /* Register GPIO subsystem */
@@ -358,6 +360,7 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
358struct at91_init_soc __initdata at91sam9263_soc = { 360struct at91_init_soc __initdata at91sam9263_soc = {
359 .map_io = at91sam9263_map_io, 361 .map_io = at91sam9263_map_io,
360 .default_irq_priority = at91sam9263_default_irq_priority, 362 .default_irq_priority = at91sam9263_default_irq_priority,
363 .ioremap_registers = at91sam9263_ioremap_registers,
361 .register_clocks = at91sam9263_register_clocks, 364 .register_clocks = at91sam9263_register_clocks,
362 .init = at91sam9263_initialize, 365 .init = at91sam9263_initialize,
363}; 366};
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index d5fbac9ff4f..7b46b278702 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -70,7 +70,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
70 70
71 /* Enable VBus control for UHP ports */ 71 /* Enable VBus control for UHP ports */
72 for (i = 0; i < data->ports; i++) { 72 for (i = 0; i < data->ports; i++) {
73 if (data->vbus_pin[i]) 73 if (gpio_is_valid(data->vbus_pin[i]))
74 at91_set_gpio_output(data->vbus_pin[i], 0); 74 at91_set_gpio_output(data->vbus_pin[i], 0);
75 } 75 }
76 76
@@ -123,7 +123,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data)
123 if (!data) 123 if (!data)
124 return; 124 return;
125 125
126 if (data->vbus_pin) { 126 if (gpio_is_valid(data->vbus_pin)) {
127 at91_set_gpio_input(data->vbus_pin, 0); 127 at91_set_gpio_input(data->vbus_pin, 0);
128 at91_set_deglitch(data->vbus_pin, 1); 128 at91_set_deglitch(data->vbus_pin, 1);
129 } 129 }
@@ -144,7 +144,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
144 144
145#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 145#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
146static u64 eth_dmamask = DMA_BIT_MASK(32); 146static u64 eth_dmamask = DMA_BIT_MASK(32);
147static struct at91_eth_data eth_data; 147static struct macb_platform_data eth_data;
148 148
149static struct resource eth_resources[] = { 149static struct resource eth_resources[] = {
150 [0] = { 150 [0] = {
@@ -171,12 +171,12 @@ static struct platform_device at91sam9263_eth_device = {
171 .num_resources = ARRAY_SIZE(eth_resources), 171 .num_resources = ARRAY_SIZE(eth_resources),
172}; 172};
173 173
174void __init at91_add_device_eth(struct at91_eth_data *data) 174void __init at91_add_device_eth(struct macb_platform_data *data)
175{ 175{
176 if (!data) 176 if (!data)
177 return; 177 return;
178 178
179 if (data->phy_irq_pin) { 179 if (gpio_is_valid(data->phy_irq_pin)) {
180 at91_set_gpio_input(data->phy_irq_pin, 0); 180 at91_set_gpio_input(data->phy_irq_pin, 0);
181 at91_set_deglitch(data->phy_irq_pin, 1); 181 at91_set_deglitch(data->phy_irq_pin, 1);
182 } 182 }
@@ -208,7 +208,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
208 platform_device_register(&at91sam9263_eth_device); 208 platform_device_register(&at91sam9263_eth_device);
209} 209}
210#else 210#else
211void __init at91_add_device_eth(struct at91_eth_data *data) {} 211void __init at91_add_device_eth(struct macb_platform_data *data) {}
212#endif 212#endif
213 213
214 214
@@ -276,13 +276,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
276 return; 276 return;
277 277
278 /* input/irq */ 278 /* input/irq */
279 if (data->det_pin) { 279 if (gpio_is_valid(data->det_pin)) {
280 at91_set_gpio_input(data->det_pin, 1); 280 at91_set_gpio_input(data->det_pin, 1);
281 at91_set_deglitch(data->det_pin, 1); 281 at91_set_deglitch(data->det_pin, 1);
282 } 282 }
283 if (data->wp_pin) 283 if (gpio_is_valid(data->wp_pin))
284 at91_set_gpio_input(data->wp_pin, 1); 284 at91_set_gpio_input(data->wp_pin, 1);
285 if (data->vcc_pin) 285 if (gpio_is_valid(data->vcc_pin))
286 at91_set_gpio_output(data->vcc_pin, 0); 286 at91_set_gpio_output(data->vcc_pin, 0);
287 287
288 if (mmc_id == 0) { /* MCI0 */ 288 if (mmc_id == 0) { /* MCI0 */
@@ -430,17 +430,17 @@ void __init at91_add_device_cf(struct at91_cf_data *data)
430 } 430 }
431 at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa); 431 at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
432 432
433 if (data->det_pin) { 433 if (gpio_is_valid(data->det_pin)) {
434 at91_set_gpio_input(data->det_pin, 1); 434 at91_set_gpio_input(data->det_pin, 1);
435 at91_set_deglitch(data->det_pin, 1); 435 at91_set_deglitch(data->det_pin, 1);
436 } 436 }
437 437
438 if (data->irq_pin) { 438 if (gpio_is_valid(data->irq_pin)) {
439 at91_set_gpio_input(data->irq_pin, 1); 439 at91_set_gpio_input(data->irq_pin, 1);
440 at91_set_deglitch(data->irq_pin, 1); 440 at91_set_deglitch(data->irq_pin, 1);
441 } 441 }
442 442
443 if (data->vcc_pin) 443 if (gpio_is_valid(data->vcc_pin))
444 /* initially off */ 444 /* initially off */
445 at91_set_gpio_output(data->vcc_pin, 0); 445 at91_set_gpio_output(data->vcc_pin, 0);
446 446
@@ -473,8 +473,8 @@ static struct resource nand_resources[] = {
473 .flags = IORESOURCE_MEM, 473 .flags = IORESOURCE_MEM,
474 }, 474 },
475 [1] = { 475 [1] = {
476 .start = AT91_BASE_SYS + AT91_ECC0, 476 .start = AT91SAM9263_BASE_ECC0,
477 .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1, 477 .end = AT91SAM9263_BASE_ECC0 + SZ_512 - 1,
478 .flags = IORESOURCE_MEM, 478 .flags = IORESOURCE_MEM,
479 } 479 }
480}; 480};
@@ -500,15 +500,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
500 at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA); 500 at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
501 501
502 /* enable pin */ 502 /* enable pin */
503 if (data->enable_pin) 503 if (gpio_is_valid(data->enable_pin))
504 at91_set_gpio_output(data->enable_pin, 1); 504 at91_set_gpio_output(data->enable_pin, 1);
505 505
506 /* ready/busy pin */ 506 /* ready/busy pin */
507 if (data->rdy_pin) 507 if (gpio_is_valid(data->rdy_pin))
508 at91_set_gpio_input(data->rdy_pin, 1); 508 at91_set_gpio_input(data->rdy_pin, 1);
509 509
510 /* card detect pin */ 510 /* card detect pin */
511 if (data->det_pin) 511 if (gpio_is_valid(data->det_pin))
512 at91_set_gpio_input(data->det_pin, 1); 512 at91_set_gpio_input(data->det_pin, 1);
513 513
514 nand_data = *data; 514 nand_data = *data;
@@ -749,7 +749,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
749 at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ 749 at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */
750 750
751 /* reset */ 751 /* reset */
752 if (data->reset_pin) 752 if (gpio_is_valid(data->reset_pin))
753 at91_set_gpio_output(data->reset_pin, 0); 753 at91_set_gpio_output(data->reset_pin, 0);
754 754
755 ac97_data = *data; 755 ac97_data = *data;
@@ -956,8 +956,8 @@ static void __init at91_add_device_tc(void) { }
956 956
957static struct resource rtt0_resources[] = { 957static struct resource rtt0_resources[] = {
958 { 958 {
959 .start = AT91_BASE_SYS + AT91_RTT0, 959 .start = AT91SAM9263_BASE_RTT0,
960 .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1, 960 .end = AT91SAM9263_BASE_RTT0 + SZ_16 - 1,
961 .flags = IORESOURCE_MEM, 961 .flags = IORESOURCE_MEM,
962 } 962 }
963}; 963};
@@ -971,8 +971,8 @@ static struct platform_device at91sam9263_rtt0_device = {
971 971
972static struct resource rtt1_resources[] = { 972static struct resource rtt1_resources[] = {
973 { 973 {
974 .start = AT91_BASE_SYS + AT91_RTT1, 974 .start = AT91SAM9263_BASE_RTT1,
975 .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1, 975 .end = AT91SAM9263_BASE_RTT1 + SZ_16 - 1,
976 .flags = IORESOURCE_MEM, 976 .flags = IORESOURCE_MEM,
977 } 977 }
978}; 978};
@@ -996,10 +996,19 @@ static void __init at91_add_device_rtt(void)
996 * -------------------------------------------------------------------- */ 996 * -------------------------------------------------------------------- */
997 997
998#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 998#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
999static struct resource wdt_resources[] = {
1000 {
1001 .start = AT91SAM9263_BASE_WDT,
1002 .end = AT91SAM9263_BASE_WDT + SZ_16 - 1,
1003 .flags = IORESOURCE_MEM,
1004 }
1005};
1006
999static struct platform_device at91sam9263_wdt_device = { 1007static struct platform_device at91sam9263_wdt_device = {
1000 .name = "at91_wdt", 1008 .name = "at91_wdt",
1001 .id = -1, 1009 .id = -1,
1002 .num_resources = 0, 1010 .resource = wdt_resources,
1011 .num_resources = ARRAY_SIZE(wdt_resources),
1003}; 1012};
1004 1013
1005static void __init at91_add_device_watchdog(void) 1014static void __init at91_add_device_watchdog(void)
@@ -1196,8 +1205,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1196 1205
1197static struct resource dbgu_resources[] = { 1206static struct resource dbgu_resources[] = {
1198 [0] = { 1207 [0] = {
1199 .start = AT91_BASE_SYS + AT91_DBGU, 1208 .start = AT91SAM9263_BASE_DBGU,
1200 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 1209 .end = AT91SAM9263_BASE_DBGU + SZ_512 - 1,
1201 .flags = IORESOURCE_MEM, 1210 .flags = IORESOURCE_MEM,
1202 }, 1211 },
1203 [1] = { 1212 [1] = {
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 4ba85499fa9..d89ead740a9 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -25,7 +25,17 @@
25 25
26static u32 pit_cycle; /* write-once */ 26static u32 pit_cycle; /* write-once */
27static u32 pit_cnt; /* access only w/system irq blocked */ 27static u32 pit_cnt; /* access only w/system irq blocked */
28static void __iomem *pit_base_addr __read_mostly;
28 29
30static inline unsigned int pit_read(unsigned int reg_offset)
31{
32 return __raw_readl(pit_base_addr + reg_offset);
33}
34
35static inline void pit_write(unsigned int reg_offset, unsigned long value)
36{
37 __raw_writel(value, pit_base_addr + reg_offset);
38}
29 39
30/* 40/*
31 * Clocksource: just a monotonic counter of MCK/16 cycles. 41 * Clocksource: just a monotonic counter of MCK/16 cycles.
@@ -39,7 +49,7 @@ static cycle_t read_pit_clk(struct clocksource *cs)
39 49
40 raw_local_irq_save(flags); 50 raw_local_irq_save(flags);
41 elapsed = pit_cnt; 51 elapsed = pit_cnt;
42 t = at91_sys_read(AT91_PIT_PIIR); 52 t = pit_read(AT91_PIT_PIIR);
43 raw_local_irq_restore(flags); 53 raw_local_irq_restore(flags);
44 54
45 elapsed += PIT_PICNT(t) * pit_cycle; 55 elapsed += PIT_PICNT(t) * pit_cycle;
@@ -64,8 +74,8 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
64 switch (mode) { 74 switch (mode) {
65 case CLOCK_EVT_MODE_PERIODIC: 75 case CLOCK_EVT_MODE_PERIODIC:
66 /* update clocksource counter */ 76 /* update clocksource counter */
67 pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); 77 pit_cnt += pit_cycle * PIT_PICNT(pit_read(AT91_PIT_PIVR));
68 at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN 78 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
69 | AT91_PIT_PITIEN); 79 | AT91_PIT_PITIEN);
70 break; 80 break;
71 case CLOCK_EVT_MODE_ONESHOT: 81 case CLOCK_EVT_MODE_ONESHOT:
@@ -74,7 +84,7 @@ pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
74 case CLOCK_EVT_MODE_SHUTDOWN: 84 case CLOCK_EVT_MODE_SHUTDOWN:
75 case CLOCK_EVT_MODE_UNUSED: 85 case CLOCK_EVT_MODE_UNUSED:
76 /* disable irq, leaving the clocksource active */ 86 /* disable irq, leaving the clocksource active */
77 at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); 87 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
78 break; 88 break;
79 case CLOCK_EVT_MODE_RESUME: 89 case CLOCK_EVT_MODE_RESUME:
80 break; 90 break;
@@ -103,11 +113,11 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
103 113
104 /* The PIT interrupt may be disabled, and is shared */ 114 /* The PIT interrupt may be disabled, and is shared */
105 if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC) 115 if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
106 && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) { 116 && (pit_read(AT91_PIT_SR) & AT91_PIT_PITS)) {
107 unsigned nr_ticks; 117 unsigned nr_ticks;
108 118
109 /* Get number of ticks performed before irq, and ack it */ 119 /* Get number of ticks performed before irq, and ack it */
110 nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); 120 nr_ticks = PIT_PICNT(pit_read(AT91_PIT_PIVR));
111 do { 121 do {
112 pit_cnt += pit_cycle; 122 pit_cnt += pit_cycle;
113 pit_clkevt.event_handler(&pit_clkevt); 123 pit_clkevt.event_handler(&pit_clkevt);
@@ -129,14 +139,14 @@ static struct irqaction at91sam926x_pit_irq = {
129static void at91sam926x_pit_reset(void) 139static void at91sam926x_pit_reset(void)
130{ 140{
131 /* Disable timer and irqs */ 141 /* Disable timer and irqs */
132 at91_sys_write(AT91_PIT_MR, 0); 142 pit_write(AT91_PIT_MR, 0);
133 143
134 /* Clear any pending interrupts, wait for PIT to stop counting */ 144 /* Clear any pending interrupts, wait for PIT to stop counting */
135 while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0) 145 while (PIT_CPIV(pit_read(AT91_PIT_PIVR)) != 0)
136 cpu_relax(); 146 cpu_relax();
137 147
138 /* Start PIT but don't enable IRQ */ 148 /* Start PIT but don't enable IRQ */
139 at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN); 149 pit_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
140} 150}
141 151
142/* 152/*
@@ -178,7 +188,15 @@ static void __init at91sam926x_pit_init(void)
178static void at91sam926x_pit_suspend(void) 188static void at91sam926x_pit_suspend(void)
179{ 189{
180 /* Disable timer */ 190 /* Disable timer */
181 at91_sys_write(AT91_PIT_MR, 0); 191 pit_write(AT91_PIT_MR, 0);
192}
193
194void __init at91sam926x_ioremap_pit(u32 addr)
195{
196 pit_base_addr = ioremap(addr, 16);
197
198 if (!pit_base_addr)
199 panic("Impossible to ioremap PIT\n");
182} 200}
183 201
184struct sys_timer at91sam926x_timer = { 202struct sys_timer at91sam926x_timer = {
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index ff21f7a60c6..7032dd32cdf 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/pm.h>
15#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
16 15
17#include <asm/irq.h> 16#include <asm/irq.h>
@@ -20,12 +19,12 @@
20#include <mach/at91sam9g45.h> 19#include <mach/at91sam9g45.h>
21#include <mach/at91_pmc.h> 20#include <mach/at91_pmc.h>
22#include <mach/at91_rstc.h> 21#include <mach/at91_rstc.h>
23#include <mach/at91_shdwc.h>
24#include <mach/cpu.h> 22#include <mach/cpu.h>
25 23
26#include "soc.h" 24#include "soc.h"
27#include "generic.h" 25#include "generic.h"
28#include "clock.h" 26#include "clock.h"
27#include "sam9_smc.h"
29 28
30/* -------------------------------------------------------------------- 29/* --------------------------------------------------------------------
31 * Clocks 30 * Clocks
@@ -150,7 +149,7 @@ static struct clk ac97_clk = {
150 .type = CLK_TYPE_PERIPHERAL, 149 .type = CLK_TYPE_PERIPHERAL,
151}; 150};
152static struct clk macb_clk = { 151static struct clk macb_clk = {
153 .name = "macb_clk", 152 .name = "pclk",
154 .pmc_mask = 1 << AT91SAM9G45_ID_EMAC, 153 .pmc_mask = 1 << AT91SAM9G45_ID_EMAC,
155 .type = CLK_TYPE_PERIPHERAL, 154 .type = CLK_TYPE_PERIPHERAL,
156}; 155};
@@ -209,6 +208,8 @@ static struct clk *periph_clocks[] __initdata = {
209}; 208};
210 209
211static struct clk_lookup periph_clocks_lookups[] = { 210static struct clk_lookup periph_clocks_lookups[] = {
211 /* One additional fake clock for macb_hclk */
212 CLKDEV_CON_ID("hclk", &macb_clk),
212 /* One additional fake clock for ohci */ 213 /* One additional fake clock for ohci */
213 CLKDEV_CON_ID("ohci_clk", &uhphs_clk), 214 CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
214 CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk), 215 CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
@@ -231,6 +232,11 @@ static struct clk_lookup periph_clocks_lookups[] = {
231 CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk), 232 CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk),
232 /* fake hclk clock */ 233 /* fake hclk clock */
233 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), 234 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
235 CLKDEV_CON_ID("pioA", &pioA_clk),
236 CLKDEV_CON_ID("pioB", &pioB_clk),
237 CLKDEV_CON_ID("pioC", &pioC_clk),
238 CLKDEV_CON_ID("pioD", &pioDE_clk),
239 CLKDEV_CON_ID("pioE", &pioDE_clk),
234}; 240};
235 241
236static struct clk_lookup usart_clocks_lookups[] = { 242static struct clk_lookup usart_clocks_lookups[] = {
@@ -293,27 +299,22 @@ void __init at91sam9g45_set_console_clock(int id)
293 * GPIO 299 * GPIO
294 * -------------------------------------------------------------------- */ 300 * -------------------------------------------------------------------- */
295 301
296static struct at91_gpio_bank at91sam9g45_gpio[] = { 302static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
297 { 303 {
298 .id = AT91SAM9G45_ID_PIOA, 304 .id = AT91SAM9G45_ID_PIOA,
299 .offset = AT91_PIOA, 305 .regbase = AT91SAM9G45_BASE_PIOA,
300 .clock = &pioA_clk,
301 }, { 306 }, {
302 .id = AT91SAM9G45_ID_PIOB, 307 .id = AT91SAM9G45_ID_PIOB,
303 .offset = AT91_PIOB, 308 .regbase = AT91SAM9G45_BASE_PIOB,
304 .clock = &pioB_clk,
305 }, { 309 }, {
306 .id = AT91SAM9G45_ID_PIOC, 310 .id = AT91SAM9G45_ID_PIOC,
307 .offset = AT91_PIOC, 311 .regbase = AT91SAM9G45_BASE_PIOC,
308 .clock = &pioC_clk,
309 }, { 312 }, {
310 .id = AT91SAM9G45_ID_PIODE, 313 .id = AT91SAM9G45_ID_PIODE,
311 .offset = AT91_PIOD, 314 .regbase = AT91SAM9G45_BASE_PIOD,
312 .clock = &pioDE_clk,
313 }, { 315 }, {
314 .id = AT91SAM9G45_ID_PIODE, 316 .id = AT91SAM9G45_ID_PIODE,
315 .offset = AT91_PIOE, 317 .regbase = AT91SAM9G45_BASE_PIOE,
316 .clock = &pioDE_clk,
317 } 318 }
318}; 319};
319 320
@@ -322,12 +323,6 @@ static void at91sam9g45_restart(char mode, const char *cmd)
322 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 323 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
323} 324}
324 325
325static void at91sam9g45_poweroff(void)
326{
327 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
328}
329
330
331/* -------------------------------------------------------------------- 326/* --------------------------------------------------------------------
332 * AT91SAM9G45 processor initialization 327 * AT91SAM9G45 processor initialization
333 * -------------------------------------------------------------------- */ 328 * -------------------------------------------------------------------- */
@@ -338,10 +333,16 @@ static void __init at91sam9g45_map_io(void)
338 init_consistent_dma_size(SZ_4M); 333 init_consistent_dma_size(SZ_4M);
339} 334}
340 335
336static void __init at91sam9g45_ioremap_registers(void)
337{
338 at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC);
339 at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT);
340 at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC);
341}
342
341static void __init at91sam9g45_initialize(void) 343static void __init at91sam9g45_initialize(void)
342{ 344{
343 arm_pm_restart = at91sam9g45_restart; 345 arm_pm_restart = at91sam9g45_restart;
344 pm_power_off = at91sam9g45_poweroff;
345 at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0); 346 at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
346 347
347 /* Register GPIO subsystem */ 348 /* Register GPIO subsystem */
@@ -393,6 +394,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
393struct at91_init_soc __initdata at91sam9g45_soc = { 394struct at91_init_soc __initdata at91sam9g45_soc = {
394 .map_io = at91sam9g45_map_io, 395 .map_io = at91sam9g45_map_io,
395 .default_irq_priority = at91sam9g45_default_irq_priority, 396 .default_irq_priority = at91sam9g45_default_irq_priority,
397 .ioremap_registers = at91sam9g45_ioremap_registers,
396 .register_clocks = at91sam9g45_register_clocks, 398 .register_clocks = at91sam9g45_register_clocks,
397 .init = at91sam9g45_initialize, 399 .init = at91sam9g45_initialize,
398}; 400};
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index 09a16d6bd5c..b7582dd10dc 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -44,8 +44,8 @@ static struct at_dma_platform_data atdma_pdata = {
44 44
45static struct resource hdmac_resources[] = { 45static struct resource hdmac_resources[] = {
46 [0] = { 46 [0] = {
47 .start = AT91_BASE_SYS + AT91_DMA, 47 .start = AT91SAM9G45_BASE_DMA,
48 .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, 48 .end = AT91SAM9G45_BASE_DMA + SZ_512 - 1,
49 .flags = IORESOURCE_MEM, 49 .flags = IORESOURCE_MEM,
50 }, 50 },
51 [1] = { 51 [1] = {
@@ -120,7 +120,7 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
120 120
121 /* Enable VBus control for UHP ports */ 121 /* Enable VBus control for UHP ports */
122 for (i = 0; i < data->ports; i++) { 122 for (i = 0; i < data->ports; i++) {
123 if (data->vbus_pin[i]) 123 if (gpio_is_valid(data->vbus_pin[i]))
124 at91_set_gpio_output(data->vbus_pin[i], 0); 124 at91_set_gpio_output(data->vbus_pin[i], 0);
125 } 125 }
126 126
@@ -181,7 +181,7 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
181 181
182 /* Enable VBus control for UHP ports */ 182 /* Enable VBus control for UHP ports */
183 for (i = 0; i < data->ports; i++) { 183 for (i = 0; i < data->ports; i++) {
184 if (data->vbus_pin[i]) 184 if (gpio_is_valid(data->vbus_pin[i]))
185 at91_set_gpio_output(data->vbus_pin[i], 0); 185 at91_set_gpio_output(data->vbus_pin[i], 0);
186 } 186 }
187 187
@@ -263,7 +263,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data)
263 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); 263 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
264 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); 264 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
265 265
266 if (data && data->vbus_pin > 0) { 266 if (data && gpio_is_valid(data->vbus_pin)) {
267 at91_set_gpio_input(data->vbus_pin, 0); 267 at91_set_gpio_input(data->vbus_pin, 0);
268 at91_set_deglitch(data->vbus_pin, 1); 268 at91_set_deglitch(data->vbus_pin, 1);
269 usba_udc_data.pdata.vbus_pin = data->vbus_pin; 269 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
@@ -284,7 +284,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data) {}
284 284
285#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 285#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
286static u64 eth_dmamask = DMA_BIT_MASK(32); 286static u64 eth_dmamask = DMA_BIT_MASK(32);
287static struct at91_eth_data eth_data; 287static struct macb_platform_data eth_data;
288 288
289static struct resource eth_resources[] = { 289static struct resource eth_resources[] = {
290 [0] = { 290 [0] = {
@@ -311,12 +311,12 @@ static struct platform_device at91sam9g45_eth_device = {
311 .num_resources = ARRAY_SIZE(eth_resources), 311 .num_resources = ARRAY_SIZE(eth_resources),
312}; 312};
313 313
314void __init at91_add_device_eth(struct at91_eth_data *data) 314void __init at91_add_device_eth(struct macb_platform_data *data)
315{ 315{
316 if (!data) 316 if (!data)
317 return; 317 return;
318 318
319 if (data->phy_irq_pin) { 319 if (gpio_is_valid(data->phy_irq_pin)) {
320 at91_set_gpio_input(data->phy_irq_pin, 0); 320 at91_set_gpio_input(data->phy_irq_pin, 0);
321 at91_set_deglitch(data->phy_irq_pin, 1); 321 at91_set_deglitch(data->phy_irq_pin, 1);
322 } 322 }
@@ -348,7 +348,7 @@ void __init at91_add_device_eth(struct at91_eth_data *data)
348 platform_device_register(&at91sam9g45_eth_device); 348 platform_device_register(&at91sam9g45_eth_device);
349} 349}
350#else 350#else
351void __init at91_add_device_eth(struct at91_eth_data *data) {} 351void __init at91_add_device_eth(struct macb_platform_data *data) {}
352#endif 352#endif
353 353
354 354
@@ -449,11 +449,11 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
449 449
450 450
451 /* input/irq */ 451 /* input/irq */
452 if (data->slot[0].detect_pin) { 452 if (gpio_is_valid(data->slot[0].detect_pin)) {
453 at91_set_gpio_input(data->slot[0].detect_pin, 1); 453 at91_set_gpio_input(data->slot[0].detect_pin, 1);
454 at91_set_deglitch(data->slot[0].detect_pin, 1); 454 at91_set_deglitch(data->slot[0].detect_pin, 1);
455 } 455 }
456 if (data->slot[0].wp_pin) 456 if (gpio_is_valid(data->slot[0].wp_pin))
457 at91_set_gpio_input(data->slot[0].wp_pin, 1); 457 at91_set_gpio_input(data->slot[0].wp_pin, 1);
458 458
459 if (mmc_id == 0) { /* MCI0 */ 459 if (mmc_id == 0) { /* MCI0 */
@@ -529,8 +529,8 @@ static struct resource nand_resources[] = {
529 .flags = IORESOURCE_MEM, 529 .flags = IORESOURCE_MEM,
530 }, 530 },
531 [1] = { 531 [1] = {
532 .start = AT91_BASE_SYS + AT91_ECC, 532 .start = AT91SAM9G45_BASE_ECC,
533 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, 533 .end = AT91SAM9G45_BASE_ECC + SZ_512 - 1,
534 .flags = IORESOURCE_MEM, 534 .flags = IORESOURCE_MEM,
535 } 535 }
536}; 536};
@@ -556,15 +556,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
556 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA); 556 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
557 557
558 /* enable pin */ 558 /* enable pin */
559 if (data->enable_pin) 559 if (gpio_is_valid(data->enable_pin))
560 at91_set_gpio_output(data->enable_pin, 1); 560 at91_set_gpio_output(data->enable_pin, 1);
561 561
562 /* ready/busy pin */ 562 /* ready/busy pin */
563 if (data->rdy_pin) 563 if (gpio_is_valid(data->rdy_pin))
564 at91_set_gpio_input(data->rdy_pin, 1); 564 at91_set_gpio_input(data->rdy_pin, 1);
565 565
566 /* card detect pin */ 566 /* card detect pin */
567 if (data->det_pin) 567 if (gpio_is_valid(data->det_pin))
568 at91_set_gpio_input(data->det_pin, 1); 568 at91_set_gpio_input(data->det_pin, 1);
569 569
570 nand_data = *data; 570 nand_data = *data;
@@ -859,7 +859,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
859 at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */ 859 at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */
860 860
861 /* reset */ 861 /* reset */
862 if (data->reset_pin) 862 if (gpio_is_valid(data->reset_pin))
863 at91_set_gpio_output(data->reset_pin, 0); 863 at91_set_gpio_output(data->reset_pin, 0);
864 864
865 ac97_data = *data; 865 ac97_data = *data;
@@ -1009,10 +1009,24 @@ static void __init at91_add_device_tc(void) { }
1009 * -------------------------------------------------------------------- */ 1009 * -------------------------------------------------------------------- */
1010 1010
1011#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) 1011#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
1012static struct resource rtc_resources[] = {
1013 [0] = {
1014 .start = AT91SAM9G45_BASE_RTC,
1015 .end = AT91SAM9G45_BASE_RTC + SZ_256 - 1,
1016 .flags = IORESOURCE_MEM,
1017 },
1018 [1] = {
1019 .start = AT91_ID_SYS,
1020 .end = AT91_ID_SYS,
1021 .flags = IORESOURCE_IRQ,
1022 },
1023};
1024
1012static struct platform_device at91sam9g45_rtc_device = { 1025static struct platform_device at91sam9g45_rtc_device = {
1013 .name = "at91_rtc", 1026 .name = "at91_rtc",
1014 .id = -1, 1027 .id = -1,
1015 .num_resources = 0, 1028 .resource = rtc_resources,
1029 .num_resources = ARRAY_SIZE(rtc_resources),
1016}; 1030};
1017 1031
1018static void __init at91_add_device_rtc(void) 1032static void __init at91_add_device_rtc(void)
@@ -1081,8 +1095,8 @@ void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
1081 1095
1082static struct resource rtt_resources[] = { 1096static struct resource rtt_resources[] = {
1083 { 1097 {
1084 .start = AT91_BASE_SYS + AT91_RTT, 1098 .start = AT91SAM9G45_BASE_RTT,
1085 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, 1099 .end = AT91SAM9G45_BASE_RTT + SZ_16 - 1,
1086 .flags = IORESOURCE_MEM, 1100 .flags = IORESOURCE_MEM,
1087 } 1101 }
1088}; 1102};
@@ -1133,10 +1147,19 @@ static void __init at91_add_device_trng(void) {}
1133 * -------------------------------------------------------------------- */ 1147 * -------------------------------------------------------------------- */
1134 1148
1135#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 1149#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
1150static struct resource wdt_resources[] = {
1151 {
1152 .start = AT91SAM9G45_BASE_WDT,
1153 .end = AT91SAM9G45_BASE_WDT + SZ_16 - 1,
1154 .flags = IORESOURCE_MEM,
1155 }
1156};
1157
1136static struct platform_device at91sam9g45_wdt_device = { 1158static struct platform_device at91sam9g45_wdt_device = {
1137 .name = "at91_wdt", 1159 .name = "at91_wdt",
1138 .id = -1, 1160 .id = -1,
1139 .num_resources = 0, 1161 .resource = wdt_resources,
1162 .num_resources = ARRAY_SIZE(wdt_resources),
1140}; 1163};
1141 1164
1142static void __init at91_add_device_watchdog(void) 1165static void __init at91_add_device_watchdog(void)
@@ -1332,8 +1355,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
1332#if defined(CONFIG_SERIAL_ATMEL) 1355#if defined(CONFIG_SERIAL_ATMEL)
1333static struct resource dbgu_resources[] = { 1356static struct resource dbgu_resources[] = {
1334 [0] = { 1357 [0] = {
1335 .start = AT91_BASE_SYS + AT91_DBGU, 1358 .start = AT91SAM9G45_BASE_DBGU,
1336 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 1359 .end = AT91SAM9G45_BASE_DBGU + SZ_512 - 1,
1337 .flags = IORESOURCE_MEM, 1360 .flags = IORESOURCE_MEM,
1338 }, 1361 },
1339 [1] = { 1362 [1] = {
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 61cbb46f5b0..d6bcb1da11d 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/pm.h>
14 13
15#include <asm/irq.h> 14#include <asm/irq.h>
16#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
@@ -20,11 +19,11 @@
20#include <mach/at91sam9rl.h> 19#include <mach/at91sam9rl.h>
21#include <mach/at91_pmc.h> 20#include <mach/at91_pmc.h>
22#include <mach/at91_rstc.h> 21#include <mach/at91_rstc.h>
23#include <mach/at91_shdwc.h>
24 22
25#include "soc.h" 23#include "soc.h"
26#include "generic.h" 24#include "generic.h"
27#include "clock.h" 25#include "clock.h"
26#include "sam9_smc.h"
28 27
29/* -------------------------------------------------------------------- 28/* --------------------------------------------------------------------
30 * Clocks 29 * Clocks
@@ -184,6 +183,10 @@ static struct clk_lookup periph_clocks_lookups[] = {
184 CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), 183 CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
185 CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), 184 CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
186 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), 185 CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
186 CLKDEV_CON_ID("pioA", &pioA_clk),
187 CLKDEV_CON_ID("pioB", &pioB_clk),
188 CLKDEV_CON_ID("pioC", &pioC_clk),
189 CLKDEV_CON_ID("pioD", &pioD_clk),
187}; 190};
188 191
189static struct clk_lookup usart_clocks_lookups[] = { 192static struct clk_lookup usart_clocks_lookups[] = {
@@ -243,32 +246,22 @@ void __init at91sam9rl_set_console_clock(int id)
243 * GPIO 246 * GPIO
244 * -------------------------------------------------------------------- */ 247 * -------------------------------------------------------------------- */
245 248
246static struct at91_gpio_bank at91sam9rl_gpio[] = { 249static struct at91_gpio_bank at91sam9rl_gpio[] __initdata = {
247 { 250 {
248 .id = AT91SAM9RL_ID_PIOA, 251 .id = AT91SAM9RL_ID_PIOA,
249 .offset = AT91_PIOA, 252 .regbase = AT91SAM9RL_BASE_PIOA,
250 .clock = &pioA_clk,
251 }, { 253 }, {
252 .id = AT91SAM9RL_ID_PIOB, 254 .id = AT91SAM9RL_ID_PIOB,
253 .offset = AT91_PIOB, 255 .regbase = AT91SAM9RL_BASE_PIOB,
254 .clock = &pioB_clk,
255 }, { 256 }, {
256 .id = AT91SAM9RL_ID_PIOC, 257 .id = AT91SAM9RL_ID_PIOC,
257 .offset = AT91_PIOC, 258 .regbase = AT91SAM9RL_BASE_PIOC,
258 .clock = &pioC_clk,
259 }, { 259 }, {
260 .id = AT91SAM9RL_ID_PIOD, 260 .id = AT91SAM9RL_ID_PIOD,
261 .offset = AT91_PIOD, 261 .regbase = AT91SAM9RL_BASE_PIOD,
262 .clock = &pioD_clk,
263 } 262 }
264}; 263};
265 264
266static void at91sam9rl_poweroff(void)
267{
268 at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
269}
270
271
272/* -------------------------------------------------------------------- 265/* --------------------------------------------------------------------
273 * AT91SAM9RL processor initialization 266 * AT91SAM9RL processor initialization
274 * -------------------------------------------------------------------- */ 267 * -------------------------------------------------------------------- */
@@ -290,10 +283,16 @@ static void __init at91sam9rl_map_io(void)
290 at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size); 283 at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size);
291} 284}
292 285
286static void __init at91sam9rl_ioremap_registers(void)
287{
288 at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC);
289 at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT);
290 at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
291}
292
293static void __init at91sam9rl_initialize(void) 293static void __init at91sam9rl_initialize(void)
294{ 294{
295 arm_pm_restart = at91sam9_alt_restart; 295 arm_pm_restart = at91sam9_alt_restart;
296 pm_power_off = at91sam9rl_poweroff;
297 at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0); 296 at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
298 297
299 /* Register GPIO subsystem */ 298 /* Register GPIO subsystem */
@@ -345,6 +344,7 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
345struct at91_init_soc __initdata at91sam9rl_soc = { 344struct at91_init_soc __initdata at91sam9rl_soc = {
346 .map_io = at91sam9rl_map_io, 345 .map_io = at91sam9rl_map_io,
347 .default_irq_priority = at91sam9rl_default_irq_priority, 346 .default_irq_priority = at91sam9rl_default_irq_priority,
347 .ioremap_registers = at91sam9rl_ioremap_registers,
348 .register_clocks = at91sam9rl_register_clocks, 348 .register_clocks = at91sam9rl_register_clocks,
349 .init = at91sam9rl_initialize, 349 .init = at91sam9rl_initialize,
350}; 350};
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 628eb566d60..61908dce978 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -39,8 +39,8 @@ static struct at_dma_platform_data atdma_pdata = {
39 39
40static struct resource hdmac_resources[] = { 40static struct resource hdmac_resources[] = {
41 [0] = { 41 [0] = {
42 .start = AT91_BASE_SYS + AT91_DMA, 42 .start = AT91SAM9RL_BASE_DMA,
43 .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, 43 .end = AT91SAM9RL_BASE_DMA + SZ_512 - 1,
44 .flags = IORESOURCE_MEM, 44 .flags = IORESOURCE_MEM,
45 }, 45 },
46 [2] = { 46 [2] = {
@@ -147,7 +147,7 @@ void __init at91_add_device_usba(struct usba_platform_data *data)
147 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep); 147 usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
148 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep)); 148 memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
149 149
150 if (data && data->vbus_pin > 0) { 150 if (data && gpio_is_valid(data->vbus_pin)) {
151 at91_set_gpio_input(data->vbus_pin, 0); 151 at91_set_gpio_input(data->vbus_pin, 0);
152 at91_set_deglitch(data->vbus_pin, 1); 152 at91_set_deglitch(data->vbus_pin, 1);
153 usba_udc_data.pdata.vbus_pin = data->vbus_pin; 153 usba_udc_data.pdata.vbus_pin = data->vbus_pin;
@@ -201,13 +201,13 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
201 return; 201 return;
202 202
203 /* input/irq */ 203 /* input/irq */
204 if (data->det_pin) { 204 if (gpio_is_valid(data->det_pin)) {
205 at91_set_gpio_input(data->det_pin, 1); 205 at91_set_gpio_input(data->det_pin, 1);
206 at91_set_deglitch(data->det_pin, 1); 206 at91_set_deglitch(data->det_pin, 1);
207 } 207 }
208 if (data->wp_pin) 208 if (gpio_is_valid(data->wp_pin))
209 at91_set_gpio_input(data->wp_pin, 1); 209 at91_set_gpio_input(data->wp_pin, 1);
210 if (data->vcc_pin) 210 if (gpio_is_valid(data->vcc_pin))
211 at91_set_gpio_output(data->vcc_pin, 0); 211 at91_set_gpio_output(data->vcc_pin, 0);
212 212
213 /* CLK */ 213 /* CLK */
@@ -248,8 +248,8 @@ static struct resource nand_resources[] = {
248 .flags = IORESOURCE_MEM, 248 .flags = IORESOURCE_MEM,
249 }, 249 },
250 [1] = { 250 [1] = {
251 .start = AT91_BASE_SYS + AT91_ECC, 251 .start = AT91SAM9RL_BASE_ECC,
252 .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1, 252 .end = AT91SAM9RL_BASE_ECC + SZ_512 - 1,
253 .flags = IORESOURCE_MEM, 253 .flags = IORESOURCE_MEM,
254 } 254 }
255}; 255};
@@ -275,15 +275,15 @@ void __init at91_add_device_nand(struct atmel_nand_data *data)
275 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA); 275 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
276 276
277 /* enable pin */ 277 /* enable pin */
278 if (data->enable_pin) 278 if (gpio_is_valid(data->enable_pin))
279 at91_set_gpio_output(data->enable_pin, 1); 279 at91_set_gpio_output(data->enable_pin, 1);
280 280
281 /* ready/busy pin */ 281 /* ready/busy pin */
282 if (data->rdy_pin) 282 if (gpio_is_valid(data->rdy_pin))
283 at91_set_gpio_input(data->rdy_pin, 1); 283 at91_set_gpio_input(data->rdy_pin, 1);
284 284
285 /* card detect pin */ 285 /* card detect pin */
286 if (data->det_pin) 286 if (gpio_is_valid(data->det_pin))
287 at91_set_gpio_input(data->det_pin, 1); 287 at91_set_gpio_input(data->det_pin, 1);
288 288
289 at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */ 289 at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */
@@ -483,7 +483,7 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
483 at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */ 483 at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */
484 484
485 /* reset */ 485 /* reset */
486 if (data->reset_pin) 486 if (gpio_is_valid(data->reset_pin))
487 at91_set_gpio_output(data->reset_pin, 0); 487 at91_set_gpio_output(data->reset_pin, 0);
488 488
489 ac97_data = *data; 489 ac97_data = *data;
@@ -685,8 +685,8 @@ static void __init at91_add_device_rtc(void) {}
685 685
686static struct resource rtt_resources[] = { 686static struct resource rtt_resources[] = {
687 { 687 {
688 .start = AT91_BASE_SYS + AT91_RTT, 688 .start = AT91SAM9RL_BASE_RTT,
689 .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1, 689 .end = AT91SAM9RL_BASE_RTT + SZ_16 - 1,
690 .flags = IORESOURCE_MEM, 690 .flags = IORESOURCE_MEM,
691 } 691 }
692}; 692};
@@ -709,10 +709,19 @@ static void __init at91_add_device_rtt(void)
709 * -------------------------------------------------------------------- */ 709 * -------------------------------------------------------------------- */
710 710
711#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE) 711#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
712static struct resource wdt_resources[] = {
713 {
714 .start = AT91SAM9RL_BASE_WDT,
715 .end = AT91SAM9RL_BASE_WDT + SZ_16 - 1,
716 .flags = IORESOURCE_MEM,
717 }
718};
719
712static struct platform_device at91sam9rl_wdt_device = { 720static struct platform_device at91sam9rl_wdt_device = {
713 .name = "at91_wdt", 721 .name = "at91_wdt",
714 .id = -1, 722 .id = -1,
715 .num_resources = 0, 723 .resource = wdt_resources,
724 .num_resources = ARRAY_SIZE(wdt_resources),
716}; 725};
717 726
718static void __init at91_add_device_watchdog(void) 727static void __init at91_add_device_watchdog(void)
@@ -908,8 +917,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
908#if defined(CONFIG_SERIAL_ATMEL) 917#if defined(CONFIG_SERIAL_ATMEL)
909static struct resource dbgu_resources[] = { 918static struct resource dbgu_resources[] = {
910 [0] = { 919 [0] = {
911 .start = AT91_BASE_SYS + AT91_DBGU, 920 .start = AT91SAM9RL_BASE_DBGU,
912 .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, 921 .end = AT91SAM9RL_BASE_DBGU + SZ_512 - 1,
913 .flags = IORESOURCE_MEM, 922 .flags = IORESOURCE_MEM,
914 }, 923 },
915 [1] = { 924 [1] = {
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
index 367d5cd5e36..2628384aaae 100644
--- a/arch/arm/mach-at91/board-1arm.c
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -63,13 +63,15 @@ static void __init onearm_init_early(void)
63 at91_set_serial_console(0); 63 at91_set_serial_console(0);
64} 64}
65 65
66static struct at91_eth_data __initdata onearm_eth_data = { 66static struct macb_platform_data __initdata onearm_eth_data = {
67 .phy_irq_pin = AT91_PIN_PC4, 67 .phy_irq_pin = AT91_PIN_PC4,
68 .is_rmii = 1, 68 .is_rmii = 1,
69}; 69};
70 70
71static struct at91_usbh_data __initdata onearm_usbh_data = { 71static struct at91_usbh_data __initdata onearm_usbh_data = {
72 .ports = 1, 72 .ports = 1,
73 .vbus_pin = {-EINVAL, -EINVAL},
74 .overcurrent_pin= {-EINVAL, -EINVAL},
73}; 75};
74 76
75static struct at91_udc_data __initdata onearm_udc_data = { 77static struct at91_udc_data __initdata onearm_udc_data = {
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 4282d96dffa..3bb40694b02 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -75,6 +75,8 @@ static void __init afeb9260_init_early(void)
75 */ 75 */
76static struct at91_usbh_data __initdata afeb9260_usbh_data = { 76static struct at91_usbh_data __initdata afeb9260_usbh_data = {
77 .ports = 1, 77 .ports = 1,
78 .vbus_pin = {-EINVAL, -EINVAL},
79 .overcurrent_pin= {-EINVAL, -EINVAL},
78}; 80};
79 81
80/* 82/*
@@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata afeb9260_usbh_data = {
82 */ 84 */
83static struct at91_udc_data __initdata afeb9260_udc_data = { 85static struct at91_udc_data __initdata afeb9260_udc_data = {
84 .vbus_pin = AT91_PIN_PC5, 86 .vbus_pin = AT91_PIN_PC5,
85 .pullup_pin = 0, /* pull-up driven by UDC */ 87 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
86}; 88};
87 89
88 90
@@ -103,7 +105,7 @@ static struct spi_board_info afeb9260_spi_devices[] = {
103/* 105/*
104 * MACB Ethernet device 106 * MACB Ethernet device
105 */ 107 */
106static struct at91_eth_data __initdata afeb9260_macb_data = { 108static struct macb_platform_data __initdata afeb9260_macb_data = {
107 .phy_irq_pin = AT91_PIN_PA9, 109 .phy_irq_pin = AT91_PIN_PA9,
108 .is_rmii = 0, 110 .is_rmii = 0,
109}; 111};
@@ -138,6 +140,7 @@ static struct atmel_nand_data __initdata afeb9260_nand_data = {
138 .bus_width_16 = 0, 140 .bus_width_16 = 0,
139 .parts = afeb9260_nand_partition, 141 .parts = afeb9260_nand_partition,
140 .num_parts = ARRAY_SIZE(afeb9260_nand_partition), 142 .num_parts = ARRAY_SIZE(afeb9260_nand_partition),
143 .det_pin = -EINVAL,
141}; 144};
142 145
143 146
@@ -149,6 +152,7 @@ static struct at91_mmc_data __initdata afeb9260_mmc_data = {
149 .wp_pin = AT91_PIN_PC4, 152 .wp_pin = AT91_PIN_PC4,
150 .slot_b = 1, 153 .slot_b = 1,
151 .wire4 = 1, 154 .wire4 = 1,
155 .vcc_pin = -EINVAL,
152}; 156};
153 157
154 158
@@ -169,6 +173,8 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
169static struct at91_cf_data afeb9260_cf_data = { 173static struct at91_cf_data afeb9260_cf_data = {
170 .chipselect = 4, 174 .chipselect = 4,
171 .irq_pin = AT91_PIN_PA6, 175 .irq_pin = AT91_PIN_PA6,
176 .det_pin = -EINVAL,
177 .vcc_pin = -EINVAL,
172 .rst_pin = AT91_PIN_PA7, 178 .rst_pin = AT91_PIN_PA7,
173 .flags = AT91_CF_TRUE_IDE, 179 .flags = AT91_CF_TRUE_IDE,
174}; 180};
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
index f90cfb32bad..8510e9e5498 100644
--- a/arch/arm/mach-at91/board-cam60.c
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -62,6 +62,8 @@ static void __init cam60_init_early(void)
62 */ 62 */
63static struct at91_usbh_data __initdata cam60_usbh_data = { 63static struct at91_usbh_data __initdata cam60_usbh_data = {
64 .ports = 1, 64 .ports = 1,
65 .vbus_pin = {-EINVAL, -EINVAL},
66 .overcurrent_pin= {-EINVAL, -EINVAL},
65}; 67};
66 68
67 69
@@ -115,7 +117,7 @@ static struct spi_board_info cam60_spi_devices[] __initdata = {
115/* 117/*
116 * MACB Ethernet device 118 * MACB Ethernet device
117 */ 119 */
118static struct __initdata at91_eth_data cam60_macb_data = { 120static struct __initdata macb_platform_data cam60_macb_data = {
119 .phy_irq_pin = AT91_PIN_PB5, 121 .phy_irq_pin = AT91_PIN_PB5,
120 .is_rmii = 0, 122 .is_rmii = 0,
121}; 123};
@@ -135,7 +137,7 @@ static struct mtd_partition __initdata cam60_nand_partition[] = {
135static struct atmel_nand_data __initdata cam60_nand_data = { 137static struct atmel_nand_data __initdata cam60_nand_data = {
136 .ale = 21, 138 .ale = 21,
137 .cle = 22, 139 .cle = 22,
138 // .det_pin = ... not there 140 .det_pin = -EINVAL,
139 .rdy_pin = AT91_PIN_PA9, 141 .rdy_pin = AT91_PIN_PA9,
140 .enable_pin = AT91_PIN_PA7, 142 .enable_pin = AT91_PIN_PA7,
141 .parts = cam60_nand_partition, 143 .parts = cam60_nand_partition,
@@ -163,7 +165,7 @@ static struct sam9_smc_config __initdata cam60_nand_smc_config = {
163static void __init cam60_add_device_nand(void) 165static void __init cam60_add_device_nand(void)
164{ 166{
165 /* configure chip-select 3 (NAND) */ 167 /* configure chip-select 3 (NAND) */
166 sam9_smc_configure(3, &cam60_nand_smc_config); 168 sam9_smc_configure(0, 3, &cam60_nand_smc_config);
167 169
168 at91_add_device_nand(&cam60_nand_data); 170 at91_add_device_nand(&cam60_nand_data);
169} 171}
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
index 5dffd3be62d..ac3de4f7c31 100644
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -70,6 +70,8 @@ static void __init cap9adk_init_early(void)
70 */ 70 */
71static struct at91_usbh_data __initdata cap9adk_usbh_data = { 71static struct at91_usbh_data __initdata cap9adk_usbh_data = {
72 .ports = 2, 72 .ports = 2,
73 .vbus_pin = {-EINVAL, -EINVAL},
74 .overcurrent_pin= {-EINVAL, -EINVAL},
73}; 75};
74 76
75/* 77/*
@@ -144,16 +146,17 @@ static struct spi_board_info cap9adk_spi_devices[] = {
144 */ 146 */
145static struct at91_mmc_data __initdata cap9adk_mmc_data = { 147static struct at91_mmc_data __initdata cap9adk_mmc_data = {
146 .wire4 = 1, 148 .wire4 = 1,
147// .det_pin = ... not connected 149 .det_pin = -EINVAL,
148// .wp_pin = ... not connected 150 .wp_pin = -EINVAL,
149// .vcc_pin = ... not connected 151 .vcc_pin = -EINVAL,
150}; 152};
151 153
152 154
153/* 155/*
154 * MACB Ethernet device 156 * MACB Ethernet device
155 */ 157 */
156static struct at91_eth_data __initdata cap9adk_macb_data = { 158static struct macb_platform_data __initdata cap9adk_macb_data = {
159 .phy_irq_pin = -EINVAL,
157 .is_rmii = 1, 160 .is_rmii = 1,
158}; 161};
159 162
@@ -172,8 +175,8 @@ static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
172static struct atmel_nand_data __initdata cap9adk_nand_data = { 175static struct atmel_nand_data __initdata cap9adk_nand_data = {
173 .ale = 21, 176 .ale = 21,
174 .cle = 22, 177 .cle = 22,
175// .det_pin = ... not connected 178 .det_pin = -EINVAL,
176// .rdy_pin = ... not connected 179 .rdy_pin = -EINVAL,
177 .enable_pin = AT91_PIN_PD15, 180 .enable_pin = AT91_PIN_PD15,
178 .parts = cap9adk_nand_partitions, 181 .parts = cap9adk_nand_partitions,
179 .num_parts = ARRAY_SIZE(cap9adk_nand_partitions), 182 .num_parts = ARRAY_SIZE(cap9adk_nand_partitions),
@@ -212,7 +215,7 @@ static void __init cap9adk_add_device_nand(void)
212 cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8; 215 cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8;
213 216
214 /* configure chip-select 3 (NAND) */ 217 /* configure chip-select 3 (NAND) */
215 sam9_smc_configure(3, &cap9adk_nand_smc_config); 218 sam9_smc_configure(0, 3, &cap9adk_nand_smc_config);
216 219
217 at91_add_device_nand(&cap9adk_nand_data); 220 at91_add_device_nand(&cap9adk_nand_data);
218} 221}
@@ -282,7 +285,7 @@ static __init void cap9adk_add_device_nor(void)
282 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V); 285 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
283 286
284 /* configure chip-select 0 (NOR) */ 287 /* configure chip-select 0 (NOR) */
285 sam9_smc_configure(0, &cap9adk_nor_smc_config); 288 sam9_smc_configure(0, 0, &cap9adk_nor_smc_config);
286 289
287 platform_device_register(&cap9adk_nor_flash); 290 platform_device_register(&cap9adk_nor_flash);
288} 291}
@@ -351,7 +354,7 @@ static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
351 * AC97 354 * AC97
352 */ 355 */
353static struct ac97c_platform_data cap9adk_ac97_data = { 356static struct ac97c_platform_data cap9adk_ac97_data = {
354// .reset_pin = ... not connected 357 .reset_pin = -EINVAL,
355}; 358};
356 359
357 360
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index 774c87fcbd5..59d9cf99753 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -57,13 +57,15 @@ static void __init carmeva_init_early(void)
57 at91_set_serial_console(0); 57 at91_set_serial_console(0);
58} 58}
59 59
60static struct at91_eth_data __initdata carmeva_eth_data = { 60static struct macb_platform_data __initdata carmeva_eth_data = {
61 .phy_irq_pin = AT91_PIN_PC4, 61 .phy_irq_pin = AT91_PIN_PC4,
62 .is_rmii = 1, 62 .is_rmii = 1,
63}; 63};
64 64
65static struct at91_usbh_data __initdata carmeva_usbh_data = { 65static struct at91_usbh_data __initdata carmeva_usbh_data = {
66 .ports = 2, 66 .ports = 2,
67 .vbus_pin = {-EINVAL, -EINVAL},
68 .overcurrent_pin= {-EINVAL, -EINVAL},
67}; 69};
68 70
69static struct at91_udc_data __initdata carmeva_udc_data = { 71static struct at91_udc_data __initdata carmeva_udc_data = {
@@ -75,8 +77,8 @@ static struct at91_udc_data __initdata carmeva_udc_data = {
75// static struct at91_cf_data __initdata carmeva_cf_data = { 77// static struct at91_cf_data __initdata carmeva_cf_data = {
76// .det_pin = AT91_PIN_PB0, 78// .det_pin = AT91_PIN_PB0,
77// .rst_pin = AT91_PIN_PC5, 79// .rst_pin = AT91_PIN_PC5,
78 // .irq_pin = ... not connected 80 // .irq_pin = -EINVAL,
79 // .vcc_pin = ... always powered 81 // .vcc_pin = -EINVAL,
80// }; 82// };
81 83
82static struct at91_mmc_data __initdata carmeva_mmc_data = { 84static struct at91_mmc_data __initdata carmeva_mmc_data = {
@@ -84,6 +86,7 @@ static struct at91_mmc_data __initdata carmeva_mmc_data = {
84 .wire4 = 1, 86 .wire4 = 1,
85 .det_pin = AT91_PIN_PB10, 87 .det_pin = AT91_PIN_PB10,
86 .wp_pin = AT91_PIN_PC14, 88 .wp_pin = AT91_PIN_PC14,
89 .vcc_pin = -EINVAL,
87}; 90};
88 91
89static struct spi_board_info carmeva_spi_devices[] = { 92static struct spi_board_info carmeva_spi_devices[] = {
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
index fc885a4ce24..9ab3d1ea326 100644
--- a/arch/arm/mach-at91/board-cpu9krea.c
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -86,6 +86,8 @@ static void __init cpu9krea_init_early(void)
86 */ 86 */
87static struct at91_usbh_data __initdata cpu9krea_usbh_data = { 87static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
88 .ports = 2, 88 .ports = 2,
89 .vbus_pin = {-EINVAL, -EINVAL},
90 .overcurrent_pin= {-EINVAL, -EINVAL},
89}; 91};
90 92
91/* 93/*
@@ -93,13 +95,14 @@ static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
93 */ 95 */
94static struct at91_udc_data __initdata cpu9krea_udc_data = { 96static struct at91_udc_data __initdata cpu9krea_udc_data = {
95 .vbus_pin = AT91_PIN_PC8, 97 .vbus_pin = AT91_PIN_PC8,
96 .pullup_pin = 0, /* pull-up driven by UDC */ 98 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
97}; 99};
98 100
99/* 101/*
100 * MACB Ethernet device 102 * MACB Ethernet device
101 */ 103 */
102static struct at91_eth_data __initdata cpu9krea_macb_data = { 104static struct macb_platform_data __initdata cpu9krea_macb_data = {
105 .phy_irq_pin = -EINVAL,
103 .is_rmii = 1, 106 .is_rmii = 1,
104}; 107};
105 108
@@ -112,6 +115,7 @@ static struct atmel_nand_data __initdata cpu9krea_nand_data = {
112 .rdy_pin = AT91_PIN_PC13, 115 .rdy_pin = AT91_PIN_PC13,
113 .enable_pin = AT91_PIN_PC14, 116 .enable_pin = AT91_PIN_PC14,
114 .bus_width_16 = 0, 117 .bus_width_16 = 0,
118 .det_pin = -EINVAL,
115}; 119};
116 120
117#ifdef CONFIG_MACH_CPU9260 121#ifdef CONFIG_MACH_CPU9260
@@ -156,7 +160,7 @@ static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
156 160
157static void __init cpu9krea_add_device_nand(void) 161static void __init cpu9krea_add_device_nand(void)
158{ 162{
159 sam9_smc_configure(3, &cpu9krea_nand_smc_config); 163 sam9_smc_configure(0, 3, &cpu9krea_nand_smc_config);
160 at91_add_device_nand(&cpu9krea_nand_data); 164 at91_add_device_nand(&cpu9krea_nand_data);
161} 165}
162 166
@@ -238,7 +242,7 @@ static __init void cpu9krea_add_device_nor(void)
238 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V); 242 at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
239 243
240 /* configure chip-select 0 (NOR) */ 244 /* configure chip-select 0 (NOR) */
241 sam9_smc_configure(0, &cpu9krea_nor_smc_config); 245 sam9_smc_configure(0, 0, &cpu9krea_nor_smc_config);
242 246
243 platform_device_register(&cpu9krea_nor_flash); 247 platform_device_register(&cpu9krea_nor_flash);
244} 248}
@@ -337,6 +341,8 @@ static struct at91_mmc_data __initdata cpu9krea_mmc_data = {
337 .slot_b = 0, 341 .slot_b = 0,
338 .wire4 = 1, 342 .wire4 = 1,
339 .det_pin = AT91_PIN_PA29, 343 .det_pin = AT91_PIN_PA29,
344 .wp_pin = -EINVAL,
345 .vcc_pin = -EINVAL,
340}; 346};
341 347
342static void __init cpu9krea_board_init(void) 348static void __init cpu9krea_board_init(void)
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c
index d35e65b08cc..368e1427ad9 100644
--- a/arch/arm/mach-at91/board-cpuat91.c
+++ b/arch/arm/mach-at91/board-cpuat91.c
@@ -82,12 +82,15 @@ static void __init cpuat91_init_early(void)
82 at91_set_serial_console(0); 82 at91_set_serial_console(0);
83} 83}
84 84
85static struct at91_eth_data __initdata cpuat91_eth_data = { 85static struct macb_platform_data __initdata cpuat91_eth_data = {
86 .phy_irq_pin = -EINVAL,
86 .is_rmii = 1, 87 .is_rmii = 1,
87}; 88};
88 89
89static struct at91_usbh_data __initdata cpuat91_usbh_data = { 90static struct at91_usbh_data __initdata cpuat91_usbh_data = {
90 .ports = 1, 91 .ports = 1,
92 .vbus_pin = {-EINVAL, -EINVAL},
93 .overcurrent_pin= {-EINVAL, -EINVAL},
91}; 94};
92 95
93static struct at91_udc_data __initdata cpuat91_udc_data = { 96static struct at91_udc_data __initdata cpuat91_udc_data = {
@@ -98,6 +101,8 @@ static struct at91_udc_data __initdata cpuat91_udc_data = {
98static struct at91_mmc_data __initdata cpuat91_mmc_data = { 101static struct at91_mmc_data __initdata cpuat91_mmc_data = {
99 .det_pin = AT91_PIN_PC2, 102 .det_pin = AT91_PIN_PC2,
100 .wire4 = 1, 103 .wire4 = 1,
104 .wp_pin = -EINVAL,
105 .vcc_pin = -EINVAL,
101}; 106};
102 107
103static struct physmap_flash_data cpuat91_flash_data = { 108static struct physmap_flash_data cpuat91_flash_data = {
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index c3936665e64..1a1547b1ce4 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -58,18 +58,20 @@ static void __init csb337_init_early(void)
58 at91_set_serial_console(0); 58 at91_set_serial_console(0);
59} 59}
60 60
61static struct at91_eth_data __initdata csb337_eth_data = { 61static struct macb_platform_data __initdata csb337_eth_data = {
62 .phy_irq_pin = AT91_PIN_PC2, 62 .phy_irq_pin = AT91_PIN_PC2,
63 .is_rmii = 0, 63 .is_rmii = 0,
64}; 64};
65 65
66static struct at91_usbh_data __initdata csb337_usbh_data = { 66static struct at91_usbh_data __initdata csb337_usbh_data = {
67 .ports = 2, 67 .ports = 2,
68 .vbus_pin = {-EINVAL, -EINVAL},
69 .overcurrent_pin= {-EINVAL, -EINVAL},
68}; 70};
69 71
70static struct at91_udc_data __initdata csb337_udc_data = { 72static struct at91_udc_data __initdata csb337_udc_data = {
71 // this has no VBUS sensing pin
72 .pullup_pin = AT91_PIN_PA24, 73 .pullup_pin = AT91_PIN_PA24,
74 .vbus_pin = -EINVAL,
73}; 75};
74 76
75static struct i2c_board_info __initdata csb337_i2c_devices[] = { 77static struct i2c_board_info __initdata csb337_i2c_devices[] = {
@@ -98,6 +100,7 @@ static struct at91_mmc_data __initdata csb337_mmc_data = {
98 .slot_b = 0, 100 .slot_b = 0,
99 .wire4 = 1, 101 .wire4 = 1,
100 .wp_pin = AT91_PIN_PD6, 102 .wp_pin = AT91_PIN_PD6,
103 .vcc_pin = -EINVAL,
101}; 104};
102 105
103static struct spi_board_info csb337_spi_devices[] = { 106static struct spi_board_info csb337_spi_devices[] = {
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index 586100e2acb..f650bf39455 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -52,13 +52,15 @@ static void __init csb637_init_early(void)
52 at91_set_serial_console(0); 52 at91_set_serial_console(0);
53} 53}
54 54
55static struct at91_eth_data __initdata csb637_eth_data = { 55static struct macb_platform_data __initdata csb637_eth_data = {
56 .phy_irq_pin = AT91_PIN_PC0, 56 .phy_irq_pin = AT91_PIN_PC0,
57 .is_rmii = 0, 57 .is_rmii = 0,
58}; 58};
59 59
60static struct at91_usbh_data __initdata csb637_usbh_data = { 60static struct at91_usbh_data __initdata csb637_usbh_data = {
61 .ports = 2, 61 .ports = 2,
62 .vbus_pin = {-EINVAL, -EINVAL},
63 .overcurrent_pin= {-EINVAL, -EINVAL},
62}; 64};
63 65
64static struct at91_udc_data __initdata csb637_udc_data = { 66static struct at91_udc_data __initdata csb637_udc_data = {
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index 0b7d3277821..bb6b434ec0c 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -50,6 +50,7 @@ static void __init ek_init_early(void)
50static struct atmel_nand_data __initdata ek_nand_data = { 50static struct atmel_nand_data __initdata ek_nand_data = {
51 .ale = 21, 51 .ale = 21,
52 .cle = 22, 52 .cle = 22,
53 .det_pin = -EINVAL,
53 .rdy_pin = AT91_PIN_PC8, 54 .rdy_pin = AT91_PIN_PC8,
54 .enable_pin = AT91_PIN_PC14, 55 .enable_pin = AT91_PIN_PC14,
55}; 56};
@@ -82,7 +83,7 @@ static void __init ek_add_device_nand(void)
82 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 83 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
83 84
84 /* configure chip-select 3 (NAND) */ 85 /* configure chip-select 3 (NAND) */
85 sam9_smc_configure(3, &ek_nand_smc_config); 86 sam9_smc_configure(0, 3, &ek_nand_smc_config);
86 87
87 at91_add_device_nand(&ek_nand_data); 88 at91_add_device_nand(&ek_nand_data);
88} 89}
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index 45db7a3dbef..d302ca3eeb6 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -60,13 +60,15 @@ static void __init eb9200_init_early(void)
60 at91_set_serial_console(0); 60 at91_set_serial_console(0);
61} 61}
62 62
63static struct at91_eth_data __initdata eb9200_eth_data = { 63static struct macb_platform_data __initdata eb9200_eth_data = {
64 .phy_irq_pin = AT91_PIN_PC4, 64 .phy_irq_pin = AT91_PIN_PC4,
65 .is_rmii = 1, 65 .is_rmii = 1,
66}; 66};
67 67
68static struct at91_usbh_data __initdata eb9200_usbh_data = { 68static struct at91_usbh_data __initdata eb9200_usbh_data = {
69 .ports = 2, 69 .ports = 2,
70 .vbus_pin = {-EINVAL, -EINVAL},
71 .overcurrent_pin= {-EINVAL, -EINVAL},
70}; 72};
71 73
72static struct at91_udc_data __initdata eb9200_udc_data = { 74static struct at91_udc_data __initdata eb9200_udc_data = {
@@ -75,15 +77,18 @@ static struct at91_udc_data __initdata eb9200_udc_data = {
75}; 77};
76 78
77static struct at91_cf_data __initdata eb9200_cf_data = { 79static struct at91_cf_data __initdata eb9200_cf_data = {
80 .irq_pin = -EINVAL,
78 .det_pin = AT91_PIN_PB0, 81 .det_pin = AT91_PIN_PB0,
82 .vcc_pin = -EINVAL,
79 .rst_pin = AT91_PIN_PC5, 83 .rst_pin = AT91_PIN_PC5,
80 // .irq_pin = ... not connected
81 // .vcc_pin = ... always powered
82}; 84};
83 85
84static struct at91_mmc_data __initdata eb9200_mmc_data = { 86static struct at91_mmc_data __initdata eb9200_mmc_data = {
85 .slot_b = 0, 87 .slot_b = 0,
86 .wire4 = 1, 88 .wire4 = 1,
89 .det_pin = -EINVAL,
90 .wp_pin = -EINVAL,
91 .vcc_pin = -EINVAL,
87}; 92};
88 93
89static struct i2c_board_info __initdata eb9200_i2c_devices[] = { 94static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c
index 2f9c16d2921..69966ce4d77 100644
--- a/arch/arm/mach-at91/board-ecbat91.c
+++ b/arch/arm/mach-at91/board-ecbat91.c
@@ -64,18 +64,23 @@ static void __init ecb_at91init_early(void)
64 at91_set_serial_console(0); 64 at91_set_serial_console(0);
65} 65}
66 66
67static struct at91_eth_data __initdata ecb_at91eth_data = { 67static struct macb_platform_data __initdata ecb_at91eth_data = {
68 .phy_irq_pin = AT91_PIN_PC4, 68 .phy_irq_pin = AT91_PIN_PC4,
69 .is_rmii = 0, 69 .is_rmii = 0,
70}; 70};
71 71
72static struct at91_usbh_data __initdata ecb_at91usbh_data = { 72static struct at91_usbh_data __initdata ecb_at91usbh_data = {
73 .ports = 1, 73 .ports = 1,
74 .vbus_pin = {-EINVAL, -EINVAL},
75 .overcurrent_pin= {-EINVAL, -EINVAL},
74}; 76};
75 77
76static struct at91_mmc_data __initdata ecb_at91mmc_data = { 78static struct at91_mmc_data __initdata ecb_at91mmc_data = {
77 .slot_b = 0, 79 .slot_b = 0,
78 .wire4 = 1, 80 .wire4 = 1,
81 .det_pin = -EINVAL,
82 .wp_pin = -EINVAL,
83 .vcc_pin = -EINVAL,
79}; 84};
80 85
81 86
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c
index 8252c722607..07ef35b0ec2 100644
--- a/arch/arm/mach-at91/board-eco920.c
+++ b/arch/arm/mach-at91/board-eco920.c
@@ -47,13 +47,15 @@ static void __init eco920_init_early(void)
47 at91_set_serial_console(0); 47 at91_set_serial_console(0);
48} 48}
49 49
50static struct at91_eth_data __initdata eco920_eth_data = { 50static struct macb_platform_data __initdata eco920_eth_data = {
51 .phy_irq_pin = AT91_PIN_PC2, 51 .phy_irq_pin = AT91_PIN_PC2,
52 .is_rmii = 1, 52 .is_rmii = 1,
53}; 53};
54 54
55static struct at91_usbh_data __initdata eco920_usbh_data = { 55static struct at91_usbh_data __initdata eco920_usbh_data = {
56 .ports = 1, 56 .ports = 1,
57 .vbus_pin = {-EINVAL, -EINVAL},
58 .overcurrent_pin= {-EINVAL, -EINVAL},
57}; 59};
58 60
59static struct at91_udc_data __initdata eco920_udc_data = { 61static struct at91_udc_data __initdata eco920_udc_data = {
@@ -64,6 +66,9 @@ static struct at91_udc_data __initdata eco920_udc_data = {
64static struct at91_mmc_data __initdata eco920_mmc_data = { 66static struct at91_mmc_data __initdata eco920_mmc_data = {
65 .slot_b = 0, 67 .slot_b = 0,
66 .wire4 = 0, 68 .wire4 = 0,
69 .det_pin = -EINVAL,
70 .wp_pin = -EINVAL,
71 .vcc_pin = -EINVAL,
67}; 72};
68 73
69static struct physmap_flash_data eco920_flash_data = { 74static struct physmap_flash_data eco920_flash_data = {
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index 4c3f65d9c59..eec02cd57ce 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -52,12 +52,14 @@ static void __init flexibity_init_early(void)
52/* USB Host port */ 52/* USB Host port */
53static struct at91_usbh_data __initdata flexibity_usbh_data = { 53static struct at91_usbh_data __initdata flexibity_usbh_data = {
54 .ports = 2, 54 .ports = 2,
55 .vbus_pin = {-EINVAL, -EINVAL},
56 .overcurrent_pin= {-EINVAL, -EINVAL},
55}; 57};
56 58
57/* USB Device port */ 59/* USB Device port */
58static struct at91_udc_data __initdata flexibity_udc_data = { 60static struct at91_udc_data __initdata flexibity_udc_data = {
59 .vbus_pin = AT91_PIN_PC5, 61 .vbus_pin = AT91_PIN_PC5,
60 .pullup_pin = 0, /* pull-up driven by UDC */ 62 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
61}; 63};
62 64
63/* SPI devices */ 65/* SPI devices */
@@ -76,6 +78,7 @@ static struct at91_mmc_data __initdata flexibity_mmc_data = {
76 .wire4 = 1, 78 .wire4 = 1,
77 .det_pin = AT91_PIN_PC9, 79 .det_pin = AT91_PIN_PC9,
78 .wp_pin = AT91_PIN_PC4, 80 .wp_pin = AT91_PIN_PC4,
81 .vcc_pin = -EINVAL,
79}; 82};
80 83
81/* LEDs */ 84/* LEDs */
diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c
index f27d1a780cf..caf017f0f4e 100644
--- a/arch/arm/mach-at91/board-foxg20.c
+++ b/arch/arm/mach-at91/board-foxg20.c
@@ -106,6 +106,8 @@ static void __init foxg20_init_early(void)
106 */ 106 */
107static struct at91_usbh_data __initdata foxg20_usbh_data = { 107static struct at91_usbh_data __initdata foxg20_usbh_data = {
108 .ports = 2, 108 .ports = 2,
109 .vbus_pin = {-EINVAL, -EINVAL},
110 .overcurrent_pin= {-EINVAL, -EINVAL},
109}; 111};
110 112
111/* 113/*
@@ -113,7 +115,7 @@ static struct at91_usbh_data __initdata foxg20_usbh_data = {
113 */ 115 */
114static struct at91_udc_data __initdata foxg20_udc_data = { 116static struct at91_udc_data __initdata foxg20_udc_data = {
115 .vbus_pin = AT91_PIN_PC6, 117 .vbus_pin = AT91_PIN_PC6,
116 .pullup_pin = 0, /* pull-up driven by UDC */ 118 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
117}; 119};
118 120
119 121
@@ -135,7 +137,7 @@ static struct spi_board_info foxg20_spi_devices[] = {
135/* 137/*
136 * MACB Ethernet device 138 * MACB Ethernet device
137 */ 139 */
138static struct at91_eth_data __initdata foxg20_macb_data = { 140static struct macb_platform_data __initdata foxg20_macb_data = {
139 .phy_irq_pin = AT91_PIN_PA7, 141 .phy_irq_pin = AT91_PIN_PA7,
140 .is_rmii = 1, 142 .is_rmii = 1,
141}; 143};
@@ -147,6 +149,9 @@ static struct at91_eth_data __initdata foxg20_macb_data = {
147static struct at91_mmc_data __initdata foxg20_mmc_data = { 149static struct at91_mmc_data __initdata foxg20_mmc_data = {
148 .slot_b = 1, 150 .slot_b = 1,
149 .wire4 = 1, 151 .wire4 = 1,
152 .det_pin = -EINVAL,
153 .wp_pin = -EINVAL,
154 .vcc_pin = -EINVAL,
150}; 155};
151 156
152 157
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c
index 2e95949737e..230e71969fb 100644
--- a/arch/arm/mach-at91/board-gsia18s.c
+++ b/arch/arm/mach-at91/board-gsia18s.c
@@ -80,6 +80,8 @@ static void __init gsia18s_init_early(void)
80 */ 80 */
81static struct at91_usbh_data __initdata usbh_data = { 81static struct at91_usbh_data __initdata usbh_data = {
82 .ports = 2, 82 .ports = 2,
83 .vbus_pin = {-EINVAL, -EINVAL},
84 .overcurrent_pin= {-EINVAL, -EINVAL},
83}; 85};
84 86
85/* 87/*
@@ -87,13 +89,13 @@ static struct at91_usbh_data __initdata usbh_data = {
87 */ 89 */
88static struct at91_udc_data __initdata udc_data = { 90static struct at91_udc_data __initdata udc_data = {
89 .vbus_pin = AT91_PIN_PA22, 91 .vbus_pin = AT91_PIN_PA22,
90 .pullup_pin = 0, /* pull-up driven by UDC */ 92 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
91}; 93};
92 94
93/* 95/*
94 * MACB Ethernet device 96 * MACB Ethernet device
95 */ 97 */
96static struct at91_eth_data __initdata macb_data = { 98static struct macb_platform_data __initdata macb_data = {
97 .phy_irq_pin = AT91_PIN_PA28, 99 .phy_irq_pin = AT91_PIN_PA28,
98 .is_rmii = 1, 100 .is_rmii = 1,
99}; 101};
@@ -530,6 +532,7 @@ static struct i2c_board_info __initdata gsia18s_i2c_devices[] = {
530static struct at91_cf_data __initdata gsia18s_cf1_data = { 532static struct at91_cf_data __initdata gsia18s_cf1_data = {
531 .irq_pin = AT91_PIN_PA27, 533 .irq_pin = AT91_PIN_PA27,
532 .det_pin = AT91_PIN_PB30, 534 .det_pin = AT91_PIN_PB30,
535 .vcc_pin = -EINVAL,
533 .rst_pin = AT91_PIN_PB31, 536 .rst_pin = AT91_PIN_PB31,
534 .chipselect = 5, 537 .chipselect = 5,
535 .flags = AT91_CF_TRUE_IDE, 538 .flags = AT91_CF_TRUE_IDE,
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index 3bae73e6363..efde1b2327c 100644
--- a/arch/arm/mach-at91/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -61,13 +61,15 @@ static void __init kafa_init_early(void)
61 at91_set_serial_console(0); 61 at91_set_serial_console(0);
62} 62}
63 63
64static struct at91_eth_data __initdata kafa_eth_data = { 64static struct macb_platform_data __initdata kafa_eth_data = {
65 .phy_irq_pin = AT91_PIN_PC4, 65 .phy_irq_pin = AT91_PIN_PC4,
66 .is_rmii = 0, 66 .is_rmii = 0,
67}; 67};
68 68
69static struct at91_usbh_data __initdata kafa_usbh_data = { 69static struct at91_usbh_data __initdata kafa_usbh_data = {
70 .ports = 1, 70 .ports = 1,
71 .vbus_pin = {-EINVAL, -EINVAL},
72 .overcurrent_pin= {-EINVAL, -EINVAL},
71}; 73};
72 74
73static struct at91_udc_data __initdata kafa_udc_data = { 75static struct at91_udc_data __initdata kafa_udc_data = {
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index e61351ffad5..d75a4a2ad9c 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -69,13 +69,15 @@ static void __init kb9202_init_early(void)
69 at91_set_serial_console(0); 69 at91_set_serial_console(0);
70} 70}
71 71
72static struct at91_eth_data __initdata kb9202_eth_data = { 72static struct macb_platform_data __initdata kb9202_eth_data = {
73 .phy_irq_pin = AT91_PIN_PB29, 73 .phy_irq_pin = AT91_PIN_PB29,
74 .is_rmii = 0, 74 .is_rmii = 0,
75}; 75};
76 76
77static struct at91_usbh_data __initdata kb9202_usbh_data = { 77static struct at91_usbh_data __initdata kb9202_usbh_data = {
78 .ports = 1, 78 .ports = 1,
79 .vbus_pin = {-EINVAL, -EINVAL},
80 .overcurrent_pin= {-EINVAL, -EINVAL},
79}; 81};
80 82
81static struct at91_udc_data __initdata kb9202_udc_data = { 83static struct at91_udc_data __initdata kb9202_udc_data = {
@@ -87,6 +89,8 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = {
87 .det_pin = AT91_PIN_PB2, 89 .det_pin = AT91_PIN_PB2,
88 .slot_b = 0, 90 .slot_b = 0,
89 .wire4 = 1, 91 .wire4 = 1,
92 .wp_pin = -EINVAL,
93 .vcc_pin = -EINVAL,
90}; 94};
91 95
92static struct mtd_partition __initdata kb9202_nand_partition[] = { 96static struct mtd_partition __initdata kb9202_nand_partition[] = {
@@ -100,7 +104,7 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = {
100static struct atmel_nand_data __initdata kb9202_nand_data = { 104static struct atmel_nand_data __initdata kb9202_nand_data = {
101 .ale = 22, 105 .ale = 22,
102 .cle = 21, 106 .cle = 21,
103 // .det_pin = ... not there 107 .det_pin = -EINVAL,
104 .rdy_pin = AT91_PIN_PC29, 108 .rdy_pin = AT91_PIN_PC29,
105 .enable_pin = AT91_PIN_PC28, 109 .enable_pin = AT91_PIN_PC28,
106 .parts = kb9202_nand_partition, 110 .parts = kb9202_nand_partition,
diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c
index ef816c17dc6..3f8617c0e04 100644
--- a/arch/arm/mach-at91/board-neocore926.c
+++ b/arch/arm/mach-at91/board-neocore926.c
@@ -72,6 +72,7 @@ static void __init neocore926_init_early(void)
72static struct at91_usbh_data __initdata neocore926_usbh_data = { 72static struct at91_usbh_data __initdata neocore926_usbh_data = {
73 .ports = 2, 73 .ports = 2,
74 .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, 74 .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 },
75 .overcurrent_pin= {-EINVAL, -EINVAL},
75}; 76};
76 77
77/* 78/*
@@ -79,7 +80,7 @@ static struct at91_usbh_data __initdata neocore926_usbh_data = {
79 */ 80 */
80static struct at91_udc_data __initdata neocore926_udc_data = { 81static struct at91_udc_data __initdata neocore926_udc_data = {
81 .vbus_pin = AT91_PIN_PA25, 82 .vbus_pin = AT91_PIN_PA25,
82 .pullup_pin = 0, /* pull-up driven by UDC */ 83 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
83}; 84};
84 85
85 86
@@ -149,13 +150,14 @@ static struct at91_mmc_data __initdata neocore926_mmc_data = {
149 .wire4 = 1, 150 .wire4 = 1,
150 .det_pin = AT91_PIN_PE18, 151 .det_pin = AT91_PIN_PE18,
151 .wp_pin = AT91_PIN_PE19, 152 .wp_pin = AT91_PIN_PE19,
153 .vcc_pin = -EINVAL,
152}; 154};
153 155
154 156
155/* 157/*
156 * MACB Ethernet device 158 * MACB Ethernet device
157 */ 159 */
158static struct at91_eth_data __initdata neocore926_macb_data = { 160static struct macb_platform_data __initdata neocore926_macb_data = {
159 .phy_irq_pin = AT91_PIN_PE31, 161 .phy_irq_pin = AT91_PIN_PE31,
160 .is_rmii = 1, 162 .is_rmii = 1,
161}; 163};
@@ -190,6 +192,7 @@ static struct atmel_nand_data __initdata neocore926_nand_data = {
190 .enable_pin = AT91_PIN_PD15, 192 .enable_pin = AT91_PIN_PD15,
191 .parts = neocore926_nand_partition, 193 .parts = neocore926_nand_partition,
192 .num_parts = ARRAY_SIZE(neocore926_nand_partition), 194 .num_parts = ARRAY_SIZE(neocore926_nand_partition),
195 .det_pin = -EINVAL,
193}; 196};
194 197
195static struct sam9_smc_config __initdata neocore926_nand_smc_config = { 198static struct sam9_smc_config __initdata neocore926_nand_smc_config = {
@@ -213,7 +216,7 @@ static struct sam9_smc_config __initdata neocore926_nand_smc_config = {
213static void __init neocore926_add_device_nand(void) 216static void __init neocore926_add_device_nand(void)
214{ 217{
215 /* configure chip-select 3 (NAND) */ 218 /* configure chip-select 3 (NAND) */
216 sam9_smc_configure(3, &neocore926_nand_smc_config); 219 sam9_smc_configure(0, 3, &neocore926_nand_smc_config);
217 220
218 at91_add_device_nand(&neocore926_nand_data); 221 at91_add_device_nand(&neocore926_nand_data);
219} 222}
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
index 49e3f699b48..b4a12fc184c 100644
--- a/arch/arm/mach-at91/board-pcontrol-g20.c
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -96,9 +96,9 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
96static void __init add_device_pcontrol(void) 96static void __init add_device_pcontrol(void)
97{ 97{
98 /* configure chip-select 4 (IO compatible to 8051 X4 ) */ 98 /* configure chip-select 4 (IO compatible to 8051 X4 ) */
99 sam9_smc_configure(4, &pcontrol_smc_config[0]); 99 sam9_smc_configure(0, 4, &pcontrol_smc_config[0]);
100 /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */ 100 /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */
101 sam9_smc_configure(7, &pcontrol_smc_config[1]); 101 sam9_smc_configure(0, 7, &pcontrol_smc_config[1]);
102} 102}
103 103
104 104
@@ -107,6 +107,8 @@ static void __init add_device_pcontrol(void)
107 */ 107 */
108static struct at91_usbh_data __initdata usbh_data = { 108static struct at91_usbh_data __initdata usbh_data = {
109 .ports = 2, 109 .ports = 2,
110 .vbus_pin = {-EINVAL, -EINVAL},
111 .overcurrent_pin= {-EINVAL, -EINVAL},
110}; 112};
111 113
112 114
@@ -122,7 +124,7 @@ static struct at91_udc_data __initdata pcontrol_g20_udc_data = {
122/* 124/*
123 * MACB Ethernet device 125 * MACB Ethernet device
124 */ 126 */
125static struct at91_eth_data __initdata macb_data = { 127static struct macb_platform_data __initdata macb_data = {
126 .phy_irq_pin = AT91_PIN_PA28, 128 .phy_irq_pin = AT91_PIN_PA28,
127 .is_rmii = 1, 129 .is_rmii = 1,
128}; 130};
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index 0a8fe6a1b7c..ab024fa11d5 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -60,13 +60,15 @@ static void __init picotux200_init_early(void)
60 at91_set_serial_console(0); 60 at91_set_serial_console(0);
61} 61}
62 62
63static struct at91_eth_data __initdata picotux200_eth_data = { 63static struct macb_platform_data __initdata picotux200_eth_data = {
64 .phy_irq_pin = AT91_PIN_PC4, 64 .phy_irq_pin = AT91_PIN_PC4,
65 .is_rmii = 1, 65 .is_rmii = 1,
66}; 66};
67 67
68static struct at91_usbh_data __initdata picotux200_usbh_data = { 68static struct at91_usbh_data __initdata picotux200_usbh_data = {
69 .ports = 1, 69 .ports = 1,
70 .vbus_pin = {-EINVAL, -EINVAL},
71 .overcurrent_pin= {-EINVAL, -EINVAL},
70}; 72};
71 73
72static struct at91_mmc_data __initdata picotux200_mmc_data = { 74static struct at91_mmc_data __initdata picotux200_mmc_data = {
@@ -74,6 +76,7 @@ static struct at91_mmc_data __initdata picotux200_mmc_data = {
74 .slot_b = 0, 76 .slot_b = 0,
75 .wire4 = 1, 77 .wire4 = 1,
76 .wp_pin = AT91_PIN_PA17, 78 .wp_pin = AT91_PIN_PA17,
79 .vcc_pin = -EINVAL,
77}; 80};
78 81
79#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 82#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c
index 07421bdb88e..e029d220cb8 100644
--- a/arch/arm/mach-at91/board-qil-a9260.c
+++ b/arch/arm/mach-at91/board-qil-a9260.c
@@ -77,6 +77,8 @@ static void __init ek_init_early(void)
77 */ 77 */
78static struct at91_usbh_data __initdata ek_usbh_data = { 78static struct at91_usbh_data __initdata ek_usbh_data = {
79 .ports = 2, 79 .ports = 2,
80 .vbus_pin = {-EINVAL, -EINVAL},
81 .overcurrent_pin= {-EINVAL, -EINVAL},
80}; 82};
81 83
82/* 84/*
@@ -84,7 +86,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
84 */ 86 */
85static struct at91_udc_data __initdata ek_udc_data = { 87static struct at91_udc_data __initdata ek_udc_data = {
86 .vbus_pin = AT91_PIN_PC5, 88 .vbus_pin = AT91_PIN_PC5,
87 .pullup_pin = 0, /* pull-up driven by UDC */ 89 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
88}; 90};
89 91
90/* 92/*
@@ -104,7 +106,7 @@ static struct spi_board_info ek_spi_devices[] = {
104/* 106/*
105 * MACB Ethernet device 107 * MACB Ethernet device
106 */ 108 */
107static struct at91_eth_data __initdata ek_macb_data = { 109static struct macb_platform_data __initdata ek_macb_data = {
108 .phy_irq_pin = AT91_PIN_PA31, 110 .phy_irq_pin = AT91_PIN_PA31,
109 .is_rmii = 1, 111 .is_rmii = 1,
110}; 112};
@@ -133,7 +135,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
133static struct atmel_nand_data __initdata ek_nand_data = { 135static struct atmel_nand_data __initdata ek_nand_data = {
134 .ale = 21, 136 .ale = 21,
135 .cle = 22, 137 .cle = 22,
136// .det_pin = ... not connected 138 .det_pin = -EINVAL,
137 .rdy_pin = AT91_PIN_PC13, 139 .rdy_pin = AT91_PIN_PC13,
138 .enable_pin = AT91_PIN_PC14, 140 .enable_pin = AT91_PIN_PC14,
139 .parts = ek_nand_partition, 141 .parts = ek_nand_partition,
@@ -161,7 +163,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
161static void __init ek_add_device_nand(void) 163static void __init ek_add_device_nand(void)
162{ 164{
163 /* configure chip-select 3 (NAND) */ 165 /* configure chip-select 3 (NAND) */
164 sam9_smc_configure(3, &ek_nand_smc_config); 166 sam9_smc_configure(0, 3, &ek_nand_smc_config);
165 167
166 at91_add_device_nand(&ek_nand_data); 168 at91_add_device_nand(&ek_nand_data);
167} 169}
@@ -172,9 +174,9 @@ static void __init ek_add_device_nand(void)
172static struct at91_mmc_data __initdata ek_mmc_data = { 174static struct at91_mmc_data __initdata ek_mmc_data = {
173 .slot_b = 0, 175 .slot_b = 0,
174 .wire4 = 1, 176 .wire4 = 1,
175// .det_pin = ... not connected 177 .det_pin = -EINVAL,
176// .wp_pin = ... not connected 178 .wp_pin = -EINVAL,
177// .vcc_pin = ... not connected 179 .vcc_pin = -EINVAL,
178}; 180};
179 181
180/* 182/*
@@ -251,7 +253,7 @@ static void __init ek_board_init(void)
251 /* LEDs */ 253 /* LEDs */
252 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); 254 at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
253 /* shutdown controller, wakeup button (5 msec low) */ 255 /* shutdown controller, wakeup button (5 msec low) */
254 at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW 256 at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
255 | AT91_SHDW_RTTWKEN); 257 | AT91_SHDW_RTTWKEN);
256} 258}
257 259
diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c
index 80a8c9c6e92..782f37946af 100644
--- a/arch/arm/mach-at91/board-rm9200dk.c
+++ b/arch/arm/mach-at91/board-rm9200dk.c
@@ -65,13 +65,15 @@ static void __init dk_init_early(void)
65 at91_set_serial_console(0); 65 at91_set_serial_console(0);
66} 66}
67 67
68static struct at91_eth_data __initdata dk_eth_data = { 68static struct macb_platform_data __initdata dk_eth_data = {
69 .phy_irq_pin = AT91_PIN_PC4, 69 .phy_irq_pin = AT91_PIN_PC4,
70 .is_rmii = 1, 70 .is_rmii = 1,
71}; 71};
72 72
73static struct at91_usbh_data __initdata dk_usbh_data = { 73static struct at91_usbh_data __initdata dk_usbh_data = {
74 .ports = 2, 74 .ports = 2,
75 .vbus_pin = {-EINVAL, -EINVAL},
76 .overcurrent_pin= {-EINVAL, -EINVAL},
75}; 77};
76 78
77static struct at91_udc_data __initdata dk_udc_data = { 79static struct at91_udc_data __initdata dk_udc_data = {
@@ -80,16 +82,19 @@ static struct at91_udc_data __initdata dk_udc_data = {
80}; 82};
81 83
82static struct at91_cf_data __initdata dk_cf_data = { 84static struct at91_cf_data __initdata dk_cf_data = {
85 .irq_pin = -EINVAL,
83 .det_pin = AT91_PIN_PB0, 86 .det_pin = AT91_PIN_PB0,
87 .vcc_pin = -EINVAL,
84 .rst_pin = AT91_PIN_PC5, 88 .rst_pin = AT91_PIN_PC5,
85 // .irq_pin = ... not connected
86 // .vcc_pin = ... always powered
87}; 89};
88 90
89#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD 91#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
90static struct at91_mmc_data __initdata dk_mmc_data = { 92static struct at91_mmc_data __initdata dk_mmc_data = {
91 .slot_b = 0, 93 .slot_b = 0,
92 .wire4 = 1, 94 .wire4 = 1,
95 .det_pin = -EINVAL,
96 .wp_pin = -EINVAL,
97 .vcc_pin = -EINVAL,
93}; 98};
94#endif 99#endif
95 100
@@ -143,7 +148,7 @@ static struct atmel_nand_data __initdata dk_nand_data = {
143 .cle = 21, 148 .cle = 21,
144 .det_pin = AT91_PIN_PB1, 149 .det_pin = AT91_PIN_PB1,
145 .rdy_pin = AT91_PIN_PC2, 150 .rdy_pin = AT91_PIN_PC2,
146 // .enable_pin = ... not there 151 .enable_pin = -EINVAL,
147 .parts = dk_nand_partition, 152 .parts = dk_nand_partition,
148 .num_parts = ARRAY_SIZE(dk_nand_partition), 153 .num_parts = ARRAY_SIZE(dk_nand_partition),
149}; 154};
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c
index 99fd7f8aee0..ef7c12a9224 100644
--- a/arch/arm/mach-at91/board-rm9200ek.c
+++ b/arch/arm/mach-at91/board-rm9200ek.c
@@ -65,13 +65,15 @@ static void __init ek_init_early(void)
65 at91_set_serial_console(0); 65 at91_set_serial_console(0);
66} 66}
67 67
68static struct at91_eth_data __initdata ek_eth_data = { 68static struct macb_platform_data __initdata ek_eth_data = {
69 .phy_irq_pin = AT91_PIN_PC4, 69 .phy_irq_pin = AT91_PIN_PC4,
70 .is_rmii = 1, 70 .is_rmii = 1,
71}; 71};
72 72
73static struct at91_usbh_data __initdata ek_usbh_data = { 73static struct at91_usbh_data __initdata ek_usbh_data = {
74 .ports = 2, 74 .ports = 2,
75 .vbus_pin = {-EINVAL, -EINVAL},
76 .overcurrent_pin= {-EINVAL, -EINVAL},
75}; 77};
76 78
77static struct at91_udc_data __initdata ek_udc_data = { 79static struct at91_udc_data __initdata ek_udc_data = {
@@ -85,6 +87,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
85 .slot_b = 0, 87 .slot_b = 0,
86 .wire4 = 1, 88 .wire4 = 1,
87 .wp_pin = AT91_PIN_PA17, 89 .wp_pin = AT91_PIN_PA17,
90 .vcc_pin = -EINVAL,
88}; 91};
89#endif 92#endif
90 93
diff --git a/arch/arm/mach-at91/board-rsi-ews.c b/arch/arm/mach-at91/board-rsi-ews.c
index e927df0175d..af0750fafa2 100644
--- a/arch/arm/mach-at91/board-rsi-ews.c
+++ b/arch/arm/mach-at91/board-rsi-ews.c
@@ -60,7 +60,7 @@ static void __init rsi_ews_init_early(void)
60/* 60/*
61 * Ethernet 61 * Ethernet
62 */ 62 */
63static struct at91_eth_data rsi_ews_eth_data __initdata = { 63static struct macb_platform_data rsi_ews_eth_data __initdata = {
64 .phy_irq_pin = AT91_PIN_PC4, 64 .phy_irq_pin = AT91_PIN_PC4,
65 .is_rmii = 1, 65 .is_rmii = 1,
66}; 66};
@@ -70,6 +70,8 @@ static struct at91_eth_data rsi_ews_eth_data __initdata = {
70 */ 70 */
71static struct at91_usbh_data rsi_ews_usbh_data __initdata = { 71static struct at91_usbh_data rsi_ews_usbh_data __initdata = {
72 .ports = 1, 72 .ports = 1,
73 .vbus_pin = {-EINVAL, -EINVAL},
74 .overcurrent_pin= {-EINVAL, -EINVAL},
73}; 75};
74 76
75/* 77/*
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
index 072d53af98d..84bce587735 100644
--- a/arch/arm/mach-at91/board-sam9-l9260.c
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -72,6 +72,8 @@ static void __init ek_init_early(void)
72 */ 72 */
73static struct at91_usbh_data __initdata ek_usbh_data = { 73static struct at91_usbh_data __initdata ek_usbh_data = {
74 .ports = 2, 74 .ports = 2,
75 .vbus_pin = {-EINVAL, -EINVAL},
76 .overcurrent_pin= {-EINVAL, -EINVAL},
75}; 77};
76 78
77/* 79/*
@@ -79,7 +81,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
79 */ 81 */
80static struct at91_udc_data __initdata ek_udc_data = { 82static struct at91_udc_data __initdata ek_udc_data = {
81 .vbus_pin = AT91_PIN_PC5, 83 .vbus_pin = AT91_PIN_PC5,
82 .pullup_pin = 0, /* pull-up driven by UDC */ 84 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
83}; 85};
84 86
85 87
@@ -109,7 +111,7 @@ static struct spi_board_info ek_spi_devices[] = {
109/* 111/*
110 * MACB Ethernet device 112 * MACB Ethernet device
111 */ 113 */
112static struct at91_eth_data __initdata ek_macb_data = { 114static struct macb_platform_data __initdata ek_macb_data = {
113 .phy_irq_pin = AT91_PIN_PA7, 115 .phy_irq_pin = AT91_PIN_PA7,
114 .is_rmii = 0, 116 .is_rmii = 0,
115}; 117};
@@ -134,7 +136,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
134static struct atmel_nand_data __initdata ek_nand_data = { 136static struct atmel_nand_data __initdata ek_nand_data = {
135 .ale = 21, 137 .ale = 21,
136 .cle = 22, 138 .cle = 22,
137// .det_pin = ... not connected 139 .det_pin = -EINVAL,
138 .rdy_pin = AT91_PIN_PC13, 140 .rdy_pin = AT91_PIN_PC13,
139 .enable_pin = AT91_PIN_PC14, 141 .enable_pin = AT91_PIN_PC14,
140 .parts = ek_nand_partition, 142 .parts = ek_nand_partition,
@@ -162,7 +164,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
162static void __init ek_add_device_nand(void) 164static void __init ek_add_device_nand(void)
163{ 165{
164 /* configure chip-select 3 (NAND) */ 166 /* configure chip-select 3 (NAND) */
165 sam9_smc_configure(3, &ek_nand_smc_config); 167 sam9_smc_configure(0, 3, &ek_nand_smc_config);
166 168
167 at91_add_device_nand(&ek_nand_data); 169 at91_add_device_nand(&ek_nand_data);
168} 170}
@@ -176,7 +178,7 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
176 .wire4 = 1, 178 .wire4 = 1,
177 .det_pin = AT91_PIN_PC8, 179 .det_pin = AT91_PIN_PC8,
178 .wp_pin = AT91_PIN_PC4, 180 .wp_pin = AT91_PIN_PC4,
179// .vcc_pin = ... not connected 181 .vcc_pin = -EINVAL,
180}; 182};
181 183
182static void __init ek_board_init(void) 184static void __init ek_board_init(void)
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 4f10181a078..be8233bcabd 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -75,6 +75,8 @@ static void __init ek_init_early(void)
75 */ 75 */
76static struct at91_usbh_data __initdata ek_usbh_data = { 76static struct at91_usbh_data __initdata ek_usbh_data = {
77 .ports = 2, 77 .ports = 2,
78 .vbus_pin = {-EINVAL, -EINVAL},
79 .overcurrent_pin= {-EINVAL, -EINVAL},
78}; 80};
79 81
80/* 82/*
@@ -82,7 +84,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
82 */ 84 */
83static struct at91_udc_data __initdata ek_udc_data = { 85static struct at91_udc_data __initdata ek_udc_data = {
84 .vbus_pin = AT91_PIN_PC5, 86 .vbus_pin = AT91_PIN_PC5,
85 .pullup_pin = 0, /* pull-up driven by UDC */ 87 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
86}; 88};
87 89
88 90
@@ -151,7 +153,7 @@ static struct spi_board_info ek_spi_devices[] = {
151/* 153/*
152 * MACB Ethernet device 154 * MACB Ethernet device
153 */ 155 */
154static struct at91_eth_data __initdata ek_macb_data = { 156static struct macb_platform_data __initdata ek_macb_data = {
155 .phy_irq_pin = AT91_PIN_PA7, 157 .phy_irq_pin = AT91_PIN_PA7,
156 .is_rmii = 1, 158 .is_rmii = 1,
157}; 159};
@@ -176,7 +178,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
176static struct atmel_nand_data __initdata ek_nand_data = { 178static struct atmel_nand_data __initdata ek_nand_data = {
177 .ale = 21, 179 .ale = 21,
178 .cle = 22, 180 .cle = 22,
179// .det_pin = ... not connected 181 .det_pin = -EINVAL,
180 .rdy_pin = AT91_PIN_PC13, 182 .rdy_pin = AT91_PIN_PC13,
181 .enable_pin = AT91_PIN_PC14, 183 .enable_pin = AT91_PIN_PC14,
182 .parts = ek_nand_partition, 184 .parts = ek_nand_partition,
@@ -211,7 +213,7 @@ static void __init ek_add_device_nand(void)
211 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 213 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
212 214
213 /* configure chip-select 3 (NAND) */ 215 /* configure chip-select 3 (NAND) */
214 sam9_smc_configure(3, &ek_nand_smc_config); 216 sam9_smc_configure(0, 3, &ek_nand_smc_config);
215 217
216 at91_add_device_nand(&ek_nand_data); 218 at91_add_device_nand(&ek_nand_data);
217} 219}
@@ -223,9 +225,9 @@ static void __init ek_add_device_nand(void)
223static struct at91_mmc_data __initdata ek_mmc_data = { 225static struct at91_mmc_data __initdata ek_mmc_data = {
224 .slot_b = 1, 226 .slot_b = 1,
225 .wire4 = 1, 227 .wire4 = 1,
226// .det_pin = ... not connected 228 .det_pin = -EINVAL,
227// .wp_pin = ... not connected 229 .wp_pin = -EINVAL,
228// .vcc_pin = ... not connected 230 .vcc_pin = -EINVAL,
229}; 231};
230 232
231 233
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index b005b738e8f..40895072a1a 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -131,7 +131,7 @@ static struct sam9_smc_config __initdata dm9000_smc_config = {
131static void __init ek_add_device_dm9000(void) 131static void __init ek_add_device_dm9000(void)
132{ 132{
133 /* Configure chip-select 2 (DM9000) */ 133 /* Configure chip-select 2 (DM9000) */
134 sam9_smc_configure(2, &dm9000_smc_config); 134 sam9_smc_configure(0, 2, &dm9000_smc_config);
135 135
136 /* Configure Reset signal as output */ 136 /* Configure Reset signal as output */
137 at91_set_gpio_output(AT91_PIN_PC10, 0); 137 at91_set_gpio_output(AT91_PIN_PC10, 0);
@@ -151,6 +151,8 @@ static void __init ek_add_device_dm9000(void) {}
151 */ 151 */
152static struct at91_usbh_data __initdata ek_usbh_data = { 152static struct at91_usbh_data __initdata ek_usbh_data = {
153 .ports = 2, 153 .ports = 2,
154 .vbus_pin = {-EINVAL, -EINVAL},
155 .overcurrent_pin= {-EINVAL, -EINVAL},
154}; 156};
155 157
156 158
@@ -159,7 +161,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
159 */ 161 */
160static struct at91_udc_data __initdata ek_udc_data = { 162static struct at91_udc_data __initdata ek_udc_data = {
161 .vbus_pin = AT91_PIN_PB29, 163 .vbus_pin = AT91_PIN_PB29,
162 .pullup_pin = 0, /* pull-up driven by UDC */ 164 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
163}; 165};
164 166
165 167
@@ -182,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
182static struct atmel_nand_data __initdata ek_nand_data = { 184static struct atmel_nand_data __initdata ek_nand_data = {
183 .ale = 22, 185 .ale = 22,
184 .cle = 21, 186 .cle = 21,
185// .det_pin = ... not connected 187 .det_pin = -EINVAL,
186 .rdy_pin = AT91_PIN_PC15, 188 .rdy_pin = AT91_PIN_PC15,
187 .enable_pin = AT91_PIN_PC14, 189 .enable_pin = AT91_PIN_PC14,
188 .parts = ek_nand_partition, 190 .parts = ek_nand_partition,
@@ -217,7 +219,7 @@ static void __init ek_add_device_nand(void)
217 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 219 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
218 220
219 /* configure chip-select 3 (NAND) */ 221 /* configure chip-select 3 (NAND) */
220 sam9_smc_configure(3, &ek_nand_smc_config); 222 sam9_smc_configure(0, 3, &ek_nand_smc_config);
221 223
222 at91_add_device_nand(&ek_nand_data); 224 at91_add_device_nand(&ek_nand_data);
223} 225}
@@ -345,6 +347,9 @@ static struct spi_board_info ek_spi_devices[] = {
345 */ 347 */
346static struct at91_mmc_data __initdata ek_mmc_data = { 348static struct at91_mmc_data __initdata ek_mmc_data = {
347 .wire4 = 1, 349 .wire4 = 1,
350 .det_pin = -EINVAL,
351 .wp_pin = -EINVAL,
352 .vcc_pin = -EINVAL,
348}; 353};
349 354
350#endif /* CONFIG_SPI_ATMEL_* */ 355#endif /* CONFIG_SPI_ATMEL_* */
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index bccdcf23caa..29f66052fe6 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -74,6 +74,7 @@ static void __init ek_init_early(void)
74static struct at91_usbh_data __initdata ek_usbh_data = { 74static struct at91_usbh_data __initdata ek_usbh_data = {
75 .ports = 2, 75 .ports = 2,
76 .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, 76 .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 },
77 .overcurrent_pin= {-EINVAL, -EINVAL},
77}; 78};
78 79
79/* 80/*
@@ -81,7 +82,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
81 */ 82 */
82static struct at91_udc_data __initdata ek_udc_data = { 83static struct at91_udc_data __initdata ek_udc_data = {
83 .vbus_pin = AT91_PIN_PA25, 84 .vbus_pin = AT91_PIN_PA25,
84 .pullup_pin = 0, /* pull-up driven by UDC */ 85 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
85}; 86};
86 87
87 88
@@ -151,14 +152,14 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
151 .wire4 = 1, 152 .wire4 = 1,
152 .det_pin = AT91_PIN_PE18, 153 .det_pin = AT91_PIN_PE18,
153 .wp_pin = AT91_PIN_PE19, 154 .wp_pin = AT91_PIN_PE19,
154// .vcc_pin = ... not connected 155 .vcc_pin = -EINVAL,
155}; 156};
156 157
157 158
158/* 159/*
159 * MACB Ethernet device 160 * MACB Ethernet device
160 */ 161 */
161static struct at91_eth_data __initdata ek_macb_data = { 162static struct macb_platform_data __initdata ek_macb_data = {
162 .phy_irq_pin = AT91_PIN_PE31, 163 .phy_irq_pin = AT91_PIN_PE31,
163 .is_rmii = 1, 164 .is_rmii = 1,
164}; 165};
@@ -183,7 +184,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
183static struct atmel_nand_data __initdata ek_nand_data = { 184static struct atmel_nand_data __initdata ek_nand_data = {
184 .ale = 21, 185 .ale = 21,
185 .cle = 22, 186 .cle = 22,
186// .det_pin = ... not connected 187 .det_pin = -EINVAL,
187 .rdy_pin = AT91_PIN_PA22, 188 .rdy_pin = AT91_PIN_PA22,
188 .enable_pin = AT91_PIN_PD15, 189 .enable_pin = AT91_PIN_PD15,
189 .parts = ek_nand_partition, 190 .parts = ek_nand_partition,
@@ -218,7 +219,7 @@ static void __init ek_add_device_nand(void)
218 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 219 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
219 220
220 /* configure chip-select 3 (NAND) */ 221 /* configure chip-select 3 (NAND) */
221 sam9_smc_configure(3, &ek_nand_smc_config); 222 sam9_smc_configure(0, 3, &ek_nand_smc_config);
222 223
223 at91_add_device_nand(&ek_nand_data); 224 at91_add_device_nand(&ek_nand_data);
224} 225}
@@ -353,6 +354,7 @@ static void __init ek_add_device_buttons(void) {}
353 * reset_pin is not connected: NRST 354 * reset_pin is not connected: NRST
354 */ 355 */
355static struct ac97c_platform_data ek_ac97_data = { 356static struct ac97c_platform_data ek_ac97_data = {
357 .reset_pin = -EINVAL,
356}; 358};
357 359
358 360
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 64fc75c9d0a..843d6286c6f 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -86,6 +86,8 @@ static void __init ek_init_early(void)
86 */ 86 */
87static struct at91_usbh_data __initdata ek_usbh_data = { 87static struct at91_usbh_data __initdata ek_usbh_data = {
88 .ports = 2, 88 .ports = 2,
89 .vbus_pin = {-EINVAL, -EINVAL},
90 .overcurrent_pin= {-EINVAL, -EINVAL},
89}; 91};
90 92
91/* 93/*
@@ -93,7 +95,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
93 */ 95 */
94static struct at91_udc_data __initdata ek_udc_data = { 96static struct at91_udc_data __initdata ek_udc_data = {
95 .vbus_pin = AT91_PIN_PC5, 97 .vbus_pin = AT91_PIN_PC5,
96 .pullup_pin = 0, /* pull-up driven by UDC */ 98 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
97}; 99};
98 100
99 101
@@ -123,7 +125,7 @@ static struct spi_board_info ek_spi_devices[] = {
123/* 125/*
124 * MACB Ethernet device 126 * MACB Ethernet device
125 */ 127 */
126static struct at91_eth_data __initdata ek_macb_data = { 128static struct macb_platform_data __initdata ek_macb_data = {
127 .phy_irq_pin = AT91_PIN_PA7, 129 .phy_irq_pin = AT91_PIN_PA7,
128 .is_rmii = 1, 130 .is_rmii = 1,
129}; 131};
@@ -163,6 +165,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
163 .cle = 22, 165 .cle = 22,
164 .rdy_pin = AT91_PIN_PC13, 166 .rdy_pin = AT91_PIN_PC13,
165 .enable_pin = AT91_PIN_PC14, 167 .enable_pin = AT91_PIN_PC14,
168 .det_pin = -EINVAL,
166 .parts = ek_nand_partition, 169 .parts = ek_nand_partition,
167 .num_parts = ARRAY_SIZE(ek_nand_partition), 170 .num_parts = ARRAY_SIZE(ek_nand_partition),
168}; 171};
@@ -195,7 +198,7 @@ static void __init ek_add_device_nand(void)
195 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 198 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
196 199
197 /* configure chip-select 3 (NAND) */ 200 /* configure chip-select 3 (NAND) */
198 sam9_smc_configure(3, &ek_nand_smc_config); 201 sam9_smc_configure(0, 3, &ek_nand_smc_config);
199 202
200 at91_add_device_nand(&ek_nand_data); 203 at91_add_device_nand(&ek_nand_data);
201} 204}
@@ -210,6 +213,7 @@ static struct mci_platform_data __initdata ek_mmc_data = {
210 .slot[1] = { 213 .slot[1] = {
211 .bus_width = 4, 214 .bus_width = 4,
212 .detect_pin = AT91_PIN_PC9, 215 .detect_pin = AT91_PIN_PC9,
216 .wp_pin = -EINVAL,
213 }, 217 },
214 218
215}; 219};
@@ -218,6 +222,8 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
218 .slot_b = 1, /* Only one slot so use slot B */ 222 .slot_b = 1, /* Only one slot so use slot B */
219 .wire4 = 1, 223 .wire4 = 1,
220 .det_pin = AT91_PIN_PC9, 224 .det_pin = AT91_PIN_PC9,
225 .wp_pin = -EINVAL,
226 .vcc_pin = -EINVAL,
221}; 227};
222#endif 228#endif
223 229
@@ -227,6 +233,7 @@ static void __init ek_add_device_mmc(void)
227 if (ek_have_2mmc()) { 233 if (ek_have_2mmc()) {
228 ek_mmc_data.slot[0].bus_width = 4; 234 ek_mmc_data.slot[0].bus_width = 4;
229 ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2; 235 ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2;
236 ek_mmc_data.slot[0].wp_pin = -1;
230 } 237 }
231 at91_add_device_mci(0, &ek_mmc_data); 238 at91_add_device_mci(0, &ek_mmc_data);
232#else 239#else
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index 92de9127923..ea0d1b9c2b7 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -69,6 +69,7 @@ static void __init ek_init_early(void)
69static struct at91_usbh_data __initdata ek_usbh_hs_data = { 69static struct at91_usbh_data __initdata ek_usbh_hs_data = {
70 .ports = 2, 70 .ports = 2,
71 .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, 71 .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3},
72 .overcurrent_pin= {-EINVAL, -EINVAL},
72}; 73};
73 74
74 75
@@ -100,6 +101,7 @@ static struct mci_platform_data __initdata mci0_data = {
100 .slot[0] = { 101 .slot[0] = {
101 .bus_width = 4, 102 .bus_width = 4,
102 .detect_pin = AT91_PIN_PD10, 103 .detect_pin = AT91_PIN_PD10,
104 .wp_pin = -EINVAL,
103 }, 105 },
104}; 106};
105 107
@@ -115,7 +117,7 @@ static struct mci_platform_data __initdata mci1_data = {
115/* 117/*
116 * MACB Ethernet device 118 * MACB Ethernet device
117 */ 119 */
118static struct at91_eth_data __initdata ek_macb_data = { 120static struct macb_platform_data __initdata ek_macb_data = {
119 .phy_irq_pin = AT91_PIN_PD5, 121 .phy_irq_pin = AT91_PIN_PD5,
120 .is_rmii = 1, 122 .is_rmii = 1,
121}; 123};
@@ -143,6 +145,7 @@ static struct atmel_nand_data __initdata ek_nand_data = {
143 .cle = 22, 145 .cle = 22,
144 .rdy_pin = AT91_PIN_PC8, 146 .rdy_pin = AT91_PIN_PC8,
145 .enable_pin = AT91_PIN_PC14, 147 .enable_pin = AT91_PIN_PC14,
148 .det_pin = -EINVAL,
146 .parts = ek_nand_partition, 149 .parts = ek_nand_partition,
147 .num_parts = ARRAY_SIZE(ek_nand_partition), 150 .num_parts = ARRAY_SIZE(ek_nand_partition),
148}; 151};
@@ -175,7 +178,7 @@ static void __init ek_add_device_nand(void)
175 ek_nand_smc_config.mode |= AT91_SMC_DBW_8; 178 ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
176 179
177 /* configure chip-select 3 (NAND) */ 180 /* configure chip-select 3 (NAND) */
178 sam9_smc_configure(3, &ek_nand_smc_config); 181 sam9_smc_configure(0, 3, &ek_nand_smc_config);
179 182
180 at91_add_device_nand(&ek_nand_data); 183 at91_add_device_nand(&ek_nand_data);
181} 184}
@@ -330,6 +333,7 @@ static void __init ek_add_device_buttons(void) {}
330 * reset_pin is not connected: NRST 333 * reset_pin is not connected: NRST
331 */ 334 */
332static struct ac97c_platform_data ek_ac97_data = { 335static struct ac97c_platform_data ek_ac97_data = {
336 .reset_pin = -EINVAL,
333}; 337};
334 338
335 339
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index b2b748239f3..c1366d0032b 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -67,8 +67,8 @@ static struct usba_platform_data __initdata ek_usba_udc_data = {
67static struct at91_mmc_data __initdata ek_mmc_data = { 67static struct at91_mmc_data __initdata ek_mmc_data = {
68 .wire4 = 1, 68 .wire4 = 1,
69 .det_pin = AT91_PIN_PA15, 69 .det_pin = AT91_PIN_PA15,
70// .wp_pin = ... not connected 70 .wp_pin = -EINVAL,
71// .vcc_pin = ... not connected 71 .vcc_pin = -EINVAL,
72}; 72};
73 73
74 74
@@ -91,7 +91,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
91static struct atmel_nand_data __initdata ek_nand_data = { 91static struct atmel_nand_data __initdata ek_nand_data = {
92 .ale = 21, 92 .ale = 21,
93 .cle = 22, 93 .cle = 22,
94// .det_pin = ... not connected 94 .det_pin = -EINVAL,
95 .rdy_pin = AT91_PIN_PD17, 95 .rdy_pin = AT91_PIN_PD17,
96 .enable_pin = AT91_PIN_PB6, 96 .enable_pin = AT91_PIN_PB6,
97 .parts = ek_nand_partition, 97 .parts = ek_nand_partition,
@@ -119,7 +119,7 @@ static struct sam9_smc_config __initdata ek_nand_smc_config = {
119static void __init ek_add_device_nand(void) 119static void __init ek_add_device_nand(void)
120{ 120{
121 /* configure chip-select 3 (NAND) */ 121 /* configure chip-select 3 (NAND) */
122 sam9_smc_configure(3, &ek_nand_smc_config); 122 sam9_smc_configure(0, 3, &ek_nand_smc_config);
123 123
124 at91_add_device_nand(&ek_nand_data); 124 at91_add_device_nand(&ek_nand_data);
125} 125}
@@ -204,6 +204,7 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
204 * reset_pin is not connected: NRST 204 * reset_pin is not connected: NRST
205 */ 205 */
206static struct ac97c_platform_data ek_ac97_data = { 206static struct ac97c_platform_data ek_ac97_data = {
207 .reset_pin = -EINVAL,
207}; 208};
208 209
209 210
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
index 0df01c6e2d0..4770db08e5a 100644
--- a/arch/arm/mach-at91/board-snapper9260.c
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -57,15 +57,19 @@ static void __init snapper9260_init_early(void)
57 57
58static struct at91_usbh_data __initdata snapper9260_usbh_data = { 58static struct at91_usbh_data __initdata snapper9260_usbh_data = {
59 .ports = 2, 59 .ports = 2,
60 .vbus_pin = {-EINVAL, -EINVAL},
61 .overcurrent_pin= {-EINVAL, -EINVAL},
60}; 62};
61 63
62static struct at91_udc_data __initdata snapper9260_udc_data = { 64static struct at91_udc_data __initdata snapper9260_udc_data = {
63 .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5), 65 .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5),
64 .vbus_active_low = 1, 66 .vbus_active_low = 1,
65 .vbus_polled = 1, 67 .vbus_polled = 1,
68 .pullup_pin = -EINVAL,
66}; 69};
67 70
68static struct at91_eth_data snapper9260_macb_data = { 71static struct macb_platform_data snapper9260_macb_data = {
72 .phy_irq_pin = -EINVAL,
69 .is_rmii = 1, 73 .is_rmii = 1,
70}; 74};
71 75
@@ -104,6 +108,8 @@ static struct atmel_nand_data __initdata snapper9260_nand_data = {
104 .parts = snapper9260_nand_partitions, 108 .parts = snapper9260_nand_partitions,
105 .num_parts = ARRAY_SIZE(snapper9260_nand_partitions), 109 .num_parts = ARRAY_SIZE(snapper9260_nand_partitions),
106 .bus_width_16 = 0, 110 .bus_width_16 = 0,
111 .enable_pin = -EINVAL,
112 .det_pin = -EINVAL,
107}; 113};
108 114
109static struct sam9_smc_config __initdata snapper9260_nand_smc_config = { 115static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
@@ -149,7 +155,7 @@ static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
149static void __init snapper9260_add_device_nand(void) 155static void __init snapper9260_add_device_nand(void)
150{ 156{
151 at91_set_A_periph(AT91_PIN_PC14, 0); 157 at91_set_A_periph(AT91_PIN_PC14, 0);
152 sam9_smc_configure(3, &snapper9260_nand_smc_config); 158 sam9_smc_configure(0, 3, &snapper9260_nand_smc_config);
153 at91_add_device_nand(&snapper9260_nand_data); 159 at91_add_device_nand(&snapper9260_nand_data);
154} 160}
155 161
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
index 936e5fd7f40..72eb3b4d9ab 100644
--- a/arch/arm/mach-at91/board-stamp9g20.c
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -85,6 +85,7 @@ static struct atmel_nand_data __initdata nand_data = {
85 .rdy_pin = AT91_PIN_PC13, 85 .rdy_pin = AT91_PIN_PC13,
86 .enable_pin = AT91_PIN_PC14, 86 .enable_pin = AT91_PIN_PC14,
87 .bus_width_16 = 0, 87 .bus_width_16 = 0,
88 .det_pin = -EINVAL,
88}; 89};
89 90
90static struct sam9_smc_config __initdata nand_smc_config = { 91static struct sam9_smc_config __initdata nand_smc_config = {
@@ -108,7 +109,7 @@ static struct sam9_smc_config __initdata nand_smc_config = {
108static void __init add_device_nand(void) 109static void __init add_device_nand(void)
109{ 110{
110 /* configure chip-select 3 (NAND) */ 111 /* configure chip-select 3 (NAND) */
111 sam9_smc_configure(3, &nand_smc_config); 112 sam9_smc_configure(0, 3, &nand_smc_config);
112 113
113 at91_add_device_nand(&nand_data); 114 at91_add_device_nand(&nand_data);
114} 115}
@@ -122,12 +123,17 @@ static void __init add_device_nand(void)
122static struct mci_platform_data __initdata mmc_data = { 123static struct mci_platform_data __initdata mmc_data = {
123 .slot[0] = { 124 .slot[0] = {
124 .bus_width = 4, 125 .bus_width = 4,
126 .detect_pin = -1,
127 .wp_pin = -1,
125 }, 128 },
126}; 129};
127#else 130#else
128static struct at91_mmc_data __initdata mmc_data = { 131static struct at91_mmc_data __initdata mmc_data = {
129 .slot_b = 0, 132 .slot_b = 0,
130 .wire4 = 1, 133 .wire4 = 1,
134 .det_pin = -EINVAL,
135 .wp_pin = -EINVAL,
136 .vcc_pin = -EINVAL,
131}; 137};
132#endif 138#endif
133 139
@@ -137,6 +143,8 @@ static struct at91_mmc_data __initdata mmc_data = {
137 */ 143 */
138static struct at91_usbh_data __initdata usbh_data = { 144static struct at91_usbh_data __initdata usbh_data = {
139 .ports = 2, 145 .ports = 2,
146 .vbus_pin = {-EINVAL, -EINVAL},
147 .overcurrent_pin= {-EINVAL, -EINVAL},
140}; 148};
141 149
142 150
@@ -145,19 +153,19 @@ static struct at91_usbh_data __initdata usbh_data = {
145 */ 153 */
146static struct at91_udc_data __initdata portuxg20_udc_data = { 154static struct at91_udc_data __initdata portuxg20_udc_data = {
147 .vbus_pin = AT91_PIN_PC7, 155 .vbus_pin = AT91_PIN_PC7,
148 .pullup_pin = 0, /* pull-up driven by UDC */ 156 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
149}; 157};
150 158
151static struct at91_udc_data __initdata stamp9g20evb_udc_data = { 159static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
152 .vbus_pin = AT91_PIN_PA22, 160 .vbus_pin = AT91_PIN_PA22,
153 .pullup_pin = 0, /* pull-up driven by UDC */ 161 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
154}; 162};
155 163
156 164
157/* 165/*
158 * MACB Ethernet device 166 * MACB Ethernet device
159 */ 167 */
160static struct at91_eth_data __initdata macb_data = { 168static struct macb_platform_data __initdata macb_data = {
161 .phy_irq_pin = AT91_PIN_PA28, 169 .phy_irq_pin = AT91_PIN_PA28,
162 .is_rmii = 1, 170 .is_rmii = 1,
163}; 171};
diff --git a/arch/arm/mach-at91/board-usb-a926x.c b/arch/arm/mach-at91/board-usb-a926x.c
index 0a20bab21f9..26c36fc2d1e 100644
--- a/arch/arm/mach-at91/board-usb-a926x.c
+++ b/arch/arm/mach-at91/board-usb-a926x.c
@@ -66,6 +66,8 @@ static void __init ek_init_early(void)
66 */ 66 */
67static struct at91_usbh_data __initdata ek_usbh_data = { 67static struct at91_usbh_data __initdata ek_usbh_data = {
68 .ports = 2, 68 .ports = 2,
69 .vbus_pin = {-EINVAL, -EINVAL},
70 .overcurrent_pin= {-EINVAL, -EINVAL},
69}; 71};
70 72
71/* 73/*
@@ -73,7 +75,7 @@ static struct at91_usbh_data __initdata ek_usbh_data = {
73 */ 75 */
74static struct at91_udc_data __initdata ek_udc_data = { 76static struct at91_udc_data __initdata ek_udc_data = {
75 .vbus_pin = AT91_PIN_PB11, 77 .vbus_pin = AT91_PIN_PB11,
76 .pullup_pin = 0, /* pull-up driven by UDC */ 78 .pullup_pin = -EINVAL, /* pull-up driven by UDC */
77}; 79};
78 80
79static void __init ek_add_device_udc(void) 81static void __init ek_add_device_udc(void)
@@ -146,7 +148,7 @@ static void __init ek_add_device_spi(void)
146/* 148/*
147 * MACB Ethernet device 149 * MACB Ethernet device
148 */ 150 */
149static struct at91_eth_data __initdata ek_macb_data = { 151static struct macb_platform_data __initdata ek_macb_data = {
150 .phy_irq_pin = AT91_PIN_PE31, 152 .phy_irq_pin = AT91_PIN_PE31,
151 .is_rmii = 1, 153 .is_rmii = 1,
152}; 154};
@@ -193,7 +195,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
193static struct atmel_nand_data __initdata ek_nand_data = { 195static struct atmel_nand_data __initdata ek_nand_data = {
194 .ale = 21, 196 .ale = 21,
195 .cle = 22, 197 .cle = 22,
196// .det_pin = ... not connected 198 .det_pin = -EINVAL,
197 .rdy_pin = AT91_PIN_PA22, 199 .rdy_pin = AT91_PIN_PA22,
198 .enable_pin = AT91_PIN_PD15, 200 .enable_pin = AT91_PIN_PD15,
199 .parts = ek_nand_partition, 201 .parts = ek_nand_partition,
@@ -245,9 +247,9 @@ static void __init ek_add_device_nand(void)
245 247
246 /* configure chip-select 3 (NAND) */ 248 /* configure chip-select 3 (NAND) */
247 if (machine_is_usb_a9g20()) 249 if (machine_is_usb_a9g20())
248 sam9_smc_configure(3, &usb_a9g20_nand_smc_config); 250 sam9_smc_configure(0, 3, &usb_a9g20_nand_smc_config);
249 else 251 else
250 sam9_smc_configure(3, &usb_a9260_nand_smc_config); 252 sam9_smc_configure(0, 3, &usb_a9260_nand_smc_config);
251 253
252 at91_add_device_nand(&ek_nand_data); 254 at91_add_device_nand(&ek_nand_data);
253} 255}
@@ -344,7 +346,7 @@ static void __init ek_board_init(void)
344 /* I2C */ 346 /* I2C */
345 at91_add_device_i2c(NULL, 0); 347 at91_add_device_i2c(NULL, 0);
346 /* shutdown controller, wakeup button (5 msec low) */ 348 /* shutdown controller, wakeup button (5 msec low) */
347 at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) 349 at91_shdwc_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10)
348 | AT91_SHDW_WKMODE0_LOW 350 | AT91_SHDW_WKMODE0_LOW
349 | AT91_SHDW_RTTWKEN); 351 | AT91_SHDW_RTTWKEN);
350 } 352 }
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
index 12a3f955162..bbd553e1cd9 100644
--- a/arch/arm/mach-at91/board-yl-9200.c
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -110,7 +110,7 @@ static struct gpio_led yl9200_leds[] = {
110/* 110/*
111 * Ethernet 111 * Ethernet
112 */ 112 */
113static struct at91_eth_data __initdata yl9200_eth_data = { 113static struct macb_platform_data __initdata yl9200_eth_data = {
114 .phy_irq_pin = AT91_PIN_PB28, 114 .phy_irq_pin = AT91_PIN_PB28,
115 .is_rmii = 1, 115 .is_rmii = 1,
116}; 116};
@@ -120,6 +120,8 @@ static struct at91_eth_data __initdata yl9200_eth_data = {
120 */ 120 */
121static struct at91_usbh_data __initdata yl9200_usbh_data = { 121static struct at91_usbh_data __initdata yl9200_usbh_data = {
122 .ports = 1, /* PQFP version of AT91RM9200 */ 122 .ports = 1, /* PQFP version of AT91RM9200 */
123 .vbus_pin = {-EINVAL, -EINVAL},
124 .overcurrent_pin= {-EINVAL, -EINVAL},
123}; 125};
124 126
125/* 127/*
@@ -137,8 +139,9 @@ static struct at91_udc_data __initdata yl9200_udc_data = {
137 */ 139 */
138static struct at91_mmc_data __initdata yl9200_mmc_data = { 140static struct at91_mmc_data __initdata yl9200_mmc_data = {
139 .det_pin = AT91_PIN_PB9, 141 .det_pin = AT91_PIN_PB9,
140 // .wp_pin = ... not connected
141 .wire4 = 1, 142 .wire4 = 1,
143 .wp_pin = -EINVAL,
144 .vcc_pin = -EINVAL,
142}; 145};
143 146
144/* 147/*
@@ -175,7 +178,7 @@ static struct mtd_partition __initdata yl9200_nand_partition[] = {
175static struct atmel_nand_data __initdata yl9200_nand_data = { 178static struct atmel_nand_data __initdata yl9200_nand_data = {
176 .ale = 6, 179 .ale = 6,
177 .cle = 7, 180 .cle = 7,
178 // .det_pin = ... not connected 181 .det_pin = -EINVAL,
179 .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */ 182 .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */
180 .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */ 183 .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */
181 .parts = yl9200_nand_partition, 184 .parts = yl9200_nand_partition,
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 7f4503bc4cb..4866b8180d6 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -29,6 +29,7 @@ extern void __init at91_aic_init(unsigned int priority[]);
29 /* Timer */ 29 /* Timer */
30struct sys_timer; 30struct sys_timer;
31extern struct sys_timer at91rm9200_timer; 31extern struct sys_timer at91rm9200_timer;
32extern void at91sam926x_ioremap_pit(u32 addr);
32extern struct sys_timer at91sam926x_timer; 33extern struct sys_timer at91sam926x_timer;
33extern struct sys_timer at91x40_timer; 34extern struct sys_timer at91x40_timer;
34 35
@@ -59,14 +60,16 @@ extern void at91_irq_resume(void);
59/* reset */ 60/* reset */
60extern void at91sam9_alt_restart(char, const char *); 61extern void at91sam9_alt_restart(char, const char *);
61 62
63/* shutdown */
64extern void at91_ioremap_shdwc(u32 base_addr);
65
62 /* GPIO */ 66 /* GPIO */
63#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ 67#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */
64#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ 68#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
65 69
66struct at91_gpio_bank { 70struct at91_gpio_bank {
67 unsigned short id; /* peripheral ID */ 71 unsigned short id; /* peripheral ID */
68 unsigned long offset; /* offset from system peripheral base */ 72 unsigned long regbase; /* offset from system peripheral base */
69 struct clk *clock; /* associated clock */
70}; 73};
71extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); 74extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
72extern void __init at91_gpio_irq_setup(void); 75extern void __init at91_gpio_irq_setup(void);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 224e9e2f867..74d6783eeab 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -29,8 +29,9 @@
29struct at91_gpio_chip { 29struct at91_gpio_chip {
30 struct gpio_chip chip; 30 struct gpio_chip chip;
31 struct at91_gpio_chip *next; /* Bank sharing same clock */ 31 struct at91_gpio_chip *next; /* Bank sharing same clock */
32 struct at91_gpio_bank *bank; /* Bank definition */ 32 int id; /* ID of register bank */
33 void __iomem *regbase; /* Base of register bank */ 33 void __iomem *regbase; /* Base of register bank */
34 struct clk *clock; /* associated clock */
34}; 35};
35 36
36#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) 37#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
@@ -58,18 +59,17 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
58 } 59 }
59 60
60static struct at91_gpio_chip gpio_chip[] = { 61static struct at91_gpio_chip gpio_chip[] = {
61 AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32), 62 AT91_GPIO_CHIP("pioA", 0x00, 32),
62 AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32), 63 AT91_GPIO_CHIP("pioB", 0x20, 32),
63 AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32), 64 AT91_GPIO_CHIP("pioC", 0x40, 32),
64 AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32), 65 AT91_GPIO_CHIP("pioD", 0x60, 32),
65 AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32), 66 AT91_GPIO_CHIP("pioE", 0x80, 32),
66}; 67};
67 68
68static int gpio_banks; 69static int gpio_banks;
69 70
70static inline void __iomem *pin_to_controller(unsigned pin) 71static inline void __iomem *pin_to_controller(unsigned pin)
71{ 72{
72 pin -= PIN_BASE;
73 pin /= 32; 73 pin /= 32;
74 if (likely(pin < gpio_banks)) 74 if (likely(pin < gpio_banks))
75 return gpio_chip[pin].regbase; 75 return gpio_chip[pin].regbase;
@@ -79,7 +79,6 @@ static inline void __iomem *pin_to_controller(unsigned pin)
79 79
80static inline unsigned pin_to_mask(unsigned pin) 80static inline unsigned pin_to_mask(unsigned pin)
81{ 81{
82 pin -= PIN_BASE;
83 return 1 << (pin % 32); 82 return 1 << (pin % 32);
84} 83}
85 84
@@ -274,8 +273,9 @@ static u32 backups[MAX_GPIO_BANKS];
274 273
275static int gpio_irq_set_wake(struct irq_data *d, unsigned state) 274static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
276{ 275{
277 unsigned mask = pin_to_mask(d->irq); 276 unsigned pin = irq_to_gpio(d->irq);
278 unsigned bank = (d->irq - PIN_BASE) / 32; 277 unsigned mask = pin_to_mask(pin);
278 unsigned bank = pin / 32;
279 279
280 if (unlikely(bank >= MAX_GPIO_BANKS)) 280 if (unlikely(bank >= MAX_GPIO_BANKS))
281 return -EINVAL; 281 return -EINVAL;
@@ -285,7 +285,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
285 else 285 else
286 wakeups[bank] &= ~mask; 286 wakeups[bank] &= ~mask;
287 287
288 irq_set_irq_wake(gpio_chip[bank].bank->id, state); 288 irq_set_irq_wake(gpio_chip[bank].id, state);
289 289
290 return 0; 290 return 0;
291} 291}
@@ -302,7 +302,7 @@ void at91_gpio_suspend(void)
302 __raw_writel(wakeups[i], pio + PIO_IER); 302 __raw_writel(wakeups[i], pio + PIO_IER);
303 303
304 if (!wakeups[i]) 304 if (!wakeups[i])
305 clk_disable(gpio_chip[i].bank->clock); 305 clk_disable(gpio_chip[i].clock);
306 else { 306 else {
307#ifdef CONFIG_PM_DEBUG 307#ifdef CONFIG_PM_DEBUG
308 printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); 308 printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
@@ -319,7 +319,7 @@ void at91_gpio_resume(void)
319 void __iomem *pio = gpio_chip[i].regbase; 319 void __iomem *pio = gpio_chip[i].regbase;
320 320
321 if (!wakeups[i]) 321 if (!wakeups[i])
322 clk_enable(gpio_chip[i].bank->clock); 322 clk_enable(gpio_chip[i].clock);
323 323
324 __raw_writel(wakeups[i], pio + PIO_IDR); 324 __raw_writel(wakeups[i], pio + PIO_IDR);
325 __raw_writel(backups[i], pio + PIO_IER); 325 __raw_writel(backups[i], pio + PIO_IER);
@@ -344,8 +344,9 @@ void at91_gpio_resume(void)
344 344
345static void gpio_irq_mask(struct irq_data *d) 345static void gpio_irq_mask(struct irq_data *d)
346{ 346{
347 void __iomem *pio = pin_to_controller(d->irq); 347 unsigned pin = irq_to_gpio(d->irq);
348 unsigned mask = pin_to_mask(d->irq); 348 void __iomem *pio = pin_to_controller(pin);
349 unsigned mask = pin_to_mask(pin);
349 350
350 if (pio) 351 if (pio)
351 __raw_writel(mask, pio + PIO_IDR); 352 __raw_writel(mask, pio + PIO_IDR);
@@ -353,8 +354,9 @@ static void gpio_irq_mask(struct irq_data *d)
353 354
354static void gpio_irq_unmask(struct irq_data *d) 355static void gpio_irq_unmask(struct irq_data *d)
355{ 356{
356 void __iomem *pio = pin_to_controller(d->irq); 357 unsigned pin = irq_to_gpio(d->irq);
357 unsigned mask = pin_to_mask(d->irq); 358 void __iomem *pio = pin_to_controller(pin);
359 unsigned mask = pin_to_mask(pin);
358 360
359 if (pio) 361 if (pio)
360 __raw_writel(mask, pio + PIO_IER); 362 __raw_writel(mask, pio + PIO_IER);
@@ -382,7 +384,7 @@ static struct irq_chip gpio_irqchip = {
382 384
383static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) 385static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
384{ 386{
385 unsigned pin; 387 unsigned irq_pin;
386 struct irq_data *idata = irq_desc_get_irq_data(desc); 388 struct irq_data *idata = irq_desc_get_irq_data(desc);
387 struct irq_chip *chip = irq_data_get_irq_chip(idata); 389 struct irq_chip *chip = irq_data_get_irq_chip(idata);
388 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); 390 struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
@@ -405,12 +407,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
405 continue; 407 continue;
406 } 408 }
407 409
408 pin = at91_gpio->chip.base; 410 irq_pin = gpio_to_irq(at91_gpio->chip.base);
409 411
410 while (isr) { 412 while (isr) {
411 if (isr & 1) 413 if (isr & 1)
412 generic_handle_irq(pin); 414 generic_handle_irq(irq_pin);
413 pin++; 415 irq_pin++;
414 isr >>= 1; 416 isr >>= 1;
415 } 417 }
416 } 418 }
@@ -438,7 +440,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
438 seq_printf(s, "%i:\t", j); 440 seq_printf(s, "%i:\t", j);
439 441
440 for (bank = 0; bank < gpio_banks; bank++) { 442 for (bank = 0; bank < gpio_banks; bank++) {
441 unsigned pin = PIN_BASE + (32 * bank) + j; 443 unsigned pin = (32 * bank) + j;
442 void __iomem *pio = pin_to_controller(pin); 444 void __iomem *pio = pin_to_controller(pin);
443 unsigned mask = pin_to_mask(pin); 445 unsigned mask = pin_to_mask(pin);
444 446
@@ -491,27 +493,28 @@ static struct lock_class_key gpio_lock_class;
491 */ 493 */
492void __init at91_gpio_irq_setup(void) 494void __init at91_gpio_irq_setup(void)
493{ 495{
494 unsigned pioc, pin; 496 unsigned pioc, irq = gpio_to_irq(0);
495 struct at91_gpio_chip *this, *prev; 497 struct at91_gpio_chip *this, *prev;
496 498
497 for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL; 499 for (pioc = 0, this = gpio_chip, prev = NULL;
498 pioc++ < gpio_banks; 500 pioc++ < gpio_banks;
499 prev = this, this++) { 501 prev = this, this++) {
500 unsigned id = this->bank->id; 502 unsigned id = this->id;
501 unsigned i; 503 unsigned i;
502 504
503 __raw_writel(~0, this->regbase + PIO_IDR); 505 __raw_writel(~0, this->regbase + PIO_IDR);
504 506
505 for (i = 0, pin = this->chip.base; i < 32; i++, pin++) { 507 for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32;
506 irq_set_lockdep_class(pin, &gpio_lock_class); 508 i++, irq++) {
509 irq_set_lockdep_class(irq, &gpio_lock_class);
507 510
508 /* 511 /*
509 * Can use the "simple" and not "edge" handler since it's 512 * Can use the "simple" and not "edge" handler since it's
510 * shorter, and the AIC handles interrupts sanely. 513 * shorter, and the AIC handles interrupts sanely.
511 */ 514 */
512 irq_set_chip_and_handler(pin, &gpio_irqchip, 515 irq_set_chip_and_handler(irq, &gpio_irqchip,
513 handle_simple_irq); 516 handle_simple_irq);
514 set_irq_flags(pin, IRQF_VALID); 517 set_irq_flags(irq, IRQF_VALID);
515 } 518 }
516 519
517 /* The toplevel handler handles one bank of GPIOs, except 520 /* The toplevel handler handles one bank of GPIOs, except
@@ -524,7 +527,7 @@ void __init at91_gpio_irq_setup(void)
524 irq_set_chip_data(id, this); 527 irq_set_chip_data(id, this);
525 irq_set_chained_handler(id, gpio_irq_handler); 528 irq_set_chained_handler(id, gpio_irq_handler);
526 } 529 }
527 pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); 530 pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks);
528} 531}
529 532
530/* gpiolib support */ 533/* gpiolib support */
@@ -612,16 +615,26 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
612 for (i = 0; i < nr_banks; i++) { 615 for (i = 0; i < nr_banks; i++) {
613 at91_gpio = &gpio_chip[i]; 616 at91_gpio = &gpio_chip[i];
614 617
615 at91_gpio->bank = &data[i]; 618 at91_gpio->id = data[i].id;
616 at91_gpio->chip.base = PIN_BASE + i * 32; 619 at91_gpio->chip.base = i * 32;
617 at91_gpio->regbase = at91_gpio->bank->offset + 620
618 (void __iomem *)AT91_VA_BASE_SYS; 621 at91_gpio->regbase = ioremap(data[i].regbase, 512);
622 if (!at91_gpio->regbase) {
623 pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i);
624 continue;
625 }
626
627 at91_gpio->clock = clk_get_sys(NULL, at91_gpio->chip.label);
628 if (!at91_gpio->clock) {
629 pr_err("at91_gpio.%d, failed to get clock, ignoring.\n", i);
630 continue;
631 }
619 632
620 /* enable PIO controller's clock */ 633 /* enable PIO controller's clock */
621 clk_enable(at91_gpio->bank->clock); 634 clk_enable(at91_gpio->clock);
622 635
623 /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */ 636 /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
624 if (last && last->bank->id == at91_gpio->bank->id) 637 if (last && last->id == at91_gpio->id)
625 last->next = at91_gpio; 638 last->next = at91_gpio;
626 last = at91_gpio; 639 last = at91_gpio;
627 640
diff --git a/arch/arm/mach-at91/include/mach/at91_aic.h b/arch/arm/mach-at91/include/mach/at91_aic.h
index 03566799d3b..3045781c473 100644
--- a/arch/arm/mach-at91/include/mach/at91_aic.h
+++ b/arch/arm/mach-at91/include/mach/at91_aic.h
@@ -16,7 +16,19 @@
16#ifndef AT91_AIC_H 16#ifndef AT91_AIC_H
17#define AT91_AIC_H 17#define AT91_AIC_H
18 18
19#define AT91_AIC_SMR(n) (AT91_AIC + ((n) * 4)) /* Source Mode Registers 0-31 */ 19#ifndef __ASSEMBLY__
20extern void __iomem *at91_aic_base;
21
22#define at91_aic_read(field) \
23 __raw_readl(at91_aic_base + field)
24
25#define at91_aic_write(field, value) \
26 __raw_writel(value, at91_aic_base + field);
27#else
28.extern at91_aic_base
29#endif
30
31#define AT91_AIC_SMR(n) ((n) * 4) /* Source Mode Registers 0-31 */
20#define AT91_AIC_PRIOR (7 << 0) /* Priority Level */ 32#define AT91_AIC_PRIOR (7 << 0) /* Priority Level */
21#define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */ 33#define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */
22#define AT91_AIC_SRCTYPE_LOW (0 << 5) 34#define AT91_AIC_SRCTYPE_LOW (0 << 5)
@@ -24,30 +36,30 @@
24#define AT91_AIC_SRCTYPE_HIGH (2 << 5) 36#define AT91_AIC_SRCTYPE_HIGH (2 << 5)
25#define AT91_AIC_SRCTYPE_RISING (3 << 5) 37#define AT91_AIC_SRCTYPE_RISING (3 << 5)
26 38
27#define AT91_AIC_SVR(n) (AT91_AIC + 0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */ 39#define AT91_AIC_SVR(n) (0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */
28#define AT91_AIC_IVR (AT91_AIC + 0x100) /* Interrupt Vector Register */ 40#define AT91_AIC_IVR 0x100 /* Interrupt Vector Register */
29#define AT91_AIC_FVR (AT91_AIC + 0x104) /* Fast Interrupt Vector Register */ 41#define AT91_AIC_FVR 0x104 /* Fast Interrupt Vector Register */
30#define AT91_AIC_ISR (AT91_AIC + 0x108) /* Interrupt Status Register */ 42#define AT91_AIC_ISR 0x108 /* Interrupt Status Register */
31#define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */ 43#define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */
32 44
33#define AT91_AIC_IPR (AT91_AIC + 0x10c) /* Interrupt Pending Register */ 45#define AT91_AIC_IPR 0x10c /* Interrupt Pending Register */
34#define AT91_AIC_IMR (AT91_AIC + 0x110) /* Interrupt Mask Register */ 46#define AT91_AIC_IMR 0x110 /* Interrupt Mask Register */
35#define AT91_AIC_CISR (AT91_AIC + 0x114) /* Core Interrupt Status Register */ 47#define AT91_AIC_CISR 0x114 /* Core Interrupt Status Register */
36#define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */ 48#define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */
37#define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */ 49#define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */
38 50
39#define AT91_AIC_IECR (AT91_AIC + 0x120) /* Interrupt Enable Command Register */ 51#define AT91_AIC_IECR 0x120 /* Interrupt Enable Command Register */
40#define AT91_AIC_IDCR (AT91_AIC + 0x124) /* Interrupt Disable Command Register */ 52#define AT91_AIC_IDCR 0x124 /* Interrupt Disable Command Register */
41#define AT91_AIC_ICCR (AT91_AIC + 0x128) /* Interrupt Clear Command Register */ 53#define AT91_AIC_ICCR 0x128 /* Interrupt Clear Command Register */
42#define AT91_AIC_ISCR (AT91_AIC + 0x12c) /* Interrupt Set Command Register */ 54#define AT91_AIC_ISCR 0x12c /* Interrupt Set Command Register */
43#define AT91_AIC_EOICR (AT91_AIC + 0x130) /* End of Interrupt Command Register */ 55#define AT91_AIC_EOICR 0x130 /* End of Interrupt Command Register */
44#define AT91_AIC_SPU (AT91_AIC + 0x134) /* Spurious Interrupt Vector Register */ 56#define AT91_AIC_SPU 0x134 /* Spurious Interrupt Vector Register */
45#define AT91_AIC_DCR (AT91_AIC + 0x138) /* Debug Control Register */ 57#define AT91_AIC_DCR 0x138 /* Debug Control Register */
46#define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */ 58#define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */
47#define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */ 59#define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */
48 60
49#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */ 61#define AT91_AIC_FFER 0x140 /* Fast Forcing Enable Register [SAM9 only] */
50#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */ 62#define AT91_AIC_FFDR 0x144 /* Fast Forcing Disable Register [SAM9 only] */
51#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */ 63#define AT91_AIC_FFSR 0x148 /* Fast Forcing Status Register [SAM9 only] */
52 64
53#endif 65#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h
index dbfe455a4c4..2aa0c5e1349 100644
--- a/arch/arm/mach-at91/include/mach/at91_dbgu.h
+++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h
@@ -19,7 +19,7 @@
19#define dbgu_readl(dbgu, field) \ 19#define dbgu_readl(dbgu, field) \
20 __raw_readl(AT91_VA_BASE_SYS + dbgu + AT91_DBGU_ ## field) 20 __raw_readl(AT91_VA_BASE_SYS + dbgu + AT91_DBGU_ ## field)
21 21
22#ifdef AT91_DBGU 22#if !defined(CONFIG_ARCH_AT91X40)
23#define AT91_DBGU_CR (0x00) /* Control Register */ 23#define AT91_DBGU_CR (0x00) /* Control Register */
24#define AT91_DBGU_MR (0x04) /* Mode Register */ 24#define AT91_DBGU_MR (0x04) /* Mode Register */
25#define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ 25#define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */
diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h
index 974d0bd05b5..d1f80ad7f4d 100644
--- a/arch/arm/mach-at91/include/mach/at91_pit.h
+++ b/arch/arm/mach-at91/include/mach/at91_pit.h
@@ -16,16 +16,16 @@
16#ifndef AT91_PIT_H 16#ifndef AT91_PIT_H
17#define AT91_PIT_H 17#define AT91_PIT_H
18 18
19#define AT91_PIT_MR (AT91_PIT + 0x00) /* Mode Register */ 19#define AT91_PIT_MR 0x00 /* Mode Register */
20#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */ 20#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */
21#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */ 21#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */
22#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */ 22#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */
23 23
24#define AT91_PIT_SR (AT91_PIT + 0x04) /* Status Register */ 24#define AT91_PIT_SR 0x04 /* Status Register */
25#define AT91_PIT_PITS (1 << 0) /* Timer Status */ 25#define AT91_PIT_PITS (1 << 0) /* Timer Status */
26 26
27#define AT91_PIT_PIVR (AT91_PIT + 0x08) /* Periodic Interval Value Register */ 27#define AT91_PIT_PIVR 0x08 /* Periodic Interval Value Register */
28#define AT91_PIT_PIIR (AT91_PIT + 0x0c) /* Periodic Interval Image Register */ 28#define AT91_PIT_PIIR 0x0c /* Periodic Interval Image Register */
29#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */ 29#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */
30#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */ 30#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */
31 31
diff --git a/arch/arm/mach-at91/include/mach/at91_rtc.h b/arch/arm/mach-at91/include/mach/at91_rtc.h
index e56f4701a3e..da1945e5f71 100644
--- a/arch/arm/mach-at91/include/mach/at91_rtc.h
+++ b/arch/arm/mach-at91/include/mach/at91_rtc.h
@@ -16,7 +16,7 @@
16#ifndef AT91_RTC_H 16#ifndef AT91_RTC_H
17#define AT91_RTC_H 17#define AT91_RTC_H
18 18
19#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */ 19#define AT91_RTC_CR 0x00 /* Control Register */
20#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */ 20#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
21#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */ 21#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
22#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */ 22#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
@@ -29,44 +29,44 @@
29#define AT91_RTC_CALEVSEL_MONTH (1 << 16) 29#define AT91_RTC_CALEVSEL_MONTH (1 << 16)
30#define AT91_RTC_CALEVSEL_YEAR (2 << 16) 30#define AT91_RTC_CALEVSEL_YEAR (2 << 16)
31 31
32#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */ 32#define AT91_RTC_MR 0x04 /* Mode Register */
33#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */ 33#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
34 34
35#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */ 35#define AT91_RTC_TIMR 0x08 /* Time Register */
36#define AT91_RTC_SEC (0x7f << 0) /* Current Second */ 36#define AT91_RTC_SEC (0x7f << 0) /* Current Second */
37#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */ 37#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
38#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */ 38#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
39#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */ 39#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
40 40
41#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */ 41#define AT91_RTC_CALR 0x0c /* Calendar Register */
42#define AT91_RTC_CENT (0x7f << 0) /* Current Century */ 42#define AT91_RTC_CENT (0x7f << 0) /* Current Century */
43#define AT91_RTC_YEAR (0xff << 8) /* Current Year */ 43#define AT91_RTC_YEAR (0xff << 8) /* Current Year */
44#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */ 44#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
45#define AT91_RTC_DAY (7 << 21) /* Current Day */ 45#define AT91_RTC_DAY (7 << 21) /* Current Day */
46#define AT91_RTC_DATE (0x3f << 24) /* Current Date */ 46#define AT91_RTC_DATE (0x3f << 24) /* Current Date */
47 47
48#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */ 48#define AT91_RTC_TIMALR 0x10 /* Time Alarm Register */
49#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */ 49#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
50#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */ 50#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
51#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */ 51#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
52 52
53#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */ 53#define AT91_RTC_CALALR 0x14 /* Calendar Alarm Register */
54#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */ 54#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
55#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */ 55#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
56 56
57#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */ 57#define AT91_RTC_SR 0x18 /* Status Register */
58#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */ 58#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
59#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */ 59#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
60#define AT91_RTC_SECEV (1 << 2) /* Second Event */ 60#define AT91_RTC_SECEV (1 << 2) /* Second Event */
61#define AT91_RTC_TIMEV (1 << 3) /* Time Event */ 61#define AT91_RTC_TIMEV (1 << 3) /* Time Event */
62#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */ 62#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
63 63
64#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */ 64#define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */
65#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */ 65#define AT91_RTC_IER 0x20 /* Interrupt Enable Register */
66#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */ 66#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
67#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */ 67#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
68 68
69#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */ 69#define AT91_RTC_VER 0x2c /* Valid Entry Register */
70#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ 70#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
71#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */ 71#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
72#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */ 72#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h
index c4ce07e8a8f..1d4fe822c77 100644
--- a/arch/arm/mach-at91/include/mach/at91_shdwc.h
+++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h
@@ -16,11 +16,21 @@
16#ifndef AT91_SHDWC_H 16#ifndef AT91_SHDWC_H
17#define AT91_SHDWC_H 17#define AT91_SHDWC_H
18 18
19#define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ 19#ifndef __ASSEMBLY__
20extern void __iomem *at91_shdwc_base;
21
22#define at91_shdwc_read(field) \
23 __raw_readl(at91_shdwc_base + field)
24
25#define at91_shdwc_write(field, value) \
26 __raw_writel(value, at91_shdwc_base + field);
27#endif
28
29#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
20#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ 30#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
21#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ 31#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
22 32
23#define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ 33#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */
24#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ 34#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
25#define AT91_SHDW_WKMODE0_NONE 0 35#define AT91_SHDW_WKMODE0_NONE 0
26#define AT91_SHDW_WKMODE0_HIGH 1 36#define AT91_SHDW_WKMODE0_HIGH 1
@@ -30,7 +40,7 @@
30#define AT91_SHDW_CPTWK0_(x) ((x) << 4) 40#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
31#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */ 41#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
32 42
33#define AT91_SHDW_SR (AT91_SHDWC + 0x08) /* Shut Down Status Register */ 43#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */
34#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */ 44#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
35#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */ 45#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
36#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */ 46#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
index c5df1e8f195..4c0e2f6011d 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -79,29 +79,28 @@
79/* 79/*
80 * System Peripherals (offset from AT91_BASE_SYS) 80 * System Peripherals (offset from AT91_BASE_SYS)
81 */ 81 */
82#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
83#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS) 82#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS)
84#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) 83#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
85#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
86#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) 84#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
87#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS)
88#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
89#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
90#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
91#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
92#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
93#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
94#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
95#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 85#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
96#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 86#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
97#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
98#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
99#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
100#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
101#define AT91_GPBR (cpu_is_at91cap9_revB() ? \ 87#define AT91_GPBR (cpu_is_at91cap9_revB() ? \
102 (0xfffffd50 - AT91_BASE_SYS) : \ 88 (0xfffffd50 - AT91_BASE_SYS) : \
103 (0xfffffd60 - AT91_BASE_SYS)) 89 (0xfffffd60 - AT91_BASE_SYS))
104 90
91#define AT91CAP9_BASE_ECC 0xffffe200
92#define AT91CAP9_BASE_DMA 0xffffec00
93#define AT91CAP9_BASE_SMC 0xffffe800
94#define AT91CAP9_BASE_DBGU AT91_BASE_DBGU1
95#define AT91CAP9_BASE_PIOA 0xfffff200
96#define AT91CAP9_BASE_PIOB 0xfffff400
97#define AT91CAP9_BASE_PIOC 0xfffff600
98#define AT91CAP9_BASE_PIOD 0xfffff800
99#define AT91CAP9_BASE_SHDWC 0xfffffd10
100#define AT91CAP9_BASE_RTT 0xfffffd20
101#define AT91CAP9_BASE_PIT 0xfffffd30
102#define AT91CAP9_BASE_WDT 0xfffffd40
103
105#define AT91_USART0 AT91CAP9_BASE_US0 104#define AT91_USART0 AT91CAP9_BASE_US0
106#define AT91_USART1 AT91CAP9_BASE_US1 105#define AT91_USART1 AT91CAP9_BASE_US1
107#define AT91_USART2 AT91CAP9_BASE_US2 106#define AT91_USART2 AT91CAP9_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h
index e4037b50030..bacb5114181 100644
--- a/arch/arm/mach-at91/include/mach/at91rm9200.h
+++ b/arch/arm/mach-at91/include/mach/at91rm9200.h
@@ -79,17 +79,17 @@
79/* 79/*
80 * System Peripherals (offset from AT91_BASE_SYS) 80 * System Peripherals (offset from AT91_BASE_SYS)
81 */ 81 */
82#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */
83#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */
84#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */
85#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */
86#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */
87#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */
88#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */ 82#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */
89#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */ 83#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */
90#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */
91#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */ 84#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */
92 85
86#define AT91RM9200_BASE_DBGU AT91_BASE_DBGU0 /* Debug Unit */
87#define AT91RM9200_BASE_PIOA 0xfffff400 /* PIO Controller A */
88#define AT91RM9200_BASE_PIOB 0xfffff600 /* PIO Controller B */
89#define AT91RM9200_BASE_PIOC 0xfffff800 /* PIO Controller C */
90#define AT91RM9200_BASE_PIOD 0xfffffa00 /* PIO Controller D */
91#define AT91RM9200_BASE_RTC 0xfffffe00 /* Real-Time Clock */
92
93#define AT91_USART0 AT91RM9200_BASE_US0 93#define AT91_USART0 AT91RM9200_BASE_US0
94#define AT91_USART1 AT91RM9200_BASE_US1 94#define AT91_USART1 AT91RM9200_BASE_US1
95#define AT91_USART2 AT91RM9200_BASE_US2 95#define AT91_USART2 AT91RM9200_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h
index 9a791165913..f937c476bb6 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -80,24 +80,23 @@
80/* 80/*
81 * System Peripherals (offset from AT91_BASE_SYS) 81 * System Peripherals (offset from AT91_BASE_SYS)
82 */ 82 */
83#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
84#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) 83#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
85#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
86#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) 84#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
87#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
88#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
89#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
90#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
91#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
92#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
93#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 85#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
94#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 86#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
95#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
96#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
97#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
98#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
99#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) 87#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
100 88
89#define AT91SAM9260_BASE_ECC 0xffffe800
90#define AT91SAM9260_BASE_SMC 0xffffec00
91#define AT91SAM9260_BASE_DBGU AT91_BASE_DBGU0
92#define AT91SAM9260_BASE_PIOA 0xfffff400
93#define AT91SAM9260_BASE_PIOB 0xfffff600
94#define AT91SAM9260_BASE_PIOC 0xfffff800
95#define AT91SAM9260_BASE_SHDWC 0xfffffd10
96#define AT91SAM9260_BASE_RTT 0xfffffd20
97#define AT91SAM9260_BASE_PIT 0xfffffd30
98#define AT91SAM9260_BASE_WDT 0xfffffd40
99
101#define AT91_USART0 AT91SAM9260_BASE_US0 100#define AT91_USART0 AT91SAM9260_BASE_US0
102#define AT91_USART1 AT91SAM9260_BASE_US1 101#define AT91_USART1 AT91SAM9260_BASE_US1
103#define AT91_USART2 AT91SAM9260_BASE_US2 102#define AT91_USART2 AT91SAM9260_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index ce596204cef..175604e261b 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -66,21 +66,21 @@
66 * System Peripherals (offset from AT91_BASE_SYS) 66 * System Peripherals (offset from AT91_BASE_SYS)
67 */ 67 */
68#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) 68#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
69#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
70#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) 69#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
71#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
72#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
73#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
74#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
75#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
76#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 70#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
77#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 71#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
78#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
79#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
80#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
81#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
82#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) 72#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
83 73
74#define AT91SAM9261_BASE_SMC 0xffffec00
75#define AT91SAM9261_BASE_DBGU AT91_BASE_DBGU0
76#define AT91SAM9261_BASE_PIOA 0xfffff400
77#define AT91SAM9261_BASE_PIOB 0xfffff600
78#define AT91SAM9261_BASE_PIOC 0xfffff800
79#define AT91SAM9261_BASE_SHDWC 0xfffffd10
80#define AT91SAM9261_BASE_RTT 0xfffffd20
81#define AT91SAM9261_BASE_PIT 0xfffffd30
82#define AT91SAM9261_BASE_WDT 0xfffffd40
83
84#define AT91_USART0 AT91SAM9261_BASE_US0 84#define AT91_USART0 AT91SAM9261_BASE_US0
85#define AT91_USART1 AT91SAM9261_BASE_US1 85#define AT91_USART1 AT91SAM9261_BASE_US1
86#define AT91_USART2 AT91SAM9261_BASE_US2 86#define AT91_USART2 AT91SAM9261_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h
index f1b92961a2b..80c915002d8 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9263.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9263.h
@@ -74,30 +74,29 @@
74/* 74/*
75 * System Peripherals (offset from AT91_BASE_SYS) 75 * System Peripherals (offset from AT91_BASE_SYS)
76 */ 76 */
77#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS)
78#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS) 77#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS)
79#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS)
80#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS)
81#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) 78#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS)
82#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS)
83#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) 79#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS)
84#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS)
85#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
86#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
87#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
88#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
89#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
90#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
91#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
92#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 80#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
93#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 81#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
94#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
95#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS)
96#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
97#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
98#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS)
99#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) 82#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
100 83
84#define AT91SAM9263_BASE_ECC0 0xffffe000
85#define AT91SAM9263_BASE_SMC0 0xffffe400
86#define AT91SAM9263_BASE_ECC1 0xffffe600
87#define AT91SAM9263_BASE_SMC1 0xffffea00
88#define AT91SAM9263_BASE_DBGU AT91_BASE_DBGU1
89#define AT91SAM9263_BASE_PIOA 0xfffff200
90#define AT91SAM9263_BASE_PIOB 0xfffff400
91#define AT91SAM9263_BASE_PIOC 0xfffff600
92#define AT91SAM9263_BASE_PIOD 0xfffff800
93#define AT91SAM9263_BASE_PIOE 0xfffffa00
94#define AT91SAM9263_BASE_SHDWC 0xfffffd10
95#define AT91SAM9263_BASE_RTT0 0xfffffd20
96#define AT91SAM9263_BASE_PIT 0xfffffd30
97#define AT91SAM9263_BASE_WDT 0xfffffd40
98#define AT91SAM9263_BASE_RTT1 0xfffffd50
99
101#define AT91_USART0 AT91SAM9263_BASE_US0 100#define AT91_USART0 AT91SAM9263_BASE_US0
102#define AT91_USART1 AT91SAM9263_BASE_US1 101#define AT91_USART1 AT91SAM9263_BASE_US1
103#define AT91_USART2 AT91SAM9263_BASE_US2 102#define AT91_USART2 AT91SAM9263_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
index 57de6207e57..eb18a70fa64 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_smc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
@@ -16,7 +16,9 @@
16#ifndef AT91SAM9_SMC_H 16#ifndef AT91SAM9_SMC_H
17#define AT91SAM9_SMC_H 17#define AT91SAM9_SMC_H
18 18
19#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */ 19#include <mach/cpu.h>
20
21#define AT91_SMC_SETUP 0x00 /* Setup Register for CS n */
20#define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */ 22#define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */
21#define AT91_SMC_NWESETUP_(x) ((x) << 0) 23#define AT91_SMC_NWESETUP_(x) ((x) << 0)
22#define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */ 24#define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */
@@ -26,7 +28,7 @@
26#define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */ 28#define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */
27#define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24) 29#define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24)
28 30
29#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */ 31#define AT91_SMC_PULSE 0x04 /* Pulse Register for CS n */
30#define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */ 32#define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */
31#define AT91_SMC_NWEPULSE_(x) ((x) << 0) 33#define AT91_SMC_NWEPULSE_(x) ((x) << 0)
32#define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */ 34#define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */
@@ -36,13 +38,13 @@
36#define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */ 38#define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */
37#define AT91_SMC_NCS_RDPULSE_(x)((x) << 24) 39#define AT91_SMC_NCS_RDPULSE_(x)((x) << 24)
38 40
39#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */ 41#define AT91_SMC_CYCLE 0x08 /* Cycle Register for CS n */
40#define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */ 42#define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */
41#define AT91_SMC_NWECYCLE_(x) ((x) << 0) 43#define AT91_SMC_NWECYCLE_(x) ((x) << 0)
42#define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */ 44#define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */
43#define AT91_SMC_NRDCYCLE_(x) ((x) << 16) 45#define AT91_SMC_NRDCYCLE_(x) ((x) << 16)
44 46
45#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */ 47#define AT91_SMC_MODE 0x0c /* Mode Register for CS n */
46#define AT91_SMC_READMODE (1 << 0) /* Read Mode */ 48#define AT91_SMC_READMODE (1 << 0) /* Read Mode */
47#define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */ 49#define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */
48#define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */ 50#define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */
@@ -66,11 +68,4 @@
66#define AT91_SMC_PS_16 (2 << 28) 68#define AT91_SMC_PS_16 (2 << 28)
67#define AT91_SMC_PS_32 (3 << 28) 69#define AT91_SMC_PS_32 (3 << 28)
68 70
69#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */
70#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */
71#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */
72#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */
73#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */
74#endif
75
76#endif 71#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
index 406bb649680..f0c23c960de 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9g45.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -86,27 +86,27 @@
86/* 86/*
87 * System Peripherals (offset from AT91_BASE_SYS) 87 * System Peripherals (offset from AT91_BASE_SYS)
88 */ 88 */
89#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
90#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS) 89#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS)
91#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) 90#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
92#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
93#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) 91#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
94#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
95#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
96#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
97#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
98#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
99#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
100#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
101#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
102#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 92#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
103#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 93#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
104#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
105#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
106#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
107#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
108#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) 94#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
109#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS) 95
96#define AT91SAM9G45_BASE_ECC 0xffffe200
97#define AT91SAM9G45_BASE_DMA 0xffffec00
98#define AT91SAM9G45_BASE_SMC 0xffffe800
99#define AT91SAM9G45_BASE_DBGU AT91_BASE_DBGU1
100#define AT91SAM9G45_BASE_PIOA 0xfffff200
101#define AT91SAM9G45_BASE_PIOB 0xfffff400
102#define AT91SAM9G45_BASE_PIOC 0xfffff600
103#define AT91SAM9G45_BASE_PIOD 0xfffff800
104#define AT91SAM9G45_BASE_PIOE 0xfffffa00
105#define AT91SAM9G45_BASE_SHDWC 0xfffffd10
106#define AT91SAM9G45_BASE_RTT 0xfffffd20
107#define AT91SAM9G45_BASE_PIT 0xfffffd30
108#define AT91SAM9G45_BASE_WDT 0xfffffd40
109#define AT91SAM9G45_BASE_RTC 0xfffffdb0
110 110
111#define AT91_USART0 AT91SAM9G45_BASE_US0 111#define AT91_USART0 AT91SAM9G45_BASE_US0
112#define AT91_USART1 AT91SAM9G45_BASE_US1 112#define AT91_USART1 AT91SAM9G45_BASE_US1
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h
index 1aabacd315d..2bb359e60b9 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9rl.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -69,27 +69,26 @@
69/* 69/*
70 * System Peripherals (offset from AT91_BASE_SYS) 70 * System Peripherals (offset from AT91_BASE_SYS)
71 */ 71 */
72#define AT91_DMA (0xffffe600 - AT91_BASE_SYS)
73#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
74#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) 72#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
75#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
76#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) 73#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
77#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
78#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
79#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
80#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
81#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
82#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
83#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS)
84#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) 74#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
85#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) 75#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
86#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
87#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
88#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
89#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
90#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) 76#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS)
91#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) 77#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
92#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) 78
79#define AT91SAM9RL_BASE_DMA 0xffffe600
80#define AT91SAM9RL_BASE_ECC 0xffffe800
81#define AT91SAM9RL_BASE_SMC 0xffffec00
82#define AT91SAM9RL_BASE_DBGU AT91_BASE_DBGU0
83#define AT91SAM9RL_BASE_PIOA 0xfffff400
84#define AT91SAM9RL_BASE_PIOB 0xfffff600
85#define AT91SAM9RL_BASE_PIOC 0xfffff800
86#define AT91SAM9RL_BASE_PIOD 0xfffffa00
87#define AT91SAM9RL_BASE_SHDWC 0xfffffd10
88#define AT91SAM9RL_BASE_RTT 0xfffffd20
89#define AT91SAM9RL_BASE_PIT 0xfffffd30
90#define AT91SAM9RL_BASE_WDT 0xfffffd40
91#define AT91SAM9RL_BASE_RTC 0xfffffe00
93 92
94#define AT91_USART0 AT91SAM9RL_BASE_US0 93#define AT91_USART0 AT91SAM9RL_BASE_US0
95#define AT91_USART1 AT91SAM9RL_BASE_US1 94#define AT91_USART1 AT91SAM9RL_BASE_US1
diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h
index a152ff87e68..a57829f4fd1 100644
--- a/arch/arm/mach-at91/include/mach/at91x40.h
+++ b/arch/arm/mach-at91/include/mach/at91x40.h
@@ -40,7 +40,6 @@
40#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */ 40#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */
41#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */ 41#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */
42#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */ 42#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */
43#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */
44 43
45/* 44/*
46 * The AT91x40 series doesn't have a debug unit like the other AT91 parts. 45 * The AT91x40 series doesn't have a debug unit like the other AT91 parts.
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index eac92e995bb..d0b377b21bd 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -40,13 +40,14 @@
40#include <linux/atmel-mci.h> 40#include <linux/atmel-mci.h>
41#include <sound/atmel-ac97c.h> 41#include <sound/atmel-ac97c.h>
42#include <linux/serial.h> 42#include <linux/serial.h>
43#include <linux/platform_data/macb.h>
43 44
44 /* USB Device */ 45 /* USB Device */
45struct at91_udc_data { 46struct at91_udc_data {
46 u8 vbus_pin; /* high == host powering us */ 47 int vbus_pin; /* high == host powering us */
47 u8 vbus_active_low; /* vbus polarity */ 48 u8 vbus_active_low; /* vbus polarity */
48 u8 vbus_polled; /* Use polling, not interrupt */ 49 u8 vbus_polled; /* Use polling, not interrupt */
49 u8 pullup_pin; /* active == D+ pulled up */ 50 int pullup_pin; /* active == D+ pulled up */
50 u8 pullup_active_low; /* true == pullup_pin is active low */ 51 u8 pullup_active_low; /* true == pullup_pin is active low */
51}; 52};
52extern void __init at91_add_device_udc(struct at91_udc_data *data); 53extern void __init at91_add_device_udc(struct at91_udc_data *data);
@@ -56,10 +57,10 @@ extern void __init at91_add_device_usba(struct usba_platform_data *data);
56 57
57 /* Compact Flash */ 58 /* Compact Flash */
58struct at91_cf_data { 59struct at91_cf_data {
59 u8 irq_pin; /* I/O IRQ */ 60 int irq_pin; /* I/O IRQ */
60 u8 det_pin; /* Card detect */ 61 int det_pin; /* Card detect */
61 u8 vcc_pin; /* power switching */ 62 int vcc_pin; /* power switching */
62 u8 rst_pin; /* card reset */ 63 int rst_pin; /* card reset */
63 u8 chipselect; /* EBI Chip Select number */ 64 u8 chipselect; /* EBI Chip Select number */
64 u8 flags; 65 u8 flags;
65#define AT91_CF_TRUE_IDE 0x01 66#define AT91_CF_TRUE_IDE 0x01
@@ -70,37 +71,26 @@ extern void __init at91_add_device_cf(struct at91_cf_data *data);
70 /* MMC / SD */ 71 /* MMC / SD */
71 /* at91_mci platform config */ 72 /* at91_mci platform config */
72struct at91_mmc_data { 73struct at91_mmc_data {
73 u8 det_pin; /* card detect IRQ */ 74 int det_pin; /* card detect IRQ */
74 unsigned slot_b:1; /* uses Slot B */ 75 unsigned slot_b:1; /* uses Slot B */
75 unsigned wire4:1; /* (SD) supports DAT0..DAT3 */ 76 unsigned wire4:1; /* (SD) supports DAT0..DAT3 */
76 u8 wp_pin; /* (SD) writeprotect detect */ 77 int wp_pin; /* (SD) writeprotect detect */
77 u8 vcc_pin; /* power switching (high == on) */ 78 int vcc_pin; /* power switching (high == on) */
78}; 79};
79extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data); 80extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
80 81
81 /* atmel-mci platform config */ 82 /* atmel-mci platform config */
82extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data); 83extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
83 84
84 /* Ethernet (EMAC & MACB) */ 85extern void __init at91_add_device_eth(struct macb_platform_data *data);
85struct at91_eth_data {
86 u32 phy_mask;
87 u8 phy_irq_pin; /* PHY IRQ */
88 u8 is_rmii; /* using RMII interface? */
89};
90extern void __init at91_add_device_eth(struct at91_eth_data *data);
91
92#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
93 || defined(CONFIG_ARCH_AT91SAM9G45)
94#define eth_platform_data at91_eth_data
95#endif
96 86
97 /* USB Host */ 87 /* USB Host */
98struct at91_usbh_data { 88struct at91_usbh_data {
99 u8 ports; /* number of ports on root hub */ 89 u8 ports; /* number of ports on root hub */
100 u8 vbus_pin[2]; /* port power-control pin */ 90 int vbus_pin[2]; /* port power-control pin */
101 u8 vbus_pin_inverted; 91 u8 vbus_pin_inverted;
102 u8 overcurrent_supported; 92 u8 overcurrent_supported;
103 u8 overcurrent_pin[2]; 93 int overcurrent_pin[2];
104 u8 overcurrent_status[2]; 94 u8 overcurrent_status[2];
105 u8 overcurrent_changed[2]; 95 u8 overcurrent_changed[2];
106}; 96};
@@ -110,9 +100,9 @@ extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
110 100
111 /* NAND / SmartMedia */ 101 /* NAND / SmartMedia */
112struct atmel_nand_data { 102struct atmel_nand_data {
113 u8 enable_pin; /* chip enable */ 103 int enable_pin; /* chip enable */
114 u8 det_pin; /* card detect */ 104 int det_pin; /* card detect */
115 u8 rdy_pin; /* ready/busy */ 105 int rdy_pin; /* ready/busy */
116 u8 rdy_pin_active_low; /* rdy_pin value is inverted */ 106 u8 rdy_pin_active_low; /* rdy_pin value is inverted */
117 u8 ale; /* address line number connected to ALE */ 107 u8 ale; /* address line number connected to ALE */
118 u8 cle; /* address line number connected to CLE */ 108 u8 cle; /* address line number connected to CLE */
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S
index 0ed8648c645..c6bb9e2d9ba 100644
--- a/arch/arm/mach-at91/include/mach/debug-macro.S
+++ b/arch/arm/mach-at91/include/mach/debug-macro.S
@@ -14,9 +14,15 @@
14#include <mach/hardware.h> 14#include <mach/hardware.h>
15#include <mach/at91_dbgu.h> 15#include <mach/at91_dbgu.h>
16 16
17#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
18#define AT91_DBGU AT91_BASE_DBGU0
19#else
20#define AT91_DBGU AT91_BASE_DBGU1
21#endif
22
17 .macro addruart, rp, rv, tmp 23 .macro addruart, rp, rv, tmp
18 ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address) 24 ldr \rp, =AT91_DBGU @ System peripherals (phys address)
19 ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address) 25 ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address)
20 .endm 26 .endm
21 27
22 .macro senduart,rd,rx 28 .macro senduart,rd,rx
diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S
index 7ab68f97222..423eea0ed74 100644
--- a/arch/arm/mach-at91/include/mach/entry-macro.S
+++ b/arch/arm/mach-at91/include/mach/entry-macro.S
@@ -17,16 +17,17 @@
17 .endm 17 .endm
18 18
19 .macro get_irqnr_preamble, base, tmp 19 .macro get_irqnr_preamble, base, tmp
20 ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral 20 ldr \base, =at91_aic_base @ base virtual address of AIC peripheral
21 ldr \base, [\base]
21 .endm 22 .endm
22 23
23 .macro arch_ret_to_user, tmp1, tmp2 24 .macro arch_ret_to_user, tmp1, tmp2
24 .endm 25 .endm
25 26
26 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 27 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
27 ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) 28 ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
28 ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number 29 ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number
29 teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt 30 teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt
30 streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now. 31 streq \tmp, [\base, #AT91_AIC_EOICR] @ not going to be handled further, then ACK it now.
31 .endm 32 .endm
32 33
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index 2b9a1f51210..e3fd225121c 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -16,177 +16,175 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <asm/irq.h> 17#include <asm/irq.h>
18 18
19#define PIN_BASE NR_AIC_IRQS
20
21#define MAX_GPIO_BANKS 5 19#define MAX_GPIO_BANKS 5
22#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32)) 20#define NR_BUILTIN_GPIO (MAX_GPIO_BANKS * 32)
23 21
24/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ 22/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
25 23
26#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) 24#define AT91_PIN_PA0 (0x00 + 0)
27#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) 25#define AT91_PIN_PA1 (0x00 + 1)
28#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) 26#define AT91_PIN_PA2 (0x00 + 2)
29#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) 27#define AT91_PIN_PA3 (0x00 + 3)
30#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) 28#define AT91_PIN_PA4 (0x00 + 4)
31#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) 29#define AT91_PIN_PA5 (0x00 + 5)
32#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) 30#define AT91_PIN_PA6 (0x00 + 6)
33#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) 31#define AT91_PIN_PA7 (0x00 + 7)
34#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) 32#define AT91_PIN_PA8 (0x00 + 8)
35#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) 33#define AT91_PIN_PA9 (0x00 + 9)
36#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) 34#define AT91_PIN_PA10 (0x00 + 10)
37#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) 35#define AT91_PIN_PA11 (0x00 + 11)
38#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) 36#define AT91_PIN_PA12 (0x00 + 12)
39#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) 37#define AT91_PIN_PA13 (0x00 + 13)
40#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) 38#define AT91_PIN_PA14 (0x00 + 14)
41#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) 39#define AT91_PIN_PA15 (0x00 + 15)
42#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) 40#define AT91_PIN_PA16 (0x00 + 16)
43#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) 41#define AT91_PIN_PA17 (0x00 + 17)
44#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) 42#define AT91_PIN_PA18 (0x00 + 18)
45#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) 43#define AT91_PIN_PA19 (0x00 + 19)
46#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) 44#define AT91_PIN_PA20 (0x00 + 20)
47#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) 45#define AT91_PIN_PA21 (0x00 + 21)
48#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) 46#define AT91_PIN_PA22 (0x00 + 22)
49#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) 47#define AT91_PIN_PA23 (0x00 + 23)
50#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) 48#define AT91_PIN_PA24 (0x00 + 24)
51#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) 49#define AT91_PIN_PA25 (0x00 + 25)
52#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) 50#define AT91_PIN_PA26 (0x00 + 26)
53#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) 51#define AT91_PIN_PA27 (0x00 + 27)
54#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) 52#define AT91_PIN_PA28 (0x00 + 28)
55#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) 53#define AT91_PIN_PA29 (0x00 + 29)
56#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) 54#define AT91_PIN_PA30 (0x00 + 30)
57#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) 55#define AT91_PIN_PA31 (0x00 + 31)
58 56
59#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) 57#define AT91_PIN_PB0 (0x20 + 0)
60#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) 58#define AT91_PIN_PB1 (0x20 + 1)
61#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) 59#define AT91_PIN_PB2 (0x20 + 2)
62#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) 60#define AT91_PIN_PB3 (0x20 + 3)
63#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) 61#define AT91_PIN_PB4 (0x20 + 4)
64#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) 62#define AT91_PIN_PB5 (0x20 + 5)
65#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) 63#define AT91_PIN_PB6 (0x20 + 6)
66#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) 64#define AT91_PIN_PB7 (0x20 + 7)
67#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) 65#define AT91_PIN_PB8 (0x20 + 8)
68#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) 66#define AT91_PIN_PB9 (0x20 + 9)
69#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) 67#define AT91_PIN_PB10 (0x20 + 10)
70#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) 68#define AT91_PIN_PB11 (0x20 + 11)
71#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) 69#define AT91_PIN_PB12 (0x20 + 12)
72#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) 70#define AT91_PIN_PB13 (0x20 + 13)
73#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) 71#define AT91_PIN_PB14 (0x20 + 14)
74#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) 72#define AT91_PIN_PB15 (0x20 + 15)
75#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) 73#define AT91_PIN_PB16 (0x20 + 16)
76#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) 74#define AT91_PIN_PB17 (0x20 + 17)
77#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) 75#define AT91_PIN_PB18 (0x20 + 18)
78#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) 76#define AT91_PIN_PB19 (0x20 + 19)
79#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) 77#define AT91_PIN_PB20 (0x20 + 20)
80#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) 78#define AT91_PIN_PB21 (0x20 + 21)
81#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) 79#define AT91_PIN_PB22 (0x20 + 22)
82#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) 80#define AT91_PIN_PB23 (0x20 + 23)
83#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) 81#define AT91_PIN_PB24 (0x20 + 24)
84#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) 82#define AT91_PIN_PB25 (0x20 + 25)
85#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) 83#define AT91_PIN_PB26 (0x20 + 26)
86#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) 84#define AT91_PIN_PB27 (0x20 + 27)
87#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) 85#define AT91_PIN_PB28 (0x20 + 28)
88#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) 86#define AT91_PIN_PB29 (0x20 + 29)
89#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) 87#define AT91_PIN_PB30 (0x20 + 30)
90#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) 88#define AT91_PIN_PB31 (0x20 + 31)
91 89
92#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) 90#define AT91_PIN_PC0 (0x40 + 0)
93#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) 91#define AT91_PIN_PC1 (0x40 + 1)
94#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) 92#define AT91_PIN_PC2 (0x40 + 2)
95#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) 93#define AT91_PIN_PC3 (0x40 + 3)
96#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) 94#define AT91_PIN_PC4 (0x40 + 4)
97#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) 95#define AT91_PIN_PC5 (0x40 + 5)
98#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) 96#define AT91_PIN_PC6 (0x40 + 6)
99#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) 97#define AT91_PIN_PC7 (0x40 + 7)
100#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) 98#define AT91_PIN_PC8 (0x40 + 8)
101#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) 99#define AT91_PIN_PC9 (0x40 + 9)
102#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) 100#define AT91_PIN_PC10 (0x40 + 10)
103#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) 101#define AT91_PIN_PC11 (0x40 + 11)
104#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) 102#define AT91_PIN_PC12 (0x40 + 12)
105#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) 103#define AT91_PIN_PC13 (0x40 + 13)
106#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) 104#define AT91_PIN_PC14 (0x40 + 14)
107#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) 105#define AT91_PIN_PC15 (0x40 + 15)
108#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) 106#define AT91_PIN_PC16 (0x40 + 16)
109#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) 107#define AT91_PIN_PC17 (0x40 + 17)
110#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) 108#define AT91_PIN_PC18 (0x40 + 18)
111#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) 109#define AT91_PIN_PC19 (0x40 + 19)
112#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) 110#define AT91_PIN_PC20 (0x40 + 20)
113#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) 111#define AT91_PIN_PC21 (0x40 + 21)
114#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) 112#define AT91_PIN_PC22 (0x40 + 22)
115#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) 113#define AT91_PIN_PC23 (0x40 + 23)
116#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) 114#define AT91_PIN_PC24 (0x40 + 24)
117#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) 115#define AT91_PIN_PC25 (0x40 + 25)
118#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) 116#define AT91_PIN_PC26 (0x40 + 26)
119#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) 117#define AT91_PIN_PC27 (0x40 + 27)
120#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) 118#define AT91_PIN_PC28 (0x40 + 28)
121#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) 119#define AT91_PIN_PC29 (0x40 + 29)
122#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) 120#define AT91_PIN_PC30 (0x40 + 30)
123#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) 121#define AT91_PIN_PC31 (0x40 + 31)
124 122
125#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) 123#define AT91_PIN_PD0 (0x60 + 0)
126#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) 124#define AT91_PIN_PD1 (0x60 + 1)
127#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) 125#define AT91_PIN_PD2 (0x60 + 2)
128#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) 126#define AT91_PIN_PD3 (0x60 + 3)
129#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) 127#define AT91_PIN_PD4 (0x60 + 4)
130#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) 128#define AT91_PIN_PD5 (0x60 + 5)
131#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) 129#define AT91_PIN_PD6 (0x60 + 6)
132#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) 130#define AT91_PIN_PD7 (0x60 + 7)
133#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) 131#define AT91_PIN_PD8 (0x60 + 8)
134#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) 132#define AT91_PIN_PD9 (0x60 + 9)
135#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) 133#define AT91_PIN_PD10 (0x60 + 10)
136#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) 134#define AT91_PIN_PD11 (0x60 + 11)
137#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) 135#define AT91_PIN_PD12 (0x60 + 12)
138#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) 136#define AT91_PIN_PD13 (0x60 + 13)
139#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) 137#define AT91_PIN_PD14 (0x60 + 14)
140#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) 138#define AT91_PIN_PD15 (0x60 + 15)
141#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) 139#define AT91_PIN_PD16 (0x60 + 16)
142#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) 140#define AT91_PIN_PD17 (0x60 + 17)
143#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) 141#define AT91_PIN_PD18 (0x60 + 18)
144#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) 142#define AT91_PIN_PD19 (0x60 + 19)
145#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) 143#define AT91_PIN_PD20 (0x60 + 20)
146#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) 144#define AT91_PIN_PD21 (0x60 + 21)
147#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) 145#define AT91_PIN_PD22 (0x60 + 22)
148#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) 146#define AT91_PIN_PD23 (0x60 + 23)
149#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) 147#define AT91_PIN_PD24 (0x60 + 24)
150#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) 148#define AT91_PIN_PD25 (0x60 + 25)
151#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) 149#define AT91_PIN_PD26 (0x60 + 26)
152#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) 150#define AT91_PIN_PD27 (0x60 + 27)
153#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) 151#define AT91_PIN_PD28 (0x60 + 28)
154#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) 152#define AT91_PIN_PD29 (0x60 + 29)
155#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) 153#define AT91_PIN_PD30 (0x60 + 30)
156#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) 154#define AT91_PIN_PD31 (0x60 + 31)
157 155
158#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) 156#define AT91_PIN_PE0 (0x80 + 0)
159#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) 157#define AT91_PIN_PE1 (0x80 + 1)
160#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) 158#define AT91_PIN_PE2 (0x80 + 2)
161#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) 159#define AT91_PIN_PE3 (0x80 + 3)
162#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) 160#define AT91_PIN_PE4 (0x80 + 4)
163#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) 161#define AT91_PIN_PE5 (0x80 + 5)
164#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) 162#define AT91_PIN_PE6 (0x80 + 6)
165#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) 163#define AT91_PIN_PE7 (0x80 + 7)
166#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) 164#define AT91_PIN_PE8 (0x80 + 8)
167#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) 165#define AT91_PIN_PE9 (0x80 + 9)
168#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) 166#define AT91_PIN_PE10 (0x80 + 10)
169#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) 167#define AT91_PIN_PE11 (0x80 + 11)
170#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) 168#define AT91_PIN_PE12 (0x80 + 12)
171#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) 169#define AT91_PIN_PE13 (0x80 + 13)
172#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) 170#define AT91_PIN_PE14 (0x80 + 14)
173#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) 171#define AT91_PIN_PE15 (0x80 + 15)
174#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) 172#define AT91_PIN_PE16 (0x80 + 16)
175#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) 173#define AT91_PIN_PE17 (0x80 + 17)
176#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) 174#define AT91_PIN_PE18 (0x80 + 18)
177#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) 175#define AT91_PIN_PE19 (0x80 + 19)
178#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) 176#define AT91_PIN_PE20 (0x80 + 20)
179#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) 177#define AT91_PIN_PE21 (0x80 + 21)
180#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) 178#define AT91_PIN_PE22 (0x80 + 22)
181#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) 179#define AT91_PIN_PE23 (0x80 + 23)
182#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) 180#define AT91_PIN_PE24 (0x80 + 24)
183#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) 181#define AT91_PIN_PE25 (0x80 + 25)
184#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) 182#define AT91_PIN_PE26 (0x80 + 26)
185#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) 183#define AT91_PIN_PE27 (0x80 + 27)
186#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) 184#define AT91_PIN_PE28 (0x80 + 28)
187#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) 185#define AT91_PIN_PE29 (0x80 + 29)
188#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) 186#define AT91_PIN_PE30 (0x80 + 30)
189#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) 187#define AT91_PIN_PE31 (0x80 + 31)
190 188
191#ifndef __ASSEMBLY__ 189#ifndef __ASSEMBLY__
192/* setup setup routines, called from board init or driver probe() */ 190/* setup setup routines, called from board init or driver probe() */
@@ -215,8 +213,8 @@ extern void at91_gpio_resume(void);
215 213
216#include <asm/errno.h> 214#include <asm/errno.h>
217 215
218#define gpio_to_irq(gpio) (gpio) 216#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS)
219#define irq_to_gpio(irq) (irq) 217#define irq_to_gpio(irq) (irq - NR_AIC_IRQS)
220 218
221#endif /* __ASSEMBLY__ */ 219#endif /* __ASSEMBLY__ */
222 220
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 483478d8be6..2d0e4e99856 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -16,6 +16,12 @@
16 16
17#include <asm/sizes.h> 17#include <asm/sizes.h>
18 18
19/* DBGU base */
20/* rm9200, 9260/9g20, 9261/9g10, 9rl */
21#define AT91_BASE_DBGU0 0xfffff200
22/* 9263, 9g45, cap9 */
23#define AT91_BASE_DBGU1 0xffffee00
24
19#if defined(CONFIG_ARCH_AT91RM9200) 25#if defined(CONFIG_ARCH_AT91RM9200)
20#include <mach/at91rm9200.h> 26#include <mach/at91rm9200.h>
21#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20) 27#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
@@ -52,6 +58,12 @@
52#endif 58#endif
53 59
54/* 60/*
61 * On all at91 have the Advanced Interrupt Controller starts at address
62 * 0xfffff000
63 */
64#define AT91_AIC 0xfffff000
65
66/*
55 * Peripheral identifiers/interrupts. 67 * Peripheral identifiers/interrupts.
56 */ 68 */
57#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */ 69#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h
index 36bd55f3fc6..ac8b7dfc85e 100644
--- a/arch/arm/mach-at91/include/mach/irqs.h
+++ b/arch/arm/mach-at91/include/mach/irqs.h
@@ -31,7 +31,7 @@
31 * Acknowledge interrupt with AIC after interrupt has been handled. 31 * Acknowledge interrupt with AIC after interrupt has been handled.
32 * (by kernel/irq.c) 32 * (by kernel/irq.c)
33 */ 33 */
34#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0) 34#define irq_finish(irq) do { at91_aic_write(AT91_AIC_EOICR, 0); } while (0)
35 35
36 36
37/* 37/*
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
index 85820ad801c..5e917a66edd 100644
--- a/arch/arm/mach-at91/include/mach/timex.h
+++ b/arch/arm/mach-at91/include/mach/timex.h
@@ -23,70 +23,15 @@
23 23
24#include <mach/hardware.h> 24#include <mach/hardware.h>
25 25
26#if defined(CONFIG_ARCH_AT91RM9200) 26#ifdef CONFIG_ARCH_AT91X40
27 27
28#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK) 28#define AT91X40_MASTER_CLOCK 40000000
29 29#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
30#elif defined(CONFIG_ARCH_AT91SAM9260)
31
32#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260)
33#define AT91SAM9_MASTER_CLOCK 90000000
34#else
35#define AT91SAM9_MASTER_CLOCK 99300000
36#endif
37
38#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
39
40#elif defined(CONFIG_ARCH_AT91SAM9261)
41
42#define AT91SAM9_MASTER_CLOCK 99300000
43#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
44
45#elif defined(CONFIG_ARCH_AT91SAM9G10)
46
47#define AT91SAM9_MASTER_CLOCK 133000000
48#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
49
50#elif defined(CONFIG_ARCH_AT91SAM9263)
51
52#if defined(CONFIG_MACH_USB_A9263)
53#define AT91SAM9_MASTER_CLOCK 90000000
54#else
55#define AT91SAM9_MASTER_CLOCK 99959500
56#endif
57
58#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
59
60#elif defined(CONFIG_ARCH_AT91SAM9RL)
61
62#define AT91SAM9_MASTER_CLOCK 100000000
63#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
64
65#elif defined(CONFIG_ARCH_AT91SAM9G20)
66 30
67#if defined(CONFIG_MACH_USB_A9G20)
68#define AT91SAM9_MASTER_CLOCK 133000000
69#else 31#else
70#define AT91SAM9_MASTER_CLOCK 132096000
71#endif
72
73#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
74
75#elif defined(CONFIG_ARCH_AT91SAM9G45)
76 32
77#define AT91SAM9_MASTER_CLOCK 133333333 33#define CLOCK_TICK_RATE 12345678
78#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
79
80#elif defined(CONFIG_ARCH_AT91CAP9)
81
82#define AT91CAP9_MASTER_CLOCK 100000000
83#define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16)
84
85#elif defined(CONFIG_ARCH_AT91X40)
86
87#define AT91X40_MASTER_CLOCK 40000000
88#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
89 34
90#endif 35#endif
91 36
92#endif 37#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h
index 18bdcdeb474..0234fd9d20d 100644
--- a/arch/arm/mach-at91/include/mach/uncompress.h
+++ b/arch/arm/mach-at91/include/mach/uncompress.h
@@ -24,8 +24,10 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/atmel_serial.h> 25#include <linux/atmel_serial.h>
26 26
27#if defined(CONFIG_AT91_EARLY_DBGU) 27#if defined(CONFIG_AT91_EARLY_DBGU0)
28#define UART_OFFSET (AT91_DBGU + AT91_BASE_SYS) 28#define UART_OFFSET AT91_BASE_DBGU0
29#elif defined(CONFIG_AT91_EARLY_DBGU1)
30#define UART_OFFSET AT91_BASE_DBGU1
29#elif defined(CONFIG_AT91_EARLY_USART0) 31#elif defined(CONFIG_AT91_EARLY_USART0)
30#define UART_OFFSET AT91_USART0 32#define UART_OFFSET AT91_USART0
31#elif defined(CONFIG_AT91_EARLY_USART1) 33#elif defined(CONFIG_AT91_EARLY_USART1)
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index 9665265ec75..be6b639ecd7 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -33,17 +33,18 @@
33#include <asm/mach/irq.h> 33#include <asm/mach/irq.h>
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35 35
36void __iomem *at91_aic_base;
36 37
37static void at91_aic_mask_irq(struct irq_data *d) 38static void at91_aic_mask_irq(struct irq_data *d)
38{ 39{
39 /* Disable interrupt on AIC */ 40 /* Disable interrupt on AIC */
40 at91_sys_write(AT91_AIC_IDCR, 1 << d->irq); 41 at91_aic_write(AT91_AIC_IDCR, 1 << d->irq);
41} 42}
42 43
43static void at91_aic_unmask_irq(struct irq_data *d) 44static void at91_aic_unmask_irq(struct irq_data *d)
44{ 45{
45 /* Enable interrupt on AIC */ 46 /* Enable interrupt on AIC */
46 at91_sys_write(AT91_AIC_IECR, 1 << d->irq); 47 at91_aic_write(AT91_AIC_IECR, 1 << d->irq);
47} 48}
48 49
49unsigned int at91_extern_irq; 50unsigned int at91_extern_irq;
@@ -77,8 +78,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
77 return -EINVAL; 78 return -EINVAL;
78 } 79 }
79 80
80 smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE; 81 smr = at91_aic_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE;
81 at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype); 82 at91_aic_write(AT91_AIC_SMR(d->irq), smr | srctype);
82 return 0; 83 return 0;
83} 84}
84 85
@@ -102,15 +103,15 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
102 103
103void at91_irq_suspend(void) 104void at91_irq_suspend(void)
104{ 105{
105 backups = at91_sys_read(AT91_AIC_IMR); 106 backups = at91_aic_read(AT91_AIC_IMR);
106 at91_sys_write(AT91_AIC_IDCR, backups); 107 at91_aic_write(AT91_AIC_IDCR, backups);
107 at91_sys_write(AT91_AIC_IECR, wakeups); 108 at91_aic_write(AT91_AIC_IECR, wakeups);
108} 109}
109 110
110void at91_irq_resume(void) 111void at91_irq_resume(void)
111{ 112{
112 at91_sys_write(AT91_AIC_IDCR, wakeups); 113 at91_aic_write(AT91_AIC_IDCR, wakeups);
113 at91_sys_write(AT91_AIC_IECR, backups); 114 at91_aic_write(AT91_AIC_IECR, backups);
114} 115}
115 116
116#else 117#else
@@ -133,34 +134,39 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
133{ 134{
134 unsigned int i; 135 unsigned int i;
135 136
137 at91_aic_base = ioremap(AT91_AIC, 512);
138
139 if (!at91_aic_base)
140 panic("Impossible to ioremap AT91_AIC\n");
141
136 /* 142 /*
137 * The IVR is used by macro get_irqnr_and_base to read and verify. 143 * The IVR is used by macro get_irqnr_and_base to read and verify.
138 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. 144 * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
139 */ 145 */
140 for (i = 0; i < NR_AIC_IRQS; i++) { 146 for (i = 0; i < NR_AIC_IRQS; i++) {
141 /* Put irq number in Source Vector Register: */ 147 /* Put irq number in Source Vector Register: */
142 at91_sys_write(AT91_AIC_SVR(i), i); 148 at91_aic_write(AT91_AIC_SVR(i), i);
143 /* Active Low interrupt, with the specified priority */ 149 /* Active Low interrupt, with the specified priority */
144 at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); 150 at91_aic_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
145 151
146 irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq); 152 irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
147 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 153 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
148 154
149 /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ 155 /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
150 if (i < 8) 156 if (i < 8)
151 at91_sys_write(AT91_AIC_EOICR, 0); 157 at91_aic_write(AT91_AIC_EOICR, 0);
152 } 158 }
153 159
154 /* 160 /*
155 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS 161 * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
156 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU 162 * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
157 */ 163 */
158 at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS); 164 at91_aic_write(AT91_AIC_SPU, NR_AIC_IRQS);
159 165
160 /* No debugging in AIC: Debug (Protect) Control Register */ 166 /* No debugging in AIC: Debug (Protect) Control Register */
161 at91_sys_write(AT91_AIC_DCR, 0); 167 at91_aic_write(AT91_AIC_DCR, 0);
162 168
163 /* Disable and clear all interrupts initially */ 169 /* Disable and clear all interrupts initially */
164 at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF); 170 at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
165 at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF); 171 at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
166} 172}
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 7046158109d..62ad95556c3 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -34,7 +34,7 @@
34/* 34/*
35 * Show the reason for the previous system reset. 35 * Show the reason for the previous system reset.
36 */ 36 */
37#if defined(AT91_SHDWC) 37#if defined(AT91_RSTC)
38 38
39#include <mach/at91_rstc.h> 39#include <mach/at91_rstc.h>
40#include <mach/at91_shdwc.h> 40#include <mach/at91_shdwc.h>
@@ -58,8 +58,11 @@ static void __init show_reset_status(void)
58 char *reason, *r2 = reset; 58 char *reason, *r2 = reset;
59 u32 reset_type, wake_type; 59 u32 reset_type, wake_type;
60 60
61 if (!at91_shdwc_base)
62 return;
63
61 reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; 64 reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
62 wake_type = at91_sys_read(AT91_SHDW_SR); 65 wake_type = at91_shdwc_read(AT91_SHDW_SR);
63 66
64 switch (reset_type) { 67 switch (reset_type) {
65 case AT91_RSTC_RSTTYP_GENERAL: 68 case AT91_RSTC_RSTTYP_GENERAL:
@@ -215,7 +218,7 @@ static int at91_pm_enter(suspend_state_t state)
215 | (1 << AT91_ID_FIQ) 218 | (1 << AT91_ID_FIQ)
216 | (1 << AT91_ID_SYS) 219 | (1 << AT91_ID_SYS)
217 | (at91_extern_irq)) 220 | (at91_extern_irq))
218 & at91_sys_read(AT91_AIC_IMR), 221 & at91_aic_read(AT91_AIC_IMR),
219 state); 222 state);
220 223
221 switch (state) { 224 switch (state) {
@@ -283,7 +286,7 @@ static int at91_pm_enter(suspend_state_t state)
283 } 286 }
284 287
285 pr_debug("AT91: PM - wakeup %08x\n", 288 pr_debug("AT91: PM - wakeup %08x\n",
286 at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); 289 at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));
287 290
288error: 291error:
289 target_state = PM_SUSPEND_ON; 292 target_state = PM_SUSPEND_ON;
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
index 5eab6aa621d..8294783b679 100644
--- a/arch/arm/mach-at91/sam9_smc.c
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -10,38 +10,58 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
13 15
14#include <mach/at91sam9_smc.h> 16#include <mach/at91sam9_smc.h>
15 17
16#include "sam9_smc.h" 18#include "sam9_smc.h"
17 19
18void __init sam9_smc_configure(int cs, struct sam9_smc_config* config) 20
21#define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * 0x10))
22
23static void __iomem *smc_base_addr[2];
24
25static void __init sam9_smc_cs_configure(void __iomem *base, struct sam9_smc_config* config)
19{ 26{
27
20 /* Setup register */ 28 /* Setup register */
21 at91_sys_write(AT91_SMC_SETUP(cs), 29 __raw_writel(AT91_SMC_NWESETUP_(config->nwe_setup)
22 AT91_SMC_NWESETUP_(config->nwe_setup) 30 | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup)
23 | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup) 31 | AT91_SMC_NRDSETUP_(config->nrd_setup)
24 | AT91_SMC_NRDSETUP_(config->nrd_setup) 32 | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup),
25 | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup) 33 base + AT91_SMC_SETUP);
26 );
27 34
28 /* Pulse register */ 35 /* Pulse register */
29 at91_sys_write(AT91_SMC_PULSE(cs), 36 __raw_writel(AT91_SMC_NWEPULSE_(config->nwe_pulse)
30 AT91_SMC_NWEPULSE_(config->nwe_pulse) 37 | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse)
31 | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse) 38 | AT91_SMC_NRDPULSE_(config->nrd_pulse)
32 | AT91_SMC_NRDPULSE_(config->nrd_pulse) 39 | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse),
33 | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse) 40 base + AT91_SMC_PULSE);
34 );
35 41
36 /* Cycle register */ 42 /* Cycle register */
37 at91_sys_write(AT91_SMC_CYCLE(cs), 43 __raw_writel(AT91_SMC_NWECYCLE_(config->write_cycle)
38 AT91_SMC_NWECYCLE_(config->write_cycle) 44 | AT91_SMC_NRDCYCLE_(config->read_cycle),
39 | AT91_SMC_NRDCYCLE_(config->read_cycle) 45 base + AT91_SMC_CYCLE);
40 );
41 46
42 /* Mode register */ 47 /* Mode register */
43 at91_sys_write(AT91_SMC_MODE(cs), 48 __raw_writel(config->mode
44 config->mode 49 | AT91_SMC_TDF_(config->tdf_cycles),
45 | AT91_SMC_TDF_(config->tdf_cycles) 50 base + AT91_SMC_MODE);
46 ); 51}
52
53void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config)
54{
55 sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config);
56}
57
58void __init at91sam9_ioremap_smc(int id, u32 addr)
59{
60 if (id > 1) {
61 pr_warn("%s: id > 2\n", __func__);
62 return;
63 }
64 smc_base_addr[id] = ioremap(addr, 512);
65 if (!smc_base_addr[id])
66 pr_warn("Impossible to ioremap smc.%d 0x%x\n", id, addr);
47} 67}
diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h
index bf72cfb3455..039c5ce17ae 100644
--- a/arch/arm/mach-at91/sam9_smc.h
+++ b/arch/arm/mach-at91/sam9_smc.h
@@ -30,4 +30,5 @@ struct sam9_smc_config {
30 u8 tdf_cycles:4; 30 u8 tdf_cycles:4;
31}; 31};
32 32
33extern void __init sam9_smc_configure(int cs, struct sam9_smc_config* config); 33extern void __init sam9_smc_configure(int id, int cs, struct sam9_smc_config* config);
34extern void __init at91sam9_ioremap_smc(int id, u32 addr);
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index cf98a8f94dc..8bdcc3cb601 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/io.h> 9#include <linux/io.h>
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/pm.h>
11 12
12#include <asm/mach/map.h> 13#include <asm/mach/map.h>
13 14
@@ -15,6 +16,7 @@
15#include <mach/cpu.h> 16#include <mach/cpu.h>
16#include <mach/at91_dbgu.h> 17#include <mach/at91_dbgu.h>
17#include <mach/at91_pmc.h> 18#include <mach/at91_pmc.h>
19#include <mach/at91_shdwc.h>
18 20
19#include "soc.h" 21#include "soc.h"
20#include "generic.h" 22#include "generic.h"
@@ -73,9 +75,6 @@ static struct map_desc at91_io_desc __initdata = {
73 .type = MT_DEVICE, 75 .type = MT_DEVICE,
74}; 76};
75 77
76#define AT91_DBGU0 0xfffff200
77#define AT91_DBGU1 0xffffee00
78
79static void __init soc_detect(u32 dbgu_base) 78static void __init soc_detect(u32 dbgu_base)
80{ 79{
81 u32 cidr, socid; 80 u32 cidr, socid;
@@ -248,9 +247,9 @@ void __init at91_map_io(void)
248 at91_soc_initdata.type = AT91_SOC_NONE; 247 at91_soc_initdata.type = AT91_SOC_NONE;
249 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; 248 at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
250 249
251 soc_detect(AT91_DBGU0); 250 soc_detect(AT91_BASE_DBGU0);
252 if (!at91_soc_is_detected()) 251 if (!at91_soc_is_detected())
253 soc_detect(AT91_DBGU1); 252 soc_detect(AT91_BASE_DBGU1);
254 253
255 if (!at91_soc_is_detected()) 254 if (!at91_soc_is_detected())
256 panic("AT91: Impossible to detect the SOC type"); 255 panic("AT91: Impossible to detect the SOC type");
@@ -267,8 +266,25 @@ void __init at91_map_io(void)
267 at91_boot_soc.map_io(); 266 at91_boot_soc.map_io();
268} 267}
269 268
269void __iomem *at91_shdwc_base = NULL;
270
271static void at91sam9_poweroff(void)
272{
273 at91_shdwc_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
274}
275
276void __init at91_ioremap_shdwc(u32 base_addr)
277{
278 at91_shdwc_base = ioremap(base_addr, 16);
279 if (!at91_shdwc_base)
280 panic("Impossible to ioremap at91_shdwc_base\n");
281 pm_power_off = at91sam9_poweroff;
282}
283
270void __init at91_initialize(unsigned long main_clock) 284void __init at91_initialize(unsigned long main_clock)
271{ 285{
286 at91_boot_soc.ioremap_registers();
287
272 /* Init clock subsystem */ 288 /* Init clock subsystem */
273 at91_clock_init(main_clock); 289 at91_clock_init(main_clock);
274 290
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 21ed8816e6f..4588ae6f7ac 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -7,6 +7,7 @@
7struct at91_init_soc { 7struct at91_init_soc {
8 unsigned int *default_irq_priority; 8 unsigned int *default_irq_priority;
9 void (*map_io)(void); 9 void (*map_io)(void);
10 void (*ioremap_registers)(void);
10 void (*register_clocks)(void); 11 void (*register_clocks)(void);
11 void (*init)(void); 12 void (*init)(void);
12}; 13};
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index f8a682f60a4..6b22b543a83 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -127,7 +127,7 @@ static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
127 size_t retlen; 127 size_t retlen;
128 128
129 if (!strcmp(mtd->name, "MAC-Address")) { 129 if (!strcmp(mtd->name, "MAC-Address")) {
130 mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr); 130 mtd_read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
131 if (retlen == ETH_ALEN) 131 if (retlen == ETH_ALEN)
132 pr_info("Read MAC addr from SPI Flash: %pM\n", 132 pr_info("Read MAC addr from SPI Flash: %pM\n",
133 mac_addr); 133 mac_addr);
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 00861139101..008772e3b84 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -31,19 +31,12 @@ static LIST_HEAD(clocks);
31static DEFINE_MUTEX(clocks_mutex); 31static DEFINE_MUTEX(clocks_mutex);
32static DEFINE_SPINLOCK(clockfw_lock); 32static DEFINE_SPINLOCK(clockfw_lock);
33 33
34static unsigned psc_domain(struct clk *clk)
35{
36 return (clk->flags & PSC_DSP)
37 ? DAVINCI_GPSC_DSPDOMAIN
38 : DAVINCI_GPSC_ARMDOMAIN;
39}
40
41static void __clk_enable(struct clk *clk) 34static void __clk_enable(struct clk *clk)
42{ 35{
43 if (clk->parent) 36 if (clk->parent)
44 __clk_enable(clk->parent); 37 __clk_enable(clk->parent);
45 if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) 38 if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
46 davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 39 davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
47 true, clk->flags); 40 true, clk->flags);
48} 41}
49 42
@@ -53,7 +46,7 @@ static void __clk_disable(struct clk *clk)
53 return; 46 return;
54 if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && 47 if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
55 (clk->flags & CLK_PSC)) 48 (clk->flags & CLK_PSC))
56 davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 49 davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
57 false, clk->flags); 50 false, clk->flags);
58 if (clk->parent) 51 if (clk->parent)
59 __clk_disable(clk->parent); 52 __clk_disable(clk->parent);
@@ -237,7 +230,7 @@ static int __init clk_disable_unused(void)
237 230
238 pr_debug("Clocks: disable unused %s\n", ck->name); 231 pr_debug("Clocks: disable unused %s\n", ck->name);
239 232
240 davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 233 davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc,
241 false, ck->flags); 234 false, ck->flags);
242 } 235 }
243 spin_unlock_irq(&clockfw_lock); 236 spin_unlock_irq(&clockfw_lock);
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index a705f367a84..46f0f1bf1a4 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -93,6 +93,7 @@ struct clk {
93 u8 usecount; 93 u8 usecount;
94 u8 lpsc; 94 u8 lpsc;
95 u8 gpsc; 95 u8 gpsc;
96 u8 domain;
96 u32 flags; 97 u32 flags;
97 struct clk *parent; 98 struct clk *parent;
98 struct list_head children; /* list of children */ 99 struct list_head children; /* list of children */
@@ -107,11 +108,10 @@ struct clk {
107/* Clock flags: SoC-specific flags start at BIT(16) */ 108/* Clock flags: SoC-specific flags start at BIT(16) */
108#define ALWAYS_ENABLED BIT(1) 109#define ALWAYS_ENABLED BIT(1)
109#define CLK_PSC BIT(2) 110#define CLK_PSC BIT(2)
110#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ 111#define CLK_PLL BIT(3) /* PLL-derived clock */
111#define CLK_PLL BIT(4) /* PLL-derived clock */ 112#define PRE_PLL BIT(4) /* source is before PLL mult/div */
112#define PRE_PLL BIT(5) /* source is before PLL mult/div */ 113#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */
113#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ 114#define PSC_FORCE BIT(6) /* Force module state transtition */
114#define PSC_FORCE BIT(7) /* Force module state transtition */
115 115
116#define CLK(dev, con, ck) \ 116#define CLK(dev, con, ck) \
117 { \ 117 { \
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 0800f9cf33b..43a48ee1917 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -130,7 +130,7 @@ static struct clk dsp_clk = {
130 .name = "dsp", 130 .name = "dsp",
131 .parent = &pll1_sysclk1, 131 .parent = &pll1_sysclk1,
132 .lpsc = DAVINCI_LPSC_GEM, 132 .lpsc = DAVINCI_LPSC_GEM,
133 .flags = PSC_DSP, 133 .domain = DAVINCI_GPSC_DSPDOMAIN,
134 .usecount = 1, /* REVISIT how to disable? */ 134 .usecount = 1, /* REVISIT how to disable? */
135}; 135};
136 136
@@ -145,7 +145,7 @@ static struct clk vicp_clk = {
145 .name = "vicp", 145 .name = "vicp",
146 .parent = &pll1_sysclk2, 146 .parent = &pll1_sysclk2,
147 .lpsc = DAVINCI_LPSC_IMCOP, 147 .lpsc = DAVINCI_LPSC_IMCOP,
148 .flags = PSC_DSP, 148 .domain = DAVINCI_GPSC_DSPDOMAIN,
149 .usecount = 1, /* REVISIT how to disable? */ 149 .usecount = 1, /* REVISIT how to disable? */
150}; 150};
151 151
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
index 2a00fe5ac25..a8ee6c9f0bb 100644
--- a/arch/arm/mach-davinci/include/mach/dm646x.h
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -16,6 +16,7 @@
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/videodev2.h> 17#include <linux/videodev2.h>
18#include <linux/davinci_emac.h> 18#include <linux/davinci_emac.h>
19#include <media/davinci/vpif_types.h>
19 20
20#define DM646X_EMAC_BASE (0x01C80000) 21#define DM646X_EMAC_BASE (0x01C80000)
21#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) 22#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000)
@@ -34,58 +35,6 @@ int __init dm646x_init_edma(struct edma_rsv_info *rsv);
34 35
35void dm646x_video_init(void); 36void dm646x_video_init(void);
36 37
37enum vpif_if_type {
38 VPIF_IF_BT656,
39 VPIF_IF_BT1120,
40 VPIF_IF_RAW_BAYER
41};
42
43struct vpif_interface {
44 enum vpif_if_type if_type;
45 unsigned hd_pol:1;
46 unsigned vd_pol:1;
47 unsigned fid_pol:1;
48};
49
50struct vpif_subdev_info {
51 const char *name;
52 struct i2c_board_info board_info;
53 u32 input;
54 u32 output;
55 unsigned can_route:1;
56 struct vpif_interface vpif_if;
57};
58
59struct vpif_display_config {
60 int (*set_clock)(int, int);
61 struct vpif_subdev_info *subdevinfo;
62 int subdev_count;
63 const char **output;
64 int output_count;
65 const char *card_name;
66};
67
68struct vpif_input {
69 struct v4l2_input input;
70 const char *subdev_name;
71};
72
73#define VPIF_CAPTURE_MAX_CHANNELS 2
74
75struct vpif_capture_chan_config {
76 const struct vpif_input *inputs;
77 int input_count;
78};
79
80struct vpif_capture_config {
81 int (*setup_input_channel_mode)(int);
82 int (*setup_input_path)(int, const char *);
83 struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
84 struct vpif_subdev_info *subdev_info;
85 int subdev_count;
86 const char *card_name;
87};
88
89void dm646x_setup_vpif(struct vpif_display_config *, 38void dm646x_setup_vpif(struct vpif_display_config *,
90 struct vpif_capture_config *); 39 struct vpif_capture_config *);
91 40
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c
index 00be4fc26dd..98b8c83b09a 100644
--- a/arch/arm/mach-dove/addr-map.c
+++ b/arch/arm/mach-dove/addr-map.c
@@ -14,6 +14,7 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
16#include <asm/setup.h> 16#include <asm/setup.h>
17#include <plat/addr-map.h>
17#include "common.h" 18#include "common.h"
18 19
19/* 20/*
@@ -34,98 +35,72 @@
34#define ATTR_PCIE_MEM 0xe8 35#define ATTR_PCIE_MEM 0xe8
35#define ATTR_SCRATCHPAD 0x0 36#define ATTR_SCRATCHPAD 0x0
36 37
37/*
38 * CPU Address Decode Windows registers
39 */
40#define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
41#define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
42#define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
43#define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
44
45struct mbus_dram_target_info dove_mbus_dram_info;
46
47static inline void __iomem *ddr_map_sc(int i) 38static inline void __iomem *ddr_map_sc(int i)
48{ 39{
49 return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4)); 40 return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
50} 41}
51 42
52static int cpu_win_can_remap(int win) 43/*
53{ 44 * Description of the windows needed by the platform code
54 if (win < 4) 45 */
55 return 1; 46static struct __initdata orion_addr_map_cfg addr_map_cfg = {
56 47 .num_wins = 8,
57 return 0; 48 .remappable_wins = 4,
58} 49 .bridge_virt_base = BRIDGE_VIRT_BASE,
59 50};
60static void __init setup_cpu_win(int win, u32 base, u32 size,
61 u8 target, u8 attr, int remap)
62{
63 u32 ctrl;
64
65 base &= 0xffff0000;
66 ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
67
68 writel(base, WIN_BASE(win));
69 writel(ctrl, WIN_CTRL(win));
70 if (cpu_win_can_remap(win)) {
71 if (remap < 0)
72 remap = base;
73 writel(remap & 0xffff0000, WIN_REMAP_LO(win));
74 writel(0, WIN_REMAP_HI(win));
75 }
76}
77
78void __init dove_setup_cpu_mbus(void)
79{
80 int i;
81 int cs;
82 51
52static const struct __initdata orion_addr_map_info addr_map_info[] = {
83 /* 53 /*
84 * First, disable and clear windows. 54 * Windows for PCIe IO+MEM space.
85 */ 55 */
86 for (i = 0; i < 8; i++) { 56 { 0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
87 writel(0, WIN_BASE(i)); 57 TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE
88 writel(0, WIN_CTRL(i)); 58 },
89 if (cpu_win_can_remap(i)) { 59 { 1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
90 writel(0, WIN_REMAP_LO(i)); 60 TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE
91 writel(0, WIN_REMAP_HI(i)); 61 },
92 } 62 { 2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
93 } 63 TARGET_PCIE0, ATTR_PCIE_MEM, -1
94 64 },
65 { 3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
66 TARGET_PCIE1, ATTR_PCIE_MEM, -1
67 },
95 /* 68 /*
96 * Setup windows for PCIe IO+MEM space. 69 * Window for CESA engine.
97 */ 70 */
98 setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE, 71 { 4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
99 TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE); 72 TARGET_CESA, ATTR_CESA, -1
100 setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE, 73 },
101 TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
102 setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
103 TARGET_PCIE0, ATTR_PCIE_MEM, -1);
104 setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
105 TARGET_PCIE1, ATTR_PCIE_MEM, -1);
106
107 /* 74 /*
108 * Setup window for CESA engine. 75 * Window to the BootROM for Standby and Sleep Resume
109 */ 76 */
110 setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE, 77 { 5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
111 TARGET_CESA, ATTR_CESA, -1); 78 TARGET_BOOTROM, ATTR_BOOTROM, -1
112 79 },
113 /* 80 /*
114 * Setup the Window to the BootROM for Standby and Sleep Resume 81 * Window to the PMU Scratch Pad space
115 */ 82 */
116 setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE, 83 { 6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
117 TARGET_BOOTROM, ATTR_BOOTROM, -1); 84 TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1
85 },
86 /* End marker */
87 { -1, 0, 0, 0, 0, 0 }
88};
89
90void __init dove_setup_cpu_mbus(void)
91{
92 int i;
93 int cs;
118 94
119 /* 95 /*
120 * Setup the Window to the PMU Scratch Pad space 96 * Disable, clear and configure windows.
121 */ 97 */
122 setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE, 98 orion_config_wins(&addr_map_cfg, addr_map_info);
123 TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
124 99
125 /* 100 /*
126 * Setup MBUS dram target info. 101 * Setup MBUS dram target info.
127 */ 102 */
128 dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 103 orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
129 104
130 for (i = 0, cs = 0; i < 2; i++) { 105 for (i = 0, cs = 0; i < 2; i++) {
131 u32 map = readl(ddr_map_sc(i)); 106 u32 map = readl(ddr_map_sc(i));
@@ -136,7 +111,7 @@ void __init dove_setup_cpu_mbus(void)
136 if (map & 1) { 111 if (map & 1) {
137 struct mbus_dram_window *w; 112 struct mbus_dram_window *w;
138 113
139 w = &dove_mbus_dram_info.cs[cs++]; 114 w = &orion_mbus_dram_info.cs[cs++];
140 w->cs_index = i; 115 w->cs_index = i;
141 w->mbus_attr = 0; /* CS address decoding done inside */ 116 w->mbus_attr = 0; /* CS address decoding done inside */
142 /* the DDR controller, no need to */ 117 /* the DDR controller, no need to */
@@ -145,5 +120,5 @@ void __init dove_setup_cpu_mbus(void)
145 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4); 120 w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
146 } 121 }
147 } 122 }
148 dove_mbus_dram_info.num_cs = cs; 123 orion_mbus_dram_info.num_cs = cs;
149} 124}
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
index 13bb236cd0c..dd1429ae640 100644
--- a/arch/arm/mach-dove/common.c
+++ b/arch/arm/mach-dove/common.c
@@ -14,7 +14,6 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/mbus.h>
18#include <linux/ata_platform.h> 17#include <linux/ata_platform.h>
19#include <linux/gpio.h> 18#include <linux/gpio.h>
20#include <asm/page.h> 19#include <asm/page.h>
@@ -30,6 +29,7 @@
30#include <linux/irq.h> 29#include <linux/irq.h>
31#include <plat/time.h> 30#include <plat/time.h>
32#include <plat/common.h> 31#include <plat/common.h>
32#include <plat/addr-map.h>
33#include "common.h" 33#include "common.h"
34 34
35static int get_tclk(void); 35static int get_tclk(void);
@@ -71,8 +71,7 @@ void __init dove_map_io(void)
71 ****************************************************************************/ 71 ****************************************************************************/
72void __init dove_ehci0_init(void) 72void __init dove_ehci0_init(void)
73{ 73{
74 orion_ehci_init(&dove_mbus_dram_info, 74 orion_ehci_init(DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0);
75 DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0);
76} 75}
77 76
78/***************************************************************************** 77/*****************************************************************************
@@ -80,8 +79,7 @@ void __init dove_ehci0_init(void)
80 ****************************************************************************/ 79 ****************************************************************************/
81void __init dove_ehci1_init(void) 80void __init dove_ehci1_init(void)
82{ 81{
83 orion_ehci_1_init(&dove_mbus_dram_info, 82 orion_ehci_1_init(DOVE_USB1_PHYS_BASE, IRQ_DOVE_USB1);
84 DOVE_USB1_PHYS_BASE, IRQ_DOVE_USB1);
85} 83}
86 84
87/***************************************************************************** 85/*****************************************************************************
@@ -89,7 +87,7 @@ void __init dove_ehci1_init(void)
89 ****************************************************************************/ 87 ****************************************************************************/
90void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) 88void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
91{ 89{
92 orion_ge00_init(eth_data, &dove_mbus_dram_info, 90 orion_ge00_init(eth_data,
93 DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 91 DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
94 0, get_tclk()); 92 0, get_tclk());
95} 93}
@@ -107,8 +105,7 @@ void __init dove_rtc_init(void)
107 ****************************************************************************/ 105 ****************************************************************************/
108void __init dove_sata_init(struct mv_sata_platform_data *sata_data) 106void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
109{ 107{
110 orion_sata_init(sata_data, &dove_mbus_dram_info, 108 orion_sata_init(sata_data, DOVE_SATA_PHYS_BASE, IRQ_DOVE_SATA);
111 DOVE_SATA_PHYS_BASE, IRQ_DOVE_SATA);
112 109
113} 110}
114 111
@@ -198,8 +195,7 @@ struct sys_timer dove_timer = {
198 ****************************************************************************/ 195 ****************************************************************************/
199void __init dove_xor0_init(void) 196void __init dove_xor0_init(void)
200{ 197{
201 orion_xor0_init(&dove_mbus_dram_info, 198 orion_xor0_init(DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
202 DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
203 IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01); 199 IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
204} 200}
205 201
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
index 42027305c10..6432a3ba864 100644
--- a/arch/arm/mach-dove/common.h
+++ b/arch/arm/mach-dove/common.h
@@ -15,7 +15,6 @@ struct mv643xx_eth_platform_data;
15struct mv_sata_platform_data; 15struct mv_sata_platform_data;
16 16
17extern struct sys_timer dove_timer; 17extern struct sys_timer dove_timer;
18extern struct mbus_dram_target_info dove_mbus_dram_info;
19 18
20/* 19/*
21 * Basic Dove init functions used early by machine-setup. 20 * Basic Dove init functions used early by machine-setup.
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
index aa2b3a09a51..6c11a4df717 100644
--- a/arch/arm/mach-dove/pcie.c
+++ b/arch/arm/mach-dove/pcie.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/mbus.h>
14#include <video/vga.h> 13#include <video/vga.h>
15#include <asm/mach/pci.h> 14#include <asm/mach/pci.h>
16#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
@@ -19,6 +18,7 @@
19#include <plat/pcie.h> 18#include <plat/pcie.h>
20#include <mach/irqs.h> 19#include <mach/irqs.h>
21#include <mach/bridge-regs.h> 20#include <mach/bridge-regs.h>
21#include <plat/addr-map.h>
22#include "common.h" 22#include "common.h"
23 23
24struct pcie_port { 24struct pcie_port {
@@ -50,7 +50,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
50 */ 50 */
51 orion_pcie_set_local_bus_nr(pp->base, sys->busnr); 51 orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
52 52
53 orion_pcie_setup(pp->base, &dove_mbus_dram_info); 53 orion_pcie_setup(pp->base);
54 54
55 /* 55 /*
56 * IORESOURCE_IO 56 * IORESOURCE_IO
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index e1efbca2a53..5d602f68a0e 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -59,6 +59,11 @@ config EXYNOS4_MCT
59 help 59 help
60 Use MCT (Multi Core Timer) as kernel timers 60 Use MCT (Multi Core Timer) as kernel timers
61 61
62config EXYNOS4_DEV_DMA
63 bool
64 help
65 Compile in amba device definitions for DMA controller
66
62config EXYNOS4_DEV_AHCI 67config EXYNOS4_DEV_AHCI
63 bool 68 bool
64 help 69 help
@@ -84,6 +89,11 @@ config EXYNOS4_DEV_DWMCI
84 help 89 help
85 Compile in platform device definitions for DWMCI 90 Compile in platform device definitions for DWMCI
86 91
92config EXYNOS4_DEV_USB_OHCI
93 bool
94 help
95 Compile in platform device definition for USB OHCI
96
87config EXYNOS4_SETUP_I2C1 97config EXYNOS4_SETUP_I2C1
88 bool 98 bool
89 help 99 help
@@ -145,6 +155,11 @@ config EXYNOS4_SETUP_USB_PHY
145 help 155 help
146 Common setup code for USB PHY controller 156 Common setup code for USB PHY controller
147 157
158config EXYNOS4_SETUP_SPI
159 bool
160 help
161 Common setup code for SPI GPIO configurations.
162
148# machine support 163# machine support
149 164
150if ARCH_EXYNOS4 165if ARCH_EXYNOS4
@@ -179,8 +194,10 @@ config MACH_SMDKV310
179 select SAMSUNG_DEV_BACKLIGHT 194 select SAMSUNG_DEV_BACKLIGHT
180 select EXYNOS4_DEV_AHCI 195 select EXYNOS4_DEV_AHCI
181 select SAMSUNG_DEV_KEYPAD 196 select SAMSUNG_DEV_KEYPAD
197 select EXYNOS4_DEV_DMA
182 select EXYNOS4_DEV_PD 198 select EXYNOS4_DEV_PD
183 select SAMSUNG_DEV_PWM 199 select SAMSUNG_DEV_PWM
200 select EXYNOS4_DEV_USB_OHCI
184 select EXYNOS4_DEV_SYSMMU 201 select EXYNOS4_DEV_SYSMMU
185 select EXYNOS4_SETUP_FIMD0 202 select EXYNOS4_SETUP_FIMD0
186 select EXYNOS4_SETUP_I2C1 203 select EXYNOS4_SETUP_I2C1
@@ -199,6 +216,7 @@ config MACH_ARMLEX4210
199 select S3C_DEV_HSMMC2 216 select S3C_DEV_HSMMC2
200 select S3C_DEV_HSMMC3 217 select S3C_DEV_HSMMC3
201 select EXYNOS4_DEV_AHCI 218 select EXYNOS4_DEV_AHCI
219 select EXYNOS4_DEV_DMA
202 select EXYNOS4_DEV_SYSMMU 220 select EXYNOS4_DEV_SYSMMU
203 select EXYNOS4_SETUP_SDHCI 221 select EXYNOS4_SETUP_SDHCI
204 help 222 help
@@ -224,6 +242,7 @@ config MACH_UNIVERSAL_C210
224 select S5P_DEV_MFC 242 select S5P_DEV_MFC
225 select S5P_DEV_ONENAND 243 select S5P_DEV_ONENAND
226 select S5P_DEV_TV 244 select S5P_DEV_TV
245 select EXYNOS4_DEV_DMA
227 select EXYNOS4_DEV_PD 246 select EXYNOS4_DEV_PD
228 select EXYNOS4_SETUP_FIMD0 247 select EXYNOS4_SETUP_FIMD0
229 select EXYNOS4_SETUP_I2C1 248 select EXYNOS4_SETUP_I2C1
@@ -257,6 +276,7 @@ config MACH_NURI
257 select S5P_DEV_MFC 276 select S5P_DEV_MFC
258 select S5P_DEV_USB_EHCI 277 select S5P_DEV_USB_EHCI
259 select S5P_SETUP_MIPIPHY 278 select S5P_SETUP_MIPIPHY
279 select EXYNOS4_DEV_DMA
260 select EXYNOS4_DEV_PD 280 select EXYNOS4_DEV_PD
261 select EXYNOS4_SETUP_FIMC 281 select EXYNOS4_SETUP_FIMC
262 select EXYNOS4_SETUP_FIMD0 282 select EXYNOS4_SETUP_FIMD0
@@ -289,7 +309,9 @@ config MACH_ORIGEN
289 select S5P_DEV_USB_EHCI 309 select S5P_DEV_USB_EHCI
290 select SAMSUNG_DEV_BACKLIGHT 310 select SAMSUNG_DEV_BACKLIGHT
291 select SAMSUNG_DEV_PWM 311 select SAMSUNG_DEV_PWM
312 select EXYNOS4_DEV_DMA
292 select EXYNOS4_DEV_PD 313 select EXYNOS4_DEV_PD
314 select EXYNOS4_DEV_USB_OHCI
293 select EXYNOS4_SETUP_FIMD0 315 select EXYNOS4_SETUP_FIMD0
294 select EXYNOS4_SETUP_SDHCI 316 select EXYNOS4_SETUP_SDHCI
295 select EXYNOS4_SETUP_USB_PHY 317 select EXYNOS4_SETUP_USB_PHY
@@ -329,6 +351,20 @@ config MACH_SMDK4412
329 Machine support for Samsung SMDK4412 351 Machine support for Samsung SMDK4412
330endif 352endif
331 353
354comment "Flattened Device Tree based board for Exynos4 based SoC"
355
356config MACH_EXYNOS4_DT
357 bool "Samsung Exynos4 Machine using device tree"
358 select CPU_EXYNOS4210
359 select USE_OF
360 select ARM_AMBA
361 select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
362 help
363 Machine support for Samsung Exynos4 machine with device tree enabled.
364 Select this if a fdt blob is available for the Exynos4 SoC based board.
365 Note: This is under development and not all peripherals can be supported
366 with this machine file.
367
332if ARCH_EXYNOS4 368if ARCH_EXYNOS4
333 369
334comment "Configuration for HSMMC 8-bit bus width" 370comment "Configuration for HSMMC 8-bit bus width"
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index bcb9efc576e..5fc202cdfdb 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -19,7 +19,7 @@ obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
19obj-$(CONFIG_PM) += pm.o 19obj-$(CONFIG_PM) += pm.o
20obj-$(CONFIG_CPU_IDLE) += cpuidle.o 20obj-$(CONFIG_CPU_IDLE) += cpuidle.o
21 21
22obj-$(CONFIG_ARCH_EXYNOS4) += dma.o pmu.o 22obj-$(CONFIG_ARCH_EXYNOS4) += pmu.o
23 23
24obj-$(CONFIG_SMP) += platsmp.o headsmp.o 24obj-$(CONFIG_SMP) += platsmp.o headsmp.o
25 25
@@ -39,6 +39,8 @@ obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o
39obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o 39obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o
40obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o 40obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o
41 41
42obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o
43
42# device support 44# device support
43 45
44obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o 46obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
@@ -46,6 +48,8 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
46obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o 48obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
47obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o 49obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
48obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o 50obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
51obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
52obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
49 53
50obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o 54obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o
51obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o 55obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
@@ -58,6 +62,6 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
58obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o 62obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
59obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o 63obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
60obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o 64obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
61obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
62obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 65obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
63obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o 66obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
67obj-$(CONFIG_EXYNOS4_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index 83616a039b1..5a8c42e9000 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -554,16 +554,6 @@ static struct clk init_clocks_off[] = {
554 .enable = exynos4_clk_dac_ctrl, 554 .enable = exynos4_clk_dac_ctrl,
555 .ctrlbit = (1 << 0), 555 .ctrlbit = (1 << 0),
556 }, { 556 }, {
557 .name = "dma",
558 .devname = "dma-pl330.0",
559 .enable = exynos4_clk_ip_fsys_ctrl,
560 .ctrlbit = (1 << 0),
561 }, {
562 .name = "dma",
563 .devname = "dma-pl330.1",
564 .enable = exynos4_clk_ip_fsys_ctrl,
565 .ctrlbit = (1 << 1),
566 }, {
567 .name = "adc", 557 .name = "adc",
568 .enable = exynos4_clk_ip_peril_ctrl, 558 .enable = exynos4_clk_ip_peril_ctrl,
569 .ctrlbit = (1 << 15), 559 .ctrlbit = (1 << 15),
@@ -779,6 +769,20 @@ static struct clk init_clocks[] = {
779 } 769 }
780}; 770};
781 771
772static struct clk clk_pdma0 = {
773 .name = "dma",
774 .devname = "dma-pl330.0",
775 .enable = exynos4_clk_ip_fsys_ctrl,
776 .ctrlbit = (1 << 0),
777};
778
779static struct clk clk_pdma1 = {
780 .name = "dma",
781 .devname = "dma-pl330.1",
782 .enable = exynos4_clk_ip_fsys_ctrl,
783 .ctrlbit = (1 << 1),
784};
785
782struct clk *clkset_group_list[] = { 786struct clk *clkset_group_list[] = {
783 [0] = &clk_ext_xtal_mux, 787 [0] = &clk_ext_xtal_mux,
784 [1] = &clk_xusbxti, 788 [1] = &clk_xusbxti,
@@ -1010,46 +1014,6 @@ static struct clksrc_clk clk_dout_mmc4 = {
1010 1014
1011static struct clksrc_clk clksrcs[] = { 1015static struct clksrc_clk clksrcs[] = {
1012 { 1016 {
1013 .clk = {
1014 .name = "uclk1",
1015 .devname = "s5pv210-uart.0",
1016 .enable = exynos4_clksrc_mask_peril0_ctrl,
1017 .ctrlbit = (1 << 0),
1018 },
1019 .sources = &clkset_group,
1020 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
1021 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
1022 }, {
1023 .clk = {
1024 .name = "uclk1",
1025 .devname = "s5pv210-uart.1",
1026 .enable = exynos4_clksrc_mask_peril0_ctrl,
1027 .ctrlbit = (1 << 4),
1028 },
1029 .sources = &clkset_group,
1030 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
1031 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
1032 }, {
1033 .clk = {
1034 .name = "uclk1",
1035 .devname = "s5pv210-uart.2",
1036 .enable = exynos4_clksrc_mask_peril0_ctrl,
1037 .ctrlbit = (1 << 8),
1038 },
1039 .sources = &clkset_group,
1040 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
1041 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
1042 }, {
1043 .clk = {
1044 .name = "uclk1",
1045 .devname = "s5pv210-uart.3",
1046 .enable = exynos4_clksrc_mask_peril0_ctrl,
1047 .ctrlbit = (1 << 12),
1048 },
1049 .sources = &clkset_group,
1050 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
1051 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
1052 }, {
1053 .clk = { 1017 .clk = {
1054 .name = "sclk_pwm", 1018 .name = "sclk_pwm",
1055 .enable = exynos4_clksrc_mask_peril0_ctrl, 1019 .enable = exynos4_clksrc_mask_peril0_ctrl,
@@ -1148,36 +1112,6 @@ static struct clksrc_clk clksrcs[] = {
1148 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 }, 1112 .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
1149 }, { 1113 }, {
1150 .clk = { 1114 .clk = {
1151 .name = "sclk_spi",
1152 .devname = "s3c64xx-spi.0",
1153 .enable = exynos4_clksrc_mask_peril1_ctrl,
1154 .ctrlbit = (1 << 16),
1155 },
1156 .sources = &clkset_group,
1157 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1158 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1159 }, {
1160 .clk = {
1161 .name = "sclk_spi",
1162 .devname = "s3c64xx-spi.1",
1163 .enable = exynos4_clksrc_mask_peril1_ctrl,
1164 .ctrlbit = (1 << 20),
1165 },
1166 .sources = &clkset_group,
1167 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1168 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1169 }, {
1170 .clk = {
1171 .name = "sclk_spi",
1172 .devname = "s3c64xx-spi.2",
1173 .enable = exynos4_clksrc_mask_peril1_ctrl,
1174 .ctrlbit = (1 << 24),
1175 },
1176 .sources = &clkset_group,
1177 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1178 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1179 }, {
1180 .clk = {
1181 .name = "sclk_fimg2d", 1115 .name = "sclk_fimg2d",
1182 }, 1116 },
1183 .sources = &clkset_mout_g2d, 1117 .sources = &clkset_mout_g2d,
@@ -1193,42 +1127,6 @@ static struct clksrc_clk clksrcs[] = {
1193 .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 }, 1127 .reg_div = { .reg = S5P_CLKDIV_MFC, .shift = 0, .size = 4 },
1194 }, { 1128 }, {
1195 .clk = { 1129 .clk = {
1196 .name = "sclk_mmc",
1197 .devname = "s3c-sdhci.0",
1198 .parent = &clk_dout_mmc0.clk,
1199 .enable = exynos4_clksrc_mask_fsys_ctrl,
1200 .ctrlbit = (1 << 0),
1201 },
1202 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1203 }, {
1204 .clk = {
1205 .name = "sclk_mmc",
1206 .devname = "s3c-sdhci.1",
1207 .parent = &clk_dout_mmc1.clk,
1208 .enable = exynos4_clksrc_mask_fsys_ctrl,
1209 .ctrlbit = (1 << 4),
1210 },
1211 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1212 }, {
1213 .clk = {
1214 .name = "sclk_mmc",
1215 .devname = "s3c-sdhci.2",
1216 .parent = &clk_dout_mmc2.clk,
1217 .enable = exynos4_clksrc_mask_fsys_ctrl,
1218 .ctrlbit = (1 << 8),
1219 },
1220 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1221 }, {
1222 .clk = {
1223 .name = "sclk_mmc",
1224 .devname = "s3c-sdhci.3",
1225 .parent = &clk_dout_mmc3.clk,
1226 .enable = exynos4_clksrc_mask_fsys_ctrl,
1227 .ctrlbit = (1 << 12),
1228 },
1229 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1230 }, {
1231 .clk = {
1232 .name = "sclk_dwmmc", 1130 .name = "sclk_dwmmc",
1233 .parent = &clk_dout_mmc4.clk, 1131 .parent = &clk_dout_mmc4.clk,
1234 .enable = exynos4_clksrc_mask_fsys_ctrl, 1132 .enable = exynos4_clksrc_mask_fsys_ctrl,
@@ -1238,6 +1136,134 @@ static struct clksrc_clk clksrcs[] = {
1238 } 1136 }
1239}; 1137};
1240 1138
1139static struct clksrc_clk clk_sclk_uart0 = {
1140 .clk = {
1141 .name = "uclk1",
1142 .devname = "exynos4210-uart.0",
1143 .enable = exynos4_clksrc_mask_peril0_ctrl,
1144 .ctrlbit = (1 << 0),
1145 },
1146 .sources = &clkset_group,
1147 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
1148 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
1149};
1150
1151static struct clksrc_clk clk_sclk_uart1 = {
1152 .clk = {
1153 .name = "uclk1",
1154 .devname = "exynos4210-uart.1",
1155 .enable = exynos4_clksrc_mask_peril0_ctrl,
1156 .ctrlbit = (1 << 4),
1157 },
1158 .sources = &clkset_group,
1159 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
1160 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
1161};
1162
1163static struct clksrc_clk clk_sclk_uart2 = {
1164 .clk = {
1165 .name = "uclk1",
1166 .devname = "exynos4210-uart.2",
1167 .enable = exynos4_clksrc_mask_peril0_ctrl,
1168 .ctrlbit = (1 << 8),
1169 },
1170 .sources = &clkset_group,
1171 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
1172 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
1173};
1174
1175static struct clksrc_clk clk_sclk_uart3 = {
1176 .clk = {
1177 .name = "uclk1",
1178 .devname = "exynos4210-uart.3",
1179 .enable = exynos4_clksrc_mask_peril0_ctrl,
1180 .ctrlbit = (1 << 12),
1181 },
1182 .sources = &clkset_group,
1183 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
1184 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
1185};
1186
1187static struct clksrc_clk clk_sclk_mmc0 = {
1188 .clk = {
1189 .name = "sclk_mmc",
1190 .devname = "s3c-sdhci.0",
1191 .parent = &clk_dout_mmc0.clk,
1192 .enable = exynos4_clksrc_mask_fsys_ctrl,
1193 .ctrlbit = (1 << 0),
1194 },
1195 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
1196};
1197
1198static struct clksrc_clk clk_sclk_mmc1 = {
1199 .clk = {
1200 .name = "sclk_mmc",
1201 .devname = "s3c-sdhci.1",
1202 .parent = &clk_dout_mmc1.clk,
1203 .enable = exynos4_clksrc_mask_fsys_ctrl,
1204 .ctrlbit = (1 << 4),
1205 },
1206 .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
1207};
1208
1209static struct clksrc_clk clk_sclk_mmc2 = {
1210 .clk = {
1211 .name = "sclk_mmc",
1212 .devname = "s3c-sdhci.2",
1213 .parent = &clk_dout_mmc2.clk,
1214 .enable = exynos4_clksrc_mask_fsys_ctrl,
1215 .ctrlbit = (1 << 8),
1216 },
1217 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
1218};
1219
1220static struct clksrc_clk clk_sclk_mmc3 = {
1221 .clk = {
1222 .name = "sclk_mmc",
1223 .devname = "s3c-sdhci.3",
1224 .parent = &clk_dout_mmc3.clk,
1225 .enable = exynos4_clksrc_mask_fsys_ctrl,
1226 .ctrlbit = (1 << 12),
1227 },
1228 .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1229};
1230
1231static struct clksrc_clk clk_sclk_spi0 = {
1232 .clk = {
1233 .name = "sclk_spi",
1234 .devname = "s3c64xx-spi.0",
1235 .enable = exynos4_clksrc_mask_peril1_ctrl,
1236 .ctrlbit = (1 << 16),
1237 },
1238 .sources = &clkset_group,
1239 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1240 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1241};
1242
1243static struct clksrc_clk clk_sclk_spi1 = {
1244 .clk = {
1245 .name = "sclk_spi",
1246 .devname = "s3c64xx-spi.1",
1247 .enable = exynos4_clksrc_mask_peril1_ctrl,
1248 .ctrlbit = (1 << 20),
1249 },
1250 .sources = &clkset_group,
1251 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1252 .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1253};
1254
1255static struct clksrc_clk clk_sclk_spi2 = {
1256 .clk = {
1257 .name = "sclk_spi",
1258 .devname = "s3c64xx-spi.2",
1259 .enable = exynos4_clksrc_mask_peril1_ctrl,
1260 .ctrlbit = (1 << 24),
1261 },
1262 .sources = &clkset_group,
1263 .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1264 .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1265};
1266
1241/* Clock initialization code */ 1267/* Clock initialization code */
1242static struct clksrc_clk *sysclks[] = { 1268static struct clksrc_clk *sysclks[] = {
1243 &clk_mout_apll, 1269 &clk_mout_apll,
@@ -1272,6 +1298,42 @@ static struct clksrc_clk *sysclks[] = {
1272 &clk_mout_mfc1, 1298 &clk_mout_mfc1,
1273}; 1299};
1274 1300
1301static struct clk *clk_cdev[] = {
1302 &clk_pdma0,
1303 &clk_pdma1,
1304};
1305
1306static struct clksrc_clk *clksrc_cdev[] = {
1307 &clk_sclk_uart0,
1308 &clk_sclk_uart1,
1309 &clk_sclk_uart2,
1310 &clk_sclk_uart3,
1311 &clk_sclk_mmc0,
1312 &clk_sclk_mmc1,
1313 &clk_sclk_mmc2,
1314 &clk_sclk_mmc3,
1315 &clk_sclk_spi0,
1316 &clk_sclk_spi1,
1317 &clk_sclk_spi2,
1318
1319};
1320
1321static struct clk_lookup exynos4_clk_lookup[] = {
1322 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk),
1323 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
1324 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
1325 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
1326 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1327 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1328 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1329 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1330 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
1331 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
1332 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &clk_sclk_spi0.clk),
1333 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &clk_sclk_spi1.clk),
1334 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &clk_sclk_spi2.clk),
1335};
1336
1275static int xtal_rate; 1337static int xtal_rate;
1276 1338
1277static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) 1339static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
@@ -1479,11 +1541,19 @@ void __init exynos4_register_clocks(void)
1479 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) 1541 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1480 s3c_register_clksrc(sclk_tv[ptr], 1); 1542 s3c_register_clksrc(sclk_tv[ptr], 1);
1481 1543
1544 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1545 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1546
1482 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1547 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1483 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1548 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1484 1549
1550 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1551 for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1552 s3c_disable_clocks(clk_cdev[ptr], 1);
1553
1485 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1554 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1486 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1555 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1556 clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
1487 1557
1488 register_syscore_ops(&exynos4_clock_syscore_ops); 1558 register_syscore_ops(&exynos4_clock_syscore_ops);
1489 s3c24xx_register_clock(&dummy_apb_pclk); 1559 s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index b6ac6ee658c..c59e1887100 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -17,8 +17,11 @@
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/serial_core.h> 19#include <linux/serial_core.h>
20#include <linux/of.h>
21#include <linux/of_irq.h>
20 22
21#include <asm/proc-fns.h> 23#include <asm/proc-fns.h>
24#include <asm/exception.h>
22#include <asm/hardware/cache-l2x0.h> 25#include <asm/hardware/cache-l2x0.h>
23#include <asm/hardware/gic.h> 26#include <asm/hardware/gic.h>
24#include <asm/mach/map.h> 27#include <asm/mach/map.h>
@@ -43,8 +46,6 @@
43 46
44#include "common.h" 47#include "common.h"
45 48
46unsigned int gic_bank_offset __read_mostly;
47
48static const char name_exynos4210[] = "EXYNOS4210"; 49static const char name_exynos4210[] = "EXYNOS4210";
49static const char name_exynos4212[] = "EXYNOS4212"; 50static const char name_exynos4212[] = "EXYNOS4212";
50static const char name_exynos4412[] = "EXYNOS4412"; 51static const char name_exynos4412[] = "EXYNOS4412";
@@ -386,27 +387,26 @@ static void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
386 } 387 }
387} 388}
388 389
389static void exynos4_gic_irq_fix_base(struct irq_data *d) 390#ifdef CONFIG_OF
390{ 391static const struct of_device_id exynos4_dt_irq_match[] = {
391 struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); 392 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
392 393 {},
393 gic_data->cpu_base = S5P_VA_GIC_CPU + 394};
394 (gic_bank_offset * smp_processor_id()); 395#endif
395
396 gic_data->dist_base = S5P_VA_GIC_DIST +
397 (gic_bank_offset * smp_processor_id());
398}
399 396
400void __init exynos4_init_irq(void) 397void __init exynos4_init_irq(void)
401{ 398{
402 int irq; 399 int irq;
400 unsigned int gic_bank_offset;
403 401
404 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; 402 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
405 403
406 gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); 404 if (!of_have_populated_dt())
407 gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; 405 gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
408 gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; 406#ifdef CONFIG_OF
409 gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; 407 else
408 of_irq_init(exynos4_dt_irq_match);
409#endif
410 410
411 for (irq = 0; irq < MAX_COMBINER_NR; irq++) { 411 for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
412 412
@@ -474,15 +474,6 @@ int __init exynos_init(void)
474 return device_register(&exynos4_dev); 474 return device_register(&exynos4_dev);
475} 475}
476 476
477static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
478 [0] = {
479 .name = "uclk1",
480 .divisor = 1,
481 .min_baud = 0,
482 .max_baud = 0,
483 },
484};
485
486/* uart registration process */ 477/* uart registration process */
487 478
488void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no) 479void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
@@ -490,16 +481,10 @@ void __init exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no)
490 struct s3c2410_uartcfg *tcfg = cfg; 481 struct s3c2410_uartcfg *tcfg = cfg;
491 u32 ucnt; 482 u32 ucnt;
492 483
493 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { 484 for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
494 if (!tcfg->clocks) { 485 tcfg->has_fracval = 1;
495 tcfg->has_fracval = 1;
496 tcfg->clocks = exynos4_serial_clocks;
497 tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
498 }
499 tcfg->flags |= NO_NEED_CHECK_CLKSRC;
500 }
501 486
502 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); 487 s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
503} 488}
504 489
505static DEFINE_SPINLOCK(eint_lock); 490static DEFINE_SPINLOCK(eint_lock);
diff --git a/arch/arm/mach-exynos/dev-ohci.c b/arch/arm/mach-exynos/dev-ohci.c
new file mode 100644
index 00000000000..b8e75300c77
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-ohci.c
@@ -0,0 +1,52 @@
1/* linux/arch/arm/mach-exynos/dev-ohci.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS - OHCI support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18#include <mach/ohci.h>
19
20#include <plat/devs.h>
21#include <plat/usb-phy.h>
22
23static struct resource exynos4_ohci_resource[] = {
24 [0] = DEFINE_RES_MEM(EXYNOS4_PA_OHCI, SZ_256),
25 [1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
26};
27
28static u64 exynos4_ohci_dma_mask = DMA_BIT_MASK(32);
29
30struct platform_device exynos4_device_ohci = {
31 .name = "exynos-ohci",
32 .id = -1,
33 .num_resources = ARRAY_SIZE(exynos4_ohci_resource),
34 .resource = exynos4_ohci_resource,
35 .dev = {
36 .dma_mask = &exynos4_ohci_dma_mask,
37 .coherent_dma_mask = DMA_BIT_MASK(32),
38 }
39};
40
41void __init exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd)
42{
43 struct exynos4_ohci_platdata *npd;
44
45 npd = s3c_set_platdata(pd, sizeof(struct exynos4_ohci_platdata),
46 &exynos4_device_ohci);
47
48 if (!npd->phy_init)
49 npd->phy_init = s5p_usb_phy_init;
50 if (!npd->phy_exit)
51 npd->phy_exit = s5p_usb_phy_exit;
52}
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 9667c61e64f..b10fcd270f0 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -24,6 +24,7 @@
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h> 26#include <linux/amba/pl330.h>
27#include <linux/of.h>
27 28
28#include <asm/irq.h> 29#include <asm/irq.h>
29#include <plat/devs.h> 30#include <plat/devs.h>
@@ -35,95 +36,42 @@
35 36
36static u64 dma_dmamask = DMA_BIT_MASK(32); 37static u64 dma_dmamask = DMA_BIT_MASK(32);
37 38
38struct dma_pl330_peri pdma0_peri[28] = { 39u8 pdma0_peri[] = {
39 { 40 DMACH_PCM0_RX,
40 .peri_id = (u8)DMACH_PCM0_RX, 41 DMACH_PCM0_TX,
41 .rqtype = DEVTOMEM, 42 DMACH_PCM2_RX,
42 }, { 43 DMACH_PCM2_TX,
43 .peri_id = (u8)DMACH_PCM0_TX, 44 DMACH_MSM_REQ0,
44 .rqtype = MEMTODEV, 45 DMACH_MSM_REQ2,
45 }, { 46 DMACH_SPI0_RX,
46 .peri_id = (u8)DMACH_PCM2_RX, 47 DMACH_SPI0_TX,
47 .rqtype = DEVTOMEM, 48 DMACH_SPI2_RX,
48 }, { 49 DMACH_SPI2_TX,
49 .peri_id = (u8)DMACH_PCM2_TX, 50 DMACH_I2S0S_TX,
50 .rqtype = MEMTODEV, 51 DMACH_I2S0_RX,
51 }, { 52 DMACH_I2S0_TX,
52 .peri_id = (u8)DMACH_MSM_REQ0, 53 DMACH_I2S2_RX,
53 }, { 54 DMACH_I2S2_TX,
54 .peri_id = (u8)DMACH_MSM_REQ2, 55 DMACH_UART0_RX,
55 }, { 56 DMACH_UART0_TX,
56 .peri_id = (u8)DMACH_SPI0_RX, 57 DMACH_UART2_RX,
57 .rqtype = DEVTOMEM, 58 DMACH_UART2_TX,
58 }, { 59 DMACH_UART4_RX,
59 .peri_id = (u8)DMACH_SPI0_TX, 60 DMACH_UART4_TX,
60 .rqtype = MEMTODEV, 61 DMACH_SLIMBUS0_RX,
61 }, { 62 DMACH_SLIMBUS0_TX,
62 .peri_id = (u8)DMACH_SPI2_RX, 63 DMACH_SLIMBUS2_RX,
63 .rqtype = DEVTOMEM, 64 DMACH_SLIMBUS2_TX,
64 }, { 65 DMACH_SLIMBUS4_RX,
65 .peri_id = (u8)DMACH_SPI2_TX, 66 DMACH_SLIMBUS4_TX,
66 .rqtype = MEMTODEV, 67 DMACH_AC97_MICIN,
67 }, { 68 DMACH_AC97_PCMIN,
68 .peri_id = (u8)DMACH_I2S0S_TX, 69 DMACH_AC97_PCMOUT,
69 .rqtype = MEMTODEV,
70 }, {
71 .peri_id = (u8)DMACH_I2S0_RX,
72 .rqtype = DEVTOMEM,
73 }, {
74 .peri_id = (u8)DMACH_I2S0_TX,
75 .rqtype = MEMTODEV,
76 }, {
77 .peri_id = (u8)DMACH_UART0_RX,
78 .rqtype = DEVTOMEM,
79 }, {
80 .peri_id = (u8)DMACH_UART0_TX,
81 .rqtype = MEMTODEV,
82 }, {
83 .peri_id = (u8)DMACH_UART2_RX,
84 .rqtype = DEVTOMEM,
85 }, {
86 .peri_id = (u8)DMACH_UART2_TX,
87 .rqtype = MEMTODEV,
88 }, {
89 .peri_id = (u8)DMACH_UART4_RX,
90 .rqtype = DEVTOMEM,
91 }, {
92 .peri_id = (u8)DMACH_UART4_TX,
93 .rqtype = MEMTODEV,
94 }, {
95 .peri_id = (u8)DMACH_SLIMBUS0_RX,
96 .rqtype = DEVTOMEM,
97 }, {
98 .peri_id = (u8)DMACH_SLIMBUS0_TX,
99 .rqtype = MEMTODEV,
100 }, {
101 .peri_id = (u8)DMACH_SLIMBUS2_RX,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_SLIMBUS2_TX,
105 .rqtype = MEMTODEV,
106 }, {
107 .peri_id = (u8)DMACH_SLIMBUS4_RX,
108 .rqtype = DEVTOMEM,
109 }, {
110 .peri_id = (u8)DMACH_SLIMBUS4_TX,
111 .rqtype = MEMTODEV,
112 }, {
113 .peri_id = (u8)DMACH_AC97_MICIN,
114 .rqtype = DEVTOMEM,
115 }, {
116 .peri_id = (u8)DMACH_AC97_PCMIN,
117 .rqtype = DEVTOMEM,
118 }, {
119 .peri_id = (u8)DMACH_AC97_PCMOUT,
120 .rqtype = MEMTODEV,
121 },
122}; 70};
123 71
124struct dma_pl330_platdata exynos4_pdma0_pdata = { 72struct dma_pl330_platdata exynos4_pdma0_pdata = {
125 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 73 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
126 .peri = pdma0_peri, 74 .peri_id = pdma0_peri,
127}; 75};
128 76
129struct amba_device exynos4_device_pdma0 = { 77struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +90,37 @@ struct amba_device exynos4_device_pdma0 = {
142 .periphid = 0x00041330, 90 .periphid = 0x00041330,
143}; 91};
144 92
145struct dma_pl330_peri pdma1_peri[25] = { 93u8 pdma1_peri[] = {
146 { 94 DMACH_PCM0_RX,
147 .peri_id = (u8)DMACH_PCM0_RX, 95 DMACH_PCM0_TX,
148 .rqtype = DEVTOMEM, 96 DMACH_PCM1_RX,
149 }, { 97 DMACH_PCM1_TX,
150 .peri_id = (u8)DMACH_PCM0_TX, 98 DMACH_MSM_REQ1,
151 .rqtype = MEMTODEV, 99 DMACH_MSM_REQ3,
152 }, { 100 DMACH_SPI1_RX,
153 .peri_id = (u8)DMACH_PCM1_RX, 101 DMACH_SPI1_TX,
154 .rqtype = DEVTOMEM, 102 DMACH_I2S0S_TX,
155 }, { 103 DMACH_I2S0_RX,
156 .peri_id = (u8)DMACH_PCM1_TX, 104 DMACH_I2S0_TX,
157 .rqtype = MEMTODEV, 105 DMACH_I2S1_RX,
158 }, { 106 DMACH_I2S1_TX,
159 .peri_id = (u8)DMACH_MSM_REQ1, 107 DMACH_UART0_RX,
160 }, { 108 DMACH_UART0_TX,
161 .peri_id = (u8)DMACH_MSM_REQ3, 109 DMACH_UART1_RX,
162 }, { 110 DMACH_UART1_TX,
163 .peri_id = (u8)DMACH_SPI1_RX, 111 DMACH_UART3_RX,
164 .rqtype = DEVTOMEM, 112 DMACH_UART3_TX,
165 }, { 113 DMACH_SLIMBUS1_RX,
166 .peri_id = (u8)DMACH_SPI1_TX, 114 DMACH_SLIMBUS1_TX,
167 .rqtype = MEMTODEV, 115 DMACH_SLIMBUS3_RX,
168 }, { 116 DMACH_SLIMBUS3_TX,
169 .peri_id = (u8)DMACH_I2S0S_TX, 117 DMACH_SLIMBUS5_RX,
170 .rqtype = MEMTODEV, 118 DMACH_SLIMBUS5_TX,
171 }, {
172 .peri_id = (u8)DMACH_I2S0_RX,
173 .rqtype = DEVTOMEM,
174 }, {
175 .peri_id = (u8)DMACH_I2S0_TX,
176 .rqtype = MEMTODEV,
177 }, {
178 .peri_id = (u8)DMACH_I2S1_RX,
179 .rqtype = DEVTOMEM,
180 }, {
181 .peri_id = (u8)DMACH_I2S1_TX,
182 .rqtype = MEMTODEV,
183 }, {
184 .peri_id = (u8)DMACH_UART0_RX,
185 .rqtype = DEVTOMEM,
186 }, {
187 .peri_id = (u8)DMACH_UART0_TX,
188 .rqtype = MEMTODEV,
189 }, {
190 .peri_id = (u8)DMACH_UART1_RX,
191 .rqtype = DEVTOMEM,
192 }, {
193 .peri_id = (u8)DMACH_UART1_TX,
194 .rqtype = MEMTODEV,
195 }, {
196 .peri_id = (u8)DMACH_UART3_RX,
197 .rqtype = DEVTOMEM,
198 }, {
199 .peri_id = (u8)DMACH_UART3_TX,
200 .rqtype = MEMTODEV,
201 }, {
202 .peri_id = (u8)DMACH_SLIMBUS1_RX,
203 .rqtype = DEVTOMEM,
204 }, {
205 .peri_id = (u8)DMACH_SLIMBUS1_TX,
206 .rqtype = MEMTODEV,
207 }, {
208 .peri_id = (u8)DMACH_SLIMBUS3_RX,
209 .rqtype = DEVTOMEM,
210 }, {
211 .peri_id = (u8)DMACH_SLIMBUS3_TX,
212 .rqtype = MEMTODEV,
213 }, {
214 .peri_id = (u8)DMACH_SLIMBUS5_RX,
215 .rqtype = DEVTOMEM,
216 }, {
217 .peri_id = (u8)DMACH_SLIMBUS5_TX,
218 .rqtype = MEMTODEV,
219 },
220}; 119};
221 120
222struct dma_pl330_platdata exynos4_pdma1_pdata = { 121struct dma_pl330_platdata exynos4_pdma1_pdata = {
223 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 122 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
224 .peri = pdma1_peri, 123 .peri_id = pdma1_peri,
225}; 124};
226 125
227struct amba_device exynos4_device_pdma1 = { 126struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +141,15 @@ struct amba_device exynos4_device_pdma1 = {
242 141
243static int __init exynos4_dma_init(void) 142static int __init exynos4_dma_init(void)
244{ 143{
144 if (of_have_populated_dt())
145 return 0;
146
147 dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
148 dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
245 amba_device_register(&exynos4_device_pdma0, &iomem_resource); 149 amba_device_register(&exynos4_device_pdma0, &iomem_resource);
150
151 dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
152 dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
246 amba_device_register(&exynos4_device_pdma1, &iomem_resource); 153 amba_device_register(&exynos4_device_pdma1, &iomem_resource);
247 154
248 return 0; 155 return 0;
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index dfd4b7eecb9..f77bce04789 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -17,13 +17,13 @@
17 17
18/* PPI: Private Peripheral Interrupt */ 18/* PPI: Private Peripheral Interrupt */
19 19
20#define IRQ_PPI(x) S5P_IRQ(x+16) 20#define IRQ_PPI(x) (x+16)
21 21
22#define IRQ_MCT_LOCALTIMER IRQ_PPI(12) 22#define IRQ_MCT_LOCALTIMER IRQ_PPI(12)
23 23
24/* SPI: Shared Peripheral Interrupt */ 24/* SPI: Shared Peripheral Interrupt */
25 25
26#define IRQ_SPI(x) S5P_IRQ(x+32) 26#define IRQ_SPI(x) (x+32)
27 27
28#define IRQ_EINT0 IRQ_SPI(16) 28#define IRQ_EINT0 IRQ_SPI(16)
29#define IRQ_EINT1 IRQ_SPI(17) 29#define IRQ_EINT1 IRQ_SPI(17)
@@ -72,6 +72,9 @@
72#define IRQ_IIC5 IRQ_SPI(63) 72#define IRQ_IIC5 IRQ_SPI(63)
73#define IRQ_IIC6 IRQ_SPI(64) 73#define IRQ_IIC6 IRQ_SPI(64)
74#define IRQ_IIC7 IRQ_SPI(65) 74#define IRQ_IIC7 IRQ_SPI(65)
75#define IRQ_SPI0 IRQ_SPI(66)
76#define IRQ_SPI1 IRQ_SPI(67)
77#define IRQ_SPI2 IRQ_SPI(68)
75 78
76#define IRQ_USB_HOST IRQ_SPI(70) 79#define IRQ_USB_HOST IRQ_SPI(70)
77#define IRQ_USB_HSOTG IRQ_SPI(71) 80#define IRQ_USB_HSOTG IRQ_SPI(71)
@@ -163,7 +166,9 @@
163#define IRQ_GPIO2_NR_GROUPS 9 166#define IRQ_GPIO2_NR_GROUPS 9
164#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) 167#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
165 168
169#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64)
170
166/* Set the default NR_IRQS */ 171/* Set the default NR_IRQS */
167#define NR_IRQS (IRQ_GPIO_END + 64) 172#define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
168 173
169#endif /* __ASM_ARCH_IRQS_H */ 174#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index d1829860a0e..c754a22a2bb 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -87,6 +87,10 @@
87#define EXYNOS4_PA_SYSMMU_TV 0x12E20000 87#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
88#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000 88#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
89#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000 89#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
90#define EXYNOS4_PA_SPI0 0x13920000
91#define EXYNOS4_PA_SPI1 0x13930000
92#define EXYNOS4_PA_SPI2 0x13940000
93
90 94
91#define EXYNOS4_PA_GPIO1 0x11400000 95#define EXYNOS4_PA_GPIO1 0x11400000
92#define EXYNOS4_PA_GPIO2 0x11000000 96#define EXYNOS4_PA_GPIO2 0x11000000
@@ -107,6 +111,7 @@
107#define EXYNOS4_PA_SROMC 0x12570000 111#define EXYNOS4_PA_SROMC 0x12570000
108 112
109#define EXYNOS4_PA_EHCI 0x12580000 113#define EXYNOS4_PA_EHCI 0x12580000
114#define EXYNOS4_PA_OHCI 0x12590000
110#define EXYNOS4_PA_HSPHY 0x125B0000 115#define EXYNOS4_PA_HSPHY 0x125B0000
111#define EXYNOS4_PA_MFC 0x13400000 116#define EXYNOS4_PA_MFC 0x13400000
112 117
@@ -148,6 +153,9 @@
148#define S3C_PA_RTC EXYNOS4_PA_RTC 153#define S3C_PA_RTC EXYNOS4_PA_RTC
149#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG 154#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
150#define S3C_PA_UART EXYNOS4_PA_UART 155#define S3C_PA_UART EXYNOS4_PA_UART
156#define S3C_PA_SPI0 EXYNOS4_PA_SPI0
157#define S3C_PA_SPI1 EXYNOS4_PA_SPI1
158#define S3C_PA_SPI2 EXYNOS4_PA_SPI2
151 159
152#define S5P_PA_EHCI EXYNOS4_PA_EHCI 160#define S5P_PA_EHCI EXYNOS4_PA_EHCI
153#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0 161#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
diff --git a/arch/arm/mach-exynos/include/mach/ohci.h b/arch/arm/mach-exynos/include/mach/ohci.h
new file mode 100644
index 00000000000..c256c595be5
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/ohci.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * http://www.samsung.com/
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MACH_EXYNOS_OHCI_H
12#define __MACH_EXYNOS_OHCI_H
13
14struct exynos4_ohci_platdata {
15 int (*phy_init)(struct platform_device *pdev, int type);
16 int (*phy_exit)(struct platform_device *pdev, int type);
17};
18
19extern void exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd);
20
21#endif /* __MACH_EXYNOS_OHCI_H */
diff --git a/arch/arm/mach-exynos/include/mach/spi-clocks.h b/arch/arm/mach-exynos/include/mach/spi-clocks.h
new file mode 100644
index 00000000000..576efdf6d09
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/spi-clocks.h
@@ -0,0 +1,16 @@
1/* linux/arch/arm/mach-exynos4/include/mach/spi-clocks.h
2 *
3 * Copyright (C) 2011 Samsung Electronics Co. Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef __ASM_ARCH_SPI_CLKS_H
11#define __ASM_ARCH_SPI_CLKS_H __FILE__
12
13/* Must source from SCLK_SPI */
14#define EXYNOS4_SPI_SRCCLK_SCLK 0
15
16#endif /* __ASM_ARCH_SPI_CLKS_H */
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
new file mode 100644
index 00000000000..85fa02767d6
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -0,0 +1,85 @@
1/*
2 * Samsung's Exynos4210 flattened device tree enabled machine
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/of_platform.h>
15#include <linux/serial_core.h>
16
17#include <asm/mach/arch.h>
18#include <mach/map.h>
19
20#include <plat/cpu.h>
21#include <plat/regs-serial.h>
22#include <plat/exynos4.h>
23
24/*
25 * The following lookup table is used to override device names when devices
26 * are registered from device tree. This is temporarily added to enable
27 * device tree support addition for the Exynos4 architecture.
28 *
29 * For drivers that require platform data to be provided from the machine
30 * file, a platform data pointer can also be supplied along with the
31 * devices names. Usually, the platform data elements that cannot be parsed
32 * from the device tree by the drivers (example: function pointers) are
33 * supplied. But it should be noted that this is a temporary mechanism and
34 * at some point, the drivers should be capable of parsing all the platform
35 * data from the device tree.
36 */
37static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
38 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0,
39 "exynos4210-uart.0", NULL),
40 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1,
41 "exynos4210-uart.1", NULL),
42 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2,
43 "exynos4210-uart.2", NULL),
44 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3,
45 "exynos4210-uart.3", NULL),
46 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
47 "exynos4-sdhci.0", NULL),
48 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
49 "exynos4-sdhci.1", NULL),
50 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
51 "exynos4-sdhci.2", NULL),
52 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
53 "exynos4-sdhci.3", NULL),
54 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
55 "s3c2440-i2c.0", NULL),
56 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
57 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
58 {},
59};
60
61static void __init exynos4210_dt_map_io(void)
62{
63 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
64 s3c24xx_init_clocks(24000000);
65}
66
67static void __init exynos4210_dt_machine_init(void)
68{
69 of_platform_populate(NULL, of_default_bus_match_table,
70 exynos4210_auxdata_lookup, NULL);
71}
72
73static char const *exynos4210_dt_compat[] __initdata = {
74 "samsung,exynos4210",
75 NULL
76};
77
78DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
79 /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
80 .init_irq = exynos4_init_irq,
81 .map_io = exynos4210_dt_map_io,
82 .init_machine = exynos4210_dt_machine_init,
83 .timer = &exynos4_timer,
84 .dt_compat = exynos4210_dt_compat,
85MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 635fb97e31a..b895ec03110 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -249,13 +249,8 @@ static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
249 249
250static int nuri_bl_init(struct device *dev) 250static int nuri_bl_init(struct device *dev)
251{ 251{
252 int ret, gpio = EXYNOS4_GPE2(3); 252 return gpio_request_one(EXYNOS4_GPE2(3), GPIOF_OUT_INIT_LOW,
253 253 "LCD_LD0_EN");
254 ret = gpio_request(gpio, "LCD_LDO_EN");
255 if (!ret)
256 gpio_direction_output(gpio, 0);
257
258 return ret;
259} 254}
260 255
261static int nuri_bl_notify(struct device *dev, int brightness) 256static int nuri_bl_notify(struct device *dev, int brightness)
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 586eb995aa9..2b11e046d39 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -41,6 +41,7 @@
41#include <plat/fb.h> 41#include <plat/fb.h>
42#include <plat/mfc.h> 42#include <plat/mfc.h>
43 43
44#include <mach/ohci.h>
44#include <mach/map.h> 45#include <mach/map.h>
45 46
46#include "common.h" 47#include "common.h"
@@ -485,6 +486,16 @@ static void __init origen_ehci_init(void)
485 s5p_ehci_set_platdata(pdata); 486 s5p_ehci_set_platdata(pdata);
486} 487}
487 488
489/* USB OHCI */
490static struct exynos4_ohci_platdata origen_ohci_pdata;
491
492static void __init origen_ohci_init(void)
493{
494 struct exynos4_ohci_platdata *pdata = &origen_ohci_pdata;
495
496 exynos4_ohci_set_platdata(pdata);
497}
498
488static struct gpio_keys_button origen_gpio_keys_table[] = { 499static struct gpio_keys_button origen_gpio_keys_table[] = {
489 { 500 {
490 .code = KEY_MENU, 501 .code = KEY_MENU,
@@ -608,6 +619,7 @@ static struct platform_device *origen_devices[] __initdata = {
608 &s5p_device_mfc_l, 619 &s5p_device_mfc_l,
609 &s5p_device_mfc_r, 620 &s5p_device_mfc_r,
610 &s5p_device_mixer, 621 &s5p_device_mixer,
622 &exynos4_device_ohci,
611 &exynos4_device_pd[PD_LCD0], 623 &exynos4_device_pd[PD_LCD0],
612 &exynos4_device_pd[PD_TV], 624 &exynos4_device_pd[PD_TV],
613 &exynos4_device_pd[PD_G3D], 625 &exynos4_device_pd[PD_G3D],
@@ -672,6 +684,7 @@ static void __init origen_machine_init(void)
672 s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata); 684 s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);
673 685
674 origen_ehci_init(); 686 origen_ehci_init();
687 origen_ohci_init();
675 clk_xusbxti.rate = 24000000; 688 clk_xusbxti.rate = 24000000;
676 689
677 s5p_tv_setup(); 690 s5p_tv_setup();
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index 5b365613b47..b2c5557f50e 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -42,6 +42,7 @@
42#include <plat/clock.h> 42#include <plat/clock.h>
43 43
44#include <mach/map.h> 44#include <mach/map.h>
45#include <mach/ohci.h>
45 46
46#include "common.h" 47#include "common.h"
47 48
@@ -131,9 +132,7 @@ static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
131 gpio_free(EXYNOS4_GPD0(1)); 132 gpio_free(EXYNOS4_GPD0(1));
132#endif 133#endif
133 /* fire nRESET on power up */ 134 /* fire nRESET on power up */
134 gpio_request(EXYNOS4_GPX0(6), "GPX0"); 135 gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
135
136 gpio_direction_output(EXYNOS4_GPX0(6), 1);
137 mdelay(100); 136 mdelay(100);
138 137
139 gpio_set_value(EXYNOS4_GPX0(6), 0); 138 gpio_set_value(EXYNOS4_GPX0(6), 0);
@@ -247,6 +246,16 @@ static void __init smdkv310_ehci_init(void)
247 s5p_ehci_set_platdata(pdata); 246 s5p_ehci_set_platdata(pdata);
248} 247}
249 248
249/* USB OHCI */
250static struct exynos4_ohci_platdata smdkv310_ohci_pdata;
251
252static void __init smdkv310_ohci_init(void)
253{
254 struct exynos4_ohci_platdata *pdata = &smdkv310_ohci_pdata;
255
256 exynos4_ohci_set_platdata(pdata);
257}
258
250static struct platform_device *smdkv310_devices[] __initdata = { 259static struct platform_device *smdkv310_devices[] __initdata = {
251 &s3c_device_hsmmc0, 260 &s3c_device_hsmmc0,
252 &s3c_device_hsmmc1, 261 &s3c_device_hsmmc1,
@@ -263,6 +272,7 @@ static struct platform_device *smdkv310_devices[] __initdata = {
263 &s5p_device_fimc3, 272 &s5p_device_fimc3,
264 &exynos4_device_ac97, 273 &exynos4_device_ac97,
265 &exynos4_device_i2s0, 274 &exynos4_device_i2s0,
275 &exynos4_device_ohci,
266 &samsung_device_keypad, 276 &samsung_device_keypad,
267 &s5p_device_mfc, 277 &s5p_device_mfc,
268 &s5p_device_mfc_l, 278 &s5p_device_mfc_l,
@@ -365,6 +375,7 @@ static void __init smdkv310_machine_init(void)
365 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata); 375 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
366 376
367 smdkv310_ehci_init(); 377 smdkv310_ehci_init();
378 smdkv310_ohci_init();
368 clk_xusbxti.rate = 24000000; 379 clk_xusbxti.rate = 24000000;
369 380
370 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); 381 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 52aea972746..37ac93e8d6d 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -610,8 +610,7 @@ static void __init universal_tsp_init(void)
610 610
611 /* TSP_LDO_ON: XMDMADDR_11 */ 611 /* TSP_LDO_ON: XMDMADDR_11 */
612 gpio = EXYNOS4_GPE2(3); 612 gpio = EXYNOS4_GPE2(3);
613 gpio_request(gpio, "TSP_LDO_ON"); 613 gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "TSP_LDO_ON");
614 gpio_direction_output(gpio, 1);
615 gpio_export(gpio, 0); 614 gpio_export(gpio, 0);
616 615
617 /* TSP_INT: XMDMADDR_7 */ 616 /* TSP_INT: XMDMADDR_7 */
@@ -671,8 +670,7 @@ static void __init universal_touchkey_init(void)
671 i2c_gpio12_devs[0].irq = gpio_to_irq(gpio); 670 i2c_gpio12_devs[0].irq = gpio_to_irq(gpio);
672 671
673 gpio = EXYNOS4_GPE3(3); /* XMDMDATA_3 */ 672 gpio = EXYNOS4_GPE3(3); /* XMDMDATA_3 */
674 gpio_request(gpio, "3_TOUCH_EN"); 673 gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "3_TOUCH_EN");
675 gpio_direction_output(gpio, 1);
676} 674}
677 675
678static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = { 676static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = {
@@ -1002,9 +1000,7 @@ static void __init universal_map_io(void)
1002void s5p_tv_setup(void) 1000void s5p_tv_setup(void)
1003{ 1001{
1004 /* direct HPD to HDMI chip */ 1002 /* direct HPD to HDMI chip */
1005 gpio_request(EXYNOS4_GPX3(7), "hpd-plug"); 1003 gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
1006
1007 gpio_direction_input(EXYNOS4_GPX3(7));
1008 s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3)); 1004 s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
1009 s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE); 1005 s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
1010 1006
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index c4f792dcad1..a4f61a43c7b 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -23,6 +23,7 @@
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/hardware/cache-l2x0.h> 25#include <asm/hardware/cache-l2x0.h>
26#include <asm/smp_scu.h>
26 27
27#include <plat/cpu.h> 28#include <plat/cpu.h>
28#include <plat/pm.h> 29#include <plat/pm.h>
@@ -213,27 +214,6 @@ static int exynos4_pm_add(struct device *dev)
213 return 0; 214 return 0;
214} 215}
215 216
216/* This function copy from linux/arch/arm/kernel/smp_scu.c */
217
218void exynos4_scu_enable(void __iomem *scu_base)
219{
220 u32 scu_ctrl;
221
222 scu_ctrl = __raw_readl(scu_base);
223 /* already enabled? */
224 if (scu_ctrl & 1)
225 return;
226
227 scu_ctrl |= 1;
228 __raw_writel(scu_ctrl, scu_base);
229
230 /*
231 * Ensure that the data accessed by CPU0 before the SCU was
232 * initialised is visible to the other CPUs.
233 */
234 flush_cache_all();
235}
236
237static unsigned long pll_base_rate; 217static unsigned long pll_base_rate;
238 218
239static void exynos4_restore_pll(void) 219static void exynos4_restore_pll(void)
@@ -404,7 +384,7 @@ static void exynos4_pm_resume(void)
404 384
405 exynos4_restore_pll(); 385 exynos4_restore_pll();
406 386
407 exynos4_scu_enable(S5P_VA_SCU); 387 scu_enable(S5P_VA_SCU);
408 388
409#ifdef CONFIG_CACHE_L2X0 389#ifdef CONFIG_CACHE_L2X0
410 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save)); 390 s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
diff --git a/arch/arm/mach-exynos/setup-sdhci.c b/arch/arm/mach-exynos/setup-sdhci.c
deleted file mode 100644
index 92937b41090..00000000000
--- a/arch/arm/mach-exynos/setup-sdhci.c
+++ /dev/null
@@ -1,22 +0,0 @@
1/* linux/arch/arm/mach-exynos4/setup-sdhci.c
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/types.h>
14
15/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
16
17char *exynos4_hsmmc_clksrcs[4] = {
18 [0] = NULL,
19 [1] = NULL,
20 [2] = "sclk_mmc", /* mmc_bus */
21 [3] = NULL,
22};
diff --git a/arch/arm/mach-exynos/setup-spi.c b/arch/arm/mach-exynos/setup-spi.c
new file mode 100644
index 00000000000..833ff40ee0e
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-spi.c
@@ -0,0 +1,72 @@
1/* linux/arch/arm/mach-exynos4/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16
17#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
19 .fifo_lvl_mask = 0x1ff,
20 .rx_lvl_offset = 15,
21 .high_speed = 1,
22 .clk_from_cmu = true,
23 .tx_st_done = 25,
24};
25
26int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
27{
28 s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP);
30 s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
31 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
32 return 0;
33}
34#endif
35
36#ifdef CONFIG_S3C64XX_DEV_SPI1
37struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
38 .fifo_lvl_mask = 0x7f,
39 .rx_lvl_offset = 15,
40 .high_speed = 1,
41 .clk_from_cmu = true,
42 .tx_st_done = 25,
43};
44
45int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
46{
47 s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2));
48 s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP);
49 s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
50 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
51 return 0;
52}
53#endif
54
55#ifdef CONFIG_S3C64XX_DEV_SPI2
56struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = {
57 .fifo_lvl_mask = 0x7f,
58 .rx_lvl_offset = 15,
59 .high_speed = 1,
60 .clk_from_cmu = true,
61 .tx_st_done = 25,
62};
63
64int s3c64xx_spi2_cfg_gpio(struct platform_device *dev)
65{
66 s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5));
67 s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP);
68 s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
69 S3C_GPIO_SFN(5), S3C_GPIO_PULL_UP);
70 return 0;
71}
72#endif
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index 39aca045f66..41743d21e8c 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -19,6 +19,13 @@
19#include <plat/cpu.h> 19#include <plat/cpu.h>
20#include <plat/usb-phy.h> 20#include <plat/usb-phy.h>
21 21
22static atomic_t host_usage;
23
24static int exynos4_usb_host_phy_is_on(void)
25{
26 return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
27}
28
22static int exynos4_usb_phy1_init(struct platform_device *pdev) 29static int exynos4_usb_phy1_init(struct platform_device *pdev)
23{ 30{
24 struct clk *otg_clk; 31 struct clk *otg_clk;
@@ -27,6 +34,8 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
27 u32 rstcon; 34 u32 rstcon;
28 int err; 35 int err;
29 36
37 atomic_inc(&host_usage);
38
30 otg_clk = clk_get(&pdev->dev, "otg"); 39 otg_clk = clk_get(&pdev->dev, "otg");
31 if (IS_ERR(otg_clk)) { 40 if (IS_ERR(otg_clk)) {
32 dev_err(&pdev->dev, "Failed to get otg clock\n"); 41 dev_err(&pdev->dev, "Failed to get otg clock\n");
@@ -39,6 +48,9 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
39 return err; 48 return err;
40 } 49 }
41 50
51 if (exynos4_usb_host_phy_is_on())
52 return 0;
53
42 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, 54 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
43 S5P_USBHOST_PHY_CONTROL); 55 S5P_USBHOST_PHY_CONTROL);
44 56
@@ -95,6 +107,9 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev)
95 struct clk *otg_clk; 107 struct clk *otg_clk;
96 int err; 108 int err;
97 109
110 if (atomic_dec_return(&host_usage) > 0)
111 return 0;
112
98 otg_clk = clk_get(&pdev->dev, "otg"); 113 otg_clk = clk_get(&pdev->dev, "otg");
99 if (IS_ERR(otg_clk)) { 114 if (IS_ERR(otg_clk)) {
100 dev_err(&pdev->dev, "Failed to get otg clock\n"); 115 dev_err(&pdev->dev, "Failed to get otg clock\n");
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 35a218cb5c7..0e6de366c64 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -98,6 +98,7 @@ config MACH_SCB9328
98config MACH_APF9328 98config MACH_APF9328
99 bool "APF9328" 99 bool "APF9328"
100 select SOC_IMX1 100 select SOC_IMX1
101 select IMX_HAVE_PLATFORM_IMX_I2C
101 select IMX_HAVE_PLATFORM_IMX_UART 102 select IMX_HAVE_PLATFORM_IMX_UART
102 help 103 help
103 Say Yes here if you are using the Armadeus APF9328 development board 104 Say Yes here if you are using the Armadeus APF9328 development board
@@ -595,6 +596,7 @@ comment "i.MX6 family:"
595 596
596config SOC_IMX6Q 597config SOC_IMX6Q
597 bool "i.MX6 Quad support" 598 bool "i.MX6 Quad support"
599 select ARM_CPU_SUSPEND if PM
598 select ARM_GIC 600 select ARM_GIC
599 select CPU_V7 601 select CPU_V7
600 select HAVE_ARM_SCU 602 select HAVE_ARM_SCU
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d97f409ce98..f5920c24f7d 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -70,4 +70,8 @@ AFLAGS_head-v7.o :=-Wa,-march=armv7-a
70obj-$(CONFIG_SMP) += platsmp.o 70obj-$(CONFIG_SMP) += platsmp.o
71obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 71obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
72obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 72obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o pm-imx6q.o 73obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
74
75ifeq ($(CONFIG_PM),y)
76obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o
77endif
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index cfede5768aa..5f4d06af491 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -25,3 +25,6 @@ initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000
25zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000 25zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000
26params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100 26params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100
27initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000 27initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000
28
29dtb-$(CONFIG_SOC_IMX6Q) += imx6q-arm2.dtb \
30 imx6q-sabrelite.dtb
diff --git a/arch/arm/mach-imx/head-v7.S b/arch/arm/mach-imx/head-v7.S
index 6229efbc70c..7e49deb128a 100644
--- a/arch/arm/mach-imx/head-v7.S
+++ b/arch/arm/mach-imx/head-v7.S
@@ -16,7 +16,6 @@
16#include <asm/hardware/cache-l2x0.h> 16#include <asm/hardware/cache-l2x0.h>
17 17
18 .section ".text.head", "ax" 18 .section ".text.head", "ax"
19 __CPUINIT
20 19
21/* 20/*
22 * The secondary kernel init calls v7_flush_dcache_all before it enables 21 * The secondary kernel init calls v7_flush_dcache_all before it enables
@@ -33,6 +32,7 @@
33 */ 32 */
34ENTRY(v7_invalidate_l1) 33ENTRY(v7_invalidate_l1)
35 mov r0, #0 34 mov r0, #0
35 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
36 mcr p15, 2, r0, c0, c0, 0 36 mcr p15, 2, r0, c0, c0, 0
37 mrc p15, 1, r0, c0, c0, 0 37 mrc p15, 1, r0, c0, c0, 0
38 38
@@ -71,6 +71,7 @@ ENTRY(v7_secondary_startup)
71ENDPROC(v7_secondary_startup) 71ENDPROC(v7_secondary_startup)
72#endif 72#endif
73 73
74#ifdef CONFIG_PM
74/* 75/*
75 * The following code is located into the .data section. This is to 76 * The following code is located into the .data section. This is to
76 * allow phys_l2x0_saved_regs to be accessed with a relative load 77 * allow phys_l2x0_saved_regs to be accessed with a relative load
@@ -79,6 +80,7 @@ ENDPROC(v7_secondary_startup)
79 .data 80 .data
80 .align 81 .align
81 82
83#ifdef CONFIG_CACHE_L2X0
82 .macro pl310_resume 84 .macro pl310_resume
83 ldr r2, phys_l2x0_saved_regs 85 ldr r2, phys_l2x0_saved_regs
84 ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0 86 ldr r0, [r2, #L2X0_R_PHY_BASE] @ get physical base of l2x0
@@ -88,12 +90,17 @@ ENDPROC(v7_secondary_startup)
88 str r1, [r0, #L2X0_CTRL] @ re-enable L2 90 str r1, [r0, #L2X0_CTRL] @ re-enable L2
89 .endm 91 .endm
90 92
93 .globl phys_l2x0_saved_regs
94phys_l2x0_saved_regs:
95 .long 0
96#else
97 .macro pl310_resume
98 .endm
99#endif
100
91ENTRY(v7_cpu_resume) 101ENTRY(v7_cpu_resume)
92 bl v7_invalidate_l1 102 bl v7_invalidate_l1
93 pl310_resume 103 pl310_resume
94 b cpu_resume 104 b cpu_resume
95ENDPROC(v7_cpu_resume) 105ENDPROC(v7_cpu_resume)
96 106#endif
97 .globl phys_l2x0_saved_regs
98phys_l2x0_saved_regs:
99 .long 0
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c
index 146a4f07346..f4a63ee9e21 100644
--- a/arch/arm/mach-imx/mach-apf9328.c
+++ b/arch/arm/mach-imx/mach-apf9328.c
@@ -18,6 +18,7 @@
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/mtd/physmap.h> 19#include <linux/mtd/physmap.h>
20#include <linux/dm9000.h> 20#include <linux/dm9000.h>
21#include <linux/i2c.h>
21 22
22#include <asm/mach-types.h> 23#include <asm/mach-types.h>
23#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
@@ -41,6 +42,9 @@ static const int apf9328_pins[] __initconst = {
41 PB29_PF_UART2_RTS, 42 PB29_PF_UART2_RTS,
42 PB30_PF_UART2_TXD, 43 PB30_PF_UART2_TXD,
43 PB31_PF_UART2_RXD, 44 PB31_PF_UART2_RXD,
45 /* I2C */
46 PA15_PF_I2C_SDA,
47 PA16_PF_I2C_SCL,
44}; 48};
45 49
46/* 50/*
@@ -103,6 +107,10 @@ static const struct imxuart_platform_data uart1_pdata __initconst = {
103 .flags = IMXUART_HAVE_RTSCTS, 107 .flags = IMXUART_HAVE_RTSCTS,
104}; 108};
105 109
110static const struct imxi2c_platform_data apf9328_i2c_data __initconst = {
111 .bitrate = 100000,
112};
113
106static struct platform_device *devices[] __initdata = { 114static struct platform_device *devices[] __initdata = {
107 &apf9328_flash_device, 115 &apf9328_flash_device,
108 &dm9000x_device, 116 &dm9000x_device,
@@ -119,6 +127,8 @@ static void __init apf9328_init(void)
119 imx1_add_imx_uart0(NULL); 127 imx1_add_imx_uart0(NULL);
120 imx1_add_imx_uart1(&uart1_pdata); 128 imx1_add_imx_uart1(&uart1_pdata);
121 129
130 imx1_add_imx_i2c(&apf9328_i2c_data);
131
122 platform_add_devices(devices, ARRAY_SIZE(devices)); 132 platform_add_devices(devices, ARRAY_SIZE(devices));
123} 133}
124 134
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 05b49bb5d67..c2572810691 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -19,6 +19,8 @@
19#include <linux/of_address.h> 19#include <linux/of_address.h>
20#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21#include <linux/of_platform.h> 21#include <linux/of_platform.h>
22#include <linux/phy.h>
23#include <linux/micrel_phy.h>
22#include <asm/hardware/cache-l2x0.h> 24#include <asm/hardware/cache-l2x0.h>
23#include <asm/hardware/gic.h> 25#include <asm/hardware/gic.h>
24#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
@@ -56,8 +58,27 @@ soft:
56 soft_restart(0); 58 soft_restart(0);
57} 59}
58 60
61/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */
62static int ksz9021rn_phy_fixup(struct phy_device *phydev)
63{
64 /* min rx data delay */
65 phy_write(phydev, 0x0b, 0x8105);
66 phy_write(phydev, 0x0c, 0x0000);
67
68 /* max rx/tx clock delay, min rx/tx control delay */
69 phy_write(phydev, 0x0b, 0x8104);
70 phy_write(phydev, 0x0c, 0xf0f0);
71 phy_write(phydev, 0x0b, 0x104);
72
73 return 0;
74}
75
59static void __init imx6q_init_machine(void) 76static void __init imx6q_init_machine(void)
60{ 77{
78 if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
79 phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
80 ksz9021rn_phy_fixup);
81
61 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 82 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
62 83
63 imx6q_pm_init(); 84 imx6q_pm_init();
@@ -105,7 +126,8 @@ static struct sys_timer imx6q_timer = {
105}; 126};
106 127
107static const char *imx6q_dt_compat[] __initdata = { 128static const char *imx6q_dt_compat[] __initdata = {
108 "fsl,imx6q-sabreauto", 129 "fsl,imx6q-arm2",
130 "fsl,imx6q-sabrelite",
109 NULL, 131 NULL,
110}; 132};
111 133
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 2b565c38134..89c33258639 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -492,7 +492,7 @@ static struct mc13xxx_platform_data mc13783_pdata = {
492 .regulators = mx31_3ds_regulators, 492 .regulators = mx31_3ds_regulators,
493 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), 493 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
494 }, 494 },
495 .flags = MC13XXX_USE_TOUCHSCREEN, 495 .flags = MC13XXX_USE_TOUCHSCREEN | MC13XXX_USE_RTC,
496}; 496};
497 497
498/* SPI */ 498/* SPI */
diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c
index f20f191d7cc..f7b0c2b1b90 100644
--- a/arch/arm/mach-imx/pm-imx6q.c
+++ b/arch/arm/mach-imx/pm-imx6q.c
@@ -64,7 +64,9 @@ void __init imx6q_pm_init(void)
64 * address of the data structure used by l2x0 core to save registers, 64 * address of the data structure used by l2x0 core to save registers,
65 * and later restore the necessary ones in imx6q resume entry. 65 * and later restore the necessary ones in imx6q resume entry.
66 */ 66 */
67#ifdef CONFIG_CACHE_L2X0
67 phys_l2x0_saved_regs = __pa(&l2x0_saved_regs); 68 phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
69#endif
68 70
69 suspend_set_ops(&imx6q_pm_ops); 71 suspend_set_ops(&imx6q_pm_ops);
70} 72}
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 8d03bcef518..e9a7180863d 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -13,12 +13,12 @@
13#include <linux/mbus.h> 13#include <linux/mbus.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <mach/hardware.h> 15#include <mach/hardware.h>
16#include <plat/addr-map.h>
16#include "common.h" 17#include "common.h"
17 18
18/* 19/*
19 * Generic Address Decode Windows bit settings 20 * Generic Address Decode Windows bit settings
20 */ 21 */
21#define TARGET_DDR 0
22#define TARGET_DEV_BUS 1 22#define TARGET_DEV_BUS 1
23#define TARGET_SRAM 3 23#define TARGET_SRAM 3
24#define TARGET_PCIE 4 24#define TARGET_PCIE 4
@@ -36,118 +36,55 @@
36#define ATTR_SRAM 0x01 36#define ATTR_SRAM 0x01
37 37
38/* 38/*
39 * Helpers to get DDR bank info 39 * Description of the windows needed by the platform code
40 */ 40 */
41#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) 41static struct __initdata orion_addr_map_cfg addr_map_cfg = {
42#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) 42 .num_wins = 8,
43 43 .remappable_wins = 4,
44/* 44 .bridge_virt_base = BRIDGE_VIRT_BASE,
45 * CPU Address Decode Windows registers 45};
46 */
47#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
48#define WIN_CTRL_OFF 0x0000
49#define WIN_BASE_OFF 0x0004
50#define WIN_REMAP_LO_OFF 0x0008
51#define WIN_REMAP_HI_OFF 0x000c
52
53
54struct mbus_dram_target_info kirkwood_mbus_dram_info;
55
56static int __init cpu_win_can_remap(int win)
57{
58 if (win < 4)
59 return 1;
60
61 return 0;
62}
63
64static void __init setup_cpu_win(int win, u32 base, u32 size,
65 u8 target, u8 attr, int remap)
66{
67 void __iomem *addr = (void __iomem *)WIN_OFF(win);
68 u32 ctrl;
69
70 base &= 0xffff0000;
71 ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
72
73 writel(base, addr + WIN_BASE_OFF);
74 writel(ctrl, addr + WIN_CTRL_OFF);
75 if (cpu_win_can_remap(win)) {
76 if (remap < 0)
77 remap = base;
78
79 writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
80 writel(0, addr + WIN_REMAP_HI_OFF);
81 }
82}
83
84void __init kirkwood_setup_cpu_mbus(void)
85{
86 void __iomem *addr;
87 int i;
88 int cs;
89 46
47static const struct __initdata orion_addr_map_info addr_map_info[] = {
90 /* 48 /*
91 * First, disable and clear windows. 49 * Windows for PCIe IO+MEM space.
92 */ 50 */
93 for (i = 0; i < 8; i++) { 51 { 0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
94 addr = (void __iomem *)WIN_OFF(i); 52 TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE
95 53 },
96 writel(0, addr + WIN_BASE_OFF); 54 { 1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
97 writel(0, addr + WIN_CTRL_OFF); 55 TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE
98 if (cpu_win_can_remap(i)) { 56 },
99 writel(0, addr + WIN_REMAP_LO_OFF); 57 { 2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
100 writel(0, addr + WIN_REMAP_HI_OFF); 58 TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE
101 } 59 },
102 } 60 { 3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
103 61 TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE
62 },
104 /* 63 /*
105 * Setup windows for PCIe IO+MEM space. 64 * Window for NAND controller.
106 */ 65 */
107 setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE, 66 { 4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
108 TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); 67 TARGET_DEV_BUS, ATTR_DEV_NAND, -1
109 setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, 68 },
110 TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
111 setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
112 TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
113 setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
114 TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
115
116 /* 69 /*
117 * Setup window for NAND controller. 70 * Window for SRAM.
118 */ 71 */
119 setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, 72 { 5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
120 TARGET_DEV_BUS, ATTR_DEV_NAND, -1); 73 TARGET_SRAM, ATTR_SRAM, -1
74 },
75 /* End marker */
76 { -1, 0, 0, 0, 0, 0 }
77};
121 78
79void __init kirkwood_setup_cpu_mbus(void)
80{
122 /* 81 /*
123 * Setup window for SRAM. 82 * Disable, clear and configure windows.
124 */ 83 */
125 setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, 84 orion_config_wins(&addr_map_cfg, addr_map_info);
126 TARGET_SRAM, ATTR_SRAM, -1);
127 85
128 /* 86 /*
129 * Setup MBUS dram target info. 87 * Setup MBUS dram target info.
130 */ 88 */
131 kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 89 orion_setup_cpu_mbus_target(&addr_map_cfg, DDR_WINDOW_CPU_BASE);
132
133 addr = (void __iomem *)DDR_WINDOW_CPU_BASE;
134
135 for (i = 0, cs = 0; i < 4; i++) {
136 u32 base = readl(addr + DDR_BASE_CS_OFF(i));
137 u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
138
139 /*
140 * Chip select enabled?
141 */
142 if (size & 1) {
143 struct mbus_dram_window *w;
144
145 w = &kirkwood_mbus_dram_info.cs[cs++];
146 w->cs_index = i;
147 w->mbus_attr = 0xf & ~(1 << i);
148 w->base = base & 0xffff0000;
149 w->size = (size | 0x0000ffff) + 1;
150 }
151 }
152 kirkwood_mbus_dram_info.num_cs = cs;
153} 90}
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 0bff4a91623..cc15426787b 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/mbus.h>
16#include <linux/ata_platform.h> 15#include <linux/ata_platform.h>
17#include <linux/mtd/nand.h> 16#include <linux/mtd/nand.h>
18#include <linux/dma-mapping.h> 17#include <linux/dma-mapping.h>
@@ -30,6 +29,7 @@
30#include <plat/orion_nand.h> 29#include <plat/orion_nand.h>
31#include <plat/common.h> 30#include <plat/common.h>
32#include <plat/time.h> 31#include <plat/time.h>
32#include <plat/addr-map.h>
33#include "common.h" 33#include "common.h"
34 34
35/***************************************************************************** 35/*****************************************************************************
@@ -73,8 +73,7 @@ unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
73void __init kirkwood_ehci_init(void) 73void __init kirkwood_ehci_init(void)
74{ 74{
75 kirkwood_clk_ctrl |= CGC_USB0; 75 kirkwood_clk_ctrl |= CGC_USB0;
76 orion_ehci_init(&kirkwood_mbus_dram_info, 76 orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB);
77 USB_PHYS_BASE, IRQ_KIRKWOOD_USB);
78} 77}
79 78
80 79
@@ -85,7 +84,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
85{ 84{
86 kirkwood_clk_ctrl |= CGC_GE0; 85 kirkwood_clk_ctrl |= CGC_GE0;
87 86
88 orion_ge00_init(eth_data, &kirkwood_mbus_dram_info, 87 orion_ge00_init(eth_data,
89 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, 88 GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
90 IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); 89 IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
91} 90}
@@ -99,7 +98,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
99 98
100 kirkwood_clk_ctrl |= CGC_GE1; 99 kirkwood_clk_ctrl |= CGC_GE1;
101 100
102 orion_ge01_init(eth_data, &kirkwood_mbus_dram_info, 101 orion_ge01_init(eth_data,
103 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, 102 GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
104 IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); 103 IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
105} 104}
@@ -178,8 +177,7 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
178 if (sata_data->n_ports > 1) 177 if (sata_data->n_ports > 1)
179 kirkwood_clk_ctrl |= CGC_SATA1; 178 kirkwood_clk_ctrl |= CGC_SATA1;
180 179
181 orion_sata_init(sata_data, &kirkwood_mbus_dram_info, 180 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
182 SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
183} 181}
184 182
185 183
@@ -221,7 +219,6 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
221 mvsdio_data->clock = 100000000; 219 mvsdio_data->clock = 100000000;
222 else 220 else
223 mvsdio_data->clock = 200000000; 221 mvsdio_data->clock = 200000000;
224 mvsdio_data->dram = &kirkwood_mbus_dram_info;
225 kirkwood_clk_ctrl |= CGC_SDIO; 222 kirkwood_clk_ctrl |= CGC_SDIO;
226 kirkwood_sdio.dev.platform_data = mvsdio_data; 223 kirkwood_sdio.dev.platform_data = mvsdio_data;
227 platform_device_register(&kirkwood_sdio); 224 platform_device_register(&kirkwood_sdio);
@@ -285,8 +282,7 @@ static void __init kirkwood_xor0_init(void)
285{ 282{
286 kirkwood_clk_ctrl |= CGC_XOR0; 283 kirkwood_clk_ctrl |= CGC_XOR0;
287 284
288 orion_xor0_init(&kirkwood_mbus_dram_info, 285 orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
289 XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
290 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); 286 IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
291} 287}
292 288
@@ -364,7 +360,6 @@ static struct resource kirkwood_i2s_resources[] = {
364}; 360};
365 361
366static struct kirkwood_asoc_platform_data kirkwood_i2s_data = { 362static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
367 .dram = &kirkwood_mbus_dram_info,
368 .burst = 128, 363 .burst = 128,
369}; 364};
370 365
@@ -430,6 +425,8 @@ static char * __init kirkwood_id(void)
430 } else if (dev == MV88F6282_DEV_ID) { 425 } else if (dev == MV88F6282_DEV_ID) {
431 if (rev == MV88F6282_REV_A0) 426 if (rev == MV88F6282_REV_A0)
432 return "MV88F6282-Rev-A0"; 427 return "MV88F6282-Rev-A0";
428 else if (rev == MV88F6282_REV_A1)
429 return "MV88F6282-Rev-A1";
433 else 430 else
434 return "MV88F6282-Rev-Unsupported"; 431 return "MV88F6282-Rev-Unsupported";
435 } else { 432 } else {
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 1529280246d..9071a397136 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -30,7 +30,6 @@ void kirkwood_init(void);
30void kirkwood_init_early(void); 30void kirkwood_init_early(void);
31void kirkwood_init_irq(void); 31void kirkwood_init_irq(void);
32 32
33extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
34void kirkwood_setup_cpu_mbus(void); 33void kirkwood_setup_cpu_mbus(void);
35 34
36void kirkwood_enable_pcie(void); 35void kirkwood_enable_pcie(void);
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 010bdeb4ac5..fede3d503ef 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -135,4 +135,5 @@
135 135
136#define MV88F6282_DEV_ID 0x6282 136#define MV88F6282_DEV_ID 0x6282
137#define MV88F6282_REV_A0 0 137#define MV88F6282_REV_A0 0
138#define MV88F6282_REV_A1 1
138#endif 139#endif
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
index cc431fa22cc..0c6ad63f10c 100644
--- a/arch/arm/mach-kirkwood/mpp.c
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -10,7 +10,6 @@
10#include <linux/gpio.h> 10#include <linux/gpio.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h> 13#include <linux/io.h>
15#include <mach/hardware.h> 14#include <mach/hardware.h>
16#include <plat/mpp.h> 15#include <plat/mpp.h>
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h
index ac787957e2d..e8fda45c073 100644
--- a/arch/arm/mach-kirkwood/mpp.h
+++ b/arch/arm/mach-kirkwood/mpp.h
@@ -102,6 +102,7 @@
102#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1, 1 ) 102#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1, 1 )
103 103
104#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 ) 104#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 )
105#define MPP12_GPIO MPP( 12, 0x0, 1, 1, 0, 0, 0, 1, 0 )
105#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1, 1 ) 106#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1, 1 )
106#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 1, 0, 0, 0, 0, 1 ) 107#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 1, 0, 0, 0, 0, 1 )
107#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 1, 0, 0, 0, 0, 1 ) 108#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 1, 0, 0, 0, 0, 1 )
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index 74b992d810e..fb451bfe478 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -11,12 +11,12 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/mbus.h>
15#include <video/vga.h> 14#include <video/vga.h>
16#include <asm/irq.h> 15#include <asm/irq.h>
17#include <asm/mach/pci.h> 16#include <asm/mach/pci.h>
18#include <plat/pcie.h> 17#include <plat/pcie.h>
19#include <mach/bridge-regs.h> 18#include <mach/bridge-regs.h>
19#include <plat/addr-map.h>
20#include "common.h" 20#include "common.h"
21 21
22void kirkwood_enable_pcie(void) 22void kirkwood_enable_pcie(void)
@@ -208,7 +208,7 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
208 */ 208 */
209 orion_pcie_set_local_bus_nr(pp->base, sys->busnr); 209 orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
210 210
211 orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info); 211 orion_pcie_setup(pp->base);
212 212
213 return 1; 213 return 1;
214} 214}
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 3e6dfab59ef..17cb7606012 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -120,8 +120,8 @@ static struct resource smc91x_resources[] = {
120 .flags = IORESOURCE_MEM, 120 .flags = IORESOURCE_MEM,
121 }, 121 },
122 [1] = { 122 [1] = {
123 .start = gpio_to_irq(27), 123 .start = MMP_GPIO_TO_IRQ(27),
124 .end = gpio_to_irq(27), 124 .end = MMP_GPIO_TO_IRQ(27),
125 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 125 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
126 } 126 }
127}; 127};
@@ -232,6 +232,7 @@ static void __init common_init(void)
232 pxa168_add_nand(&aspenite_nand_info); 232 pxa168_add_nand(&aspenite_nand_info);
233 pxa168_add_fb(&aspenite_lcd_info); 233 pxa168_add_fb(&aspenite_lcd_info);
234 pxa168_add_keypad(&aspenite_keypad_info); 234 pxa168_add_keypad(&aspenite_keypad_info);
235 platform_device_register(&pxa168_device_gpio);
235 236
236 /* off-chip devices */ 237 /* off-chip devices */
237 platform_device_register(&smc91x_device); 238 platform_device_register(&smc91x_device);
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index 8de3dc6131a..b148a9dc5a4 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -38,6 +38,7 @@ static void __init avengers_lite_init(void)
38 38
39 /* on-chip devices */ 39 /* on-chip devices */
40 pxa168_add_uart(2); 40 pxa168_add_uart(2);
41 platform_device_register(&pxa168_device_gpio);
41} 42}
42 43
43MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") 44MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index e16f04b39b1..d839fe6421e 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -202,6 +202,7 @@ static void __init brownstone_init(void)
202 /* on-chip devices */ 202 /* on-chip devices */
203 mmp2_add_uart(1); 203 mmp2_add_uart(1);
204 mmp2_add_uart(3); 204 mmp2_add_uart(3);
205 platform_device_register(&mmp2_device_gpio);
205 mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); 206 mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
206 mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */ 207 mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
207 mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */ 208 mmp2_add_sdhost(2, &mmp2_sdh_platdata_mmc2); /* eMMC */
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 5a6a27a6cfd..2ee8cd7829d 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -87,8 +87,8 @@ static struct resource smc91x_resources[] = {
87 .flags = IORESOURCE_MEM, 87 .flags = IORESOURCE_MEM,
88 }, 88 },
89 [1] = { 89 [1] = {
90 .start = gpio_to_irq(155), 90 .start = MMP_GPIO_TO_IRQ(155),
91 .end = gpio_to_irq(155), 91 .end = MMP_GPIO_TO_IRQ(155),
92 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 92 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
93 } 93 }
94}; 94};
@@ -110,6 +110,7 @@ static void __init flint_init(void)
110 /* on-chip devices */ 110 /* on-chip devices */
111 mmp2_add_uart(1); 111 mmp2_add_uart(1);
112 mmp2_add_uart(2); 112 mmp2_add_uart(2);
113 platform_device_register(&mmp2_device_gpio);
113 114
114 /* off-chip devices */ 115 /* off-chip devices */
115 platform_device_register(&smc91x_device); 116 platform_device_register(&smc91x_device);
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 1e3abbe37ca..87765467de6 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -184,6 +184,7 @@ static void __init gplugd_init(void)
184 pxa168_add_uart(3); 184 pxa168_add_uart(3);
185 pxa168_add_ssp(1); 185 pxa168_add_ssp(1);
186 pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info)); 186 pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
187 platform_device_register(&pxa168_device_gpio);
187 188
188 pxa168_add_eth(&gplugd_eth_platform_data); 189 pxa168_add_eth(&gplugd_eth_platform_data);
189} 190}
diff --git a/arch/arm/mach-mmp/include/mach/gpio-pxa.h b/arch/arm/mach-mmp/include/mach/gpio-pxa.h
index 99b4ce1b656..0e135a599f3 100644
--- a/arch/arm/mach-mmp/include/mach/gpio-pxa.h
+++ b/arch/arm/mach-mmp/include/mach/gpio-pxa.h
@@ -2,6 +2,7 @@
2#define __ASM_MACH_GPIO_PXA_H 2#define __ASM_MACH_GPIO_PXA_H
3 3
4#include <mach/addr-map.h> 4#include <mach/addr-map.h>
5#include <mach/cputype.h>
5#include <mach/irqs.h> 6#include <mach/irqs.h>
6 7
7#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000) 8#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000)
@@ -9,8 +10,6 @@
9#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) 10#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
10#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x))) 11#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
11 12
12#define NR_BUILTIN_GPIO IRQ_GPIO_NUM
13
14#define gpio_to_bank(gpio) ((gpio) >> 5) 13#define gpio_to_bank(gpio) ((gpio) >> 5)
15 14
16/* NOTE: these macros are defined here to make optimization of 15/* NOTE: these macros are defined here to make optimization of
diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h
index 681262359d1..13219ebf512 100644
--- a/arch/arm/mach-mmp/include/mach/gpio.h
+++ b/arch/arm/mach-mmp/include/mach/gpio.h
@@ -3,11 +3,6 @@
3 3
4#include <asm-generic/gpio.h> 4#include <asm-generic/gpio.h>
5 5
6#define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio)) 6#include <mach/cputype.h>
7#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_START)
8 7
9#define __gpio_is_inverted(gpio) (0)
10#define __gpio_is_occupied(gpio) (0)
11
12#include <plat/gpio.h>
13#endif /* __ASM_MACH_GPIO_H */ 8#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index a09d328e2dd..34635a0bbb5 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -219,10 +219,10 @@
219#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2) 219#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2)
220 220
221#define IRQ_GPIO_START 128 221#define IRQ_GPIO_START 128
222#define IRQ_GPIO_NUM 192 222#define MMP_NR_BUILTIN_GPIO 192
223#define IRQ_GPIO(x) (IRQ_GPIO_START + (x)) 223#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio))
224 224
225#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM) 225#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
226 226
227#define NR_IRQS (IRQ_BOARD_START) 227#define NR_IRQS (IRQ_BOARD_START)
228 228
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
index 2f7b2d3c2b1..cba22fed226 100644
--- a/arch/arm/mach-mmp/include/mach/mmp2.h
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -32,6 +32,8 @@ extern struct pxa_device_desc mmp2_device_sdh3;
32extern struct pxa_device_desc mmp2_device_asram; 32extern struct pxa_device_desc mmp2_device_asram;
33extern struct pxa_device_desc mmp2_device_isram; 33extern struct pxa_device_desc mmp2_device_isram;
34 34
35extern struct platform_device mmp2_device_gpio;
36
35static inline int mmp2_add_uart(int id) 37static inline int mmp2_add_uart(int id)
36{ 38{
37 struct pxa_device_desc *d = NULL; 39 struct pxa_device_desc *d = NULL;
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
index a677aa732c2..dc03d580a06 100644
--- a/arch/arm/mach-mmp/include/mach/pxa168.h
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -43,6 +43,8 @@ struct pxa168_usb_pdata {
43/* pdata can be NULL */ 43/* pdata can be NULL */
44int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata); 44int __init pxa168_add_usb_host(struct pxa168_usb_pdata *pdata);
45 45
46extern struct platform_device pxa168_device_gpio;
47
46static inline int pxa168_add_uart(int id) 48static inline int pxa168_add_uart(int id)
47{ 49{
48 struct pxa_device_desc *d = NULL; 50 struct pxa_device_desc *d = NULL;
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
index 91be7559139..4de13abef7b 100644
--- a/arch/arm/mach-mmp/include/mach/pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -21,6 +21,8 @@ extern struct pxa_device_desc pxa910_device_pwm3;
21extern struct pxa_device_desc pxa910_device_pwm4; 21extern struct pxa_device_desc pxa910_device_pwm4;
22extern struct pxa_device_desc pxa910_device_nand; 22extern struct pxa_device_desc pxa910_device_nand;
23 23
24extern struct platform_device pxa910_device_gpio;
25
24static inline int pxa910_add_uart(int id) 26static inline int pxa910_add_uart(int id)
25{ 27{
26 struct pxa_device_desc *d = NULL; 28 struct pxa_device_desc *d = NULL;
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
index 5dd1d4a6aeb..617c60a170a 100644
--- a/arch/arm/mach-mmp/mmp2.c
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/platform_device.h>
16 17
17#include <asm/hardware/cache-tauros2.h> 18#include <asm/hardware/cache-tauros2.h>
18 19
@@ -24,7 +25,6 @@
24#include <mach/irqs.h> 25#include <mach/irqs.h>
25#include <mach/dma.h> 26#include <mach/dma.h>
26#include <mach/mfp.h> 27#include <mach/mfp.h>
27#include <mach/gpio-pxa.h>
28#include <mach/devices.h> 28#include <mach/devices.h>
29#include <mach/mmp2.h> 29#include <mach/mmp2.h>
30 30
@@ -33,8 +33,6 @@
33 33
34#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000) 34#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
35 35
36#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
37
38static struct mfp_addr_map mmp2_addr_map[] __initdata = { 36static struct mfp_addr_map mmp2_addr_map[] __initdata = {
39 37
40 MFP_ADDR_X(GPIO0, GPIO58, 0x54), 38 MFP_ADDR_X(GPIO0, GPIO58, 0x54),
@@ -95,24 +93,9 @@ void mmp2_clear_pmic_int(void)
95 __raw_writel(data, mfpr_pmic); 93 __raw_writel(data, mfpr_pmic);
96} 94}
97 95
98static void __init mmp2_init_gpio(void)
99{
100 int i;
101
102 /* enable GPIO clock */
103 __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO);
104
105 /* unmask GPIO edge detection for all 6 banks -- APMASKx */
106 for (i = 0; i < 6; i++)
107 __raw_writel(0xffffffff, APMASK(i));
108
109 pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL);
110}
111
112void __init mmp2_init_irq(void) 96void __init mmp2_init_irq(void)
113{ 97{
114 mmp2_init_icu(); 98 mmp2_init_icu();
115 mmp2_init_gpio();
116} 99}
117 100
118static void sdhc_clk_enable(struct clk *clk) 101static void sdhc_clk_enable(struct clk *clk)
@@ -149,6 +132,7 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
149static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); 132static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
150static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); 133static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
151static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); 134static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
135static APBC_CLK(gpio, MMP2_GPIO, 0, 26000000);
152 136
153static APMU_CLK(nand, NAND, 0xbf, 100000000); 137static APMU_CLK(nand, NAND, 0xbf, 100000000);
154static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops); 138static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops);
@@ -168,6 +152,7 @@ static struct clk_lookup mmp2_clkregs[] = {
168 INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL), 152 INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
169 INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL), 153 INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
170 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), 154 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
155 INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
171 INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"), 156 INIT_CLKREG(&clk_sdh0, "sdhci-pxav3.0", "PXA-SDHCLK"),
172 INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"), 157 INIT_CLKREG(&clk_sdh1, "sdhci-pxav3.1", "PXA-SDHCLK"),
173 INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"), 158 INIT_CLKREG(&clk_sdh2, "sdhci-pxav3.2", "PXA-SDHCLK"),
@@ -230,3 +215,21 @@ MMP2_DEVICE(asram, "asram", -1, NONE, 0xe0000000, 0x4000);
230/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */ 215/* 0xd1000000 ~ 0xd101ffff is reserved for secure processor */
231MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000); 216MMP2_DEVICE(isram, "isram", -1, NONE, 0xd1020000, 0x18000);
232 217
218struct resource mmp2_resource_gpio[] = {
219 {
220 .start = 0xd4019000,
221 .end = 0xd4019fff,
222 .flags = IORESOURCE_MEM,
223 }, {
224 .start = IRQ_MMP2_GPIO,
225 .end = IRQ_MMP2_GPIO,
226 .flags = IORESOURCE_IRQ,
227 },
228};
229
230struct platform_device mmp2_device_gpio = {
231 .name = "pxa-gpio",
232 .id = -1,
233 .num_resources = ARRAY_SIZE(mmp2_resource_gpio),
234 .resource = mmp2_resource_gpio,
235};
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 13f23867a86..7bc17eaa12e 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -13,6 +13,7 @@
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/platform_device.h>
16 17
17#include <asm/mach/time.h> 18#include <asm/mach/time.h>
18#include <mach/addr-map.h> 19#include <mach/addr-map.h>
@@ -20,7 +21,6 @@
20#include <mach/regs-apbc.h> 21#include <mach/regs-apbc.h>
21#include <mach/regs-apmu.h> 22#include <mach/regs-apmu.h>
22#include <mach/irqs.h> 23#include <mach/irqs.h>
23#include <mach/gpio-pxa.h>
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <mach/devices.h> 25#include <mach/devices.h>
26#include <mach/mfp.h> 26#include <mach/mfp.h>
@@ -43,26 +43,9 @@ static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
43 MFP_ADDR_END, 43 MFP_ADDR_END,
44}; 44};
45 45
46#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
47
48static void __init pxa168_init_gpio(void)
49{
50 int i;
51
52 /* enable GPIO clock */
53 __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO);
54
55 /* unmask GPIO edge detection for all 4 banks - APMASKx */
56 for (i = 0; i < 4; i++)
57 __raw_writel(0xffffffff, APMASK(i));
58
59 pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL);
60}
61
62void __init pxa168_init_irq(void) 46void __init pxa168_init_irq(void)
63{ 47{
64 icu_init_irq(); 48 icu_init_irq();
65 pxa168_init_gpio();
66} 49}
67 50
68/* APB peripheral clocks */ 51/* APB peripheral clocks */
@@ -80,6 +63,7 @@ static APBC_CLK(ssp2, PXA168_SSP2, 4, 0);
80static APBC_CLK(ssp3, PXA168_SSP3, 4, 0); 63static APBC_CLK(ssp3, PXA168_SSP3, 4, 0);
81static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); 64static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
82static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); 65static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
66static APBC_CLK(gpio, PXA168_GPIO, 0, 13000000);
83static APBC_CLK(keypad, PXA168_KPC, 0, 32000); 67static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
84 68
85static APMU_CLK(nand, NAND, 0x19b, 156000000); 69static APMU_CLK(nand, NAND, 0x19b, 156000000);
@@ -105,6 +89,7 @@ static struct clk_lookup pxa168_clkregs[] = {
105 INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL), 89 INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
106 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), 90 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
107 INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL), 91 INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
92 INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
108 INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL), 93 INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
109 INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"), 94 INIT_CLKREG(&clk_eth, "pxa168-eth", "MFUCLK"),
110 INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"), 95 INIT_CLKREG(&clk_usb, "pxa168-ehci", "PXA168-USBCLK"),
@@ -174,6 +159,25 @@ PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
174PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c); 159PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
175PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff); 160PXA168_DEVICE(eth, "pxa168-eth", -1, MFU, 0xc0800000, 0x0fff);
176 161
162struct resource pxa168_resource_gpio[] = {
163 {
164 .start = 0xd4019000,
165 .end = 0xd4019fff,
166 .flags = IORESOURCE_MEM,
167 }, {
168 .start = IRQ_PXA168_GPIOX,
169 .end = IRQ_PXA168_GPIOX,
170 .flags = IORESOURCE_IRQ,
171 },
172};
173
174struct platform_device pxa168_device_gpio = {
175 .name = "pxa-gpio",
176 .id = -1,
177 .num_resources = ARRAY_SIZE(pxa168_resource_gpio),
178 .resource = pxa168_resource_gpio,
179};
180
177struct resource pxa168_usb_host_resources[] = { 181struct resource pxa168_usb_host_resources[] = {
178 /* USB Host conroller register base */ 182 /* USB Host conroller register base */
179 [0] = { 183 [0] = {
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 4ebbfbba39f..3241a25784d 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/platform_device.h>
15 16
16#include <asm/mach/time.h> 17#include <asm/mach/time.h>
17#include <mach/addr-map.h> 18#include <mach/addr-map.h>
@@ -19,7 +20,6 @@
19#include <mach/regs-apmu.h> 20#include <mach/regs-apmu.h>
20#include <mach/cputype.h> 21#include <mach/cputype.h>
21#include <mach/irqs.h> 22#include <mach/irqs.h>
22#include <mach/gpio-pxa.h>
23#include <mach/dma.h> 23#include <mach/dma.h>
24#include <mach/mfp.h> 24#include <mach/mfp.h>
25#include <mach/devices.h> 25#include <mach/devices.h>
@@ -77,26 +77,9 @@ static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata =
77 MFP_ADDR_END, 77 MFP_ADDR_END,
78}; 78};
79 79
80#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
81
82static void __init pxa910_init_gpio(void)
83{
84 int i;
85
86 /* enable GPIO clock */
87 __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO);
88
89 /* unmask GPIO edge detection for all 4 banks - APMASKx */
90 for (i = 0; i < 4; i++)
91 __raw_writel(0xffffffff, APMASK(i));
92
93 pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL);
94}
95
96void __init pxa910_init_irq(void) 80void __init pxa910_init_irq(void)
97{ 81{
98 icu_init_irq(); 82 icu_init_irq();
99 pxa910_init_gpio();
100} 83}
101 84
102/* APB peripheral clocks */ 85/* APB peripheral clocks */
@@ -108,6 +91,7 @@ static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000);
108static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000); 91static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
109static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); 92static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
110static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); 93static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
94static APBC_CLK(gpio, PXA910_GPIO, 0, 13000000);
111 95
112static APMU_CLK(nand, NAND, 0x19b, 156000000); 96static APMU_CLK(nand, NAND, 0x19b, 156000000);
113static APMU_CLK(u2o, USB, 0x1b, 480000000); 97static APMU_CLK(u2o, USB, 0x1b, 480000000);
@@ -123,6 +107,7 @@ static struct clk_lookup pxa910_clkregs[] = {
123 INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL), 107 INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
124 INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL), 108 INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
125 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL), 109 INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
110 INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
126 INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"), 111 INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
127}; 112};
128 113
@@ -179,3 +164,22 @@ PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10);
179PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10); 164PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10);
180PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10); 165PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10);
181PXA910_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99); 166PXA910_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
167
168struct resource pxa910_resource_gpio[] = {
169 {
170 .start = 0xd4019000,
171 .end = 0xd4019fff,
172 .flags = IORESOURCE_MEM,
173 }, {
174 .start = IRQ_PXA910_AP_GPIO,
175 .end = IRQ_PXA910_AP_GPIO,
176 .flags = IORESOURCE_IRQ,
177 },
178};
179
180struct platform_device pxa910_device_gpio = {
181 .name = "pxa-gpio",
182 .id = -1,
183 .num_resources = ARRAY_SIZE(pxa910_resource_gpio),
184 .resource = pxa910_resource_gpio,
185};
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 257a21283ec..8e3b5af04a5 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -19,6 +19,7 @@
19#include <mach/addr-map.h> 19#include <mach/addr-map.h>
20#include <mach/mfp-pxa910.h> 20#include <mach/mfp-pxa910.h>
21#include <mach/pxa910.h> 21#include <mach/pxa910.h>
22#include <mach/irqs.h>
22 23
23#include "common.h" 24#include "common.h"
24 25
@@ -71,8 +72,8 @@ static struct resource smc91x_resources[] = {
71 .flags = IORESOURCE_MEM, 72 .flags = IORESOURCE_MEM,
72 }, 73 },
73 [1] = { 74 [1] = {
74 .start = gpio_to_irq(80), 75 .start = MMP_GPIO_TO_IRQ(80),
75 .end = gpio_to_irq(80), 76 .end = MMP_GPIO_TO_IRQ(80),
76 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 77 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
77 } 78 }
78}; 79};
@@ -93,6 +94,7 @@ static void __init tavorevb_init(void)
93 94
94 /* on-chip devices */ 95 /* on-chip devices */
95 pxa910_add_uart(1); 96 pxa910_add_uart(1);
97 platform_device_register(&pxa910_device_gpio);
96 98
97 /* off-chip devices */ 99 /* off-chip devices */
98 platform_device_register(&smc91x_device); 100 platform_device_register(&smc91x_device);
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 8ac22a62bf1..0523e422990 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -66,7 +66,7 @@ static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
66static struct i2c_board_info teton_bga_i2c_info[] __initdata = { 66static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
67 { 67 {
68 I2C_BOARD_INFO("ds1337", 0x68), 68 I2C_BOARD_INFO("ds1337", 0x68),
69 .irq = gpio_to_irq(RTC_INT_GPIO) 69 .irq = MMP_GPIO_TO_IRQ(RTC_INT_GPIO)
70 }, 70 },
71}; 71};
72 72
@@ -78,6 +78,7 @@ static void __init teton_bga_init(void)
78 pxa168_add_uart(1); 78 pxa168_add_uart(1);
79 pxa168_add_keypad(&teton_bga_keypad_info); 79 pxa168_add_keypad(&teton_bga_keypad_info);
80 pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info)); 80 pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
81 platform_device_register(&pxa168_device_gpio);
81} 82}
82 83
83MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") 84MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index f0265882557..5ac5d5832e4 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -24,12 +24,13 @@
24#include <mach/addr-map.h> 24#include <mach/addr-map.h>
25#include <mach/mfp-pxa910.h> 25#include <mach/mfp-pxa910.h>
26#include <mach/pxa910.h> 26#include <mach/pxa910.h>
27#include <mach/irqs.h>
27 28
28#include "common.h" 29#include "common.h"
29 30
30#define TTCDKB_GPIO_EXT0(x) (NR_BUILTIN_GPIO + ((x < 0) ? 0 : \ 31#define TTCDKB_GPIO_EXT0(x) (MMP_NR_BUILTIN_GPIO + ((x < 0) ? 0 : \
31 ((x < 16) ? x : 15))) 32 ((x < 16) ? x : 15)))
32#define TTCDKB_GPIO_EXT1(x) (NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \ 33#define TTCDKB_GPIO_EXT1(x) (MMP_NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \
33 ((x < 16) ? x : 15))) 34 ((x < 16) ? x : 15)))
34 35
35/* 36/*
@@ -122,6 +123,7 @@ static struct platform_device ttc_dkb_device_onenand = {
122}; 123};
123 124
124static struct platform_device *ttc_dkb_devices[] = { 125static struct platform_device *ttc_dkb_devices[] = {
126 &pxa910_device_gpio,
125 &ttc_dkb_device_onenand, 127 &ttc_dkb_device_onenand,
126}; 128};
127 129
@@ -136,7 +138,7 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = {
136 { 138 {
137 .type = "max7312", 139 .type = "max7312",
138 .addr = 0x23, 140 .addr = 0x23,
139 .irq = IRQ_GPIO(80), 141 .irq = MMP_GPIO_TO_IRQ(80),
140 .platform_data = &max7312_data, 142 .platform_data = &max7312_data,
141 }, 143 },
142}; 144};
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index e6beaff7621..1cd40ad301d 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -13,7 +13,6 @@ config ARCH_MSM7X00A
13 select CPU_V6 13 select CPU_V6
14 select GPIO_MSM_V1 14 select GPIO_MSM_V1
15 select MSM_PROC_COMM 15 select MSM_PROC_COMM
16 select HAS_MSM_DEBUG_UART_PHYS
17 16
18config ARCH_MSM7X30 17config ARCH_MSM7X30
19 bool "MSM7x30" 18 bool "MSM7x30"
@@ -25,7 +24,6 @@ config ARCH_MSM7X30
25 select MSM_GPIOMUX 24 select MSM_GPIOMUX
26 select GPIO_MSM_V1 25 select GPIO_MSM_V1
27 select MSM_PROC_COMM 26 select MSM_PROC_COMM
28 select HAS_MSM_DEBUG_UART_PHYS
29 27
30config ARCH_QSD8X50 28config ARCH_QSD8X50
31 bool "QSD8X50" 29 bool "QSD8X50"
@@ -37,7 +35,6 @@ config ARCH_QSD8X50
37 select MSM_GPIOMUX 35 select MSM_GPIOMUX
38 select GPIO_MSM_V1 36 select GPIO_MSM_V1
39 select MSM_PROC_COMM 37 select MSM_PROC_COMM
40 select HAS_MSM_DEBUG_UART_PHYS
41 38
42config ARCH_MSM8X60 39config ARCH_MSM8X60
43 bool "MSM8X60" 40 bool "MSM8X60"
@@ -63,6 +60,9 @@ config ARCH_MSM8960
63 60
64endchoice 61endchoice
65 62
63config MSM_HAS_DEBUG_UART_HS
64 bool
65
66config MSM_SOC_REV_A 66config MSM_SOC_REV_A
67 bool 67 bool
68config ARCH_MSM_SCORPIONMP 68config ARCH_MSM_SCORPIONMP
@@ -74,9 +74,6 @@ config ARCH_MSM_ARM11
74config ARCH_MSM_SCORPION 74config ARCH_MSM_SCORPION
75 bool 75 bool
76 76
77config HAS_MSM_DEBUG_UART_PHYS
78 bool
79
80config MSM_VIC 77config MSM_VIC
81 bool 78 bool
82 79
@@ -153,32 +150,6 @@ config MACH_MSM8960_RUMI3
153 150
154endmenu 151endmenu
155 152
156config MSM_DEBUG_UART
157 int
158 default 1 if MSM_DEBUG_UART1
159 default 2 if MSM_DEBUG_UART2
160 default 3 if MSM_DEBUG_UART3
161
162if HAS_MSM_DEBUG_UART_PHYS
163choice
164 prompt "Debug UART"
165
166 default MSM_DEBUG_UART_NONE
167
168 config MSM_DEBUG_UART_NONE
169 bool "None"
170
171 config MSM_DEBUG_UART1
172 bool "UART1"
173
174 config MSM_DEBUG_UART2
175 bool "UART2"
176
177 config MSM_DEBUG_UART3
178 bool "UART3"
179endchoice
180endif
181
182config MSM_SMD_PKG3 153config MSM_SMD_PKG3
183 bool 154 bool
184 155
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S
index 2dc73ccddb1..3ffd8668c9a 100644
--- a/arch/arm/mach-msm/include/mach/debug-macro.S
+++ b/arch/arm/mach-msm/include/mach/debug-macro.S
@@ -1,6 +1,7 @@
1/* arch/arm/mach-msm7200/include/mach/debug-macro.S 1/*
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com> 5 * Author: Brian Swetland <swetland@google.com>
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * This software is licensed under the terms of the GNU General Public
@@ -14,40 +15,52 @@
14 * 15 *
15 */ 16 */
16 17
17
18
19#include <mach/hardware.h> 18#include <mach/hardware.h>
20#include <mach/msm_iomap.h> 19#include <mach/msm_iomap.h>
21 20
22#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE)
23 .macro addruart, rp, rv, tmp 21 .macro addruart, rp, rv, tmp
22#ifdef MSM_DEBUG_UART_PHYS
24 ldr \rp, =MSM_DEBUG_UART_PHYS 23 ldr \rp, =MSM_DEBUG_UART_PHYS
25 ldr \rv, =MSM_DEBUG_UART_BASE 24 ldr \rv, =MSM_DEBUG_UART_BASE
25#endif
26 .endm 26 .endm
27 27
28 .macro senduart,rd,rx 28 .macro senduart, rd, rx
29#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
30 @ Write the 1 character to UARTDM_TF
31 str \rd, [\rx, #0x70]
32#else
29 teq \rx, #0 33 teq \rx, #0
30 strne \rd, [\rx, #0x0C] 34 strne \rd, [\rx, #0x0C]
35#endif
31 .endm 36 .endm
32 37
33 .macro waituart,rd,rx 38 .macro waituart, rd, rx
39#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
40 @ check for TX_EMT in UARTDM_SR
41 ldr \rd, [\rx, #0x08]
42 tst \rd, #0x08
43 bne 1002f
44 @ wait for TXREADY in UARTDM_ISR
451001: ldr \rd, [\rx, #0x14]
46 tst \rd, #0x80
47 beq 1001b
481002:
49 @ Clear TX_READY by writing to the UARTDM_CR register
50 mov \rd, #0x300
51 str \rd, [\rx, #0x10]
52 @ Write 0x1 to NCF register
53 mov \rd, #0x1
54 str \rd, [\rx, #0x40]
55 @ UARTDM reg. Read to induce delay
56 ldr \rd, [\rx, #0x08]
57#else
34 @ wait for TX_READY 58 @ wait for TX_READY
351001: ldr \rd, [\rx, #0x08] 591001: ldr \rd, [\rx, #0x08]
36 tst \rd, #0x04 60 tst \rd, #0x04
37 beq 1001b 61 beq 1001b
38 .endm
39#else
40 .macro addruart, rp, rv, tmp
41 mov \rv, #0xff000000
42 orr \rv, \rv, #0x00f00000
43 .endm
44
45 .macro senduart,rd,rx
46 .endm
47
48 .macro waituart,rd,rx
49 .endm
50#endif 62#endif
63 .endm
51 64
52 .macro busyuart,rd,rx 65 .macro busyuart, rd, rx
53 .endm 66 .endm
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
index 94fe9fe6feb..8af46123dab 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -78,18 +78,6 @@
78#define MSM_UART3_PHYS 0xA9C00000 78#define MSM_UART3_PHYS 0xA9C00000
79#define MSM_UART3_SIZE SZ_4K 79#define MSM_UART3_SIZE SZ_4K
80 80
81#ifdef CONFIG_MSM_DEBUG_UART
82#define MSM_DEBUG_UART_BASE 0xE1000000
83#if CONFIG_MSM_DEBUG_UART == 1
84#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
85#elif CONFIG_MSM_DEBUG_UART == 2
86#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
87#elif CONFIG_MSM_DEBUG_UART == 3
88#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
89#endif
90#define MSM_DEBUG_UART_SIZE SZ_4K
91#endif
92
93#define MSM_SDC1_PHYS 0xA0400000 81#define MSM_SDC1_PHYS 0xA0400000
94#define MSM_SDC1_SIZE SZ_4K 82#define MSM_SDC1_SIZE SZ_4K
95 83
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
index 37694442d1b..198202c267c 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -89,18 +89,6 @@
89#define MSM_UART3_PHYS 0xACC00000 89#define MSM_UART3_PHYS 0xACC00000
90#define MSM_UART3_SIZE SZ_4K 90#define MSM_UART3_SIZE SZ_4K
91 91
92#ifdef CONFIG_MSM_DEBUG_UART
93#define MSM_DEBUG_UART_BASE 0xE1000000
94#if CONFIG_MSM_DEBUG_UART == 1
95#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
96#elif CONFIG_MSM_DEBUG_UART == 2
97#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
98#elif CONFIG_MSM_DEBUG_UART == 3
99#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
100#endif
101#define MSM_DEBUG_UART_SIZE SZ_4K
102#endif
103
104#define MSM_MDC_BASE IOMEM(0xE0200000) 92#define MSM_MDC_BASE IOMEM(0xE0200000)
105#define MSM_MDC_PHYS 0xAA500000 93#define MSM_MDC_PHYS 0xAA500000
106#define MSM_MDC_SIZE SZ_1M 94#define MSM_MDC_SIZE SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
index 3c9d9602a31..800b55767e6 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -45,4 +45,9 @@
45#define MSM8960_TMR0_PHYS 0x0208A000 45#define MSM8960_TMR0_PHYS 0x0208A000
46#define MSM8960_TMR0_SIZE SZ_4K 46#define MSM8960_TMR0_SIZE SZ_4K
47 47
48#ifdef CONFIG_DEBUG_MSM8960_UART
49#define MSM_DEBUG_UART_BASE 0xE1040000
50#define MSM_DEBUG_UART_PHYS 0x16440000
51#endif
52
48#endif 53#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
index d67cd73316f..0faa894729b 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -83,18 +83,6 @@
83#define MSM_UART3_PHYS 0xA9C00000 83#define MSM_UART3_PHYS 0xA9C00000
84#define MSM_UART3_SIZE SZ_4K 84#define MSM_UART3_SIZE SZ_4K
85 85
86#ifdef CONFIG_MSM_DEBUG_UART
87#define MSM_DEBUG_UART_BASE 0xE1000000
88#if CONFIG_MSM_DEBUG_UART == 1
89#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
90#elif CONFIG_MSM_DEBUG_UART == 2
91#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
92#elif CONFIG_MSM_DEBUG_UART == 3
93#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
94#endif
95#define MSM_DEBUG_UART_SIZE SZ_4K
96#endif
97
98#define MSM_MDC_BASE IOMEM(0xE0200000) 86#define MSM_MDC_BASE IOMEM(0xE0200000)
99#define MSM_MDC_PHYS 0xAA500000 87#define MSM_MDC_PHYS 0xAA500000
100#define MSM_MDC_SIZE SZ_1M 88#define MSM_MDC_SIZE SZ_1M
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
index 3b19b8f244b..54e12caa8d8 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -62,4 +62,9 @@
62#define MSM8X60_TMR0_PHYS 0x02040000 62#define MSM8X60_TMR0_PHYS 0x02040000
63#define MSM8X60_TMR0_SIZE SZ_4K 63#define MSM8X60_TMR0_SIZE SZ_4K
64 64
65#ifdef CONFIG_DEBUG_MSM8660_UART
66#define MSM_DEBUG_UART_BASE 0xE1040000
67#define MSM_DEBUG_UART_PHYS 0x19C40000
68#endif
69
65#endif 70#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index 4ded15238b6..90682f4599d 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -55,6 +55,18 @@
55 55
56#include "msm_iomap-8960.h" 56#include "msm_iomap-8960.h"
57 57
58#define MSM_DEBUG_UART_SIZE SZ_4K
59#if defined(CONFIG_DEBUG_MSM_UART1)
60#define MSM_DEBUG_UART_BASE 0xE1000000
61#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
62#elif defined(CONFIG_DEBUG_MSM_UART2)
63#define MSM_DEBUG_UART_BASE 0xE1000000
64#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
65#elif defined(CONFIG_DEBUG_MSM_UART3)
66#define MSM_DEBUG_UART_BASE 0xE1000000
67#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
68#endif
69
58/* Virtual addresses shared across all MSM targets. */ 70/* Virtual addresses shared across all MSM targets. */
59#define MSM_CSR_BASE IOMEM(0xE0001000) 71#define MSM_CSR_BASE IOMEM(0xE0001000)
60#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000) 72#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000)
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
index d94292c29d8..169a8400745 100644
--- a/arch/arm/mach-msm/include/mach/uncompress.h
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -1,6 +1,6 @@
1/* arch/arm/mach-msm/include/mach/uncompress.h 1/*
2 *
3 * Copyright (C) 2007 Google, Inc. 2 * Copyright (C) 2007 Google, Inc.
3 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
4 * 4 *
5 * This software is licensed under the terms of the GNU General Public 5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and 6 * License version 2, as published by the Free Software Foundation, and
@@ -14,17 +14,40 @@
14 */ 14 */
15 15
16#ifndef __ASM_ARCH_MSM_UNCOMPRESS_H 16#ifndef __ASM_ARCH_MSM_UNCOMPRESS_H
17#define __ASM_ARCH_MSM_UNCOMPRESS_H
18
19#include <asm/processor.h>
20#include <mach/msm_iomap.h>
21
22#define UART_CSR (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08))
23#define UART_TF (*(volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x0c))
17 24
18#include "hardware.h" 25#define UART_DM_SR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x08)))
19#include "linux/io.h" 26#define UART_DM_CR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x10)))
20#include "mach/msm_iomap.h" 27#define UART_DM_ISR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x14)))
28#define UART_DM_NCHAR (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x40)))
29#define UART_DM_TF (*((volatile uint32_t *)(MSM_DEBUG_UART_PHYS + 0x70)))
21 30
22static void putc(int c) 31static void putc(int c)
23{ 32{
24#if defined(MSM_DEBUG_UART_PHYS) 33#if defined(MSM_DEBUG_UART_PHYS)
25 unsigned base = MSM_DEBUG_UART_PHYS; 34#ifdef CONFIG_MSM_HAS_DEBUG_UART_HS
26 while (!(readl(base + 0x08) & 0x04)) ; 35 /*
27 writel(c, base + 0x0c); 36 * Wait for TX_READY to be set; but skip it if we have a
37 * TX underrun.
38 */
39 if (UART_DM_SR & 0x08)
40 while (!(UART_DM_ISR & 0x80))
41 cpu_relax();
42
43 UART_DM_CR = 0x300;
44 UART_DM_NCHAR = 0x1;
45 UART_DM_TF = c;
46#else
47 while (!(UART_CSR & 0x04))
48 cpu_relax();
49 UART_TF = c;
50#endif
28#endif 51#endif
29} 52}
30 53
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 8759ecf7454..578b04e42de 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -47,7 +47,8 @@ static struct map_desc msm_io_desc[] __initdata = {
47 MSM_CHIP_DEVICE(GPIO1, MSM7X00), 47 MSM_CHIP_DEVICE(GPIO1, MSM7X00),
48 MSM_CHIP_DEVICE(GPIO2, MSM7X00), 48 MSM_CHIP_DEVICE(GPIO2, MSM7X00),
49 MSM_DEVICE(CLK_CTL), 49 MSM_DEVICE(CLK_CTL),
50#ifdef CONFIG_MSM_DEBUG_UART 50#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
51 defined(CONFIG_DEBUG_MSM_UART3)
51 MSM_DEVICE(DEBUG_UART), 52 MSM_DEVICE(DEBUG_UART),
52#endif 53#endif
53#ifdef CONFIG_ARCH_MSM7X30 54#ifdef CONFIG_ARCH_MSM7X30
@@ -84,7 +85,8 @@ static struct map_desc qsd8x50_io_desc[] __initdata = {
84 MSM_DEVICE(SCPLL), 85 MSM_DEVICE(SCPLL),
85 MSM_DEVICE(AD5), 86 MSM_DEVICE(AD5),
86 MSM_DEVICE(MDC), 87 MSM_DEVICE(MDC),
87#ifdef CONFIG_MSM_DEBUG_UART 88#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
89 defined(CONFIG_DEBUG_MSM_UART3)
88 MSM_DEVICE(DEBUG_UART), 90 MSM_DEVICE(DEBUG_UART),
89#endif 91#endif
90 { 92 {
@@ -109,6 +111,9 @@ static struct map_desc msm8x60_io_desc[] __initdata = {
109 MSM_CHIP_DEVICE(TMR0, MSM8X60), 111 MSM_CHIP_DEVICE(TMR0, MSM8X60),
110 MSM_DEVICE(ACC), 112 MSM_DEVICE(ACC),
111 MSM_DEVICE(GCC), 113 MSM_DEVICE(GCC),
114#ifdef CONFIG_DEBUG_MSM8660_UART
115 MSM_DEVICE(DEBUG_UART),
116#endif
112}; 117};
113 118
114void __init msm_map_msm8x60_io(void) 119void __init msm_map_msm8x60_io(void)
@@ -123,6 +128,9 @@ static struct map_desc msm8960_io_desc[] __initdata = {
123 MSM_CHIP_DEVICE(QGIC_CPU, MSM8960), 128 MSM_CHIP_DEVICE(QGIC_CPU, MSM8960),
124 MSM_CHIP_DEVICE(TMR, MSM8960), 129 MSM_CHIP_DEVICE(TMR, MSM8960),
125 MSM_CHIP_DEVICE(TMR0, MSM8960), 130 MSM_CHIP_DEVICE(TMR0, MSM8960),
131#ifdef CONFIG_DEBUG_MSM8960_UART
132 MSM_DEVICE(DEBUG_UART),
133#endif
126}; 134};
127 135
128void __init msm_map_msm8960_io(void) 136void __init msm_map_msm8960_io(void)
@@ -146,7 +154,8 @@ static struct map_desc msm7x30_io_desc[] __initdata = {
146 MSM_DEVICE(SAW), 154 MSM_DEVICE(SAW),
147 MSM_DEVICE(GCC), 155 MSM_DEVICE(GCC),
148 MSM_DEVICE(TCSR), 156 MSM_DEVICE(TCSR),
149#ifdef CONFIG_MSM_DEBUG_UART 157#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
158 defined(CONFIG_DEBUG_MSM_UART3)
150 MSM_DEVICE(DEBUG_UART), 159 MSM_DEVICE(DEBUG_UART),
151#endif 160#endif
152 { 161 {
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index fdec58aaa35..0b3e357c4c8 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -79,7 +79,7 @@ static __cpuinit void prepare_cold_cpu(unsigned int cpu)
79 ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup), 79 ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
80 SCM_FLAG_COLDBOOT_CPU1); 80 SCM_FLAG_COLDBOOT_CPU1);
81 if (ret == 0) { 81 if (ret == 0) {
82 void *sc1_base_ptr; 82 void __iomem *sc1_base_ptr;
83 sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); 83 sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
84 if (sc1_base_ptr) { 84 if (sc1_base_ptr) {
85 writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); 85 writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index afeeca52fc6..11d0d8f2656 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -1,6 +1,7 @@
1/* linux/arch/arm/mach-msm/timer.c 1/*
2 * 2 *
3 * Copyright (C) 2007 Google, Inc. 3 * Copyright (C) 2007 Google, Inc.
4 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
4 * 5 *
5 * This software is licensed under the terms of the GNU General Public 6 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and 7 * License version 2, as published by the Free Software Foundation, and
@@ -13,306 +14,207 @@
13 * 14 *
14 */ 15 */
15 16
17#include <linux/clocksource.h>
18#include <linux/clockchips.h>
16#include <linux/init.h> 19#include <linux/init.h>
17#include <linux/time.h>
18#include <linux/interrupt.h> 20#include <linux/interrupt.h>
19#include <linux/irq.h> 21#include <linux/irq.h>
20#include <linux/clk.h>
21#include <linux/clockchips.h>
22#include <linux/delay.h>
23#include <linux/io.h> 22#include <linux/io.h>
24 23
25#include <asm/mach/time.h> 24#include <asm/mach/time.h>
26#include <asm/hardware/gic.h> 25#include <asm/hardware/gic.h>
26#include <asm/localtimer.h>
27 27
28#include <mach/msm_iomap.h> 28#include <mach/msm_iomap.h>
29#include <mach/cpu.h> 29#include <mach/cpu.h>
30#include <mach/board.h>
30 31
31#define TIMER_MATCH_VAL 0x0000 32#define TIMER_MATCH_VAL 0x0000
32#define TIMER_COUNT_VAL 0x0004 33#define TIMER_COUNT_VAL 0x0004
33#define TIMER_ENABLE 0x0008 34#define TIMER_ENABLE 0x0008
34#define TIMER_ENABLE_CLR_ON_MATCH_EN 2 35#define TIMER_ENABLE_CLR_ON_MATCH_EN BIT(1)
35#define TIMER_ENABLE_EN 1 36#define TIMER_ENABLE_EN BIT(0)
36#define TIMER_CLEAR 0x000C 37#define TIMER_CLEAR 0x000C
37#define DGT_CLK_CTL 0x0034 38#define DGT_CLK_CTL 0x0034
38enum { 39#define DGT_CLK_CTL_DIV_4 0x3
39 DGT_CLK_CTL_DIV_1 = 0,
40 DGT_CLK_CTL_DIV_2 = 1,
41 DGT_CLK_CTL_DIV_3 = 2,
42 DGT_CLK_CTL_DIV_4 = 3,
43};
44#define CSR_PROTECTION 0x0020
45#define CSR_PROTECTION_EN 1
46 40
47#define GPT_HZ 32768 41#define GPT_HZ 32768
48 42
49enum timer_location { 43#define MSM_DGT_SHIFT 5
50 LOCAL_TIMER = 0,
51 GLOBAL_TIMER = 1,
52};
53
54#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT
55
56/* TODO: Remove these ifdefs */
57#if defined(CONFIG_ARCH_QSD8X50)
58#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
59#define MSM_DGT_SHIFT (0)
60#elif defined(CONFIG_ARCH_MSM7X30)
61#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
62#define MSM_DGT_SHIFT (0)
63#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
64#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */
65#define MSM_DGT_SHIFT (0)
66#else
67#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
68#define MSM_DGT_SHIFT (5)
69#endif
70 44
71struct msm_clock { 45static void __iomem *event_base;
72 struct clock_event_device clockevent;
73 struct clocksource clocksource;
74 unsigned int irq;
75 void __iomem *regbase;
76 uint32_t freq;
77 uint32_t shift;
78 void __iomem *global_counter;
79 void __iomem *local_counter;
80 union {
81 struct clock_event_device *evt;
82 struct clock_event_device __percpu **percpu_evt;
83 };
84};
85
86enum {
87 MSM_CLOCK_GPT,
88 MSM_CLOCK_DGT,
89 NR_TIMERS,
90};
91
92
93static struct msm_clock msm_clocks[];
94 46
95static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) 47static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
96{ 48{
97 struct clock_event_device *evt = *(struct clock_event_device **)dev_id; 49 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
98 if (evt->event_handler == NULL) 50 /* Stop the timer tick */
99 return IRQ_HANDLED; 51 if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
52 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
53 ctrl &= ~TIMER_ENABLE_EN;
54 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
55 }
100 evt->event_handler(evt); 56 evt->event_handler(evt);
101 return IRQ_HANDLED; 57 return IRQ_HANDLED;
102} 58}
103 59
104static cycle_t msm_read_timer_count(struct clocksource *cs)
105{
106 struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource);
107
108 /*
109 * Shift timer count down by a constant due to unreliable lower bits
110 * on some targets.
111 */
112 return readl(clk->global_counter) >> clk->shift;
113}
114
115static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt)
116{
117#ifdef CONFIG_SMP
118 int i;
119 for (i = 0; i < NR_TIMERS; i++)
120 if (evt == &(msm_clocks[i].clockevent))
121 return &msm_clocks[i];
122 return &msm_clocks[MSM_GLOBAL_TIMER];
123#else
124 return container_of(evt, struct msm_clock, clockevent);
125#endif
126}
127
128static int msm_timer_set_next_event(unsigned long cycles, 60static int msm_timer_set_next_event(unsigned long cycles,
129 struct clock_event_device *evt) 61 struct clock_event_device *evt)
130{ 62{
131 struct msm_clock *clock = clockevent_to_clock(evt); 63 u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
132 uint32_t now = readl(clock->local_counter);
133 uint32_t alarm = now + (cycles << clock->shift);
134 64
135 writel(alarm, clock->regbase + TIMER_MATCH_VAL); 65 writel_relaxed(0, event_base + TIMER_CLEAR);
66 writel_relaxed(cycles, event_base + TIMER_MATCH_VAL);
67 writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE);
136 return 0; 68 return 0;
137} 69}
138 70
139static void msm_timer_set_mode(enum clock_event_mode mode, 71static void msm_timer_set_mode(enum clock_event_mode mode,
140 struct clock_event_device *evt) 72 struct clock_event_device *evt)
141{ 73{
142 struct msm_clock *clock = clockevent_to_clock(evt); 74 u32 ctrl;
75
76 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
77 ctrl &= ~(TIMER_ENABLE_EN | TIMER_ENABLE_CLR_ON_MATCH_EN);
143 78
144 switch (mode) { 79 switch (mode) {
145 case CLOCK_EVT_MODE_RESUME: 80 case CLOCK_EVT_MODE_RESUME:
146 case CLOCK_EVT_MODE_PERIODIC: 81 case CLOCK_EVT_MODE_PERIODIC:
147 break; 82 break;
148 case CLOCK_EVT_MODE_ONESHOT: 83 case CLOCK_EVT_MODE_ONESHOT:
149 writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE); 84 /* Timer is enabled in set_next_event */
150 break; 85 break;
151 case CLOCK_EVT_MODE_UNUSED: 86 case CLOCK_EVT_MODE_UNUSED:
152 case CLOCK_EVT_MODE_SHUTDOWN: 87 case CLOCK_EVT_MODE_SHUTDOWN:
153 writel(0, clock->regbase + TIMER_ENABLE);
154 break; 88 break;
155 } 89 }
90 writel_relaxed(ctrl, event_base + TIMER_ENABLE);
156} 91}
157 92
158static struct msm_clock msm_clocks[] = { 93static struct clock_event_device msm_clockevent = {
159 [MSM_CLOCK_GPT] = { 94 .name = "gp_timer",
160 .clockevent = { 95 .features = CLOCK_EVT_FEAT_ONESHOT,
161 .name = "gp_timer", 96 .rating = 200,
162 .features = CLOCK_EVT_FEAT_ONESHOT, 97 .set_next_event = msm_timer_set_next_event,
163 .shift = 32, 98 .set_mode = msm_timer_set_mode,
164 .rating = 200, 99};
165 .set_next_event = msm_timer_set_next_event, 100
166 .set_mode = msm_timer_set_mode, 101static union {
167 }, 102 struct clock_event_device *evt;
168 .clocksource = { 103 struct clock_event_device __percpu **percpu_evt;
169 .name = "gp_timer", 104} msm_evt;
170 .rating = 200, 105
171 .read = msm_read_timer_count, 106static void __iomem *source_base;
172 .mask = CLOCKSOURCE_MASK(32), 107
173 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 108static cycle_t msm_read_timer_count(struct clocksource *cs)
174 }, 109{
175 .irq = INT_GP_TIMER_EXP, 110 return readl_relaxed(source_base + TIMER_COUNT_VAL);
176 .freq = GPT_HZ, 111}
177 }, 112
178 [MSM_CLOCK_DGT] = { 113static cycle_t msm_read_timer_count_shift(struct clocksource *cs)
179 .clockevent = { 114{
180 .name = "dg_timer", 115 /*
181 .features = CLOCK_EVT_FEAT_ONESHOT, 116 * Shift timer count down by a constant due to unreliable lower bits
182 .shift = 32 + MSM_DGT_SHIFT, 117 * on some targets.
183 .rating = 300, 118 */
184 .set_next_event = msm_timer_set_next_event, 119 return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
185 .set_mode = msm_timer_set_mode, 120}
186 }, 121
187 .clocksource = { 122static struct clocksource msm_clocksource = {
188 .name = "dg_timer", 123 .name = "dg_timer",
189 .rating = 300, 124 .rating = 300,
190 .read = msm_read_timer_count, 125 .read = msm_read_timer_count,
191 .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)), 126 .mask = CLOCKSOURCE_MASK(32),
192 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 127 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
193 },
194 .irq = INT_DEBUG_TIMER_EXP,
195 .freq = DGT_HZ >> MSM_DGT_SHIFT,
196 .shift = MSM_DGT_SHIFT,
197 }
198}; 128};
199 129
200static void __init msm_timer_init(void) 130static void __init msm_timer_init(void)
201{ 131{
202 int i; 132 struct clock_event_device *ce = &msm_clockevent;
133 struct clocksource *cs = &msm_clocksource;
203 int res; 134 int res;
204 int global_offset = 0; 135 u32 dgt_hz;
205 136
206 if (cpu_is_msm7x01()) { 137 if (cpu_is_msm7x01()) {
207 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE; 138 event_base = MSM_CSR_BASE;
208 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10; 139 source_base = MSM_CSR_BASE + 0x10;
140 dgt_hz = 19200000 >> MSM_DGT_SHIFT; /* 600 KHz */
141 cs->read = msm_read_timer_count_shift;
142 cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
209 } else if (cpu_is_msm7x30()) { 143 } else if (cpu_is_msm7x30()) {
210 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04; 144 event_base = MSM_CSR_BASE + 0x04;
211 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24; 145 source_base = MSM_CSR_BASE + 0x24;
146 dgt_hz = 24576000 / 4;
212 } else if (cpu_is_qsd8x50()) { 147 } else if (cpu_is_qsd8x50()) {
213 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE; 148 event_base = MSM_CSR_BASE;
214 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10; 149 source_base = MSM_CSR_BASE + 0x10;
150 dgt_hz = 19200000 / 4;
215 } else if (cpu_is_msm8x60() || cpu_is_msm8960()) { 151 } else if (cpu_is_msm8x60() || cpu_is_msm8960()) {
216 msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04; 152 event_base = MSM_TMR_BASE + 0x04;
217 msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24; 153 /* Use CPU0's timer as the global clock source. */
218 154 source_base = MSM_TMR0_BASE + 0x24;
219 /* Use CPU0's timer as the global timer. */ 155 dgt_hz = 27000000 / 4;
220 global_offset = MSM_TMR0_BASE - MSM_TMR_BASE; 156 writel_relaxed(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
221 } else 157 } else
222 BUG(); 158 BUG();
223 159
224#ifdef CONFIG_ARCH_MSM_SCORPIONMP 160 writel_relaxed(0, event_base + TIMER_ENABLE);
225 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); 161 writel_relaxed(0, event_base + TIMER_CLEAR);
226#endif 162 writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
227 163 ce->cpumask = cpumask_of(0);
228 for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) { 164
229 struct msm_clock *clock = &msm_clocks[i]; 165 ce->irq = INT_GP_TIMER_EXP;
230 struct clock_event_device *ce = &clock->clockevent; 166 clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff);
231 struct clocksource *cs = &clock->clocksource; 167 if (cpu_is_msm8x60() || cpu_is_msm8960()) {
232 168 msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *);
233 clock->local_counter = clock->regbase + TIMER_COUNT_VAL; 169 if (!msm_evt.percpu_evt) {
234 clock->global_counter = clock->local_counter + global_offset; 170 pr_err("memory allocation failed for %s\n", ce->name);
235 171 goto err;
236 writel(0, clock->regbase + TIMER_ENABLE);
237 writel(0, clock->regbase + TIMER_CLEAR);
238 writel(~0, clock->regbase + TIMER_MATCH_VAL);
239
240 ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift);
241 /* allow at least 10 seconds to notice that the timer wrapped */
242 ce->max_delta_ns =
243 clockevent_delta2ns(0xf0000000 >> clock->shift, ce);
244 /* 4 gets rounded down to 3 */
245 ce->min_delta_ns = clockevent_delta2ns(4, ce);
246 ce->cpumask = cpumask_of(0);
247
248 res = clocksource_register_hz(cs, clock->freq);
249 if (res)
250 printk(KERN_ERR "msm_timer_init: clocksource_register "
251 "failed for %s\n", cs->name);
252
253 ce->irq = clock->irq;
254 if (cpu_is_msm8x60() || cpu_is_msm8960()) {
255 clock->percpu_evt = alloc_percpu(struct clock_event_device *);
256 if (!clock->percpu_evt) {
257 pr_err("msm_timer_init: memory allocation "
258 "failed for %s\n", ce->name);
259 continue;
260 }
261
262 *__this_cpu_ptr(clock->percpu_evt) = ce;
263 res = request_percpu_irq(ce->irq, msm_timer_interrupt,
264 ce->name, clock->percpu_evt);
265 if (!res)
266 enable_percpu_irq(ce->irq, 0);
267 } else {
268 clock->evt = ce;
269 res = request_irq(ce->irq, msm_timer_interrupt,
270 IRQF_TIMER | IRQF_NOBALANCING | IRQF_TRIGGER_RISING,
271 ce->name, &clock->evt);
272 } 172 }
273 173 *__this_cpu_ptr(msm_evt.percpu_evt) = ce;
274 if (res) 174 res = request_percpu_irq(ce->irq, msm_timer_interrupt,
275 pr_err("msm_timer_init: request_irq failed for %s\n", 175 ce->name, msm_evt.percpu_evt);
276 ce->name); 176 if (!res)
277 177 enable_percpu_irq(ce->irq, 0);
278 clockevents_register_device(ce); 178 } else {
179 msm_evt.evt = ce;
180 res = request_irq(ce->irq, msm_timer_interrupt,
181 IRQF_TIMER | IRQF_NOBALANCING |
182 IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt);
279 } 183 }
184
185 if (res)
186 pr_err("request_irq failed for %s\n", ce->name);
187err:
188 writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
189 res = clocksource_register_hz(cs, dgt_hz);
190 if (res)
191 pr_err("clocksource_register failed\n");
280} 192}
281 193
282#ifdef CONFIG_SMP 194#ifdef CONFIG_LOCAL_TIMERS
283int __cpuinit local_timer_setup(struct clock_event_device *evt) 195int __cpuinit local_timer_setup(struct clock_event_device *evt)
284{ 196{
285 static bool local_timer_inited;
286 struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
287
288 /* Use existing clock_event for cpu 0 */ 197 /* Use existing clock_event for cpu 0 */
289 if (!smp_processor_id()) 198 if (!smp_processor_id())
290 return 0; 199 return 0;
291 200
292 writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL); 201 writel_relaxed(0, event_base + TIMER_ENABLE);
293 202 writel_relaxed(0, event_base + TIMER_CLEAR);
294 if (!local_timer_inited) { 203 writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
295 writel(0, clock->regbase + TIMER_ENABLE); 204 evt->irq = msm_clockevent.irq;
296 writel(0, clock->regbase + TIMER_CLEAR);
297 writel(~0, clock->regbase + TIMER_MATCH_VAL);
298 local_timer_inited = true;
299 }
300 evt->irq = clock->irq;
301 evt->name = "local_timer"; 205 evt->name = "local_timer";
302 evt->features = CLOCK_EVT_FEAT_ONESHOT; 206 evt->features = msm_clockevent.features;
303 evt->rating = clock->clockevent.rating; 207 evt->rating = msm_clockevent.rating;
304 evt->set_mode = msm_timer_set_mode; 208 evt->set_mode = msm_timer_set_mode;
305 evt->set_next_event = msm_timer_set_next_event; 209 evt->set_next_event = msm_timer_set_next_event;
306 evt->shift = clock->clockevent.shift; 210 evt->shift = msm_clockevent.shift;
307 evt->mult = div_sc(clock->freq, NSEC_PER_SEC, evt->shift); 211 evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
308 evt->max_delta_ns = 212 evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
309 clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
310 evt->min_delta_ns = clockevent_delta2ns(4, evt); 213 evt->min_delta_ns = clockevent_delta2ns(4, evt);
311 214
312 *__this_cpu_ptr(clock->percpu_evt) = evt; 215 *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
313 enable_percpu_irq(evt->irq, 0);
314
315 clockevents_register_device(evt); 216 clockevents_register_device(evt);
217 enable_percpu_irq(evt->irq, 0);
316 return 0; 218 return 0;
317} 219}
318 220
@@ -321,8 +223,7 @@ void local_timer_stop(struct clock_event_device *evt)
321 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 223 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
322 disable_percpu_irq(evt->irq); 224 disable_percpu_irq(evt->irq);
323} 225}
324 226#endif /* CONFIG_LOCAL_TIMERS */
325#endif
326 227
327struct sys_timer msm_timer = { 228struct sys_timer msm_timer = {
328 .init = msm_timer_init 229 .init = msm_timer_init
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
index 311d5b0e9bc..62b53d710ef 100644
--- a/arch/arm/mach-mv78xx0/addr-map.c
+++ b/arch/arm/mach-mv78xx0/addr-map.c
@@ -12,12 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mbus.h> 13#include <linux/mbus.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <plat/addr-map.h>
15#include "common.h" 16#include "common.h"
16 17
17/* 18/*
18 * Generic Address Decode Windows bit settings 19 * Generic Address Decode Windows bit settings
19 */ 20 */
20#define TARGET_DDR 0
21#define TARGET_DEV_BUS 1 21#define TARGET_DEV_BUS 1
22#define TARGET_PCIE0 4 22#define TARGET_PCIE0 4
23#define TARGET_PCIE1 8 23#define TARGET_PCIE1 8
@@ -32,23 +32,10 @@
32#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l))) 32#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
33 33
34/* 34/*
35 * Helpers to get DDR bank info
36 */
37#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
38#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
39
40/*
41 * CPU Address Decode Windows registers 35 * CPU Address Decode Windows registers
42 */ 36 */
43#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4)) 37#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
44#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4)) 38#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
45#define WIN_CTRL_OFF 0x0000
46#define WIN_BASE_OFF 0x0004
47#define WIN_REMAP_LO_OFF 0x0008
48#define WIN_REMAP_HI_OFF 0x000c
49
50
51struct mbus_dram_target_info mv78xx0_mbus_dram_info;
52 39
53static void __init __iomem *win_cfg_base(int win) 40static void __init __iomem *win_cfg_base(int win)
54{ 41{
@@ -63,94 +50,43 @@ static void __init __iomem *win_cfg_base(int win)
63 return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win)); 50 return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win));
64} 51}
65 52
66static int __init cpu_win_can_remap(int win) 53/*
67{ 54 * Description of the windows needed by the platform code
68 if (win < 8) 55 */
69 return 1; 56static struct __initdata orion_addr_map_cfg addr_map_cfg = {
70 57 .num_wins = 14,
71 return 0; 58 .remappable_wins = 8,
72} 59 .win_cfg_base = win_cfg_base,
73 60};
74static void __init setup_cpu_win(int win, u32 base, u32 size,
75 u8 target, u8 attr, int remap)
76{
77 void __iomem *addr = win_cfg_base(win);
78 u32 ctrl;
79
80 base &= 0xffff0000;
81 ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
82
83 writel(base, addr + WIN_BASE_OFF);
84 writel(ctrl, addr + WIN_CTRL_OFF);
85 if (cpu_win_can_remap(win)) {
86 if (remap < 0)
87 remap = base;
88
89 writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
90 writel(0, addr + WIN_REMAP_HI_OFF);
91 }
92}
93 61
94void __init mv78xx0_setup_cpu_mbus(void) 62void __init mv78xx0_setup_cpu_mbus(void)
95{ 63{
96 void __iomem *addr;
97 int i;
98 int cs;
99
100 /* 64 /*
101 * First, disable and clear windows. 65 * Disable, clear and configure windows.
102 */ 66 */
103 for (i = 0; i < 14; i++) { 67 orion_config_wins(&addr_map_cfg, NULL);
104 addr = win_cfg_base(i);
105
106 writel(0, addr + WIN_BASE_OFF);
107 writel(0, addr + WIN_CTRL_OFF);
108 if (cpu_win_can_remap(i)) {
109 writel(0, addr + WIN_REMAP_LO_OFF);
110 writel(0, addr + WIN_REMAP_HI_OFF);
111 }
112 }
113 68
114 /* 69 /*
115 * Setup MBUS dram target info. 70 * Setup MBUS dram target info.
116 */ 71 */
117 mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
118
119 if (mv78xx0_core_index() == 0) 72 if (mv78xx0_core_index() == 0)
120 addr = (void __iomem *)DDR_WINDOW_CPU0_BASE; 73 orion_setup_cpu_mbus_target(&addr_map_cfg,
74 DDR_WINDOW_CPU0_BASE);
121 else 75 else
122 addr = (void __iomem *)DDR_WINDOW_CPU1_BASE; 76 orion_setup_cpu_mbus_target(&addr_map_cfg,
123 77 DDR_WINDOW_CPU1_BASE);
124 for (i = 0, cs = 0; i < 4; i++) {
125 u32 base = readl(addr + DDR_BASE_CS_OFF(i));
126 u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
127
128 /*
129 * Chip select enabled?
130 */
131 if (size & 1) {
132 struct mbus_dram_window *w;
133
134 w = &mv78xx0_mbus_dram_info.cs[cs++];
135 w->cs_index = i;
136 w->mbus_attr = 0xf & ~(1 << i);
137 w->base = base & 0xffff0000;
138 w->size = (size | 0x0000ffff) + 1;
139 }
140 }
141 mv78xx0_mbus_dram_info.num_cs = cs;
142} 78}
143 79
144void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, 80void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
145 int maj, int min) 81 int maj, int min)
146{ 82{
147 setup_cpu_win(window, base, size, TARGET_PCIE(maj), 83 orion_setup_cpu_win(&addr_map_cfg, window, base, size,
148 ATTR_PCIE_IO(min), -1); 84 TARGET_PCIE(maj), ATTR_PCIE_IO(min), -1);
149} 85}
150 86
151void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size, 87void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
152 int maj, int min) 88 int maj, int min)
153{ 89{
154 setup_cpu_win(window, base, size, TARGET_PCIE(maj), 90 orion_setup_cpu_win(&addr_map_cfg, window, base, size,
155 ATTR_PCIE_MEM(min), -1); 91 TARGET_PCIE(maj), ATTR_PCIE_MEM(min), -1);
156} 92}
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index 5b9632b0116..0cdd41004ad 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -12,7 +12,6 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/serial_8250.h> 14#include <linux/serial_8250.h>
15#include <linux/mbus.h>
16#include <linux/ata_platform.h> 15#include <linux/ata_platform.h>
17#include <linux/ethtool.h> 16#include <linux/ethtool.h>
18#include <asm/mach/map.h> 17#include <asm/mach/map.h>
@@ -23,6 +22,7 @@
23#include <plat/orion_nand.h> 22#include <plat/orion_nand.h>
24#include <plat/time.h> 23#include <plat/time.h>
25#include <plat/common.h> 24#include <plat/common.h>
25#include <plat/addr-map.h>
26#include "common.h" 26#include "common.h"
27 27
28static int get_tclk(void); 28static int get_tclk(void);
@@ -169,8 +169,7 @@ void __init mv78xx0_map_io(void)
169 ****************************************************************************/ 169 ****************************************************************************/
170void __init mv78xx0_ehci0_init(void) 170void __init mv78xx0_ehci0_init(void)
171{ 171{
172 orion_ehci_init(&mv78xx0_mbus_dram_info, 172 orion_ehci_init(USB0_PHYS_BASE, IRQ_MV78XX0_USB_0);
173 USB0_PHYS_BASE, IRQ_MV78XX0_USB_0);
174} 173}
175 174
176 175
@@ -179,8 +178,7 @@ void __init mv78xx0_ehci0_init(void)
179 ****************************************************************************/ 178 ****************************************************************************/
180void __init mv78xx0_ehci1_init(void) 179void __init mv78xx0_ehci1_init(void)
181{ 180{
182 orion_ehci_1_init(&mv78xx0_mbus_dram_info, 181 orion_ehci_1_init(USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
183 USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
184} 182}
185 183
186 184
@@ -189,8 +187,7 @@ void __init mv78xx0_ehci1_init(void)
189 ****************************************************************************/ 187 ****************************************************************************/
190void __init mv78xx0_ehci2_init(void) 188void __init mv78xx0_ehci2_init(void)
191{ 189{
192 orion_ehci_2_init(&mv78xx0_mbus_dram_info, 190 orion_ehci_2_init(USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
193 USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
194} 191}
195 192
196 193
@@ -199,7 +196,7 @@ void __init mv78xx0_ehci2_init(void)
199 ****************************************************************************/ 196 ****************************************************************************/
200void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) 197void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
201{ 198{
202 orion_ge00_init(eth_data, &mv78xx0_mbus_dram_info, 199 orion_ge00_init(eth_data,
203 GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, 200 GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
204 IRQ_MV78XX0_GE_ERR, get_tclk()); 201 IRQ_MV78XX0_GE_ERR, get_tclk());
205} 202}
@@ -210,7 +207,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
210 ****************************************************************************/ 207 ****************************************************************************/
211void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) 208void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
212{ 209{
213 orion_ge01_init(eth_data, &mv78xx0_mbus_dram_info, 210 orion_ge01_init(eth_data,
214 GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, 211 GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
215 NO_IRQ, get_tclk()); 212 NO_IRQ, get_tclk());
216} 213}
@@ -234,7 +231,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
234 eth_data->duplex = DUPLEX_FULL; 231 eth_data->duplex = DUPLEX_FULL;
235 } 232 }
236 233
237 orion_ge10_init(eth_data, &mv78xx0_mbus_dram_info, 234 orion_ge10_init(eth_data,
238 GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM, 235 GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
239 NO_IRQ, get_tclk()); 236 NO_IRQ, get_tclk());
240} 237}
@@ -258,7 +255,7 @@ void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
258 eth_data->duplex = DUPLEX_FULL; 255 eth_data->duplex = DUPLEX_FULL;
259 } 256 }
260 257
261 orion_ge11_init(eth_data, &mv78xx0_mbus_dram_info, 258 orion_ge11_init(eth_data,
262 GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM, 259 GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
263 NO_IRQ, get_tclk()); 260 NO_IRQ, get_tclk());
264} 261}
@@ -277,8 +274,7 @@ void __init mv78xx0_i2c_init(void)
277 ****************************************************************************/ 274 ****************************************************************************/
278void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data) 275void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
279{ 276{
280 orion_sata_init(sata_data, &mv78xx0_mbus_dram_info, 277 orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
281 SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
282} 278}
283 279
284 280
diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h
index 07d5f8f6be7..507c767d49e 100644
--- a/arch/arm/mach-mv78xx0/common.h
+++ b/arch/arm/mach-mv78xx0/common.h
@@ -23,7 +23,6 @@ void mv78xx0_init(void);
23void mv78xx0_init_early(void); 23void mv78xx0_init_early(void);
24void mv78xx0_init_irq(void); 24void mv78xx0_init_irq(void);
25 25
26extern struct mbus_dram_target_info mv78xx0_mbus_dram_info;
27void mv78xx0_setup_cpu_mbus(void); 26void mv78xx0_setup_cpu_mbus(void);
28void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size, 27void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
29 int maj, int min); 28 int maj, int min);
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
index cf4e494d44b..df50342179e 100644
--- a/arch/arm/mach-mv78xx0/mpp.c
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -10,7 +10,6 @@
10#include <linux/gpio.h> 10#include <linux/gpio.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h> 13#include <linux/io.h>
15#include <plat/mpp.h> 14#include <plat/mpp.h>
16#include <mach/hardware.h> 15#include <mach/hardware.h>
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index c51af1cac30..12fcb108b0e 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -10,11 +10,11 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/mbus.h>
14#include <video/vga.h> 13#include <video/vga.h>
15#include <asm/irq.h> 14#include <asm/irq.h>
16#include <asm/mach/pci.h> 15#include <asm/mach/pci.h>
17#include <plat/pcie.h> 16#include <plat/pcie.h>
17#include <plat/addr-map.h>
18#include "common.h" 18#include "common.h"
19 19
20struct pcie_port { 20struct pcie_port {
@@ -153,7 +153,7 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
153 * Generic PCIe unit setup. 153 * Generic PCIe unit setup.
154 */ 154 */
155 orion_pcie_set_local_bus_nr(pp->base, sys->busnr); 155 orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
156 orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info); 156 orion_pcie_setup(pp->base);
157 157
158 sys->resource[0] = &pp->res[0]; 158 sys->resource[0] = &pp->res[0];
159 sys->resource[1] = &pp->res[1]; 159 sys->resource[1] = &pp->res[1];
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index df4a508f240..bc17dfea381 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/clk.h>
16 17
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
18 19
@@ -21,10 +22,26 @@
21#include <mach/devices-common.h> 22#include <mach/devices-common.h>
22#include <mach/iomux-v3.h> 23#include <mach/iomux-v3.h>
23 24
25static struct clk *gpc_dvfs_clk;
26
24static void imx5_idle(void) 27static void imx5_idle(void)
25{ 28{
26 if (!need_resched()) 29 if (!need_resched()) {
30 /* gpc clock is needed for SRPG */
31 if (gpc_dvfs_clk == NULL) {
32 gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
33 if (IS_ERR(gpc_dvfs_clk))
34 goto err0;
35 }
36 clk_enable(gpc_dvfs_clk);
27 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); 37 mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
38 if (tzic_enable_wake())
39 goto err1;
40 cpu_do_idle();
41err1:
42 clk_disable(gpc_dvfs_clk);
43 }
44err0:
28 local_irq_enable(); 45 local_irq_enable();
29} 46}
30 47
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
index 144ebebc4a6..5eebfaad122 100644
--- a/arch/arm/mach-mx5/system.c
+++ b/arch/arm/mach-mx5/system.c
@@ -55,9 +55,6 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
55 stop_mode = 1; 55 stop_mode = 1;
56 } 56 }
57 arm_srpgcr |= MXC_SRPGCR_PCR; 57 arm_srpgcr |= MXC_SRPGCR_PCR;
58
59 if (tzic_enable_wake(1) != 0)
60 return;
61 break; 58 break;
62 case STOP_POWER_ON: 59 case STOP_POWER_ON:
63 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; 60 ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index 0163b6d8377..e12e11231dc 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -545,11 +545,11 @@ int __init mx23_clocks_init(void)
545 */ 545 */
546 clk_set_parent(&ssp_clk, &ref_io_clk); 546 clk_set_parent(&ssp_clk, &ref_io_clk);
547 547
548 clk_enable(&cpu_clk); 548 clk_prepare_enable(&cpu_clk);
549 clk_enable(&hbus_clk); 549 clk_prepare_enable(&hbus_clk);
550 clk_enable(&xbus_clk); 550 clk_prepare_enable(&xbus_clk);
551 clk_enable(&emi_clk); 551 clk_prepare_enable(&emi_clk);
552 clk_enable(&uart_clk); 552 clk_prepare_enable(&uart_clk);
553 553
554 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 554 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
555 555
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index da6e4aad177..5d68e415222 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -22,6 +22,7 @@
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/jiffies.h> 23#include <linux/jiffies.h>
24#include <linux/clkdev.h> 24#include <linux/clkdev.h>
25#include <linux/spinlock.h>
25 26
26#include <asm/clkdev.h> 27#include <asm/clkdev.h>
27#include <asm/div64.h> 28#include <asm/div64.h>
@@ -29,6 +30,7 @@
29#include <mach/mx28.h> 30#include <mach/mx28.h>
30#include <mach/common.h> 31#include <mach/common.h>
31#include <mach/clock.h> 32#include <mach/clock.h>
33#include <mach/digctl.h>
32 34
33#include "regs-clkctrl-mx28.h" 35#include "regs-clkctrl-mx28.h"
34 36
@@ -43,6 +45,33 @@ static struct clk emi_clk;
43static struct clk saif0_clk; 45static struct clk saif0_clk;
44static struct clk saif1_clk; 46static struct clk saif1_clk;
45static struct clk clk32k_clk; 47static struct clk clk32k_clk;
48static DEFINE_SPINLOCK(clkmux_lock);
49
50/*
51 * HW_SAIF_CLKMUX_SEL:
52 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
53 * clock pins selected for SAIF1 input clocks.
54 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
55 * SAIF0 clock inputs selected for SAIF1 input clocks.
56 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
57 * clocks.
58 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
59 * clocks.
60 */
61int mxs_saif_clkmux_select(unsigned int clkmux)
62{
63 if (clkmux > 0x3)
64 return -EINVAL;
65
66 spin_lock(&clkmux_lock);
67 __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
68 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
69 __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
70 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
71 spin_unlock(&clkmux_lock);
72
73 return 0;
74}
46 75
47static int _raw_clk_enable(struct clk *clk) 76static int _raw_clk_enable(struct clk *clk)
48{ 77{
@@ -775,16 +804,25 @@ int __init mx28_clocks_init(void)
775 clk_set_parent(&ssp0_clk, &ref_io0_clk); 804 clk_set_parent(&ssp0_clk, &ref_io0_clk);
776 clk_set_parent(&ssp1_clk, &ref_io0_clk); 805 clk_set_parent(&ssp1_clk, &ref_io0_clk);
777 806
778 clk_enable(&cpu_clk); 807 clk_prepare_enable(&cpu_clk);
779 clk_enable(&hbus_clk); 808 clk_prepare_enable(&hbus_clk);
780 clk_enable(&xbus_clk); 809 clk_prepare_enable(&xbus_clk);
781 clk_enable(&emi_clk); 810 clk_prepare_enable(&emi_clk);
782 clk_enable(&uart_clk); 811 clk_prepare_enable(&uart_clk);
783 812
784 clk_set_parent(&lcdif_clk, &ref_pix_clk); 813 clk_set_parent(&lcdif_clk, &ref_pix_clk);
785 clk_set_parent(&saif0_clk, &pll0_clk); 814 clk_set_parent(&saif0_clk, &pll0_clk);
786 clk_set_parent(&saif1_clk, &pll0_clk); 815 clk_set_parent(&saif1_clk, &pll0_clk);
787 816
817 /*
818 * Set an initial clock rate for the saif internal logic to work
819 * properly. This is important when working in EXTMASTER mode that
820 * uses the other saif's BITCLK&LRCLK but it still needs a basic
821 * clock which should be fast enough for the internal logic.
822 */
823 clk_set_rate(&saif0_clk, 24000000);
824 clk_set_rate(&saif1_clk, 24000000);
825
788 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 826 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
789 827
790 mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0); 828 mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
index a7093c88e6a..97a6f4acc6c 100644
--- a/arch/arm/mach-mxs/clock.c
+++ b/arch/arm/mach-mxs/clock.c
@@ -74,10 +74,15 @@ static int __clk_enable(struct clk *clk)
74 return 0; 74 return 0;
75} 75}
76 76
77/* This function increments the reference count on the clock and enables the 77/*
78 * clock if not already enabled. The parent clock tree is recursively enabled 78 * The clk_enable/clk_disable could be called by drivers in atomic context,
79 * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
80 * can hold a mutex, as the pair will only be called in non-atomic context.
81 * Before migrating to common clk framework, we can have __clk_enable and
82 * __clk_disable called in clk_prepare/clk_unprepare with mutex held and
83 * leave clk_enable/clk_disable as the dummy functions.
79 */ 84 */
80int clk_enable(struct clk *clk) 85int clk_prepare(struct clk *clk)
81{ 86{
82 int ret = 0; 87 int ret = 0;
83 88
@@ -90,13 +95,9 @@ int clk_enable(struct clk *clk)
90 95
91 return ret; 96 return ret;
92} 97}
93EXPORT_SYMBOL(clk_enable); 98EXPORT_SYMBOL(clk_prepare);
94 99
95/* This function decrements the reference count on the clock and disables 100void clk_unprepare(struct clk *clk)
96 * the clock when reference count is 0. The parent clock tree is
97 * recursively disabled
98 */
99void clk_disable(struct clk *clk)
100{ 101{
101 if (clk == NULL || IS_ERR(clk)) 102 if (clk == NULL || IS_ERR(clk))
102 return; 103 return;
@@ -105,6 +106,18 @@ void clk_disable(struct clk *clk)
105 __clk_disable(clk); 106 __clk_disable(clk);
106 mutex_unlock(&clocks_mutex); 107 mutex_unlock(&clocks_mutex);
107} 108}
109EXPORT_SYMBOL(clk_unprepare);
110
111int clk_enable(struct clk *clk)
112{
113 return 0;
114}
115EXPORT_SYMBOL(clk_enable);
116
117void clk_disable(struct clk *clk)
118{
119 /* nothing to do */
120}
108EXPORT_SYMBOL(clk_disable); 121EXPORT_SYMBOL(clk_disable);
109 122
110/* Retrieve the *current* clock rate. If the clock itself 123/* Retrieve the *current* clock rate. If the clock itself
@@ -166,7 +179,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
166 return ret; 179 return ret;
167 180
168 if (clk->usecount) 181 if (clk->usecount)
169 clk_enable(parent); 182 clk_prepare_enable(parent);
170 183
171 mutex_lock(&clocks_mutex); 184 mutex_lock(&clocks_mutex);
172 ret = clk->set_parent(clk, parent); 185 ret = clk->set_parent(clk, parent);
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index c8887103f0e..4f50094e293 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -47,6 +47,7 @@ struct platform_device *__init mx28_add_mxsfb(
47 const struct mxsfb_platform_data *pdata); 47 const struct mxsfb_platform_data *pdata);
48 48
49extern const struct mxs_saif_data mx28_saif_data[] __initconst; 49extern const struct mxs_saif_data mx28_saif_data[] __initconst;
50#define mx28_add_saif(id) mxs_add_saif(&mx28_saif_data[id]) 50#define mx28_add_saif(id, pdata) \
51 mxs_add_saif(&mx28_saif_data[id], pdata)
51 52
52struct platform_device *__init mx28_add_rtc_stmp3xxx(void); 53struct platform_device *__init mx28_add_rtc_stmp3xxx(void);
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-saif.c b/arch/arm/mach-mxs/devices/platform-mxs-saif.c
index 1ec965e9fe9..f6e3a60b420 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-saif.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-saif.c
@@ -32,7 +32,8 @@ const struct mxs_saif_data mx28_saif_data[] __initconst = {
32}; 32};
33#endif 33#endif
34 34
35struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data) 35struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data,
36 const struct mxs_saif_platform_data *pdata)
36{ 37{
37 struct resource res[] = { 38 struct resource res[] = {
38 { 39 {
@@ -56,5 +57,5 @@ struct platform_device *__init mxs_add_saif(const struct mxs_saif_data *data)
56 }; 57 };
57 58
58 return mxs_add_platform_device("mxs-saif", data->id, res, 59 return mxs_add_platform_device("mxs-saif", data->id, res,
59 ARRAY_SIZE(res), NULL, 0); 60 ARRAY_SIZE(res), pdata, sizeof(*pdata));
60} 61}
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 1388485414c..e1237ab2586 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -17,6 +17,7 @@ extern const u32 *mxs_get_ocotp(void);
17extern int mxs_reset_block(void __iomem *); 17extern int mxs_reset_block(void __iomem *);
18extern void mxs_timer_init(struct clk *, int); 18extern void mxs_timer_init(struct clk *, int);
19extern void mxs_restart(char, const char *); 19extern void mxs_restart(char, const char *);
20extern int mxs_saif_clkmux_select(unsigned int clkmux);
20 21
21extern int mx23_register_gpios(void); 22extern int mx23_register_gpios(void);
22extern int mx23_clocks_init(void); 23extern int mx23_clocks_init(void);
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index a8080f44c03..dc369c1239f 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -94,6 +94,7 @@ struct platform_device *__init mxs_add_mxs_pwm(
94 resource_size_t iobase, int id); 94 resource_size_t iobase, int id);
95 95
96/* saif */ 96/* saif */
97#include <sound/saif.h>
97struct mxs_saif_data { 98struct mxs_saif_data {
98 int id; 99 int id;
99 resource_size_t iobase; 100 resource_size_t iobase;
@@ -103,4 +104,5 @@ struct mxs_saif_data {
103}; 104};
104 105
105struct platform_device *__init mxs_add_saif( 106struct platform_device *__init mxs_add_saif(
106 const struct mxs_saif_data *data); 107 const struct mxs_saif_data *data,
108 const struct mxs_saif_platform_data *pdata);
diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h
new file mode 100644
index 00000000000..49a888c65d6
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/digctl.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __MACH_DIGCTL_H__
10#define __MACH_DIGCTL_H__
11
12/* MXS DIGCTL SAIF CLKMUX */
13#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT 0x0
14#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT 0x1
15#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
16#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
17
18#define HW_DIGCTL_CTRL 0x0
19#define BP_DIGCTL_CTRL_SAIF_CLKMUX 10
20#define BM_DIGCTL_CTRL_SAIF_CLKMUX (0x3 << 10)
21#endif
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d0cc37fd23a..fdb0a5664dd 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -27,6 +27,7 @@
27 27
28#include <mach/common.h> 28#include <mach/common.h>
29#include <mach/iomux-mx28.h> 29#include <mach/iomux-mx28.h>
30#include <mach/digctl.h>
30 31
31#include "devices-mx28.h" 32#include "devices-mx28.h"
32 33
@@ -228,7 +229,7 @@ static void __init mx28evk_fec_reset(void)
228 /* Enable fec phy clock */ 229 /* Enable fec phy clock */
229 clk = clk_get_sys("pll2", NULL); 230 clk = clk_get_sys("pll2", NULL);
230 if (!IS_ERR(clk)) 231 if (!IS_ERR(clk))
231 clk_enable(clk); 232 clk_prepare_enable(clk);
232 233
233 /* Power up fec phy */ 234 /* Power up fec phy */
234 ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power"); 235 ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
@@ -421,6 +422,18 @@ static struct gpio mx28evk_lcd_gpios[] = {
421 { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" }, 422 { MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" },
422}; 423};
423 424
425static const struct mxs_saif_platform_data
426 mx28evk_mxs_saif_pdata[] __initconst = {
427 /* working on EXTMSTR0 mode (saif0 master, saif1 slave) */
428 {
429 .master_mode = 1,
430 .master_id = 0,
431 }, {
432 .master_mode = 0,
433 .master_id = 0,
434 },
435};
436
424static void __init mx28evk_init(void) 437static void __init mx28evk_init(void)
425{ 438{
426 int ret; 439 int ret;
@@ -454,8 +467,9 @@ static void __init mx28evk_init(void)
454 else 467 else
455 mx28_add_mxsfb(&mx28evk_mxsfb_pdata); 468 mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
456 469
457 mx28_add_saif(0); 470 mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
458 mx28_add_saif(1); 471 mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]);
472 mx28_add_saif(1, &mx28evk_mxs_saif_pdata[1]);
459 473
460 mx28_add_mxs_i2c(0); 474 mx28_add_mxs_i2c(0);
461 i2c_register_board_info(0, mxs_i2c0_board_info, 475 i2c_register_board_info(0, mxs_i2c0_board_info,
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index b936633b768..54f91ad1c96 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -66,7 +66,7 @@ static int __init mxs_arch_reset_init(void)
66 66
67 clk = clk_get_sys("rtc", NULL); 67 clk = clk_get_sys("rtc", NULL);
68 if (!IS_ERR(clk)) 68 if (!IS_ERR(clk))
69 clk_enable(clk); 69 clk_prepare_enable(clk);
70 70
71 return 0; 71 return 0;
72} 72}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index cace0d2e5a5..564a63279f1 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -245,7 +245,7 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
245 245
246void __init mxs_timer_init(struct clk *timer_clk, int irq) 246void __init mxs_timer_init(struct clk *timer_clk, int irq)
247{ 247{
248 clk_enable(timer_clk); 248 clk_prepare_enable(timer_clk);
249 249
250 /* 250 /*
251 * Initialize timers to a known state 251 * Initialize timers to a known state
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 73f287d6429..4f8d66f044e 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -168,70 +168,6 @@ config MACH_OMAP_GENERIC
168 custom OMAP boards. Say Y here if you have a custom 168 custom OMAP boards. Say Y here if you have a custom
169 board. 169 board.
170 170
171comment "OMAP CPU Speed"
172 depends on ARCH_OMAP1
173
174config OMAP_ARM_216MHZ
175 bool "OMAP ARM 216 MHz CPU (1710 only)"
176 depends on ARCH_OMAP1 && ARCH_OMAP16XX
177 help
178 Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N.
179
180config OMAP_ARM_195MHZ
181 bool "OMAP ARM 195 MHz CPU"
182 depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
183 help
184 Enable 195MHz clock for OMAP CPU. If unsure, say N.
185
186config OMAP_ARM_192MHZ
187 bool "OMAP ARM 192 MHz CPU"
188 depends on ARCH_OMAP1 && ARCH_OMAP16XX
189 help
190 Enable 192MHz clock for OMAP CPU. If unsure, say N.
191
192config OMAP_ARM_182MHZ
193 bool "OMAP ARM 182 MHz CPU"
194 depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
195 help
196 Enable 182MHz clock for OMAP CPU. If unsure, say N.
197
198config OMAP_ARM_168MHZ
199 bool "OMAP ARM 168 MHz CPU"
200 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
201 help
202 Enable 168MHz clock for OMAP CPU. If unsure, say N.
203
204config OMAP_ARM_150MHZ
205 bool "OMAP ARM 150 MHz CPU"
206 depends on ARCH_OMAP1 && ARCH_OMAP15XX
207 help
208 Enable 150MHz clock for OMAP CPU. If unsure, say N.
209
210config OMAP_ARM_120MHZ
211 bool "OMAP ARM 120 MHz CPU"
212 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
213 help
214 Enable 120MHz clock for OMAP CPU. If unsure, say N.
215
216config OMAP_ARM_96MHZ
217 bool "OMAP ARM 96 MHz CPU"
218 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
219 help
220 Enable 96MHz clock for OMAP CPU. If unsure, say N.
221
222config OMAP_ARM_60MHZ
223 bool "OMAP ARM 60 MHz CPU"
224 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
225 default y
226 help
227 Enable 60MHz clock for OMAP CPU. If unsure, say Y.
228
229config OMAP_ARM_30MHZ
230 bool "OMAP ARM 30 MHz CPU"
231 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
232 help
233 Enable 30MHz clock for OMAP CPU. If unsure, say N.
234
235endmenu 171endmenu
236 172
237endif 173endif
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 84ef70476b5..0c50df05d13 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -197,11 +197,10 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate)
197 ref_rate = ck_ref_p->rate; 197 ref_rate = ck_ref_p->rate;
198 198
199 for (ptr = omap1_rate_table; ptr->rate; ptr++) { 199 for (ptr = omap1_rate_table; ptr->rate; ptr++) {
200 if (ptr->xtal != ref_rate) 200 if (!(ptr->flags & cpu_mask))
201 continue; 201 continue;
202 202
203 /* DPLL1 cannot be reprogrammed without risking system crash */ 203 if (ptr->xtal != ref_rate)
204 if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate)
205 continue; 204 continue;
206 205
207 /* Can check only after xtal frequency check */ 206 /* Can check only after xtal frequency check */
@@ -215,12 +214,8 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate)
215 /* 214 /*
216 * In most cases we should not need to reprogram DPLL. 215 * In most cases we should not need to reprogram DPLL.
217 * Reprogramming the DPLL is tricky, it must be done from SRAM. 216 * Reprogramming the DPLL is tricky, it must be done from SRAM.
218 * (on 730, bit 13 must always be 1)
219 */ 217 */
220 if (cpu_is_omap7xx()) 218 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
221 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000);
222 else
223 omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
224 219
225 /* XXX Do we need to recalculate the tree below DPLL1 at this point? */ 220 /* XXX Do we need to recalculate the tree below DPLL1 at this point? */
226 ck_dpll1_p->rate = ptr->pll_rate; 221 ck_dpll1_p->rate = ptr->pll_rate;
@@ -290,6 +285,9 @@ long omap1_round_to_table_rate(struct clk *clk, unsigned long rate)
290 highest_rate = -EINVAL; 285 highest_rate = -EINVAL;
291 286
292 for (ptr = omap1_rate_table; ptr->rate; ptr++) { 287 for (ptr = omap1_rate_table; ptr->rate; ptr++) {
288 if (!(ptr->flags & cpu_mask))
289 continue;
290
293 if (ptr->xtal != ref_rate) 291 if (ptr->xtal != ref_rate)
294 continue; 292 continue;
295 293
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 16b1423b454..3d04f4f6767 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -111,4 +111,7 @@ extern const struct clkops clkops_dummy;
111extern const struct clkops clkops_uart_16xx; 111extern const struct clkops clkops_uart_16xx;
112extern const struct clkops clkops_generic; 112extern const struct clkops clkops_generic;
113 113
114/* used for passing SoC type to omap1_{select,round_to}_table_rate() */
115extern u32 cpu_mask;
116
114#endif 117#endif
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
index 9ff90a744a2..94699a82a73 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -25,6 +25,7 @@
25#include <plat/clock.h> 25#include <plat/clock.h>
26#include <plat/cpu.h> 26#include <plat/cpu.h>
27#include <plat/clkdev_omap.h> 27#include <plat/clkdev_omap.h>
28#include <plat/sram.h> /* for omap_sram_reprogram_clock() */
28#include <plat/usb.h> /* for OTG_BASE */ 29#include <plat/usb.h> /* for OTG_BASE */
29 30
30#include "clock.h" 31#include "clock.h"
@@ -778,12 +779,14 @@ static void __init omap1_show_rates(void)
778 arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); 779 arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
779} 780}
780 781
782u32 cpu_mask;
783
781int __init omap1_clk_init(void) 784int __init omap1_clk_init(void)
782{ 785{
783 struct omap_clk *c; 786 struct omap_clk *c;
784 const struct omap_clock_config *info; 787 const struct omap_clock_config *info;
785 int crystal_type = 0; /* Default 12 MHz */ 788 int crystal_type = 0; /* Default 12 MHz */
786 u32 reg, cpu_mask; 789 u32 reg;
787 790
788#ifdef CONFIG_DEBUG_LL 791#ifdef CONFIG_DEBUG_LL
789 /* 792 /*
@@ -808,6 +811,8 @@ int __init omap1_clk_init(void)
808 clk_preinit(c->lk.clk); 811 clk_preinit(c->lk.clk);
809 812
810 cpu_mask = 0; 813 cpu_mask = 0;
814 if (cpu_is_omap1710())
815 cpu_mask |= CK_1710;
811 if (cpu_is_omap16xx()) 816 if (cpu_is_omap16xx())
812 cpu_mask |= CK_16XX; 817 cpu_mask |= CK_16XX;
813 if (cpu_is_omap1510()) 818 if (cpu_is_omap1510())
@@ -931,17 +936,13 @@ void __init omap1_clk_late_init(void)
931{ 936{
932 unsigned long rate = ck_dpll1.rate; 937 unsigned long rate = ck_dpll1.rate;
933 938
934 if (rate >= OMAP1_DPLL1_SANE_VALUE)
935 return;
936
937 /* System booting at unusable rate, force reprogramming of DPLL1 */
938 ck_dpll1_p->rate = 0;
939
940 /* Find the highest supported frequency and enable it */ 939 /* Find the highest supported frequency and enable it */
941 if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) { 940 if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
942 pr_err("System frequencies not set, using default. Check your config.\n"); 941 pr_err("System frequencies not set, using default. Check your config.\n");
943 omap_writew(0x2290, DPLL_CTL); 942 /*
944 omap_writew(cpu_is_omap7xx() ? 0x2005 : 0x0005, ARM_CKCTL); 943 * Reprogramming the DPLL is tricky, it must be done from SRAM.
944 */
945 omap_sram_reprogram_clock(0x2290, 0x0005);
945 ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE; 946 ck_dpll1.rate = OMAP1_DPLL1_SANE_VALUE;
946 } 947 }
947 propagate_rate(&ck_dpll1); 948 propagate_rate(&ck_dpll1);
diff --git a/arch/arm/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h
index 07074d79adc..79a683864a5 100644
--- a/arch/arm/mach-omap1/opp.h
+++ b/arch/arm/mach-omap1/opp.h
@@ -21,6 +21,7 @@ struct mpu_rate {
21 unsigned long pll_rate; 21 unsigned long pll_rate;
22 __u16 ckctl_val; 22 __u16 ckctl_val;
23 __u16 dpllctl_val; 23 __u16 dpllctl_val;
24 u32 flags;
24}; 25};
25 26
26extern struct mpu_rate omap1_rate_table[]; 27extern struct mpu_rate omap1_rate_table[];
diff --git a/arch/arm/mach-omap1/opp_data.c b/arch/arm/mach-omap1/opp_data.c
index 75a54651499..9cd4ddb5139 100644
--- a/arch/arm/mach-omap1/opp_data.c
+++ b/arch/arm/mach-omap1/opp_data.c
@@ -10,6 +10,7 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <plat/clkdev_omap.h>
13#include "opp.h" 14#include "opp.h"
14 15
15/*------------------------------------------------------------------------- 16/*-------------------------------------------------------------------------
@@ -20,40 +21,34 @@ struct mpu_rate omap1_rate_table[] = {
20 * NOTE: Comment order here is different from bits in CKCTL value: 21 * NOTE: Comment order here is different from bits in CKCTL value:
21 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv 22 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
22 */ 23 */
23#if defined(CONFIG_OMAP_ARM_216MHZ) 24 { 216000000, 12000000, 216000000, 0x050d, 0x2910, /* 1/1/2/2/2/8 */
24 { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ 25 CK_1710 },
25#endif 26 { 195000000, 13000000, 195000000, 0x050e, 0x2790, /* 1/1/2/2/4/8 */
26#if defined(CONFIG_OMAP_ARM_195MHZ) 27 CK_7XX },
27 { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ 28 { 192000000, 19200000, 192000000, 0x050f, 0x2510, /* 1/1/2/2/8/8 */
28#endif 29 CK_16XX },
29#if defined(CONFIG_OMAP_ARM_192MHZ) 30 { 192000000, 12000000, 192000000, 0x050f, 0x2810, /* 1/1/2/2/8/8 */
30 { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */ 31 CK_16XX },
31 { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */ 32 { 96000000, 12000000, 192000000, 0x055f, 0x2810, /* 2/2/2/2/8/8 */
32 { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */ 33 CK_16XX },
33 { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */ 34 { 48000000, 12000000, 192000000, 0x0baf, 0x2810, /* 4/4/4/8/8/8 */
34 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */ 35 CK_16XX },
35#endif 36 { 24000000, 12000000, 192000000, 0x0fff, 0x2810, /* 8/8/8/8/8/8 */
36#if defined(CONFIG_OMAP_ARM_182MHZ) 37 CK_16XX },
37 { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */ 38 { 182000000, 13000000, 182000000, 0x050e, 0x2710, /* 1/1/2/2/4/8 */
38#endif 39 CK_7XX },
39#if defined(CONFIG_OMAP_ARM_168MHZ) 40 { 168000000, 12000000, 168000000, 0x010f, 0x2710, /* 1/1/1/2/8/8 */
40 { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */ 41 CK_16XX|CK_7XX },
41#endif 42 { 150000000, 12000000, 150000000, 0x010a, 0x2cb0, /* 1/1/1/2/4/4 */
42#if defined(CONFIG_OMAP_ARM_150MHZ) 43 CK_1510 },
43 { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */ 44 { 120000000, 12000000, 120000000, 0x010a, 0x2510, /* 1/1/1/2/4/4 */
44#endif 45 CK_16XX|CK_1510|CK_310|CK_7XX },
45#if defined(CONFIG_OMAP_ARM_120MHZ) 46 { 96000000, 12000000, 96000000, 0x0005, 0x2410, /* 1/1/1/1/2/2 */
46 { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */ 47 CK_16XX|CK_1510|CK_310|CK_7XX },
47#endif 48 { 60000000, 12000000, 60000000, 0x0005, 0x2290, /* 1/1/1/1/2/2 */
48#if defined(CONFIG_OMAP_ARM_96MHZ) 49 CK_16XX|CK_1510|CK_310|CK_7XX },
49 { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */ 50 { 30000000, 12000000, 60000000, 0x0555, 0x2290, /* 2/2/2/2/2/2 */
50#endif 51 CK_16XX|CK_1510|CK_310|CK_7XX },
51#if defined(CONFIG_OMAP_ARM_60MHZ)
52 { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
53#endif
54#if defined(CONFIG_OMAP_ARM_30MHZ)
55 { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
56#endif
57 { 0, 0, 0, 0, 0 }, 52 { 0, 0, 0, 0, 0 },
58}; 53};
59 54
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 4f01533083c..904bd1dfcd2 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -78,8 +78,13 @@ config SOC_OMAP3430
78 default y 78 default y
79 select ARCH_OMAP_OTG 79 select ARCH_OMAP_OTG
80 80
81config SOC_OMAPTI816X 81config SOC_OMAPTI81XX
82 bool "TI816X support" 82 bool "TI81XX support"
83 depends on ARCH_OMAP3
84 default y
85
86config SOC_OMAPAM33XX
87 bool "AM33XX support"
83 depends on ARCH_OMAP3 88 depends on ARCH_OMAP3
84 default y 89 default y
85 90
@@ -316,7 +321,12 @@ config MACH_OMAP_3630SDP
316 321
317config MACH_TI8168EVM 322config MACH_TI8168EVM
318 bool "TI8168 Evaluation Module" 323 bool "TI8168 Evaluation Module"
319 depends on SOC_OMAPTI816X 324 depends on SOC_OMAPTI81XX
325 default y
326
327config MACH_TI8148EVM
328 bool "TI8148 Evaluation Module"
329 depends on SOC_OMAPTI81XX
320 default y 330 default y
321 331
322config MACH_OMAP_4430SDP 332config MACH_OMAP_4430SDP
@@ -355,6 +365,27 @@ config OMAP3_SDRC_AC_TIMING
355 wish to say no. Selecting yes without understanding what is 365 wish to say no. Selecting yes without understanding what is
356 going on could result in system crashes; 366 going on could result in system crashes;
357 367
368config OMAP4_ERRATA_I688
369 bool "OMAP4 errata: Async Bridge Corruption"
370 depends on ARCH_OMAP4
371 select ARCH_HAS_BARRIERS
372 help
373 If a data is stalled inside asynchronous bridge because of back
374 pressure, it may be accepted multiple times, creating pointer
375 misalignment that will corrupt next transfers on that data path
376 until next reset of the system (No recovery procedure once the
377 issue is hit, the path remains consistently broken). Async bridge
378 can be found on path between MPU to EMIF and MPU to L3 interconnect.
379 This situation can happen only when the idle is initiated by a
380 Master Request Disconnection (which is trigged by software when
381 executing WFI on CPU).
382 The work-around for this errata needs all the initiators connected
383 through async bridge must ensure that data path is properly drained
384 before issuing WFI. This condition will be met if one Strongly ordered
385 access is performed to the target right before executing the WFI.
386 In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
387 IO barrier ensure that there is no synchronisation loss on initiators
388 operating on both interconnect port simultaneously.
358endmenu 389endmenu
359 390
360endif 391endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b009f17dee5..fc9b238cbc1 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -11,10 +11,11 @@ hwmod-common = omap_hwmod.o \
11 omap_hwmod_common_data.o 11 omap_hwmod_common_data.o
12clock-common = clock.o clock_common_data.o \ 12clock-common = clock.o clock_common_data.o \
13 clkt_dpll.o clkt_clksel.o 13 clkt_dpll.o clkt_clksel.o
14secure-common = omap-smc.o omap-secure.o
14 15
15obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) 16obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
16obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) 17obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
17obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) 18obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
18 19
19obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
20 21
@@ -24,11 +25,13 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
24obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 25obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
25obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o 26obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
26obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o 27obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
27obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o 28obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
29 sleep44xx.o
28 30
29plus_sec := $(call as-instr,.arch_extension sec,+sec) 31plus_sec := $(call as-instr,.arch_extension sec,+sec)
30AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) 32AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
31AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) 33AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec)
34AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec)
32 35
33# Functions loaded to SRAM 36# Functions loaded to SRAM
34obj-$(CONFIG_SOC_OMAP2420) += sram242x.o 37obj-$(CONFIG_SOC_OMAP2420) += sram242x.o
@@ -62,7 +65,8 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
62obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o 65obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
63obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ 66obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
64 cpuidle34xx.o 67 cpuidle34xx.o
65obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o 68obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \
69 cpuidle44xx.o
66obj-$(CONFIG_PM_DEBUG) += pm-debug.o 70obj-$(CONFIG_PM_DEBUG) += pm-debug.o
67obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o 71obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
68obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o 72obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
@@ -77,6 +81,7 @@ endif
77endif 81endif
78 82
79# PRCM 83# PRCM
84obj-y += prm_common.o
80obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o 85obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
81obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ 86obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
82 vc3xxx_data.o vp3xxx_data.o 87 vc3xxx_data.o vp3xxx_data.o
@@ -86,7 +91,7 @@ obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
86obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \ 91obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
87 cm44xx.o prcm_mpu44xx.o \ 92 cm44xx.o prcm_mpu44xx.o \
88 prminst44xx.o vc44xx_data.o \ 93 prminst44xx.o vc44xx_data.o \
89 vp44xx_data.o 94 vp44xx_data.o prm44xx.o
90 95
91# OMAP voltage domains 96# OMAP voltage domains
92voltagedomain-common := voltage.o vc.o vp.o 97voltagedomain-common := voltage.o vc.o vp.o
@@ -232,6 +237,7 @@ obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
232 237
233obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o 238obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
234obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o 239obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o
240obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o
235 241
236# Platform specific device init code 242# Platform specific device init code
237 243
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9996334cb68..383717ba63b 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -475,106 +475,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
475static struct omap_board_mux board_mux[] __initdata = { 475static struct omap_board_mux board_mux[] __initdata = {
476 { .reg_offset = OMAP_MUX_TERMINATOR }, 476 { .reg_offset = OMAP_MUX_TERMINATOR },
477}; 477};
478
479static struct omap_device_pad serial1_pads[] __initdata = {
480 /*
481 * Note that off output enable is an active low
482 * signal. So setting this means pin is a
483 * input enabled in off mode
484 */
485 OMAP_MUX_STATIC("uart1_cts.uart1_cts",
486 OMAP_PIN_INPUT |
487 OMAP_PIN_OFF_INPUT_PULLDOWN |
488 OMAP_OFFOUT_EN |
489 OMAP_MUX_MODE0),
490 OMAP_MUX_STATIC("uart1_rts.uart1_rts",
491 OMAP_PIN_OUTPUT |
492 OMAP_OFF_EN |
493 OMAP_MUX_MODE0),
494 OMAP_MUX_STATIC("uart1_rx.uart1_rx",
495 OMAP_PIN_INPUT |
496 OMAP_PIN_OFF_INPUT_PULLDOWN |
497 OMAP_OFFOUT_EN |
498 OMAP_MUX_MODE0),
499 OMAP_MUX_STATIC("uart1_tx.uart1_tx",
500 OMAP_PIN_OUTPUT |
501 OMAP_OFF_EN |
502 OMAP_MUX_MODE0),
503};
504
505static struct omap_device_pad serial2_pads[] __initdata = {
506 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
507 OMAP_PIN_INPUT_PULLUP |
508 OMAP_PIN_OFF_INPUT_PULLDOWN |
509 OMAP_OFFOUT_EN |
510 OMAP_MUX_MODE0),
511 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
512 OMAP_PIN_OUTPUT |
513 OMAP_OFF_EN |
514 OMAP_MUX_MODE0),
515 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
516 OMAP_PIN_INPUT |
517 OMAP_PIN_OFF_INPUT_PULLDOWN |
518 OMAP_OFFOUT_EN |
519 OMAP_MUX_MODE0),
520 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
521 OMAP_PIN_OUTPUT |
522 OMAP_OFF_EN |
523 OMAP_MUX_MODE0),
524};
525
526static struct omap_device_pad serial3_pads[] __initdata = {
527 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
528 OMAP_PIN_INPUT_PULLDOWN |
529 OMAP_PIN_OFF_INPUT_PULLDOWN |
530 OMAP_OFFOUT_EN |
531 OMAP_MUX_MODE0),
532 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
533 OMAP_PIN_OUTPUT |
534 OMAP_OFF_EN |
535 OMAP_MUX_MODE0),
536 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
537 OMAP_PIN_INPUT |
538 OMAP_PIN_OFF_INPUT_PULLDOWN |
539 OMAP_OFFOUT_EN |
540 OMAP_MUX_MODE0),
541 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
542 OMAP_PIN_OUTPUT |
543 OMAP_OFF_EN |
544 OMAP_MUX_MODE0),
545};
546
547static struct omap_board_data serial1_data __initdata = {
548 .id = 0,
549 .pads = serial1_pads,
550 .pads_cnt = ARRAY_SIZE(serial1_pads),
551};
552
553static struct omap_board_data serial2_data __initdata = {
554 .id = 1,
555 .pads = serial2_pads,
556 .pads_cnt = ARRAY_SIZE(serial2_pads),
557};
558
559static struct omap_board_data serial3_data __initdata = {
560 .id = 2,
561 .pads = serial3_pads,
562 .pads_cnt = ARRAY_SIZE(serial3_pads),
563};
564
565static inline void board_serial_init(void)
566{
567 omap_serial_init_port(&serial1_data);
568 omap_serial_init_port(&serial2_data);
569 omap_serial_init_port(&serial3_data);
570}
571#else 478#else
572#define board_mux NULL 479#define board_mux NULL
573
574static inline void board_serial_init(void)
575{
576 omap_serial_init();
577}
578#endif 480#endif
579 481
580/* 482/*
@@ -711,7 +613,7 @@ static void __init omap_3430sdp_init(void)
711 else 613 else
712 gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; 614 gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
713 omap_ads7846_init(1, gpio_pendown, 310, NULL); 615 omap_ads7846_init(1, gpio_pendown, 310, NULL);
714 board_serial_init(); 616 omap_serial_init();
715 omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); 617 omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
716 usb_musb_init(NULL); 618 usb_musb_init(NULL);
717 board_smc91x_init(); 619 board_smc91x_init();
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index bad5d5a5ef7..2ceb75d21eb 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -372,11 +372,17 @@ static struct platform_device sdp4430_vbat = {
372 }, 372 },
373}; 373};
374 374
375static struct platform_device sdp4430_dmic_codec = {
376 .name = "dmic-codec",
377 .id = -1,
378};
379
375static struct platform_device *sdp4430_devices[] __initdata = { 380static struct platform_device *sdp4430_devices[] __initdata = {
376 &sdp4430_gpio_keys_device, 381 &sdp4430_gpio_keys_device,
377 &sdp4430_leds_gpio, 382 &sdp4430_leds_gpio,
378 &sdp4430_leds_pwm, 383 &sdp4430_leds_pwm,
379 &sdp4430_vbat, 384 &sdp4430_vbat,
385 &sdp4430_dmic_codec,
380}; 386};
381 387
382static struct omap_musb_board_data musb_board_data = { 388static struct omap_musb_board_data musb_board_data = {
@@ -404,6 +410,7 @@ static struct omap2_hsmmc_info mmc[] = {
404 { 410 {
405 .mmc = 5, 411 .mmc = 5,
406 .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, 412 .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
413 .pm_caps = MMC_PM_KEEP_POWER,
407 .gpio_cd = -EINVAL, 414 .gpio_cd = -EINVAL,
408 .gpio_wp = -EINVAL, 415 .gpio_wp = -EINVAL,
409 .ocr_mask = MMC_VDD_165_195, 416 .ocr_mask = MMC_VDD_165_195,
@@ -837,74 +844,8 @@ static struct omap_board_mux board_mux[] __initdata = {
837 { .reg_offset = OMAP_MUX_TERMINATOR }, 844 { .reg_offset = OMAP_MUX_TERMINATOR },
838}; 845};
839 846
840static struct omap_device_pad serial2_pads[] __initdata = {
841 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
842 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
843 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
844 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
845 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
846 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
847 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
848 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
849};
850
851static struct omap_device_pad serial3_pads[] __initdata = {
852 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
853 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
854 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
855 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
856 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
857 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
858 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
859 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
860};
861
862static struct omap_device_pad serial4_pads[] __initdata = {
863 OMAP_MUX_STATIC("uart4_rx.uart4_rx",
864 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
865 OMAP_MUX_STATIC("uart4_tx.uart4_tx",
866 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
867};
868
869static struct omap_board_data serial2_data __initdata = {
870 .id = 1,
871 .pads = serial2_pads,
872 .pads_cnt = ARRAY_SIZE(serial2_pads),
873};
874
875static struct omap_board_data serial3_data __initdata = {
876 .id = 2,
877 .pads = serial3_pads,
878 .pads_cnt = ARRAY_SIZE(serial3_pads),
879};
880
881static struct omap_board_data serial4_data __initdata = {
882 .id = 3,
883 .pads = serial4_pads,
884 .pads_cnt = ARRAY_SIZE(serial4_pads),
885};
886
887static inline void board_serial_init(void)
888{
889 struct omap_board_data bdata;
890 bdata.flags = 0;
891 bdata.pads = NULL;
892 bdata.pads_cnt = 0;
893 bdata.id = 0;
894 /* pass dummy data for UART1 */
895 omap_serial_init_port(&bdata);
896
897 omap_serial_init_port(&serial2_data);
898 omap_serial_init_port(&serial3_data);
899 omap_serial_init_port(&serial4_data);
900}
901#else 847#else
902#define board_mux NULL 848#define board_mux NULL
903
904static inline void board_serial_init(void)
905{
906 omap_serial_init();
907}
908 #endif 849 #endif
909 850
910static void omap4_sdp4430_wifi_mux_init(void) 851static void omap4_sdp4430_wifi_mux_init(void)
@@ -954,7 +895,7 @@ static void __init omap_4430sdp_init(void)
954 omap4_i2c_init(); 895 omap4_i2c_init();
955 omap_sfh7741prox_init(); 896 omap_sfh7741prox_init();
956 platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); 897 platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
957 board_serial_init(); 898 omap_serial_init();
958 omap_sdrc_init(NULL, NULL); 899 omap_sdrc_init(NULL, NULL);
959 omap4_sdp4430_wifi_init(); 900 omap4_sdp4430_wifi_init();
960 omap4_twl6030_hsmmc_init(mmc); 901 omap4_twl6030_hsmmc_init(mmc);
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index f5a3a3f1173..4b1cfe32e6b 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -24,6 +24,7 @@
24#include <linux/i2c/pca953x.h> 24#include <linux/i2c/pca953x.h>
25#include <linux/can/platform/ti_hecc.h> 25#include <linux/can/platform/ti_hecc.h>
26#include <linux/davinci_emac.h> 26#include <linux/davinci_emac.h>
27#include <linux/mmc/host.h>
27 28
28#include <mach/hardware.h> 29#include <mach/hardware.h>
29#include <mach/am35xx.h> 30#include <mach/am35xx.h>
@@ -40,6 +41,7 @@
40 41
41#include "mux.h" 42#include "mux.h"
42#include "control.h" 43#include "control.h"
44#include "hsmmc.h"
43 45
44#define AM35XX_EVM_MDIO_FREQUENCY (1000000) 46#define AM35XX_EVM_MDIO_FREQUENCY (1000000)
45 47
@@ -455,6 +457,23 @@ static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
455static struct omap_board_config_kernel am3517_evm_config[] __initdata = { 457static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
456}; 458};
457 459
460static struct omap2_hsmmc_info mmc[] = {
461 {
462 .mmc = 1,
463 .caps = MMC_CAP_4_BIT_DATA,
464 .gpio_cd = 127,
465 .gpio_wp = 126,
466 },
467 {
468 .mmc = 2,
469 .caps = MMC_CAP_4_BIT_DATA,
470 .gpio_cd = 128,
471 .gpio_wp = 129,
472 },
473 {} /* Terminator */
474};
475
476
458static void __init am3517_evm_init(void) 477static void __init am3517_evm_init(void)
459{ 478{
460 omap_board_config = am3517_evm_config; 479 omap_board_config = am3517_evm_config;
@@ -483,6 +502,9 @@ static void __init am3517_evm_init(void)
483 502
484 /* MUSB */ 503 /* MUSB */
485 am3517_evm_musb_init(); 504 am3517_evm_musb_init();
505
506 /* MMC init function */
507 omap2_hsmmc_init(mmc);
486} 508}
487 509
488MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") 510MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 1545102d1f9..e921e3be24a 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -53,7 +53,8 @@
53#include "hsmmc.h" 53#include "hsmmc.h"
54#include "common-board-devices.h" 54#include "common-board-devices.h"
55 55
56#define CM_T35_GPIO_PENDOWN 57 56#define CM_T35_GPIO_PENDOWN 57
57#define SB_T35_USB_HUB_RESET_GPIO 167
57 58
58#define CM_T35_SMSC911X_CS 5 59#define CM_T35_SMSC911X_CS 5
59#define CM_T35_SMSC911X_GPIO 163 60#define CM_T35_SMSC911X_GPIO 163
@@ -339,8 +340,10 @@ static struct regulator_consumer_supply cm_t35_vsim_supply[] = {
339 REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), 340 REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
340}; 341};
341 342
342static struct regulator_consumer_supply cm_t35_vdvi_supply[] = { 343static struct regulator_consumer_supply cm_t35_vio_supplies[] = {
343 REGULATOR_SUPPLY("vdvi", "omapdss"), 344 REGULATOR_SUPPLY("vcc", "spi1.0"),
345 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
346 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
344}; 347};
345 348
346/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ 349/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
@@ -373,6 +376,19 @@ static struct regulator_init_data cm_t35_vsim = {
373 .consumer_supplies = cm_t35_vsim_supply, 376 .consumer_supplies = cm_t35_vsim_supply,
374}; 377};
375 378
379static struct regulator_init_data cm_t35_vio = {
380 .constraints = {
381 .min_uV = 1800000,
382 .max_uV = 1800000,
383 .apply_uV = true,
384 .valid_modes_mask = REGULATOR_MODE_NORMAL
385 | REGULATOR_MODE_STANDBY,
386 .valid_ops_mask = REGULATOR_CHANGE_MODE,
387 },
388 .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies),
389 .consumer_supplies = cm_t35_vio_supplies,
390};
391
376static uint32_t cm_t35_keymap[] = { 392static uint32_t cm_t35_keymap[] = {
377 KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT), 393 KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT),
378 KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN), 394 KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN),
@@ -421,6 +437,23 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata = {
421 .reset_gpio_port[2] = -EINVAL 437 .reset_gpio_port[2] = -EINVAL
422}; 438};
423 439
440static void cm_t35_init_usbh(void)
441{
442 int err;
443
444 err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO,
445 GPIOF_OUT_INIT_LOW, "usb hub rst");
446 if (err) {
447 pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err);
448 } else {
449 udelay(10);
450 gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1);
451 msleep(1);
452 }
453
454 usbhs_init(&usbhs_bdata);
455}
456
424static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, 457static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
425 unsigned ngpio) 458 unsigned ngpio)
426{ 459{
@@ -456,17 +489,14 @@ static struct twl4030_platform_data cm_t35_twldata = {
456 .gpio = &cm_t35_gpio_data, 489 .gpio = &cm_t35_gpio_data,
457 .vmmc1 = &cm_t35_vmmc1, 490 .vmmc1 = &cm_t35_vmmc1,
458 .vsim = &cm_t35_vsim, 491 .vsim = &cm_t35_vsim,
492 .vio = &cm_t35_vio,
459}; 493};
460 494
461static void __init cm_t35_init_i2c(void) 495static void __init cm_t35_init_i2c(void)
462{ 496{
463 omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, 497 omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB,
464 TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); 498 TWL_COMMON_REGULATOR_VDAC |
465 499 TWL_COMMON_PDATA_AUDIO);
466 cm_t35_twldata.vpll2->constraints.name = "VDVI";
467 cm_t35_twldata.vpll2->num_consumer_supplies =
468 ARRAY_SIZE(cm_t35_vdvi_supply);
469 cm_t35_twldata.vpll2->consumer_supplies = cm_t35_vdvi_supply;
470 500
471 omap3_pmic_init("tps65930", &cm_t35_twldata); 501 omap3_pmic_init("tps65930", &cm_t35_twldata);
472} 502}
@@ -570,24 +600,28 @@ static void __init cm_t3x_common_dss_mux_init(int mux_mode)
570 600
571static void __init cm_t35_init_mux(void) 601static void __init cm_t35_init_mux(void)
572{ 602{
573 omap_mux_init_signal("gpio_70", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 603 int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT;
574 omap_mux_init_signal("gpio_71", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 604
575 omap_mux_init_signal("gpio_72", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 605 omap_mux_init_signal("dss_data0.dss_data0", mux_mode);
576 omap_mux_init_signal("gpio_73", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 606 omap_mux_init_signal("dss_data1.dss_data1", mux_mode);
577 omap_mux_init_signal("gpio_74", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 607 omap_mux_init_signal("dss_data2.dss_data2", mux_mode);
578 omap_mux_init_signal("gpio_75", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 608 omap_mux_init_signal("dss_data3.dss_data3", mux_mode);
579 cm_t3x_common_dss_mux_init(OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); 609 omap_mux_init_signal("dss_data4.dss_data4", mux_mode);
610 omap_mux_init_signal("dss_data5.dss_data5", mux_mode);
611 cm_t3x_common_dss_mux_init(mux_mode);
580} 612}
581 613
582static void __init cm_t3730_init_mux(void) 614static void __init cm_t3730_init_mux(void)
583{ 615{
584 omap_mux_init_signal("sys_boot0", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 616 int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT;
585 omap_mux_init_signal("sys_boot1", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 617
586 omap_mux_init_signal("sys_boot3", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 618 omap_mux_init_signal("sys_boot0", mux_mode);
587 omap_mux_init_signal("sys_boot4", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 619 omap_mux_init_signal("sys_boot1", mux_mode);
588 omap_mux_init_signal("sys_boot5", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 620 omap_mux_init_signal("sys_boot3", mux_mode);
589 omap_mux_init_signal("sys_boot6", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 621 omap_mux_init_signal("sys_boot4", mux_mode);
590 cm_t3x_common_dss_mux_init(OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); 622 omap_mux_init_signal("sys_boot5", mux_mode);
623 omap_mux_init_signal("sys_boot6", mux_mode);
624 cm_t3x_common_dss_mux_init(mux_mode);
591} 625}
592#else 626#else
593static inline void cm_t35_init_mux(void) {} 627static inline void cm_t35_init_mux(void) {}
@@ -612,7 +646,7 @@ static void __init cm_t3x_common_init(void)
612 cm_t35_init_display(); 646 cm_t35_init_display();
613 647
614 usb_musb_init(NULL); 648 usb_musb_init(NULL);
615 usbhs_init(&usbhs_bdata); 649 cm_t35_init_usbh();
616} 650}
617 651
618static void __init cm_t35_init(void) 652static void __init cm_t35_init(void)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index f8c5b2cc7c9..d5875606048 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -69,7 +69,6 @@ static void __init omap_generic_init(void)
69 if (node) 69 if (node)
70 irq_domain_add_simple(node, 0); 70 irq_domain_add_simple(node, 0);
71 71
72 omap_serial_init();
73 omap_sdrc_init(NULL, NULL); 72 omap_sdrc_init(NULL, NULL);
74 73
75 of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); 74 of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index cef2cf1c0b8..42a4d11fad2 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -46,7 +46,7 @@ static struct device *mmc_device;
46#define TUSB6010_GPIO_ENABLE 0 46#define TUSB6010_GPIO_ENABLE 0
47#define TUSB6010_DMACHAN 0x3f 47#define TUSB6010_DMACHAN 0x3f
48 48
49#ifdef CONFIG_USB_MUSB_TUSB6010 49#if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE)
50/* 50/*
51 * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and 51 * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
52 * 1.5 V voltage regulators of PM companion chip. Companion chip will then 52 * 1.5 V voltage regulators of PM companion chip. Companion chip will then
@@ -644,15 +644,15 @@ static inline void board_serial_init(void)
644 bdata.pads_cnt = 0; 644 bdata.pads_cnt = 0;
645 645
646 bdata.id = 0; 646 bdata.id = 0;
647 omap_serial_init_port(&bdata); 647 omap_serial_init_port(&bdata, NULL);
648 648
649 bdata.id = 1; 649 bdata.id = 1;
650 omap_serial_init_port(&bdata); 650 omap_serial_init_port(&bdata, NULL);
651 651
652 bdata.id = 2; 652 bdata.id = 2;
653 bdata.pads = serial2_pads; 653 bdata.pads = serial2_pads;
654 bdata.pads_cnt = ARRAY_SIZE(serial2_pads); 654 bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
655 omap_serial_init_port(&bdata); 655 omap_serial_init_port(&bdata, NULL);
656} 656}
657 657
658#else 658#else
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 8b06c6a60d0..e96a2e7ad36 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -364,74 +364,8 @@ static struct omap_board_mux board_mux[] __initdata = {
364 { .reg_offset = OMAP_MUX_TERMINATOR }, 364 { .reg_offset = OMAP_MUX_TERMINATOR },
365}; 365};
366 366
367static struct omap_device_pad serial2_pads[] __initdata = {
368 OMAP_MUX_STATIC("uart2_cts.uart2_cts",
369 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
370 OMAP_MUX_STATIC("uart2_rts.uart2_rts",
371 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
372 OMAP_MUX_STATIC("uart2_rx.uart2_rx",
373 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
374 OMAP_MUX_STATIC("uart2_tx.uart2_tx",
375 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
376};
377
378static struct omap_device_pad serial3_pads[] __initdata = {
379 OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
380 OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
381 OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
382 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
383 OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
384 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
385 OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
386 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
387};
388
389static struct omap_device_pad serial4_pads[] __initdata = {
390 OMAP_MUX_STATIC("uart4_rx.uart4_rx",
391 OMAP_PIN_INPUT | OMAP_MUX_MODE0),
392 OMAP_MUX_STATIC("uart4_tx.uart4_tx",
393 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
394};
395
396static struct omap_board_data serial2_data __initdata = {
397 .id = 1,
398 .pads = serial2_pads,
399 .pads_cnt = ARRAY_SIZE(serial2_pads),
400};
401
402static struct omap_board_data serial3_data __initdata = {
403 .id = 2,
404 .pads = serial3_pads,
405 .pads_cnt = ARRAY_SIZE(serial3_pads),
406};
407
408static struct omap_board_data serial4_data __initdata = {
409 .id = 3,
410 .pads = serial4_pads,
411 .pads_cnt = ARRAY_SIZE(serial4_pads),
412};
413
414static inline void board_serial_init(void)
415{
416 struct omap_board_data bdata;
417 bdata.flags = 0;
418 bdata.pads = NULL;
419 bdata.pads_cnt = 0;
420 bdata.id = 0;
421 /* pass dummy data for UART1 */
422 omap_serial_init_port(&bdata);
423
424 omap_serial_init_port(&serial2_data);
425 omap_serial_init_port(&serial3_data);
426 omap_serial_init_port(&serial4_data);
427}
428#else 367#else
429#define board_mux NULL 368#define board_mux NULL
430
431static inline void board_serial_init(void)
432{
433 omap_serial_init();
434}
435#endif 369#endif
436 370
437/* Display DVI */ 371/* Display DVI */
@@ -562,7 +496,7 @@ static void __init omap4_panda_init(void)
562 omap4_panda_i2c_init(); 496 omap4_panda_i2c_init();
563 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); 497 platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
564 platform_device_register(&omap_vwlan_device); 498 platform_device_register(&omap_vwlan_device);
565 board_serial_init(); 499 omap_serial_init();
566 omap_sdrc_init(NULL, NULL); 500 omap_sdrc_init(NULL, NULL);
567 omap4_twl6030_hsmmc_init(mmc); 501 omap4_twl6030_hsmmc_init(mmc);
568 omap4_ehci_init(); 502 omap4_ehci_init();
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 108fee6146f..d67bcdf724d 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -15,6 +15,7 @@
15#include <linux/input/matrix_keypad.h> 15#include <linux/input/matrix_keypad.h>
16#include <linux/spi/spi.h> 16#include <linux/spi/spi.h>
17#include <linux/wl12xx.h> 17#include <linux/wl12xx.h>
18#include <linux/spi/tsc2005.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
19#include <linux/i2c/twl.h> 20#include <linux/i2c/twl.h>
20#include <linux/clk.h> 21#include <linux/clk.h>
@@ -58,6 +59,9 @@
58 59
59#define RX51_USB_TRANSCEIVER_RST_GPIO 67 60#define RX51_USB_TRANSCEIVER_RST_GPIO 67
60 61
62#define RX51_TSC2005_RESET_GPIO 104
63#define RX51_TSC2005_IRQ_GPIO 100
64
61/* list all spi devices here */ 65/* list all spi devices here */
62enum { 66enum {
63 RX51_SPI_WL1251, 67 RX51_SPI_WL1251,
@@ -66,6 +70,7 @@ enum {
66}; 70};
67 71
68static struct wl12xx_platform_data wl1251_pdata; 72static struct wl12xx_platform_data wl1251_pdata;
73static struct tsc2005_platform_data tsc2005_pdata;
69 74
70#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) 75#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
71static struct tsl2563_platform_data rx51_tsl2563_platform_data = { 76static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
@@ -167,10 +172,10 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
167 .modalias = "tsc2005", 172 .modalias = "tsc2005",
168 .bus_num = 1, 173 .bus_num = 1,
169 .chip_select = 0, 174 .chip_select = 0,
170 /* .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),*/ 175 .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),
171 .max_speed_hz = 6000000, 176 .max_speed_hz = 6000000,
172 .controller_data = &tsc2005_mcspi_config, 177 .controller_data = &tsc2005_mcspi_config,
173 /* .platform_data = &tsc2005_config,*/ 178 .platform_data = &tsc2005_pdata,
174 }, 179 },
175}; 180};
176 181
@@ -1086,6 +1091,42 @@ error:
1086 */ 1091 */
1087} 1092}
1088 1093
1094static struct tsc2005_platform_data tsc2005_pdata = {
1095 .ts_pressure_max = 2048,
1096 .ts_pressure_fudge = 2,
1097 .ts_x_max = 4096,
1098 .ts_x_fudge = 4,
1099 .ts_y_max = 4096,
1100 .ts_y_fudge = 7,
1101 .ts_x_plate_ohm = 280,
1102 .esd_timeout_ms = 8000,
1103};
1104
1105static void rx51_tsc2005_set_reset(bool enable)
1106{
1107 gpio_set_value(RX51_TSC2005_RESET_GPIO, enable);
1108}
1109
1110static void __init rx51_init_tsc2005(void)
1111{
1112 int r;
1113
1114 r = gpio_request_one(RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ");
1115 if (r < 0) {
1116 printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 IRQ");
1117 rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = 0;
1118 }
1119
1120 r = gpio_request_one(RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
1121 "tsc2005 reset");
1122 if (r >= 0) {
1123 tsc2005_pdata.set_reset = rx51_tsc2005_set_reset;
1124 } else {
1125 printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 reset");
1126 tsc2005_pdata.esd_timeout_ms = 0;
1127 }
1128}
1129
1089void __init rx51_peripherals_init(void) 1130void __init rx51_peripherals_init(void)
1090{ 1131{
1091 rx51_i2c_init(); 1132 rx51_i2c_init();
@@ -1094,6 +1135,7 @@ void __init rx51_peripherals_init(void)
1094 board_smc91x_init(); 1135 board_smc91x_init();
1095 rx51_add_gpio_keys(); 1136 rx51_add_gpio_keys();
1096 rx51_init_wl1251(); 1137 rx51_init_wl1251();
1138 rx51_init_tsc2005();
1097 rx51_init_si4713(); 1139 rx51_init_si4713();
1098 spi_register_board_info(rx51_peripherals_spi_board_info, 1140 spi_register_board_info(rx51_peripherals_spi_board_info,
1099 ARRAY_SIZE(rx51_peripherals_spi_board_info)); 1141 ARRAY_SIZE(rx51_peripherals_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index 74713e3993e..ab9a7a9e9d6 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Code for TI8168 EVM. 2 * Code for TI8168/TI8148 EVM.
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ 4 * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
5 * 5 *
@@ -23,30 +23,45 @@
23#include <plat/irqs.h> 23#include <plat/irqs.h>
24#include <plat/board.h> 24#include <plat/board.h>
25#include "common.h" 25#include "common.h"
26#include <plat/usb.h>
26 27
27static struct omap_board_config_kernel ti8168_evm_config[] __initdata = { 28static struct omap_musb_board_data musb_board_data = {
29 .set_phy_power = ti81xx_musb_phy_power,
30 .interface_type = MUSB_INTERFACE_ULPI,
31 .mode = MUSB_OTG,
32 .power = 500,
28}; 33};
29 34
30static void __init ti8168_evm_init(void) 35static struct omap_board_config_kernel ti81xx_evm_config[] __initdata = {
36};
37
38static void __init ti81xx_evm_init(void)
31{ 39{
32 omap_serial_init(); 40 omap_serial_init();
33 omap_sdrc_init(NULL, NULL); 41 omap_sdrc_init(NULL, NULL);
34 omap_board_config = ti8168_evm_config; 42 omap_board_config = ti81xx_evm_config;
35 omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); 43 omap_board_config_size = ARRAY_SIZE(ti81xx_evm_config);
36} 44 usb_musb_init(&musb_board_data);
37
38static void __init ti8168_evm_map_io(void)
39{
40 omapti816x_map_common_io();
41} 45}
42 46
43MACHINE_START(TI8168EVM, "ti8168evm") 47MACHINE_START(TI8168EVM, "ti8168evm")
44 /* Maintainer: Texas Instruments */ 48 /* Maintainer: Texas Instruments */
45 .atag_offset = 0x100, 49 .atag_offset = 0x100,
46 .map_io = ti8168_evm_map_io, 50 .map_io = ti81xx_map_io,
47 .init_early = ti816x_init_early, 51 .init_early = ti81xx_init_early,
48 .init_irq = ti816x_init_irq, 52 .init_irq = ti81xx_init_irq,
53 .timer = &omap3_timer,
54 .init_machine = ti81xx_evm_init,
55 .restart = omap_prcm_restart,
56MACHINE_END
57
58MACHINE_START(TI8148EVM, "ti8148evm")
59 /* Maintainer: Texas Instruments */
60 .atag_offset = 0x100,
61 .map_io = ti81xx_map_io,
62 .init_early = ti81xx_init_early,
63 .init_irq = ti81xx_init_irq,
49 .timer = &omap3_timer, 64 .timer = &omap3_timer,
50 .init_machine = ti8168_evm_init, 65 .init_machine = ti81xx_evm_init,
51 .restart = omap_prcm_restart, 66 .restart = omap_prcm_restart,
52MACHINE_END 67MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 1f3481f8d69..f57ed5baecc 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -35,7 +35,7 @@
35#include "cm-regbits-24xx.h" 35#include "cm-regbits-24xx.h"
36#include "cm-regbits-34xx.h" 36#include "cm-regbits-34xx.h"
37 37
38u8 cpu_mask; 38u16 cpu_mask;
39 39
40/* 40/*
41 * clkdm_control: if true, then when a clock is enabled in the 41 * clkdm_control: if true, then when a clock is enabled in the
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 2311bc21722..b8c2a686481 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -132,7 +132,7 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
132 const char *core_ck_name, 132 const char *core_ck_name,
133 const char *mpu_ck_name); 133 const char *mpu_ck_name);
134 134
135extern u8 cpu_mask; 135extern u16 cpu_mask;
136 136
137extern const struct clkops clkops_omap2_dflt_wait; 137extern const struct clkops clkops_omap2_dflt_wait;
138extern const struct clkops clkops_dummy; 138extern const struct clkops clkops_dummy;
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 5d0064a4fb5..d75e5f6b8a0 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -2480,6 +2480,16 @@ static struct clk uart4_fck = {
2480 .recalc = &followparent_recalc, 2480 .recalc = &followparent_recalc,
2481}; 2481};
2482 2482
2483static struct clk uart4_fck_am35xx = {
2484 .name = "uart4_fck",
2485 .ops = &clkops_omap2_dflt_wait,
2486 .parent = &per_48m_fck,
2487 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
2488 .enable_bit = OMAP3430_EN_UART4_SHIFT,
2489 .clkdm_name = "core_l4_clkdm",
2490 .recalc = &followparent_recalc,
2491};
2492
2483static struct clk gpt2_fck = { 2493static struct clk gpt2_fck = {
2484 .name = "gpt2_fck", 2494 .name = "gpt2_fck",
2485 .ops = &clkops_omap2_dflt_wait, 2495 .ops = &clkops_omap2_dflt_wait,
@@ -3287,7 +3297,7 @@ static struct omap_clk omap3xxx_clks[] = {
3287 CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3297 CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3288 CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3298 CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3289 CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3299 CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3290 CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3300 CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3291 CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), 3301 CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
3292 CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), 3302 CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
3293 CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), 3303 CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
@@ -3323,7 +3333,7 @@ static struct omap_clk omap3xxx_clks[] = {
3323 CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), 3333 CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX),
3324 CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), 3334 CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
3325 CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3335 CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3326 CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3336 CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3327 CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3337 CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3328 CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), 3338 CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
3329 CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), 3339 CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
@@ -3369,20 +3379,18 @@ static struct omap_clk omap3xxx_clks[] = {
3369 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), 3379 CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
3370 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), 3380 CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
3371 CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3381 CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3372 CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3373 CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3382 CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3374 CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3375 CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3383 CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3376 CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), 3384 CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
3377 CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), 3385 CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
3378 CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), 3386 CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
3379 CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), 3387 CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
3380 CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), 3388 CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
3381 CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), 3389 CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
3382 CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), 3390 CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
3383 CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), 3391 CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
3384 CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), 3392 CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
3385 CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX), 3393 CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX),
3386 CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), 3394 CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
3387 CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), 3395 CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
3388 CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), 3396 CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
@@ -3403,6 +3411,7 @@ static struct omap_clk omap3xxx_clks[] = {
3403 CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX), 3411 CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX),
3404 CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX), 3412 CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX),
3405 CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX), 3413 CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX),
3414 CLK(NULL, "uart4_fck", &uart4_fck_am35xx, CK_3505 | CK_3517),
3406 CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX), 3415 CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX),
3407 CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX), 3416 CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX),
3408 CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX), 3417 CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX),
@@ -3517,6 +3526,10 @@ int __init omap3xxx_clk_init(void)
3517 } else if (cpu_is_ti816x()) { 3526 } else if (cpu_is_ti816x()) {
3518 cpu_mask = RATE_IN_TI816X; 3527 cpu_mask = RATE_IN_TI816X;
3519 cpu_clkflg = CK_TI816X; 3528 cpu_clkflg = CK_TI816X;
3529 } else if (cpu_is_am33xx()) {
3530 cpu_mask = RATE_IN_AM33XX;
3531 } else if (cpu_is_ti814x()) {
3532 cpu_mask = RATE_IN_TI814X;
3520 } else if (cpu_is_omap34xx()) { 3533 } else if (cpu_is_omap34xx()) {
3521 if (omap_rev() == OMAP3430_REV_ES1_0) { 3534 if (omap_rev() == OMAP3430_REV_ES1_0) {
3522 cpu_mask = RATE_IN_3430ES1; 3535 cpu_mask = RATE_IN_3430ES1;
@@ -3600,7 +3613,7 @@ int __init omap3xxx_clk_init(void)
3600 * Lock DPLL5 -- here only until other device init code can 3613 * Lock DPLL5 -- here only until other device init code can
3601 * handle this 3614 * handle this
3602 */ 3615 */
3603 if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) 3616 if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
3604 omap3_clk_lock_dpll5(); 3617 omap3_clk_lock_dpll5();
3605 3618
3606 /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ 3619 /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 0798a802497..08e86d793a1 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -1206,6 +1206,14 @@ static const struct clksel ocp_abe_iclk_div[] = {
1206 { .parent = NULL }, 1206 { .parent = NULL },
1207}; 1207};
1208 1208
1209static struct clk mpu_periphclk = {
1210 .name = "mpu_periphclk",
1211 .parent = &dpll_mpu_ck,
1212 .ops = &clkops_null,
1213 .fixed_div = 2,
1214 .recalc = &omap_fixed_divisor_recalc,
1215};
1216
1209static struct clk ocp_abe_iclk = { 1217static struct clk ocp_abe_iclk = {
1210 .name = "ocp_abe_iclk", 1218 .name = "ocp_abe_iclk",
1211 .parent = &aess_fclk, 1219 .parent = &aess_fclk,
@@ -3189,6 +3197,7 @@ static struct omap_clk omap44xx_clks[] = {
3189 CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X), 3197 CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X),
3190 CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X), 3198 CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X),
3191 CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X), 3199 CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X),
3200 CLK("smp_twd", NULL, &mpu_periphclk, CK_443X),
3192 CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X), 3201 CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X),
3193 CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X), 3202 CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X),
3194 CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X), 3203 CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X),
@@ -3295,7 +3304,7 @@ static struct omap_clk omap44xx_clks[] = {
3295 CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), 3304 CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
3296 CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), 3305 CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
3297 CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), 3306 CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
3298 CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X), 3307 CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X),
3299 CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), 3308 CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
3300 CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), 3309 CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
3301 CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), 3310 CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
@@ -3306,7 +3315,7 @@ static struct omap_clk omap44xx_clks[] = {
3306 CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), 3315 CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
3307 CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), 3316 CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
3308 CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), 3317 CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
3309 CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X), 3318 CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X),
3310 CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), 3319 CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
3311 CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), 3320 CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
3312 CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), 3321 CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
@@ -3314,7 +3323,7 @@ static struct omap_clk omap44xx_clks[] = {
3314 CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X), 3323 CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
3315 CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), 3324 CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
3316 CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), 3325 CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
3317 CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X), 3326 CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
3318 CLK(NULL, "usim_ck", &usim_ck, CK_443X), 3327 CLK(NULL, "usim_ck", &usim_ck, CK_443X),
3319 CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), 3328 CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
3320 CLK(NULL, "usim_fck", &usim_fck, CK_443X), 3329 CLK(NULL, "usim_fck", &usim_fck, CK_443X),
@@ -3374,8 +3383,8 @@ static struct omap_clk omap44xx_clks[] = {
3374 CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), 3383 CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
3375 CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), 3384 CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
3376 CLK(NULL, "uart4_ick", &dummy_ck, CK_443X), 3385 CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
3377 CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X), 3386 CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X),
3378 CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X), 3387 CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X),
3379 CLK("omap_wdt", "ick", &dummy_ck, CK_443X), 3388 CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
3380 CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), 3389 CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X),
3381 CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), 3390 CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X),
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
index 684b8a7cd40..aaf421178c9 100644
--- a/arch/arm/mach-omap2/common.c
+++ b/arch/arm/mach-omap2/common.c
@@ -110,23 +110,49 @@ void __init omap3_map_io(void)
110 110
111/* 111/*
112 * Adjust TAP register base such that omap3_check_revision accesses the correct 112 * Adjust TAP register base such that omap3_check_revision accesses the correct
113 * TI816X register for checking device ID (it adds 0x204 to tap base while 113 * TI81XX register for checking device ID (it adds 0x204 to tap base while
114 * TI816X DEVICE ID register is at offset 0x600 from control base). 114 * TI81XX DEVICE ID register is at offset 0x600 from control base).
115 */ 115 */
116#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ 116#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \
117 TI816X_CONTROL_DEVICE_ID - 0x204) 117 TI81XX_CONTROL_DEVICE_ID - 0x204)
118 118
119static struct omap_globals ti816x_globals = { 119static struct omap_globals ti81xx_globals = {
120 .class = OMAP343X_CLASS, 120 .class = OMAP343X_CLASS,
121 .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), 121 .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE),
122 .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), 122 .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
123 .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), 123 .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
124 .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), 124 .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
125}; 125};
126 126
127void __init omap2_set_globals_ti816x(void) 127void __init omap2_set_globals_ti81xx(void)
128{ 128{
129 __omap2_set_globals(&ti816x_globals); 129 __omap2_set_globals(&ti81xx_globals);
130}
131
132void __init ti81xx_map_io(void)
133{
134 omapti81xx_map_common_io();
135}
136
137#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \
138 TI81XX_CONTROL_DEVICE_ID - 0x204)
139
140static struct omap_globals am33xx_globals = {
141 .class = AM335X_CLASS,
142 .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE),
143 .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
144 .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
145 .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
146};
147
148void __init omap2_set_globals_am33xx(void)
149{
150 __omap2_set_globals(&am33xx_globals);
151}
152
153void __init am33xx_map_io(void)
154{
155 omapam33xx_map_common_io();
130} 156}
131#endif 157#endif
132 158
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index cda888a2e63..febffde2ff1 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -24,9 +24,11 @@
24 24
25#ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H 25#ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H
26#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H 26#define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H
27#ifndef __ASSEMBLER__
27 28
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <plat/common.h> 30#include <plat/common.h>
31#include <asm/proc-fns.h>
30 32
31#ifdef CONFIG_SOC_OMAP2420 33#ifdef CONFIG_SOC_OMAP2420
32extern void omap242x_map_common_io(void); 34extern void omap242x_map_common_io(void);
@@ -52,10 +54,18 @@ static inline void omap34xx_map_common_io(void)
52} 54}
53#endif 55#endif
54 56
55#ifdef CONFIG_SOC_OMAPTI816X 57#ifdef CONFIG_SOC_OMAPTI81XX
56extern void omapti816x_map_common_io(void); 58extern void omapti81xx_map_common_io(void);
57#else 59#else
58static inline void omapti816x_map_common_io(void) 60static inline void omapti81xx_map_common_io(void)
61{
62}
63#endif
64
65#ifdef CONFIG_SOC_OMAPAM33XX
66extern void omapam33xx_map_common_io(void);
67#else
68static inline void omapam33xx_map_common_io(void)
59{ 69{
60} 70}
61#endif 71#endif
@@ -82,7 +92,7 @@ void omap35xx_init_early(void);
82void omap3630_init_early(void); 92void omap3630_init_early(void);
83void omap3_init_early(void); /* Do not use this one */ 93void omap3_init_early(void); /* Do not use this one */
84void am35xx_init_early(void); 94void am35xx_init_early(void);
85void ti816x_init_early(void); 95void ti81xx_init_early(void);
86void omap4430_init_early(void); 96void omap4430_init_early(void);
87void omap_prcm_restart(char, const char *); 97void omap_prcm_restart(char, const char *);
88 98
@@ -107,7 +117,8 @@ void omap2_set_globals_242x(void);
107void omap2_set_globals_243x(void); 117void omap2_set_globals_243x(void);
108void omap2_set_globals_3xxx(void); 118void omap2_set_globals_3xxx(void);
109void omap2_set_globals_443x(void); 119void omap2_set_globals_443x(void);
110void omap2_set_globals_ti816x(void); 120void omap2_set_globals_ti81xx(void);
121void omap2_set_globals_am33xx(void);
111 122
112/* These get called from omap2_set_globals_xxxx(), do not call these */ 123/* These get called from omap2_set_globals_xxxx(), do not call these */
113void omap2_set_globals_tap(struct omap_globals *); 124void omap2_set_globals_tap(struct omap_globals *);
@@ -118,7 +129,9 @@ void omap2_set_globals_prcm(struct omap_globals *);
118void omap242x_map_io(void); 129void omap242x_map_io(void);
119void omap243x_map_io(void); 130void omap243x_map_io(void);
120void omap3_map_io(void); 131void omap3_map_io(void);
132void am33xx_map_io(void);
121void omap4_map_io(void); 133void omap4_map_io(void);
134void ti81xx_map_io(void);
122 135
123/** 136/**
124 * omap_test_timeout - busy-loop, testing a condition 137 * omap_test_timeout - busy-loop, testing a condition
@@ -147,7 +160,7 @@ extern struct device *omap4_get_dsp_device(void);
147 160
148void omap2_init_irq(void); 161void omap2_init_irq(void);
149void omap3_init_irq(void); 162void omap3_init_irq(void);
150void ti816x_init_irq(void); 163void ti81xx_init_irq(void);
151extern int omap_irq_pending(void); 164extern int omap_irq_pending(void);
152void omap_intc_save_context(void); 165void omap_intc_save_context(void);
153void omap_intc_restore_context(void); 166void omap_intc_restore_context(void);
@@ -157,23 +170,23 @@ void omap3_intc_resume_idle(void);
157void omap2_intc_handle_irq(struct pt_regs *regs); 170void omap2_intc_handle_irq(struct pt_regs *regs);
158void omap3_intc_handle_irq(struct pt_regs *regs); 171void omap3_intc_handle_irq(struct pt_regs *regs);
159 172
160/* 173#ifdef CONFIG_CACHE_L2X0
161 * wfi used in low power code. Directly opcode is used instead 174extern void __iomem *omap4_get_l2cache_base(void);
162 * of instruction to avoid mulit-omap build break
163 */
164#ifdef CONFIG_THUMB2_KERNEL
165#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory")
166#else
167#define do_wfi() \
168 __asm__ __volatile__ (".word 0xe320f003" : : : "memory")
169#endif 175#endif
170 176
171#ifdef CONFIG_CACHE_L2X0 177#ifdef CONFIG_SMP
172extern void __iomem *l2cache_base; 178extern void __iomem *omap4_get_scu_base(void);
179#else
180static inline void __iomem *omap4_get_scu_base(void)
181{
182 return NULL;
183}
173#endif 184#endif
174 185
175extern void __init gic_init_irq(void); 186extern void __init gic_init_irq(void);
176extern void omap_smc1(u32 fn, u32 arg); 187extern void omap_smc1(u32 fn, u32 arg);
188extern void __iomem *omap4_get_sar_ram_base(void);
189extern void omap_do_wfi(void);
177 190
178#ifdef CONFIG_SMP 191#ifdef CONFIG_SMP
179/* Needed for secondary core boot */ 192/* Needed for secondary core boot */
@@ -183,4 +196,44 @@ extern void omap_auxcoreboot_addr(u32 cpu_addr);
183extern u32 omap_read_auxcoreboot0(void); 196extern u32 omap_read_auxcoreboot0(void);
184#endif 197#endif
185 198
199#if defined(CONFIG_SMP) && defined(CONFIG_PM)
200extern int omap4_mpuss_init(void);
201extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
202extern int omap4_finish_suspend(unsigned long cpu_state);
203extern void omap4_cpu_resume(void);
204extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
205extern u32 omap4_mpuss_read_prev_context_state(void);
206#else
207static inline int omap4_enter_lowpower(unsigned int cpu,
208 unsigned int power_state)
209{
210 cpu_do_idle();
211 return 0;
212}
213
214static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
215{
216 cpu_do_idle();
217 return 0;
218}
219
220static inline int omap4_mpuss_init(void)
221{
222 return 0;
223}
224
225static inline int omap4_finish_suspend(unsigned long cpu_state)
226{
227 return 0;
228}
229
230static inline void omap4_cpu_resume(void)
231{}
232
233static inline u32 omap4_mpuss_read_prev_context_state(void)
234{
235 return 0;
236}
237#endif
238#endif /* __ASSEMBLER__ */
186#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ 239#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index d4ef75d5a38..0ba68d3764b 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -52,8 +52,8 @@
52#define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 52#define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00
53#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 53#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60
54 54
55/* TI816X spefic control submodules */ 55/* TI81XX spefic control submodules */
56#define TI816X_CONTROL_DEVCONF 0x600 56#define TI81XX_CONTROL_DEVCONF 0x600
57 57
58/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ 58/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
59 59
@@ -244,8 +244,8 @@
244#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 244#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
245#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 245#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
246 246
247/* TI816X CONTROL_DEVCONF register offsets */ 247/* TI81XX CONTROL_DEVCONF register offsets */
248#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) 248#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000)
249 249
250/* 250/*
251 * REVISIT: This list of registers is not comprehensive - there are more 251 * REVISIT: This list of registers is not comprehensive - there are more
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index e20332f4abd..464cffde58f 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -25,12 +25,12 @@
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/cpuidle.h> 26#include <linux/cpuidle.h>
27#include <linux/export.h> 27#include <linux/export.h>
28#include <linux/cpu_pm.h>
28 29
29#include <plat/prcm.h> 30#include <plat/prcm.h>
30#include <plat/irqs.h> 31#include <plat/irqs.h>
31#include "powerdomain.h" 32#include "powerdomain.h"
32#include "clockdomain.h" 33#include "clockdomain.h"
33#include <plat/serial.h>
34 34
35#include "pm.h" 35#include "pm.h"
36#include "control.h" 36#include "control.h"
@@ -124,9 +124,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
124 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); 124 pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
125 } 125 }
126 126
127 /*
128 * Call idle CPU PM enter notifier chain so that
129 * VFP context is saved.
130 */
131 if (mpu_state == PWRDM_POWER_OFF)
132 cpu_pm_enter();
133
127 /* Execute ARM wfi */ 134 /* Execute ARM wfi */
128 omap_sram_idle(); 135 omap_sram_idle();
129 136
137 /*
138 * Call idle CPU PM enter notifier chain to restore
139 * VFP context.
140 */
141 if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
142 cpu_pm_exit();
143
130 /* Re-allow idle for C1 */ 144 /* Re-allow idle for C1 */
131 if (index == 0) { 145 if (index == 0) {
132 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); 146 pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
@@ -245,11 +259,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
245 struct omap3_idle_statedata *cx; 259 struct omap3_idle_statedata *cx;
246 int ret; 260 int ret;
247 261
248 if (!omap3_can_sleep()) {
249 new_state_idx = drv->safe_state_index;
250 goto select_state;
251 }
252
253 /* 262 /*
254 * Prevent idle completely if CAM is active. 263 * Prevent idle completely if CAM is active.
255 * CAM does not have wakeup capability in OMAP3. 264 * CAM does not have wakeup capability in OMAP3.
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
new file mode 100644
index 00000000000..cfdbb86bc84
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -0,0 +1,245 @@
1/*
2 * OMAP4 CPU idle Routines
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * Rajendra Nayak <rnayak@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/sched.h>
14#include <linux/cpuidle.h>
15#include <linux/cpu_pm.h>
16#include <linux/export.h>
17#include <linux/clockchips.h>
18
19#include <asm/proc-fns.h>
20
21#include "common.h"
22#include "pm.h"
23#include "prm.h"
24
25#ifdef CONFIG_CPU_IDLE
26
27/* Machine specific information to be recorded in the C-state driver_data */
28struct omap4_idle_statedata {
29 u32 cpu_state;
30 u32 mpu_logic_state;
31 u32 mpu_state;
32 u8 valid;
33};
34
35static struct cpuidle_params cpuidle_params_table[] = {
36 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
37 {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1},
38 /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */
39 {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1},
40 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
41 {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1},
42};
43
44#define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
45
46struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES];
47static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd;
48
49/**
50 * omap4_enter_idle - Programs OMAP4 to enter the specified state
51 * @dev: cpuidle device
52 * @drv: cpuidle driver
53 * @index: the index of state to be entered
54 *
55 * Called from the CPUidle framework to program the device to the
56 * specified low power state selected by the governor.
57 * Returns the amount of time spent in the low power state.
58 */
59static int omap4_enter_idle(struct cpuidle_device *dev,
60 struct cpuidle_driver *drv,
61 int index)
62{
63 struct omap4_idle_statedata *cx =
64 cpuidle_get_statedata(&dev->states_usage[index]);
65 struct timespec ts_preidle, ts_postidle, ts_idle;
66 u32 cpu1_state;
67 int idle_time;
68 int new_state_idx;
69 int cpu_id = smp_processor_id();
70
71 /* Used to keep track of the total time in idle */
72 getnstimeofday(&ts_preidle);
73
74 local_irq_disable();
75 local_fiq_disable();
76
77 /*
78 * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state.
79 * This is necessary to honour hardware recommondation
80 * of triggeing all the possible low power modes once CPU1 is
81 * out of coherency and in OFF mode.
82 * Update dev->last_state so that governor stats reflects right
83 * data.
84 */
85 cpu1_state = pwrdm_read_pwrst(cpu1_pd);
86 if (cpu1_state != PWRDM_POWER_OFF) {
87 new_state_idx = drv->safe_state_index;
88 cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]);
89 }
90
91 if (index > 0)
92 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
93
94 /*
95 * Call idle CPU PM enter notifier chain so that
96 * VFP and per CPU interrupt context is saved.
97 */
98 if (cx->cpu_state == PWRDM_POWER_OFF)
99 cpu_pm_enter();
100
101 pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
102 omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
103
104 /*
105 * Call idle CPU cluster PM enter notifier chain
106 * to save GIC and wakeupgen context.
107 */
108 if ((cx->mpu_state == PWRDM_POWER_RET) &&
109 (cx->mpu_logic_state == PWRDM_POWER_OFF))
110 cpu_cluster_pm_enter();
111
112 omap4_enter_lowpower(dev->cpu, cx->cpu_state);
113
114 /*
115 * Call idle CPU PM exit notifier chain to restore
116 * VFP and per CPU IRQ context. Only CPU0 state is
117 * considered since CPU1 is managed by CPU hotplug.
118 */
119 if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF)
120 cpu_pm_exit();
121
122 /*
123 * Call idle CPU cluster PM exit notifier chain
124 * to restore GIC and wakeupgen context.
125 */
126 if (omap4_mpuss_read_prev_context_state())
127 cpu_cluster_pm_exit();
128
129 if (index > 0)
130 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
131
132 getnstimeofday(&ts_postidle);
133 ts_idle = timespec_sub(ts_postidle, ts_preidle);
134
135 local_irq_enable();
136 local_fiq_enable();
137
138 idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \
139 USEC_PER_SEC;
140
141 /* Update cpuidle counters */
142 dev->last_residency = idle_time;
143
144 return index;
145}
146
147DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
148
149struct cpuidle_driver omap4_idle_driver = {
150 .name = "omap4_idle",
151 .owner = THIS_MODULE,
152};
153
154static inline void _fill_cstate(struct cpuidle_driver *drv,
155 int idx, const char *descr)
156{
157 struct cpuidle_state *state = &drv->states[idx];
158
159 state->exit_latency = cpuidle_params_table[idx].exit_latency;
160 state->target_residency = cpuidle_params_table[idx].target_residency;
161 state->flags = CPUIDLE_FLAG_TIME_VALID;
162 state->enter = omap4_enter_idle;
163 sprintf(state->name, "C%d", idx + 1);
164 strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
165}
166
167static inline struct omap4_idle_statedata *_fill_cstate_usage(
168 struct cpuidle_device *dev,
169 int idx)
170{
171 struct omap4_idle_statedata *cx = &omap4_idle_data[idx];
172 struct cpuidle_state_usage *state_usage = &dev->states_usage[idx];
173
174 cx->valid = cpuidle_params_table[idx].valid;
175 cpuidle_set_statedata(state_usage, cx);
176
177 return cx;
178}
179
180
181
182/**
183 * omap4_idle_init - Init routine for OMAP4 idle
184 *
185 * Registers the OMAP4 specific cpuidle driver to the cpuidle
186 * framework with the valid set of states.
187 */
188int __init omap4_idle_init(void)
189{
190 struct omap4_idle_statedata *cx;
191 struct cpuidle_device *dev;
192 struct cpuidle_driver *drv = &omap4_idle_driver;
193 unsigned int cpu_id = 0;
194
195 mpu_pd = pwrdm_lookup("mpu_pwrdm");
196 cpu0_pd = pwrdm_lookup("cpu0_pwrdm");
197 cpu1_pd = pwrdm_lookup("cpu1_pwrdm");
198 if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd))
199 return -ENODEV;
200
201
202 drv->safe_state_index = -1;
203 dev = &per_cpu(omap4_idle_dev, cpu_id);
204 dev->cpu = cpu_id;
205
206 /* C1 - CPU0 ON + CPU1 ON + MPU ON */
207 _fill_cstate(drv, 0, "MPUSS ON");
208 drv->safe_state_index = 0;
209 cx = _fill_cstate_usage(dev, 0);
210 cx->valid = 1; /* C1 is always valid */
211 cx->cpu_state = PWRDM_POWER_ON;
212 cx->mpu_state = PWRDM_POWER_ON;
213 cx->mpu_logic_state = PWRDM_POWER_RET;
214
215 /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
216 _fill_cstate(drv, 1, "MPUSS CSWR");
217 cx = _fill_cstate_usage(dev, 1);
218 cx->cpu_state = PWRDM_POWER_OFF;
219 cx->mpu_state = PWRDM_POWER_RET;
220 cx->mpu_logic_state = PWRDM_POWER_RET;
221
222 /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
223 _fill_cstate(drv, 2, "MPUSS OSWR");
224 cx = _fill_cstate_usage(dev, 2);
225 cx->cpu_state = PWRDM_POWER_OFF;
226 cx->mpu_state = PWRDM_POWER_RET;
227 cx->mpu_logic_state = PWRDM_POWER_OFF;
228
229 drv->state_count = OMAP4_NUM_STATES;
230 cpuidle_register_driver(&omap4_idle_driver);
231
232 dev->state_count = OMAP4_NUM_STATES;
233 if (cpuidle_register_device(dev)) {
234 pr_err("%s: CPUidle register device failed\n", __func__);
235 return -EIO;
236 }
237
238 return 0;
239}
240#else
241int __init omap4_idle_init(void)
242{
243 return 0;
244}
245#endif /* CONFIG_CPU_IDLE */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index c15cfada5f1..46dfd1ae8f7 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -28,6 +28,7 @@
28#include <plat/board.h> 28#include <plat/board.h>
29#include <plat/mcbsp.h> 29#include <plat/mcbsp.h>
30#include <plat/mmc.h> 30#include <plat/mmc.h>
31#include <plat/iommu.h>
31#include <plat/dma.h> 32#include <plat/dma.h>
32#include <plat/omap_hwmod.h> 33#include <plat/omap_hwmod.h>
33#include <plat/omap_device.h> 34#include <plat/omap_device.h>
@@ -211,9 +212,15 @@ static struct platform_device omap3isp_device = {
211 .resource = omap3isp_resources, 212 .resource = omap3isp_resources,
212}; 213};
213 214
215static struct omap_iommu_arch_data omap3_isp_iommu = {
216 .name = "isp",
217};
218
214int omap3_init_camera(struct isp_platform_data *pdata) 219int omap3_init_camera(struct isp_platform_data *pdata)
215{ 220{
216 omap3isp_device.dev.platform_data = pdata; 221 omap3isp_device.dev.platform_data = pdata;
222 omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu;
223
217 return platform_device_register(&omap3isp_device); 224 return platform_device_register(&omap3isp_device);
218} 225}
219 226
@@ -336,6 +343,27 @@ static void omap_init_mcpdm(void)
336static inline void omap_init_mcpdm(void) {} 343static inline void omap_init_mcpdm(void) {}
337#endif 344#endif
338 345
346#if defined(CONFIG_SND_OMAP_SOC_DMIC) || \
347 defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE)
348
349static void omap_init_dmic(void)
350{
351 struct omap_hwmod *oh;
352 struct platform_device *pdev;
353
354 oh = omap_hwmod_lookup("dmic");
355 if (!oh) {
356 printk(KERN_ERR "Could not look up mcpdm hw_mod\n");
357 return;
358 }
359
360 pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0);
361 WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");
362}
363#else
364static inline void omap_init_dmic(void) {}
365#endif
366
339#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) 367#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
340 368
341#include <plat/mcspi.h> 369#include <plat/mcspi.h>
@@ -681,6 +709,7 @@ static int __init omap2_init_devices(void)
681 */ 709 */
682 omap_init_audio(); 710 omap_init_audio();
683 omap_init_mcpdm(); 711 omap_init_mcpdm();
712 omap_init_dmic();
684 omap_init_camera(); 713 omap_init_camera();
685 omap_init_mbox(); 714 omap_init_mbox();
686 omap_init_mcspi(); 715 omap_init_mcspi();
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index f4a1020559a..bd844af13af 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -171,6 +171,17 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
171 } 171 }
172} 172}
173 173
174static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc)
175{
176 u32 reg;
177
178 if (mmc->slots[0].internal_clock) {
179 reg = omap_ctrl_readl(control_devconf1_offset);
180 reg |= OMAP2_MMCSDIO2ADPCLKISEL;
181 omap_ctrl_writel(reg, control_devconf1_offset);
182 }
183}
184
174static void hsmmc23_before_set_reg(struct device *dev, int slot, 185static void hsmmc23_before_set_reg(struct device *dev, int slot,
175 int power_on, int vdd) 186 int power_on, int vdd)
176{ 187{
@@ -179,16 +190,19 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot,
179 if (mmc->slots[0].remux) 190 if (mmc->slots[0].remux)
180 mmc->slots[0].remux(dev, slot, power_on); 191 mmc->slots[0].remux(dev, slot, power_on);
181 192
182 if (power_on) { 193 if (power_on)
183 /* Only MMC2 supports a CLKIN */ 194 hsmmc2_select_input_clk_src(mmc);
184 if (mmc->slots[0].internal_clock) { 195}
185 u32 reg;
186 196
187 reg = omap_ctrl_readl(control_devconf1_offset); 197static int am35x_hsmmc2_set_power(struct device *dev, int slot,
188 reg |= OMAP2_MMCSDIO2ADPCLKISEL; 198 int power_on, int vdd)
189 omap_ctrl_writel(reg, control_devconf1_offset); 199{
190 } 200 struct omap_mmc_platform_data *mmc = dev->platform_data;
191 } 201
202 if (power_on)
203 hsmmc2_select_input_clk_src(mmc);
204
205 return 0;
192} 206}
193 207
194static int nop_mmc_set_power(struct device *dev, int slot, int power_on, 208static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
@@ -200,10 +214,12 @@ static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
200static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, 214static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
201 int controller_nr) 215 int controller_nr)
202{ 216{
203 if (gpio_is_valid(mmc_controller->slots[0].switch_pin)) 217 if (gpio_is_valid(mmc_controller->slots[0].switch_pin) &&
218 (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
204 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, 219 omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
205 OMAP_PIN_INPUT_PULLUP); 220 OMAP_PIN_INPUT_PULLUP);
206 if (gpio_is_valid(mmc_controller->slots[0].gpio_wp)) 221 if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) &&
222 (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
207 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, 223 omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
208 OMAP_PIN_INPUT_PULLUP); 224 OMAP_PIN_INPUT_PULLUP);
209 if (cpu_is_omap34xx()) { 225 if (cpu_is_omap34xx()) {
@@ -296,6 +312,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
296 mmc->slots[0].name = hc_name; 312 mmc->slots[0].name = hc_name;
297 mmc->nr_slots = 1; 313 mmc->nr_slots = 1;
298 mmc->slots[0].caps = c->caps; 314 mmc->slots[0].caps = c->caps;
315 mmc->slots[0].pm_caps = c->pm_caps;
299 mmc->slots[0].internal_clock = !c->ext_clock; 316 mmc->slots[0].internal_clock = !c->ext_clock;
300 mmc->dma_mask = 0xffffffff; 317 mmc->dma_mask = 0xffffffff;
301 if (cpu_is_omap44xx()) 318 if (cpu_is_omap44xx())
@@ -336,11 +353,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
336 * 353 *
337 * temporary HACK: ocr_mask instead of fixed supply 354 * temporary HACK: ocr_mask instead of fixed supply
338 */ 355 */
339 mmc->slots[0].ocr_mask = c->ocr_mask; 356 if (cpu_is_omap3505() || cpu_is_omap3517())
340 357 mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
341 if (cpu_is_omap3517() || cpu_is_omap3505()) 358 MMC_VDD_26_27 |
342 mmc->slots[0].set_power = nop_mmc_set_power; 359 MMC_VDD_27_28 |
360 MMC_VDD_29_30 |
361 MMC_VDD_30_31 |
362 MMC_VDD_31_32;
343 else 363 else
364 mmc->slots[0].ocr_mask = c->ocr_mask;
365
366 if (!cpu_is_omap3517() && !cpu_is_omap3505())
344 mmc->slots[0].features |= HSMMC_HAS_PBIAS; 367 mmc->slots[0].features |= HSMMC_HAS_PBIAS;
345 368
346 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) 369 if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
@@ -363,6 +386,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
363 } 386 }
364 } 387 }
365 388
389 if (cpu_is_omap3517() || cpu_is_omap3505())
390 mmc->slots[0].set_power = nop_mmc_set_power;
391
366 /* OMAP3630 HSMMC1 supports only 4-bit */ 392 /* OMAP3630 HSMMC1 supports only 4-bit */
367 if (cpu_is_omap3630() && 393 if (cpu_is_omap3630() &&
368 (c->caps & MMC_CAP_8_BIT_DATA)) { 394 (c->caps & MMC_CAP_8_BIT_DATA)) {
@@ -372,6 +398,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
372 } 398 }
373 break; 399 break;
374 case 2: 400 case 2:
401 if (cpu_is_omap3517() || cpu_is_omap3505())
402 mmc->slots[0].set_power = am35x_hsmmc2_set_power;
403
375 if (c->ext_clock) 404 if (c->ext_clock)
376 c->transceiver = 1; 405 c->transceiver = 1;
377 if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { 406 if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index f757e78d4d4..c4409730c4b 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -12,6 +12,7 @@ struct omap2_hsmmc_info {
12 u8 mmc; /* controller 1/2/3 */ 12 u8 mmc; /* controller 1/2/3 */
13 u32 caps; /* 4/8 wires and any additional host 13 u32 caps; /* 4/8 wires and any additional host
14 * capabilities OR'd (ref. linux/mmc/host.h) */ 14 * capabilities OR'd (ref. linux/mmc/host.h) */
15 u32 pm_caps; /* PM capabilities */
15 bool transceiver; /* MMC-2 option */ 16 bool transceiver; /* MMC-2 option */
16 bool ext_clock; /* use external pin for input clock */ 17 bool ext_clock; /* use external pin for input clock */
17 bool cover_only; /* No card detect - just cover switch */ 18 bool cover_only; /* No card detect - just cover switch */
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 27ad722df63..6c5826605ea 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -226,7 +226,7 @@ static void __init omap4_check_features(void)
226 } 226 }
227} 227}
228 228
229static void __init ti816x_check_features(void) 229static void __init ti81xx_check_features(void)
230{ 230{
231 omap_features = OMAP3_HAS_NEON; 231 omap_features = OMAP3_HAS_NEON;
232} 232}
@@ -340,6 +340,29 @@ static void __init omap3_check_revision(const char **cpu_rev)
340 break; 340 break;
341 } 341 }
342 break; 342 break;
343 case 0xb944:
344 omap_revision = AM335X_REV_ES1_0;
345 *cpu_rev = "1.0";
346 case 0xb8f2:
347 switch (rev) {
348 case 0:
349 /* FALLTHROUGH */
350 case 1:
351 omap_revision = TI8148_REV_ES1_0;
352 *cpu_rev = "1.0";
353 break;
354 case 2:
355 omap_revision = TI8148_REV_ES2_0;
356 *cpu_rev = "2.0";
357 break;
358 case 3:
359 /* FALLTHROUGH */
360 default:
361 omap_revision = TI8148_REV_ES2_1;
362 *cpu_rev = "2.1";
363 break;
364 }
365 break;
343 default: 366 default:
344 /* Unknown default to latest silicon rev as default */ 367 /* Unknown default to latest silicon rev as default */
345 omap_revision = OMAP3630_REV_ES1_2; 368 omap_revision = OMAP3630_REV_ES1_2;
@@ -367,7 +390,7 @@ static void __init omap4_check_revision(void)
367 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 390 * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
368 * Use ARM register to detect the correct ES version 391 * Use ARM register to detect the correct ES version
369 */ 392 */
370 if (!rev && (hawkeye != 0xb94e)) { 393 if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
371 idcode = read_cpuid(CPUID_ID); 394 idcode = read_cpuid(CPUID_ID);
372 rev = (idcode & 0xf) - 1; 395 rev = (idcode & 0xf) - 1;
373 } 396 }
@@ -389,8 +412,11 @@ static void __init omap4_check_revision(void)
389 omap_revision = OMAP4430_REV_ES2_1; 412 omap_revision = OMAP4430_REV_ES2_1;
390 break; 413 break;
391 case 4: 414 case 4:
392 default:
393 omap_revision = OMAP4430_REV_ES2_2; 415 omap_revision = OMAP4430_REV_ES2_2;
416 break;
417 case 6:
418 default:
419 omap_revision = OMAP4430_REV_ES2_3;
394 } 420 }
395 break; 421 break;
396 case 0xb94e: 422 case 0xb94e:
@@ -401,9 +427,17 @@ static void __init omap4_check_revision(void)
401 break; 427 break;
402 } 428 }
403 break; 429 break;
430 case 0xb975:
431 switch (rev) {
432 case 0:
433 default:
434 omap_revision = OMAP4470_REV_ES1_0;
435 break;
436 }
437 break;
404 default: 438 default:
405 /* Unknown default to latest silicon rev as default */ 439 /* Unknown default to latest silicon rev as default */
406 omap_revision = OMAP4430_REV_ES2_2; 440 omap_revision = OMAP4430_REV_ES2_3;
407 } 441 }
408 442
409 pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, 443 pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16,
@@ -432,6 +466,10 @@ static void __init omap3_cpuinfo(const char *cpu_rev)
432 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; 466 cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
433 } else if (cpu_is_ti816x()) { 467 } else if (cpu_is_ti816x()) {
434 cpu_name = "TI816X"; 468 cpu_name = "TI816X";
469 } else if (cpu_is_am335x()) {
470 cpu_name = "AM335X";
471 } else if (cpu_is_ti814x()) {
472 cpu_name = "TI814X";
435 } else if (omap3_has_iva() && omap3_has_sgx()) { 473 } else if (omap3_has_iva() && omap3_has_sgx()) {
436 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ 474 /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
437 cpu_name = "OMAP3430/3530"; 475 cpu_name = "OMAP3430/3530";
@@ -472,11 +510,11 @@ void __init omap2_check_revision(void)
472 } else if (cpu_is_omap34xx()) { 510 } else if (cpu_is_omap34xx()) {
473 omap3_check_revision(&cpu_rev); 511 omap3_check_revision(&cpu_rev);
474 512
475 /* TI816X doesn't have feature register */ 513 /* TI81XX doesn't have feature register */
476 if (!cpu_is_ti816x()) 514 if (!cpu_is_ti81xx())
477 omap3_check_features(); 515 omap3_check_features();
478 else 516 else
479 ti816x_check_features(); 517 ti81xx_check_features();
480 518
481 omap3_cpuinfo(cpu_rev); 519 omap3_cpuinfo(cpu_rev);
482 return; 520 return;
diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h
new file mode 100644
index 00000000000..4fa72c7cc7c
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/barriers.h
@@ -0,0 +1,31 @@
1/*
2 * OMAP memory barrier header.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * Richard Woodruff <r-woodruff2@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __MACH_BARRIERS_H
23#define __MACH_BARRIERS_H
24
25extern void omap_bus_sync(void);
26
27#define rmb() dsb()
28#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
29#define mb() wmb()
30
31#endif /* __MACH_BARRIERS_H */
diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S
index 13f98e59cfe..cdfc2a1f0e7 100644
--- a/arch/arm/mach-omap2/include/mach/debug-macro.S
+++ b/arch/arm/mach-omap2/include/mach/debug-macro.S
@@ -66,11 +66,11 @@ omap_uart_lsr: .word 0
66 beq 34f @ configure OMAP3UART4 66 beq 34f @ configure OMAP3UART4
67 cmp \rp, #OMAP4UART4 @ only on 44xx 67 cmp \rp, #OMAP4UART4 @ only on 44xx
68 beq 44f @ configure OMAP4UART4 68 beq 44f @ configure OMAP4UART4
69 cmp \rp, #TI816XUART1 @ ti816x UART offsets different 69 cmp \rp, #TI81XXUART1 @ ti81Xx UART offsets different
70 beq 81f @ configure UART1 70 beq 81f @ configure UART1
71 cmp \rp, #TI816XUART2 @ ti816x UART offsets different 71 cmp \rp, #TI81XXUART2 @ ti81Xx UART offsets different
72 beq 82f @ configure UART2 72 beq 82f @ configure UART2
73 cmp \rp, #TI816XUART3 @ ti816x UART offsets different 73 cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different
74 beq 83f @ configure UART3 74 beq 83f @ configure UART3
75 cmp \rp, #ZOOM_UART @ only on zoom2/3 75 cmp \rp, #ZOOM_UART @ only on zoom2/3
76 beq 95f @ configure ZOOM_UART 76 beq 95f @ configure ZOOM_UART
@@ -94,11 +94,11 @@ omap_uart_lsr: .word 0
94 b 98f 94 b 98f
9544: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) 9544: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE)
96 b 98f 96 b 98f
9781: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) 9781: mov \rp, #UART_OFFSET(TI81XX_UART1_BASE)
98 b 98f 98 b 98f
9982: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) 9982: mov \rp, #UART_OFFSET(TI81XX_UART2_BASE)
100 b 98f 100 b 98f
10183: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) 10183: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE)
102 b 98f 102 b 98f
103 103
10495: ldr \rp, =ZOOM_UART_BASE 10495: ldr \rp, =ZOOM_UART_BASE
diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h
new file mode 100644
index 00000000000..c90a43589ab
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap-secure.h
@@ -0,0 +1,57 @@
1/*
2 * omap-secure.h: OMAP Secure infrastructure header.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef OMAP_ARCH_OMAP_SECURE_H
12#define OMAP_ARCH_OMAP_SECURE_H
13
14/* Monitor error code */
15#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE
16#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF
17
18/* HAL API error codes */
19#define API_HAL_RET_VALUE_OK 0x00
20#define API_HAL_RET_VALUE_FAIL 0x01
21
22/* Secure HAL API flags */
23#define FLAG_START_CRITICAL 0x4
24#define FLAG_IRQFIQ_MASK 0x3
25#define FLAG_IRQ_ENABLE 0x2
26#define FLAG_FIQ_ENABLE 0x1
27#define NO_FLAG 0x0
28
29/* Maximum Secure memory storage size */
30#define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K)
31
32/* Secure low power HAL API index */
33#define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a
34#define OMAP4_HAL_SAVEHW_INDEX 0x1b
35#define OMAP4_HAL_SAVEALL_INDEX 0x1c
36#define OMAP4_HAL_SAVEGIC_INDEX 0x1d
37
38/* Secure Monitor mode APIs */
39#define OMAP4_MON_SCU_PWR_INDEX 0x108
40#define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100
41#define OMAP4_MON_L2X0_CTRL_INDEX 0x102
42#define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109
43#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113
44
45/* Secure PPA(Primary Protected Application) APIs */
46#define OMAP4_PPA_L2_POR_INDEX 0x23
47#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
48
49#ifndef __ASSEMBLER__
50
51extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
52 u32 arg1, u32 arg2, u32 arg3, u32 arg4);
53extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
54extern phys_addr_t omap_secure_ram_mempool_base(void);
55
56#endif /* __ASSEMBLER__ */
57#endif /* OMAP_ARCH_OMAP_SECURE_H */
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
new file mode 100644
index 00000000000..d79321b0f2a
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
@@ -0,0 +1,39 @@
1/*
2 * OMAP WakeupGen header file
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef OMAP_ARCH_WAKEUPGEN_H
12#define OMAP_ARCH_WAKEUPGEN_H
13
14#define OMAP_WKG_CONTROL_0 0x00
15#define OMAP_WKG_ENB_A_0 0x10
16#define OMAP_WKG_ENB_B_0 0x14
17#define OMAP_WKG_ENB_C_0 0x18
18#define OMAP_WKG_ENB_D_0 0x1c
19#define OMAP_WKG_ENB_SECURE_A_0 0x20
20#define OMAP_WKG_ENB_SECURE_B_0 0x24
21#define OMAP_WKG_ENB_SECURE_C_0 0x28
22#define OMAP_WKG_ENB_SECURE_D_0 0x2c
23#define OMAP_WKG_ENB_A_1 0x410
24#define OMAP_WKG_ENB_B_1 0x414
25#define OMAP_WKG_ENB_C_1 0x418
26#define OMAP_WKG_ENB_D_1 0x41c
27#define OMAP_WKG_ENB_SECURE_A_1 0x420
28#define OMAP_WKG_ENB_SECURE_B_1 0x424
29#define OMAP_WKG_ENB_SECURE_C_1 0x428
30#define OMAP_WKG_ENB_SECURE_D_1 0x42c
31#define OMAP_AUX_CORE_BOOT_0 0x800
32#define OMAP_AUX_CORE_BOOT_1 0x804
33#define OMAP_PTMSYNCREQ_MASK 0xc00
34#define OMAP_PTMSYNCREQ_EN 0xc04
35#define OMAP_TIMESTAMPCYCLELO 0xc08
36#define OMAP_TIMESTAMPCYCLEHI 0xc0c
37
38extern int __init omap_wakeupgen_init(void);
39#endif
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 3f565dd2ea8..3f174d51f67 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -176,14 +176,31 @@ static struct map_desc omap34xx_io_desc[] __initdata = {
176}; 176};
177#endif 177#endif
178 178
179#ifdef CONFIG_SOC_OMAPTI816X 179#ifdef CONFIG_SOC_OMAPTI81XX
180static struct map_desc omapti816x_io_desc[] __initdata = { 180static struct map_desc omapti81xx_io_desc[] __initdata = {
181 {
182 .virtual = L4_34XX_VIRT,
183 .pfn = __phys_to_pfn(L4_34XX_PHYS),
184 .length = L4_34XX_SIZE,
185 .type = MT_DEVICE
186 }
187};
188#endif
189
190#ifdef CONFIG_SOC_OMAPAM33XX
191static struct map_desc omapam33xx_io_desc[] __initdata = {
181 { 192 {
182 .virtual = L4_34XX_VIRT, 193 .virtual = L4_34XX_VIRT,
183 .pfn = __phys_to_pfn(L4_34XX_PHYS), 194 .pfn = __phys_to_pfn(L4_34XX_PHYS),
184 .length = L4_34XX_SIZE, 195 .length = L4_34XX_SIZE,
185 .type = MT_DEVICE 196 .type = MT_DEVICE
186 }, 197 },
198 {
199 .virtual = L4_WK_AM33XX_VIRT,
200 .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS),
201 .length = L4_WK_AM33XX_SIZE,
202 .type = MT_DEVICE
203 }
187}; 204};
188#endif 205#endif
189 206
@@ -237,6 +254,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
237 .length = L4_EMU_44XX_SIZE, 254 .length = L4_EMU_44XX_SIZE,
238 .type = MT_DEVICE, 255 .type = MT_DEVICE,
239 }, 256 },
257#ifdef CONFIG_OMAP4_ERRATA_I688
258 {
259 .virtual = OMAP4_SRAM_VA,
260 .pfn = __phys_to_pfn(OMAP4_SRAM_PA),
261 .length = PAGE_SIZE,
262 .type = MT_MEMORY_SO,
263 },
264#endif
265
240}; 266};
241#endif 267#endif
242 268
@@ -263,10 +289,17 @@ void __init omap34xx_map_common_io(void)
263} 289}
264#endif 290#endif
265 291
266#ifdef CONFIG_SOC_OMAPTI816X 292#ifdef CONFIG_SOC_OMAPTI81XX
267void __init omapti816x_map_common_io(void) 293void __init omapti81xx_map_common_io(void)
294{
295 iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
296}
297#endif
298
299#ifdef CONFIG_SOC_OMAPAM33XX
300void __init omapam33xx_map_common_io(void)
268{ 301{
269 iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); 302 iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
270} 303}
271#endif 304#endif
272 305
@@ -418,9 +451,9 @@ void __init am35xx_init_early(void)
418 omap3_init_early(); 451 omap3_init_early();
419} 452}
420 453
421void __init ti816x_init_early(void) 454void __init ti81xx_init_early(void)
422{ 455{
423 omap2_set_globals_ti816x(); 456 omap2_set_globals_ti81xx();
424 omap_common_init_early(); 457 omap_common_init_early();
425 omap3xxx_voltagedomains_init(); 458 omap3xxx_voltagedomains_init();
426 omap3xxx_powerdomains_init(); 459 omap3xxx_powerdomains_init();
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 42b1d659191..1fef061f792 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -193,7 +193,7 @@ void __init omap3_init_irq(void)
193 omap_init_irq(OMAP34XX_IC_BASE, 96); 193 omap_init_irq(OMAP34XX_IC_BASE, 96);
194} 194}
195 195
196void __init ti816x_init_irq(void) 196void __init ti81xx_init_irq(void)
197{ 197{
198 omap_init_irq(OMAP34XX_IC_BASE, 128); 198 omap_init_irq(OMAP34XX_IC_BASE, 128);
199} 199}
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 655e9480eb9..e1cc75d1a57 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -32,6 +32,8 @@
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <linux/irq.h>
36#include <linux/interrupt.h>
35 37
36#include <asm/system.h> 38#include <asm/system.h>
37 39
@@ -39,6 +41,7 @@
39 41
40#include "control.h" 42#include "control.h"
41#include "mux.h" 43#include "mux.h"
44#include "prm.h"
42 45
43#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ 46#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
44#define OMAP_MUX_BASE_SZ 0x5ca 47#define OMAP_MUX_BASE_SZ 0x5ca
@@ -306,7 +309,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
306 pad->idle = bpad->idle; 309 pad->idle = bpad->idle;
307 pad->off = bpad->off; 310 pad->off = bpad->off;
308 311
309 if (pad->flags & OMAP_DEVICE_PAD_REMUX) 312 if (pad->flags &
313 (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP))
310 nr_pads_dynamic++; 314 nr_pads_dynamic++;
311 315
312 pr_debug("%s: Initialized %s\n", __func__, pad->name); 316 pr_debug("%s: Initialized %s\n", __func__, pad->name);
@@ -331,7 +335,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
331 for (i = 0; i < hmux->nr_pads; i++) { 335 for (i = 0; i < hmux->nr_pads; i++) {
332 struct omap_device_pad *pad = &hmux->pads[i]; 336 struct omap_device_pad *pad = &hmux->pads[i];
333 337
334 if (pad->flags & OMAP_DEVICE_PAD_REMUX) { 338 if (pad->flags &
339 (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) {
335 pr_debug("%s: pad %s tagged dynamic\n", 340 pr_debug("%s: pad %s tagged dynamic\n",
336 __func__, pad->name); 341 __func__, pad->name);
337 hmux->pads_dynamic[nr_pads_dynamic] = pad; 342 hmux->pads_dynamic[nr_pads_dynamic] = pad;
@@ -351,6 +356,78 @@ err1:
351 return NULL; 356 return NULL;
352} 357}
353 358
359/**
360 * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads
361 * @hmux: Pads for a hwmod
362 * @mpu_irqs: MPU irq array for a hwmod
363 *
364 * Scans the wakeup status of pads for a single hwmod. If an irq
365 * array is defined for this mux, the parser will call the registered
366 * ISRs for corresponding pads, otherwise the parser will stop at the
367 * first wakeup active pad and return. Returns true if there is a
368 * pending and non-served wakeup event for the mux, otherwise false.
369 */
370static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux,
371 struct omap_hwmod_irq_info *mpu_irqs)
372{
373 int i, irq;
374 unsigned int val;
375 u32 handled_irqs = 0;
376
377 for (i = 0; i < hmux->nr_pads_dynamic; i++) {
378 struct omap_device_pad *pad = hmux->pads_dynamic[i];
379
380 if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) ||
381 !(pad->idle & OMAP_WAKEUP_EN))
382 continue;
383
384 val = omap_mux_read(pad->partition, pad->mux->reg_offset);
385 if (!(val & OMAP_WAKEUP_EVENT))
386 continue;
387
388 if (!hmux->irqs)
389 return true;
390
391 irq = hmux->irqs[i];
392 /* make sure we only handle each irq once */
393 if (handled_irqs & 1 << irq)
394 continue;
395
396 handled_irqs |= 1 << irq;
397
398 generic_handle_irq(mpu_irqs[irq].irq);
399 }
400
401 return false;
402}
403
404/**
405 * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod
406 *
407 * Checks a single hwmod for every wakeup capable pad to see if there is an
408 * active wakeup event. If this is the case, call the corresponding ISR.
409 */
410static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data)
411{
412 if (!oh->mux || !oh->mux->enabled)
413 return 0;
414 if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs))
415 generic_handle_irq(oh->mpu_irqs[0].irq);
416 return 0;
417}
418
419/**
420 * omap_hwmod_mux_handle_irq - Process pad wakeup irqs.
421 *
422 * Calls a function for each registered omap_hwmod to check
423 * pad wakeup statuses.
424 */
425static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused)
426{
427 omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL);
428 return IRQ_HANDLED;
429}
430
354/* Assumes the calling function takes care of locking */ 431/* Assumes the calling function takes care of locking */
355void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) 432void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
356{ 433{
@@ -715,6 +792,7 @@ static void __init omap_mux_free_names(struct omap_mux *m)
715static int __init omap_mux_late_init(void) 792static int __init omap_mux_late_init(void)
716{ 793{
717 struct omap_mux_partition *partition; 794 struct omap_mux_partition *partition;
795 int ret;
718 796
719 list_for_each_entry(partition, &mux_partitions, node) { 797 list_for_each_entry(partition, &mux_partitions, node) {
720 struct omap_mux_entry *e, *tmp; 798 struct omap_mux_entry *e, *tmp;
@@ -735,6 +813,13 @@ static int __init omap_mux_late_init(void)
735 } 813 }
736 } 814 }
737 815
816 ret = request_irq(omap_prcm_event_to_irq("io"),
817 omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND,
818 "hwmod_io", omap_mux_late_init);
819
820 if (ret)
821 pr_warning("mux: Failed to setup hwmod io irq %d\n", ret);
822
738 omap_mux_dbg_init(); 823 omap_mux_dbg_init();
739 824
740 return 0; 825 return 0;
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index 4ee6aeca885..b13ef7ef5ef 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -18,11 +18,6 @@
18#include <linux/linkage.h> 18#include <linux/linkage.h>
19#include <linux/init.h> 19#include <linux/init.h>
20 20
21/* Physical address needed since MMU not enabled yet on secondary core */
22#define OMAP4_AUX_CORE_BOOT1_PA 0x48281804
23
24 __INIT
25
26/* 21/*
27 * OMAP4 specific entry point for secondary CPU to jump from ROM 22 * OMAP4 specific entry point for secondary CPU to jump from ROM
28 * code. This routine also provides a holding flag into which 23 * code. This routine also provides a holding flag into which
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
index e5a1c3f40a8..adbe4d8c7ca 100644
--- a/arch/arm/mach-omap2/omap-hotplug.c
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -22,6 +22,8 @@
22 22
23#include "common.h" 23#include "common.h"
24 24
25#include "powerdomain.h"
26
25int platform_cpu_kill(unsigned int cpu) 27int platform_cpu_kill(unsigned int cpu)
26{ 28{
27 return 1; 29 return 1;
@@ -33,6 +35,8 @@ int platform_cpu_kill(unsigned int cpu)
33 */ 35 */
34void platform_cpu_die(unsigned int cpu) 36void platform_cpu_die(unsigned int cpu)
35{ 37{
38 unsigned int this_cpu;
39
36 flush_cache_all(); 40 flush_cache_all();
37 dsb(); 41 dsb();
38 42
@@ -40,15 +44,15 @@ void platform_cpu_die(unsigned int cpu)
40 * we're ready for shutdown now, so do it 44 * we're ready for shutdown now, so do it
41 */ 45 */
42 if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) 46 if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
43 printk(KERN_CRIT "Secure clear status failed\n"); 47 pr_err("Secure clear status failed\n");
44 48
45 for (;;) { 49 for (;;) {
46 /* 50 /*
47 * Execute WFI 51 * Enter into low power state
48 */ 52 */
49 do_wfi(); 53 omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
50 54 this_cpu = smp_processor_id();
51 if (omap_read_auxcoreboot0() == cpu) { 55 if (omap_read_auxcoreboot0() == this_cpu) {
52 /* 56 /*
53 * OK, proper wakeup, we're done 57 * OK, proper wakeup, we're done
54 */ 58 */
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
new file mode 100644
index 00000000000..1d5d0105655
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -0,0 +1,398 @@
1/*
2 * OMAP MPUSS low power code
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU
8 * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller,
9 * CPU0 and CPU1 LPRM modules.
10 * CPU0, CPU1 and MPUSS each have there own power domain and
11 * hence multiple low power combinations of MPUSS are possible.
12 *
13 * The CPU0 and CPU1 can't support Closed switch Retention (CSWR)
14 * because the mode is not supported by hw constraints of dormant
15 * mode. While waking up from the dormant mode, a reset signal
16 * to the Cortex-A9 processor must be asserted by the external
17 * power controller.
18 *
19 * With architectural inputs and hardware recommendations, only
20 * below modes are supported from power gain vs latency point of view.
21 *
22 * CPU0 CPU1 MPUSS
23 * ----------------------------------------------
24 * ON ON ON
25 * ON(Inactive) OFF ON(Inactive)
26 * OFF OFF CSWR
27 * OFF OFF OSWR
28 * OFF OFF OFF(Device OFF *TBD)
29 * ----------------------------------------------
30 *
31 * Note: CPU0 is the master core and it is the last CPU to go down
32 * and first to wake-up when MPUSS low power states are excercised
33 *
34 *
35 * This program is free software; you can redistribute it and/or modify
36 * it under the terms of the GNU General Public License version 2 as
37 * published by the Free Software Foundation.
38 */
39
40#include <linux/kernel.h>
41#include <linux/io.h>
42#include <linux/errno.h>
43#include <linux/linkage.h>
44#include <linux/smp.h>
45
46#include <asm/cacheflush.h>
47#include <asm/tlbflush.h>
48#include <asm/smp_scu.h>
49#include <asm/system.h>
50#include <asm/pgalloc.h>
51#include <asm/suspend.h>
52#include <asm/hardware/cache-l2x0.h>
53
54#include <plat/omap44xx.h>
55
56#include "common.h"
57#include "omap4-sar-layout.h"
58#include "pm.h"
59#include "prcm_mpu44xx.h"
60#include "prminst44xx.h"
61#include "prcm44xx.h"
62#include "prm44xx.h"
63#include "prm-regbits-44xx.h"
64
65#ifdef CONFIG_SMP
66
67struct omap4_cpu_pm_info {
68 struct powerdomain *pwrdm;
69 void __iomem *scu_sar_addr;
70 void __iomem *wkup_sar_addr;
71 void __iomem *l2x0_sar_addr;
72};
73
74static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
75static struct powerdomain *mpuss_pd;
76static void __iomem *sar_base;
77
78/*
79 * Program the wakeup routine address for the CPU0 and CPU1
80 * used for OFF or DORMANT wakeup.
81 */
82static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
83{
84 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
85
86 __raw_writel(addr, pm_info->wkup_sar_addr);
87}
88
89/*
90 * Set the CPUx powerdomain's previous power state
91 */
92static inline void set_cpu_next_pwrst(unsigned int cpu_id,
93 unsigned int power_state)
94{
95 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
96
97 pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
98}
99
100/*
101 * Read CPU's previous power state
102 */
103static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id)
104{
105 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
106
107 return pwrdm_read_prev_pwrst(pm_info->pwrdm);
108}
109
110/*
111 * Clear the CPUx powerdomain's previous power state
112 */
113static inline void clear_cpu_prev_pwrst(unsigned int cpu_id)
114{
115 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
116
117 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
118}
119
120/*
121 * Store the SCU power status value to scratchpad memory
122 */
123static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
124{
125 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
126 u32 scu_pwr_st;
127
128 switch (cpu_state) {
129 case PWRDM_POWER_RET:
130 scu_pwr_st = SCU_PM_DORMANT;
131 break;
132 case PWRDM_POWER_OFF:
133 scu_pwr_st = SCU_PM_POWEROFF;
134 break;
135 case PWRDM_POWER_ON:
136 case PWRDM_POWER_INACTIVE:
137 default:
138 scu_pwr_st = SCU_PM_NORMAL;
139 break;
140 }
141
142 __raw_writel(scu_pwr_st, pm_info->scu_sar_addr);
143}
144
145/* Helper functions for MPUSS OSWR */
146static inline void mpuss_clear_prev_logic_pwrst(void)
147{
148 u32 reg;
149
150 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
151 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
152 omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION,
153 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
154}
155
156static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
157{
158 u32 reg;
159
160 if (cpu_id) {
161 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
162 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
163 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
164 OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
165 } else {
166 reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
167 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
168 omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
169 OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
170 }
171}
172
173/**
174 * omap4_mpuss_read_prev_context_state:
175 * Function returns the MPUSS previous context state
176 */
177u32 omap4_mpuss_read_prev_context_state(void)
178{
179 u32 reg;
180
181 reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
182 OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
183 reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
184 return reg;
185}
186
187/*
188 * Store the CPU cluster state for L2X0 low power operations.
189 */
190static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
191{
192 struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
193
194 __raw_writel(save_state, pm_info->l2x0_sar_addr);
195}
196
197/*
198 * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to
199 * in every restore MPUSS OFF path.
200 */
201#ifdef CONFIG_CACHE_L2X0
202static void save_l2x0_context(void)
203{
204 u32 val;
205 void __iomem *l2x0_base = omap4_get_l2cache_base();
206
207 val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
208 __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
209 val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
210 __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
211}
212#else
213static void save_l2x0_context(void)
214{}
215#endif
216
217/**
218 * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
219 * The purpose of this function is to manage low power programming
220 * of OMAP4 MPUSS subsystem
221 * @cpu : CPU ID
222 * @power_state: Low power state.
223 *
224 * MPUSS states for the context save:
225 * save_state =
226 * 0 - Nothing lost and no need to save: MPUSS INACTIVE
227 * 1 - CPUx L1 and logic lost: MPUSS CSWR
228 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
229 * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
230 */
231int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
232{
233 unsigned int save_state = 0;
234 unsigned int wakeup_cpu;
235
236 if (omap_rev() == OMAP4430_REV_ES1_0)
237 return -ENXIO;
238
239 switch (power_state) {
240 case PWRDM_POWER_ON:
241 case PWRDM_POWER_INACTIVE:
242 save_state = 0;
243 break;
244 case PWRDM_POWER_OFF:
245 save_state = 1;
246 break;
247 case PWRDM_POWER_RET:
248 default:
249 /*
250 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
251 * doesn't make much scense, since logic is lost and $L1
252 * needs to be cleaned because of coherency. This makes
253 * CPUx OSWR equivalent to CPUX OFF and hence not supported
254 */
255 WARN_ON(1);
256 return -ENXIO;
257 }
258
259 pwrdm_pre_transition();
260
261 /*
262 * Check MPUSS next state and save interrupt controller if needed.
263 * In MPUSS OSWR or device OFF, interrupt controller contest is lost.
264 */
265 mpuss_clear_prev_logic_pwrst();
266 pwrdm_clear_all_prev_pwrst(mpuss_pd);
267 if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
268 (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF))
269 save_state = 2;
270
271 clear_cpu_prev_pwrst(cpu);
272 cpu_clear_prev_logic_pwrst(cpu);
273 set_cpu_next_pwrst(cpu, power_state);
274 set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
275 scu_pwrst_prepare(cpu, power_state);
276 l2x0_pwrst_prepare(cpu, save_state);
277
278 /*
279 * Call low level function with targeted low power state.
280 */
281 cpu_suspend(save_state, omap4_finish_suspend);
282
283 /*
284 * Restore the CPUx power state to ON otherwise CPUx
285 * power domain can transitions to programmed low power
286 * state while doing WFI outside the low powe code. On
287 * secure devices, CPUx does WFI which can result in
288 * domain transition
289 */
290 wakeup_cpu = smp_processor_id();
291 set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
292
293 pwrdm_post_transition();
294
295 return 0;
296}
297
298/**
299 * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
300 * @cpu : CPU ID
301 * @power_state: CPU low power state.
302 */
303int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
304{
305 unsigned int cpu_state = 0;
306
307 if (omap_rev() == OMAP4430_REV_ES1_0)
308 return -ENXIO;
309
310 if (power_state == PWRDM_POWER_OFF)
311 cpu_state = 1;
312
313 clear_cpu_prev_pwrst(cpu);
314 set_cpu_next_pwrst(cpu, power_state);
315 set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup));
316 scu_pwrst_prepare(cpu, power_state);
317
318 /*
319 * CPU never retuns back if targetted power state is OFF mode.
320 * CPU ONLINE follows normal CPU ONLINE ptah via
321 * omap_secondary_startup().
322 */
323 omap4_finish_suspend(cpu_state);
324
325 set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
326 return 0;
327}
328
329
330/*
331 * Initialise OMAP4 MPUSS
332 */
333int __init omap4_mpuss_init(void)
334{
335 struct omap4_cpu_pm_info *pm_info;
336
337 if (omap_rev() == OMAP4430_REV_ES1_0) {
338 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
339 return -ENODEV;
340 }
341
342 sar_base = omap4_get_sar_ram_base();
343
344 /* Initilaise per CPU PM information */
345 pm_info = &per_cpu(omap4_pm_info, 0x0);
346 pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
347 pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
348 pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
349 pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
350 if (!pm_info->pwrdm) {
351 pr_err("Lookup failed for CPU0 pwrdm\n");
352 return -ENODEV;
353 }
354
355 /* Clear CPU previous power domain state */
356 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
357 cpu_clear_prev_logic_pwrst(0);
358
359 /* Initialise CPU0 power domain state to ON */
360 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
361
362 pm_info = &per_cpu(omap4_pm_info, 0x1);
363 pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
364 pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
365 pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
366 pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
367 if (!pm_info->pwrdm) {
368 pr_err("Lookup failed for CPU1 pwrdm\n");
369 return -ENODEV;
370 }
371
372 /* Clear CPU previous power domain state */
373 pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
374 cpu_clear_prev_logic_pwrst(1);
375
376 /* Initialise CPU1 power domain state to ON */
377 pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
378
379 mpuss_pd = pwrdm_lookup("mpu_pwrdm");
380 if (!mpuss_pd) {
381 pr_err("Failed to lookup MPUSS power domain\n");
382 return -ENODEV;
383 }
384 pwrdm_clear_all_prev_pwrst(mpuss_pd);
385 mpuss_clear_prev_logic_pwrst();
386
387 /* Save device type on scratchpad for low level code to use */
388 if (omap_type() != OMAP2_DEVICE_TYPE_GP)
389 __raw_writel(1, sar_base + OMAP_TYPE_OFFSET);
390 else
391 __raw_writel(0, sar_base + OMAP_TYPE_OFFSET);
392
393 save_l2x0_context();
394
395 return 0;
396}
397
398#endif
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
new file mode 100644
index 00000000000..69f3c72d959
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -0,0 +1,81 @@
1/*
2 * OMAP Secure API infrastructure.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 *
8 * This program is free software,you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/memblock.h>
17
18#include <asm/cacheflush.h>
19
20#include <mach/omap-secure.h>
21
22static phys_addr_t omap_secure_memblock_base;
23
24/**
25 * omap_sec_dispatcher: Routine to dispatch low power secure
26 * service routines
27 * @idx: The HAL API index
28 * @flag: The flag indicating criticality of operation
29 * @nargs: Number of valid arguments out of four.
30 * @arg1, arg2, arg3 args4: Parameters passed to secure API
31 *
32 * Return the non-zero error value on failure.
33 */
34u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
35 u32 arg3, u32 arg4)
36{
37 u32 ret;
38 u32 param[5];
39
40 param[0] = nargs;
41 param[1] = arg1;
42 param[2] = arg2;
43 param[3] = arg3;
44 param[4] = arg4;
45
46 /*
47 * Secure API needs physical address
48 * pointer for the parameters
49 */
50 flush_cache_all();
51 outer_clean_range(__pa(param), __pa(param + 5));
52 ret = omap_smc2(idx, flag, __pa(param));
53
54 return ret;
55}
56
57/* Allocate the memory to save secure ram */
58int __init omap_secure_ram_reserve_memblock(void)
59{
60 phys_addr_t paddr;
61 u32 size = OMAP_SECURE_RAM_STORAGE;
62
63 size = ALIGN(size, SZ_1M);
64 paddr = memblock_alloc(size, SZ_1M);
65 if (!paddr) {
66 pr_err("%s: failed to reserve %x bytes\n",
67 __func__, size);
68 return -ENOMEM;
69 }
70 memblock_free(paddr, size);
71 memblock_remove(paddr, size);
72
73 omap_secure_memblock_base = paddr;
74
75 return 0;
76}
77
78phys_addr_t omap_secure_ram_mempool_base(void)
79{
80 return omap_secure_memblock_base;
81}
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap-smc.S
index e69d37d9520..f6441c13cd8 100644
--- a/arch/arm/mach-omap2/omap44xx-smc.S
+++ b/arch/arm/mach-omap2/omap-smc.S
@@ -31,6 +31,29 @@ ENTRY(omap_smc1)
31 ldmfd sp!, {r2-r12, pc} 31 ldmfd sp!, {r2-r12, pc}
32ENDPROC(omap_smc1) 32ENDPROC(omap_smc1)
33 33
34/**
35 * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
36 * Low level common routine for secure HAL and PPA APIs.
37 * @id: Application ID of HAL APIs
38 * @flag: Flag to indicate the criticality of operation
39 * @pargs: Physical address of parameter list starting
40 * with number of parametrs
41 */
42ENTRY(omap_smc2)
43 stmfd sp!, {r4-r12, lr}
44 mov r3, r2
45 mov r2, r1
46 mov r1, #0x0 @ Process ID
47 mov r6, #0xff
48 mov r12, #0x00 @ Secure Service ID
49 mov r7, #0
50 mcr p15, 0, r7, c7, c5, 6
51 dsb
52 dmb
53 smc #0
54 ldmfd sp!, {r4-r12, pc}
55ENDPROC(omap_smc2)
56
34ENTRY(omap_modify_auxcoreboot0) 57ENTRY(omap_modify_auxcoreboot0)
35 stmfd sp!, {r1-r12, lr} 58 stmfd sp!, {r1-r12, lr}
36 ldr r12, =0x104 59 ldr r12, =0x104
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index e99bc6cd471..c1bf3ef0ba0 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -24,17 +24,37 @@
24#include <asm/hardware/gic.h> 24#include <asm/hardware/gic.h>
25#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/omap-secure.h>
27 28
28#include "common.h" 29#include "common.h"
29 30
31#include "clockdomain.h"
32
30/* SCU base address */ 33/* SCU base address */
31static void __iomem *scu_base; 34static void __iomem *scu_base;
32 35
33static DEFINE_SPINLOCK(boot_lock); 36static DEFINE_SPINLOCK(boot_lock);
34 37
38void __iomem *omap4_get_scu_base(void)
39{
40 return scu_base;
41}
42
35void __cpuinit platform_secondary_init(unsigned int cpu) 43void __cpuinit platform_secondary_init(unsigned int cpu)
36{ 44{
37 /* 45 /*
46 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
47 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
48 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
49 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
50 * OMAP443X GP devices- SMP bit isn't accessible.
51 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
52 */
53 if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
54 omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
55 4, 0, 0, 0, 0, 0);
56
57 /*
38 * If any interrupts are already enabled for the primary 58 * If any interrupts are already enabled for the primary
39 * core (e.g. timer irq), then they will not have been enabled 59 * core (e.g. timer irq), then they will not have been enabled
40 * for us: do so 60 * for us: do so
@@ -50,6 +70,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
50 70
51int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) 71int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
52{ 72{
73 static struct clockdomain *cpu1_clkdm;
74 static bool booted;
53 /* 75 /*
54 * Set synchronisation state between this boot processor 76 * Set synchronisation state between this boot processor
55 * and the secondary one 77 * and the secondary one
@@ -65,6 +87,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
65 omap_modify_auxcoreboot0(0x200, 0xfffffdff); 87 omap_modify_auxcoreboot0(0x200, 0xfffffdff);
66 flush_cache_all(); 88 flush_cache_all();
67 smp_wmb(); 89 smp_wmb();
90
91 if (!cpu1_clkdm)
92 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
93
94 /*
95 * The SGI(Software Generated Interrupts) are not wakeup capable
96 * from low power states. This is known limitation on OMAP4 and
97 * needs to be worked around by using software forced clockdomain
98 * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to
99 * software force wakeup. The clockdomain is then put back to
100 * hardware supervised mode.
101 * More details can be found in OMAP4430 TRM - Version J
102 * Section :
103 * 4.3.4.2 Power States of CPU0 and CPU1
104 */
105 if (booted) {
106 clkdm_wakeup(cpu1_clkdm);
107 clkdm_allow_idle(cpu1_clkdm);
108 } else {
109 dsb_sev();
110 booted = true;
111 }
112
68 gic_raise_softirq(cpumask_of(cpu), 1); 113 gic_raise_softirq(cpumask_of(cpu), 1);
69 114
70 /* 115 /*
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
new file mode 100644
index 00000000000..d3d8971d7f3
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -0,0 +1,389 @@
1/*
2 * OMAP WakeupGen Source file
3 *
4 * OMAP WakeupGen is the interrupt controller extension used along
5 * with ARM GIC to wake the CPU out from low power states on
6 * external interrupts. It is responsible for generating wakeup
7 * event from the incoming interrupts and enable bits. It is
8 * implemented in MPU always ON power domain. During normal operation,
9 * WakeupGen delivers external interrupts directly to the GIC.
10 *
11 * Copyright (C) 2011 Texas Instruments, Inc.
12 * Santosh Shilimkar <santosh.shilimkar@ti.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/platform_device.h>
24#include <linux/cpu.h>
25#include <linux/notifier.h>
26#include <linux/cpu_pm.h>
27
28#include <asm/hardware/gic.h>
29
30#include <mach/omap-wakeupgen.h>
31#include <mach/omap-secure.h>
32
33#include "omap4-sar-layout.h"
34#include "common.h"
35
36#define NR_REG_BANKS 4
37#define MAX_IRQS 128
38#define WKG_MASK_ALL 0x00000000
39#define WKG_UNMASK_ALL 0xffffffff
40#define CPU_ENA_OFFSET 0x400
41#define CPU0_ID 0x0
42#define CPU1_ID 0x1
43
44static void __iomem *wakeupgen_base;
45static void __iomem *sar_base;
46static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks);
47static DEFINE_SPINLOCK(wakeupgen_lock);
48static unsigned int irq_target_cpu[NR_IRQS];
49
50/*
51 * Static helper functions.
52 */
53static inline u32 wakeupgen_readl(u8 idx, u32 cpu)
54{
55 return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 +
56 (cpu * CPU_ENA_OFFSET) + (idx * 4));
57}
58
59static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu)
60{
61 __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 +
62 (cpu * CPU_ENA_OFFSET) + (idx * 4));
63}
64
65static inline void sar_writel(u32 val, u32 offset, u8 idx)
66{
67 __raw_writel(val, sar_base + offset + (idx * 4));
68}
69
70static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
71{
72 u8 i;
73
74 for (i = 0; i < NR_REG_BANKS; i++)
75 wakeupgen_writel(reg, i, cpu);
76}
77
78static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index)
79{
80 unsigned int spi_irq;
81
82 /*
83 * PPIs and SGIs are not supported.
84 */
85 if (irq < OMAP44XX_IRQ_GIC_START)
86 return -EINVAL;
87
88 /*
89 * Subtract the GIC offset.
90 */
91 spi_irq = irq - OMAP44XX_IRQ_GIC_START;
92 if (spi_irq > MAX_IRQS) {
93 pr_err("omap wakeupGen: Invalid IRQ%d\n", irq);
94 return -EINVAL;
95 }
96
97 /*
98 * Each WakeupGen register controls 32 interrupt.
99 * i.e. 1 bit per SPI IRQ
100 */
101 *reg_index = spi_irq >> 5;
102 *bit_posn = spi_irq %= 32;
103
104 return 0;
105}
106
107static void _wakeupgen_clear(unsigned int irq, unsigned int cpu)
108{
109 u32 val, bit_number;
110 u8 i;
111
112 if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
113 return;
114
115 val = wakeupgen_readl(i, cpu);
116 val &= ~BIT(bit_number);
117 wakeupgen_writel(val, i, cpu);
118}
119
120static void _wakeupgen_set(unsigned int irq, unsigned int cpu)
121{
122 u32 val, bit_number;
123 u8 i;
124
125 if (_wakeupgen_get_irq_info(irq, &bit_number, &i))
126 return;
127
128 val = wakeupgen_readl(i, cpu);
129 val |= BIT(bit_number);
130 wakeupgen_writel(val, i, cpu);
131}
132
133static void _wakeupgen_save_masks(unsigned int cpu)
134{
135 u8 i;
136
137 for (i = 0; i < NR_REG_BANKS; i++)
138 per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu);
139}
140
141static void _wakeupgen_restore_masks(unsigned int cpu)
142{
143 u8 i;
144
145 for (i = 0; i < NR_REG_BANKS; i++)
146 wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu);
147}
148
149/*
150 * Architecture specific Mask extension
151 */
152static void wakeupgen_mask(struct irq_data *d)
153{
154 unsigned long flags;
155
156 spin_lock_irqsave(&wakeupgen_lock, flags);
157 _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]);
158 spin_unlock_irqrestore(&wakeupgen_lock, flags);
159}
160
161/*
162 * Architecture specific Unmask extension
163 */
164static void wakeupgen_unmask(struct irq_data *d)
165{
166 unsigned long flags;
167
168 spin_lock_irqsave(&wakeupgen_lock, flags);
169 _wakeupgen_set(d->irq, irq_target_cpu[d->irq]);
170 spin_unlock_irqrestore(&wakeupgen_lock, flags);
171}
172
173/*
174 * Mask or unmask all interrupts on given CPU.
175 * 0 = Mask all interrupts on the 'cpu'
176 * 1 = Unmask all interrupts on the 'cpu'
177 * Ensure that the initial mask is maintained. This is faster than
178 * iterating through GIC registers to arrive at the correct masks.
179 */
180static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
181{
182 unsigned long flags;
183
184 spin_lock_irqsave(&wakeupgen_lock, flags);
185 if (set) {
186 _wakeupgen_save_masks(cpu);
187 _wakeupgen_set_all(cpu, WKG_MASK_ALL);
188 } else {
189 _wakeupgen_set_all(cpu, WKG_UNMASK_ALL);
190 _wakeupgen_restore_masks(cpu);
191 }
192 spin_unlock_irqrestore(&wakeupgen_lock, flags);
193}
194
195#ifdef CONFIG_CPU_PM
196/*
197 * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
198 * ROM code. WakeupGen IP is integrated along with GIC to manage the
199 * interrupt wakeups from CPU low power states. It manages
200 * masking/unmasking of Shared peripheral interrupts(SPI). So the
201 * interrupt enable/disable control should be in sync and consistent
202 * at WakeupGen and GIC so that interrupts are not lost.
203 */
204static void irq_save_context(void)
205{
206 u32 i, val;
207
208 if (omap_rev() == OMAP4430_REV_ES1_0)
209 return;
210
211 if (!sar_base)
212 sar_base = omap4_get_sar_ram_base();
213
214 for (i = 0; i < NR_REG_BANKS; i++) {
215 /* Save the CPUx interrupt mask for IRQ 0 to 127 */
216 val = wakeupgen_readl(i, 0);
217 sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i);
218 val = wakeupgen_readl(i, 1);
219 sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i);
220
221 /*
222 * Disable the secure interrupts for CPUx. The restore
223 * code blindly restores secure and non-secure interrupt
224 * masks from SAR RAM. Secure interrupts are not suppose
225 * to be enabled from HLOS. So overwrite the SAR location
226 * so that the secure interrupt remains disabled.
227 */
228 sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
229 sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
230 }
231
232 /* Save AuxBoot* registers */
233 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
234 __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
235 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
236 __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
237
238 /* Save SyncReq generation logic */
239 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
240 __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
241 val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
242 __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
243
244 /* Save SyncReq generation logic */
245 val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
246 __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
247 val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
248 __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET);
249
250 /* Set the Backup Bit Mask status */
251 val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
252 val |= SAR_BACKUP_STATUS_WAKEUPGEN;
253 __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
254}
255
256/*
257 * Clear WakeupGen SAR backup status.
258 */
259void irq_sar_clear(void)
260{
261 u32 val;
262 val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
263 val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
264 __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
265}
266
267/*
268 * Save GIC and Wakeupgen interrupt context using secure API
269 * for HS/EMU devices.
270 */
271static void irq_save_secure_context(void)
272{
273 u32 ret;
274 ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
275 FLAG_START_CRITICAL,
276 0, 0, 0, 0, 0);
277 if (ret != API_HAL_RET_VALUE_OK)
278 pr_err("GIC and Wakeupgen context save failed\n");
279}
280#endif
281
282#ifdef CONFIG_HOTPLUG_CPU
283static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
284 unsigned long action, void *hcpu)
285{
286 unsigned int cpu = (unsigned int)hcpu;
287
288 switch (action) {
289 case CPU_ONLINE:
290 wakeupgen_irqmask_all(cpu, 0);
291 break;
292 case CPU_DEAD:
293 wakeupgen_irqmask_all(cpu, 1);
294 break;
295 }
296 return NOTIFY_OK;
297}
298
299static struct notifier_block __refdata irq_hotplug_notifier = {
300 .notifier_call = irq_cpu_hotplug_notify,
301};
302
303static void __init irq_hotplug_init(void)
304{
305 register_hotcpu_notifier(&irq_hotplug_notifier);
306}
307#else
308static void __init irq_hotplug_init(void)
309{}
310#endif
311
312#ifdef CONFIG_CPU_PM
313static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v)
314{
315 switch (cmd) {
316 case CPU_CLUSTER_PM_ENTER:
317 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
318 irq_save_context();
319 else
320 irq_save_secure_context();
321 break;
322 case CPU_CLUSTER_PM_EXIT:
323 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
324 irq_sar_clear();
325 break;
326 }
327 return NOTIFY_OK;
328}
329
330static struct notifier_block irq_notifier_block = {
331 .notifier_call = irq_notifier,
332};
333
334static void __init irq_pm_init(void)
335{
336 cpu_pm_register_notifier(&irq_notifier_block);
337}
338#else
339static void __init irq_pm_init(void)
340{}
341#endif
342
343/*
344 * Initialise the wakeupgen module.
345 */
346int __init omap_wakeupgen_init(void)
347{
348 int i;
349 unsigned int boot_cpu = smp_processor_id();
350
351 /* Not supported on OMAP4 ES1.0 silicon */
352 if (omap_rev() == OMAP4430_REV_ES1_0) {
353 WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n");
354 return -EPERM;
355 }
356
357 /* Static mapping, never released */
358 wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K);
359 if (WARN_ON(!wakeupgen_base))
360 return -ENOMEM;
361
362 /* Clear all IRQ bitmasks at wakeupGen level */
363 for (i = 0; i < NR_REG_BANKS; i++) {
364 wakeupgen_writel(0, i, CPU0_ID);
365 wakeupgen_writel(0, i, CPU1_ID);
366 }
367
368 /*
369 * Override GIC architecture specific functions to add
370 * OMAP WakeupGen interrupt controller along with GIC
371 */
372 gic_arch_extn.irq_mask = wakeupgen_mask;
373 gic_arch_extn.irq_unmask = wakeupgen_unmask;
374 gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;
375
376 /*
377 * FIXME: Add support to set_smp_affinity() once the core
378 * GIC code has necessary hooks in place.
379 */
380
381 /* Associate all the IRQs to boot CPU like GIC init does. */
382 for (i = 0; i < NR_IRQS; i++)
383 irq_target_cpu[i] = boot_cpu;
384
385 irq_hotplug_init();
386 irq_pm_init();
387
388 return 0;
389}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index beecfdd56ea..bc16c818c6b 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -15,18 +15,73 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/memblock.h>
18 19
19#include <asm/hardware/gic.h> 20#include <asm/hardware/gic.h>
20#include <asm/hardware/cache-l2x0.h> 21#include <asm/hardware/cache-l2x0.h>
22#include <asm/mach/map.h>
21 23
22#include <plat/irqs.h> 24#include <plat/irqs.h>
25#include <plat/sram.h>
23 26
24#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/omap-wakeupgen.h>
25 29
26#include "common.h" 30#include "common.h"
31#include "omap4-sar-layout.h"
27 32
28#ifdef CONFIG_CACHE_L2X0 33#ifdef CONFIG_CACHE_L2X0
29void __iomem *l2cache_base; 34static void __iomem *l2cache_base;
35#endif
36
37static void __iomem *sar_ram_base;
38
39#ifdef CONFIG_OMAP4_ERRATA_I688
40/* Used to implement memory barrier on DRAM path */
41#define OMAP4_DRAM_BARRIER_VA 0xfe600000
42
43void __iomem *dram_sync, *sram_sync;
44
45void omap_bus_sync(void)
46{
47 if (dram_sync && sram_sync) {
48 writel_relaxed(readl_relaxed(dram_sync), dram_sync);
49 writel_relaxed(readl_relaxed(sram_sync), sram_sync);
50 isb();
51 }
52}
53
54static int __init omap_barriers_init(void)
55{
56 struct map_desc dram_io_desc[1];
57 phys_addr_t paddr;
58 u32 size;
59
60 if (!cpu_is_omap44xx())
61 return -ENODEV;
62
63 size = ALIGN(PAGE_SIZE, SZ_1M);
64 paddr = memblock_alloc(size, SZ_1M);
65 if (!paddr) {
66 pr_err("%s: failed to reserve 4 Kbytes\n", __func__);
67 return -ENOMEM;
68 }
69 memblock_free(paddr, size);
70 memblock_remove(paddr, size);
71 dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
72 dram_io_desc[0].pfn = __phys_to_pfn(paddr);
73 dram_io_desc[0].length = size;
74 dram_io_desc[0].type = MT_MEMORY_SO;
75 iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
76 dram_sync = (void __iomem *) dram_io_desc[0].virtual;
77 sram_sync = (void __iomem *) OMAP4_SRAM_VA;
78
79 pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
80 (long long) paddr, dram_io_desc[0].virtual);
81
82 return 0;
83}
84core_initcall(omap_barriers_init);
30#endif 85#endif
31 86
32void __init gic_init_irq(void) 87void __init gic_init_irq(void)
@@ -42,11 +97,18 @@ void __init gic_init_irq(void)
42 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); 97 omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
43 BUG_ON(!omap_irq_base); 98 BUG_ON(!omap_irq_base);
44 99
100 omap_wakeupgen_init();
101
45 gic_init(0, 29, gic_dist_base_addr, omap_irq_base); 102 gic_init(0, 29, gic_dist_base_addr, omap_irq_base);
46} 103}
47 104
48#ifdef CONFIG_CACHE_L2X0 105#ifdef CONFIG_CACHE_L2X0
49 106
107void __iomem *omap4_get_l2cache_base(void)
108{
109 return l2cache_base;
110}
111
50static void omap4_l2x0_disable(void) 112static void omap4_l2x0_disable(void)
51{ 113{
52 /* Disable PL310 L2 Cache controller */ 114 /* Disable PL310 L2 Cache controller */
@@ -72,7 +134,8 @@ static int __init omap_l2_cache_init(void)
72 134
73 /* Static mapping, never released */ 135 /* Static mapping, never released */
74 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); 136 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
75 BUG_ON(!l2cache_base); 137 if (WARN_ON(!l2cache_base))
138 return -ENOMEM;
76 139
77 /* 140 /*
78 * 16-way associativity, parity disabled 141 * 16-way associativity, parity disabled
@@ -112,3 +175,30 @@ static int __init omap_l2_cache_init(void)
112} 175}
113early_initcall(omap_l2_cache_init); 176early_initcall(omap_l2_cache_init);
114#endif 177#endif
178
179void __iomem *omap4_get_sar_ram_base(void)
180{
181 return sar_ram_base;
182}
183
184/*
185 * SAR RAM used to save and restore the HW
186 * context in low power modes
187 */
188static int __init omap4_sar_ram_init(void)
189{
190 /*
191 * To avoid code running on other OMAPs in
192 * multi-omap builds
193 */
194 if (!cpu_is_omap44xx())
195 return -ENOMEM;
196
197 /* Static mapping, never released */
198 sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
199 if (WARN_ON(!sar_ram_base))
200 return -ENOMEM;
201
202 return 0;
203}
204early_initcall(omap4_sar_ram_init);
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
new file mode 100644
index 00000000000..fe5b545ad44
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -0,0 +1,50 @@
1/*
2 * omap4-sar-layout.h: OMAP4 SAR RAM layout header file
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H
12#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H
13
14/*
15 * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE
16 */
17#define SAR_BANK1_OFFSET 0x0000
18#define SAR_BANK2_OFFSET 0x1000
19#define SAR_BANK3_OFFSET 0x2000
20#define SAR_BANK4_OFFSET 0x3000
21
22/* Scratch pad memory offsets from SAR_BANK1 */
23#define SCU_OFFSET0 0xd00
24#define SCU_OFFSET1 0xd04
25#define OMAP_TYPE_OFFSET 0xd10
26#define L2X0_SAVE_OFFSET0 0xd14
27#define L2X0_SAVE_OFFSET1 0xd18
28#define L2X0_AUXCTRL_OFFSET 0xd1c
29#define L2X0_PREFETCH_CTRL_OFFSET 0xd20
30
31/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
32#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
33#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08
34
35#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)
36#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)
37#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508)
38
39/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */
40#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
41#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694)
42#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4)
43#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4)
44#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4)
45#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8)
46#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc)
47#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0)
48#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10
49
50#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 529142aff76..5192cabb40e 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -136,6 +136,7 @@
136#include <linux/list.h> 136#include <linux/list.h>
137#include <linux/mutex.h> 137#include <linux/mutex.h>
138#include <linux/spinlock.h> 138#include <linux/spinlock.h>
139#include <linux/slab.h>
139 140
140#include "common.h" 141#include "common.h"
141#include <plat/cpu.h> 142#include <plat/cpu.h>
@@ -381,6 +382,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
381} 382}
382 383
383/** 384/**
385 * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux
386 * @oh: struct omap_hwmod *
387 * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable
388 *
389 * Set or clear the I/O pad wakeup flag in the mux entries for the
390 * hwmod @oh. This function changes the @oh->mux->pads_dynamic array
391 * in memory. If the hwmod is currently idled, and the new idle
392 * values don't match the previous ones, this function will also
393 * update the SCM PADCTRL registers. Otherwise, if the hwmod is not
394 * currently idled, this function won't touch the hardware: the new
395 * mux settings are written to the SCM PADCTRL registers when the
396 * hwmod is idled. No return value.
397 */
398static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake)
399{
400 struct omap_device_pad *pad;
401 bool change = false;
402 u16 prev_idle;
403 int j;
404
405 if (!oh->mux || !oh->mux->enabled)
406 return;
407
408 for (j = 0; j < oh->mux->nr_pads_dynamic; j++) {
409 pad = oh->mux->pads_dynamic[j];
410
411 if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP))
412 continue;
413
414 prev_idle = pad->idle;
415
416 if (set_wake)
417 pad->idle |= OMAP_WAKEUP_EN;
418 else
419 pad->idle &= ~OMAP_WAKEUP_EN;
420
421 if (prev_idle != pad->idle)
422 change = true;
423 }
424
425 if (change && oh->_state == _HWMOD_STATE_IDLE)
426 omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
427}
428
429/**
384 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware 430 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
385 * @oh: struct omap_hwmod * 431 * @oh: struct omap_hwmod *
386 * 432 *
@@ -706,27 +752,65 @@ static void _enable_module(struct omap_hwmod *oh)
706} 752}
707 753
708/** 754/**
709 * _disable_module - enable CLKCTRL modulemode on OMAP4 755 * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4
756 * @oh: struct omap_hwmod *
757 *
758 * Wait for a module @oh to enter slave idle. Returns 0 if the module
759 * does not have an IDLEST bit or if the module successfully enters
760 * slave idle; otherwise, pass along the return value of the
761 * appropriate *_cm*_wait_module_idle() function.
762 */
763static int _omap4_wait_target_disable(struct omap_hwmod *oh)
764{
765 if (!cpu_is_omap44xx())
766 return 0;
767
768 if (!oh)
769 return -EINVAL;
770
771 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
772 return 0;
773
774 if (oh->flags & HWMOD_NO_IDLEST)
775 return 0;
776
777 return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition,
778 oh->clkdm->cm_inst,
779 oh->clkdm->clkdm_offs,
780 oh->prcm.omap4.clkctrl_offs);
781}
782
783/**
784 * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
710 * @oh: struct omap_hwmod * 785 * @oh: struct omap_hwmod *
711 * 786 *
712 * Disable the PRCM module mode related to the hwmod @oh. 787 * Disable the PRCM module mode related to the hwmod @oh.
713 * No return value. 788 * Return EINVAL if the modulemode is not supported and 0 in case of success.
714 */ 789 */
715static void _disable_module(struct omap_hwmod *oh) 790static int _omap4_disable_module(struct omap_hwmod *oh)
716{ 791{
792 int v;
793
717 /* The module mode does not exist prior OMAP4 */ 794 /* The module mode does not exist prior OMAP4 */
718 if (cpu_is_omap24xx() || cpu_is_omap34xx()) 795 if (!cpu_is_omap44xx())
719 return; 796 return -EINVAL;
720 797
721 if (!oh->clkdm || !oh->prcm.omap4.modulemode) 798 if (!oh->clkdm || !oh->prcm.omap4.modulemode)
722 return; 799 return -EINVAL;
723 800
724 pr_debug("omap_hwmod: %s: _disable_module\n", oh->name); 801 pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
725 802
726 omap4_cminst_module_disable(oh->clkdm->prcm_partition, 803 omap4_cminst_module_disable(oh->clkdm->prcm_partition,
727 oh->clkdm->cm_inst, 804 oh->clkdm->cm_inst,
728 oh->clkdm->clkdm_offs, 805 oh->clkdm->clkdm_offs,
729 oh->prcm.omap4.clkctrl_offs); 806 oh->prcm.omap4.clkctrl_offs);
807
808 v = _omap4_wait_target_disable(oh);
809 if (v)
810 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
811 oh->name);
812
813 return 0;
730} 814}
731 815
732/** 816/**
@@ -1153,36 +1237,6 @@ static int _wait_target_ready(struct omap_hwmod *oh)
1153} 1237}
1154 1238
1155/** 1239/**
1156 * _wait_target_disable - wait for a module to be disabled
1157 * @oh: struct omap_hwmod *
1158 *
1159 * Wait for a module @oh to enter slave idle. Returns 0 if the module
1160 * does not have an IDLEST bit or if the module successfully enters
1161 * slave idle; otherwise, pass along the return value of the
1162 * appropriate *_cm*_wait_module_idle() function.
1163 */
1164static int _wait_target_disable(struct omap_hwmod *oh)
1165{
1166 /* TODO: For now just handle OMAP4+ */
1167 if (cpu_is_omap24xx() || cpu_is_omap34xx())
1168 return 0;
1169
1170 if (!oh)
1171 return -EINVAL;
1172
1173 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1174 return 0;
1175
1176 if (oh->flags & HWMOD_NO_IDLEST)
1177 return 0;
1178
1179 return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition,
1180 oh->clkdm->cm_inst,
1181 oh->clkdm->clkdm_offs,
1182 oh->prcm.omap4.clkctrl_offs);
1183}
1184
1185/**
1186 * _lookup_hardreset - fill register bit info for this hwmod/reset line 1240 * _lookup_hardreset - fill register bit info for this hwmod/reset line
1187 * @oh: struct omap_hwmod * 1241 * @oh: struct omap_hwmod *
1188 * @name: name of the reset line in the context of this hwmod 1242 * @name: name of the reset line in the context of this hwmod
@@ -1441,6 +1495,25 @@ static int _enable(struct omap_hwmod *oh)
1441 1495
1442 pr_debug("omap_hwmod: %s: enabling\n", oh->name); 1496 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
1443 1497
1498 /*
1499 * hwmods with HWMOD_INIT_NO_IDLE flag set are left
1500 * in enabled state at init.
1501 * Now that someone is really trying to enable them,
1502 * just ensure that the hwmod mux is set.
1503 */
1504 if (oh->_int_flags & _HWMOD_SKIP_ENABLE) {
1505 /*
1506 * If the caller has mux data populated, do the mux'ing
1507 * which wouldn't have been done as part of the _enable()
1508 * done during setup.
1509 */
1510 if (oh->mux)
1511 omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
1512
1513 oh->_int_flags &= ~_HWMOD_SKIP_ENABLE;
1514 return 0;
1515 }
1516
1444 if (oh->_state != _HWMOD_STATE_INITIALIZED && 1517 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
1445 oh->_state != _HWMOD_STATE_IDLE && 1518 oh->_state != _HWMOD_STATE_IDLE &&
1446 oh->_state != _HWMOD_STATE_DISABLED) { 1519 oh->_state != _HWMOD_STATE_DISABLED) {
@@ -1524,8 +1597,6 @@ static int _enable(struct omap_hwmod *oh)
1524 */ 1597 */
1525static int _idle(struct omap_hwmod *oh) 1598static int _idle(struct omap_hwmod *oh)
1526{ 1599{
1527 int ret;
1528
1529 pr_debug("omap_hwmod: %s: idling\n", oh->name); 1600 pr_debug("omap_hwmod: %s: idling\n", oh->name);
1530 1601
1531 if (oh->_state != _HWMOD_STATE_ENABLED) { 1602 if (oh->_state != _HWMOD_STATE_ENABLED) {
@@ -1537,11 +1608,9 @@ static int _idle(struct omap_hwmod *oh)
1537 if (oh->class->sysc) 1608 if (oh->class->sysc)
1538 _idle_sysc(oh); 1609 _idle_sysc(oh);
1539 _del_initiator_dep(oh, mpu_oh); 1610 _del_initiator_dep(oh, mpu_oh);
1540 _disable_module(oh); 1611
1541 ret = _wait_target_disable(oh); 1612 _omap4_disable_module(oh);
1542 if (ret) 1613
1543 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1544 oh->name);
1545 /* 1614 /*
1546 * The module must be in idle mode before disabling any parents 1615 * The module must be in idle mode before disabling any parents
1547 * clocks. Otherwise, the parent clock might be disabled before 1616 * clocks. Otherwise, the parent clock might be disabled before
@@ -1642,11 +1711,7 @@ static int _shutdown(struct omap_hwmod *oh)
1642 if (oh->_state == _HWMOD_STATE_ENABLED) { 1711 if (oh->_state == _HWMOD_STATE_ENABLED) {
1643 _del_initiator_dep(oh, mpu_oh); 1712 _del_initiator_dep(oh, mpu_oh);
1644 /* XXX what about the other system initiators here? dma, dsp */ 1713 /* XXX what about the other system initiators here? dma, dsp */
1645 _disable_module(oh); 1714 _omap4_disable_module(oh);
1646 ret = _wait_target_disable(oh);
1647 if (ret)
1648 pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
1649 oh->name);
1650 _disable_clocks(oh); 1715 _disable_clocks(oh);
1651 if (oh->clkdm) 1716 if (oh->clkdm)
1652 clkdm_hwmod_disable(oh->clkdm, oh); 1717 clkdm_hwmod_disable(oh->clkdm, oh);
@@ -1744,8 +1809,10 @@ static int _setup(struct omap_hwmod *oh, void *data)
1744 * it should be set by the core code as a runtime flag during startup 1809 * it should be set by the core code as a runtime flag during startup
1745 */ 1810 */
1746 if ((oh->flags & HWMOD_INIT_NO_IDLE) && 1811 if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
1747 (postsetup_state == _HWMOD_STATE_IDLE)) 1812 (postsetup_state == _HWMOD_STATE_IDLE)) {
1813 oh->_int_flags |= _HWMOD_SKIP_ENABLE;
1748 postsetup_state = _HWMOD_STATE_ENABLED; 1814 postsetup_state = _HWMOD_STATE_ENABLED;
1815 }
1749 1816
1750 if (postsetup_state == _HWMOD_STATE_IDLE) 1817 if (postsetup_state == _HWMOD_STATE_IDLE)
1751 _idle(oh); 1818 _idle(oh);
@@ -2416,6 +2483,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
2416 v = oh->_sysc_cache; 2483 v = oh->_sysc_cache;
2417 _enable_wakeup(oh, &v); 2484 _enable_wakeup(oh, &v);
2418 _write_sysconfig(v, oh); 2485 _write_sysconfig(v, oh);
2486 _set_idle_ioring_wakeup(oh, true);
2419 spin_unlock_irqrestore(&oh->_lock, flags); 2487 spin_unlock_irqrestore(&oh->_lock, flags);
2420 2488
2421 return 0; 2489 return 0;
@@ -2446,6 +2514,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
2446 v = oh->_sysc_cache; 2514 v = oh->_sysc_cache;
2447 _disable_wakeup(oh, &v); 2515 _disable_wakeup(oh, &v);
2448 _write_sysconfig(v, oh); 2516 _write_sysconfig(v, oh);
2517 _set_idle_ioring_wakeup(oh, false);
2449 spin_unlock_irqrestore(&oh->_lock, flags); 2518 spin_unlock_irqrestore(&oh->_lock, flags);
2450 2519
2451 return 0; 2520 return 0;
@@ -2662,3 +2731,57 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
2662 2731
2663 return 0; 2732 return 0;
2664} 2733}
2734
2735/**
2736 * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ
2737 * @oh: struct omap_hwmod * containing hwmod mux entries
2738 * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup
2739 * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup
2740 *
2741 * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux
2742 * entry number @pad_idx for the hwmod @oh, trigger the interrupt
2743 * service routine for the hwmod's mpu_irqs array index @irq_idx. If
2744 * this function is not called for a given pad_idx, then the ISR
2745 * associated with @oh's first MPU IRQ will be triggered when an I/O
2746 * pad wakeup occurs on that pad. Note that @pad_idx is the index of
2747 * the _dynamic or wakeup_ entry: if there are other entries not
2748 * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these
2749 * entries are NOT COUNTED in the dynamic pad index. This function
2750 * must be called separately for each pad that requires its interrupt
2751 * to be re-routed this way. Returns -EINVAL if there is an argument
2752 * problem or if @oh does not have hwmod mux entries or MPU IRQs;
2753 * returns -ENOMEM if memory cannot be allocated; or 0 upon success.
2754 *
2755 * XXX This function interface is fragile. Rather than using array
2756 * indexes, which are subject to unpredictable change, it should be
2757 * using hwmod IRQ names, and some other stable key for the hwmod mux
2758 * pad records.
2759 */
2760int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
2761{
2762 int nr_irqs;
2763
2764 might_sleep();
2765
2766 if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
2767 pad_idx >= oh->mux->nr_pads_dynamic)
2768 return -EINVAL;
2769
2770 /* Check the number of available mpu_irqs */
2771 for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
2772 ;
2773
2774 if (irq_idx >= nr_irqs)
2775 return -EINVAL;
2776
2777 if (!oh->mux->irqs) {
2778 /* XXX What frees this? */
2779 oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
2780 GFP_KERNEL);
2781 if (!oh->mux->irqs)
2782 return -ENOMEM;
2783 }
2784 oh->mux->irqs[pad_idx] = irq_idx;
2785
2786 return 0;
2787}
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index eef43e2e163..5324e8d93bc 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -84,6 +84,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
84static struct omap_hwmod omap3xxx_mcbsp5_hwmod; 84static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
85static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod; 85static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
86static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod; 86static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
87static struct omap_hwmod omap3xxx_usb_host_hs_hwmod;
88static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod;
87 89
88/* L3 -> L4_CORE interface */ 90/* L3 -> L4_CORE interface */
89static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { 91static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -164,6 +166,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod;
164static struct omap_hwmod omap3xxx_uart2_hwmod; 166static struct omap_hwmod omap3xxx_uart2_hwmod;
165static struct omap_hwmod omap3xxx_uart3_hwmod; 167static struct omap_hwmod omap3xxx_uart3_hwmod;
166static struct omap_hwmod omap3xxx_uart4_hwmod; 168static struct omap_hwmod omap3xxx_uart4_hwmod;
169static struct omap_hwmod am35xx_uart4_hwmod;
167static struct omap_hwmod omap3xxx_usbhsotg_hwmod; 170static struct omap_hwmod omap3xxx_usbhsotg_hwmod;
168 171
169/* l3_core -> usbhsotg interface */ 172/* l3_core -> usbhsotg interface */
@@ -299,6 +302,23 @@ static struct omap_hwmod_ocp_if omap3_l4_per__uart4 = {
299 .user = OCP_USER_MPU | OCP_USER_SDMA, 302 .user = OCP_USER_MPU | OCP_USER_SDMA,
300}; 303};
301 304
305/* AM35xx: L4 CORE -> UART4 interface */
306static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = {
307 {
308 .pa_start = OMAP3_UART4_AM35XX_BASE,
309 .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1,
310 .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
311 },
312};
313
314static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = {
315 .master = &omap3xxx_l4_core_hwmod,
316 .slave = &am35xx_uart4_hwmod,
317 .clk = "uart4_ick",
318 .addr = am35xx_uart4_addr_space,
319 .user = OCP_USER_MPU | OCP_USER_SDMA,
320};
321
302/* L4 CORE -> I2C1 interface */ 322/* L4 CORE -> I2C1 interface */
303static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = { 323static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = {
304 .master = &omap3xxx_l4_core_hwmod, 324 .master = &omap3xxx_l4_core_hwmod,
@@ -1162,6 +1182,7 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = {
1162 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | 1182 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
1163 SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), 1183 SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
1164 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), 1184 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
1185 .clockact = CLOCKACT_TEST_ICLK,
1165 .sysc_fields = &omap_hwmod_sysc_type1, 1186 .sysc_fields = &omap_hwmod_sysc_type1,
1166}; 1187};
1167 1188
@@ -1309,6 +1330,39 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = {
1309 .class = &omap2_uart_class, 1330 .class = &omap2_uart_class,
1310}; 1331};
1311 1332
1333static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = {
1334 { .irq = INT_35XX_UART4_IRQ, },
1335};
1336
1337static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = {
1338 { .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, },
1339 { .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, },
1340};
1341
1342static struct omap_hwmod_ocp_if *am35xx_uart4_slaves[] = {
1343 &am35xx_l4_core__uart4,
1344};
1345
1346static struct omap_hwmod am35xx_uart4_hwmod = {
1347 .name = "uart4",
1348 .mpu_irqs = am35xx_uart4_mpu_irqs,
1349 .sdma_reqs = am35xx_uart4_sdma_reqs,
1350 .main_clk = "uart4_fck",
1351 .prcm = {
1352 .omap2 = {
1353 .module_offs = CORE_MOD,
1354 .prcm_reg_id = 1,
1355 .module_bit = OMAP3430_EN_UART4_SHIFT,
1356 .idlest_reg_id = 1,
1357 .idlest_idle_bit = OMAP3430_EN_UART4_SHIFT,
1358 },
1359 },
1360 .slaves = am35xx_uart4_slaves,
1361 .slaves_cnt = ARRAY_SIZE(am35xx_uart4_slaves),
1362 .class = &omap2_uart_class,
1363};
1364
1365
1312static struct omap_hwmod_class i2c_class = { 1366static struct omap_hwmod_class i2c_class = {
1313 .name = "i2c", 1367 .name = "i2c",
1314 .sysc = &i2c_sysc, 1368 .sysc = &i2c_sysc,
@@ -1636,7 +1690,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = {
1636 1690
1637static struct omap_hwmod omap3xxx_i2c1_hwmod = { 1691static struct omap_hwmod omap3xxx_i2c1_hwmod = {
1638 .name = "i2c1", 1692 .name = "i2c1",
1639 .flags = HWMOD_16BIT_REG, 1693 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1640 .mpu_irqs = omap2_i2c1_mpu_irqs, 1694 .mpu_irqs = omap2_i2c1_mpu_irqs,
1641 .sdma_reqs = omap2_i2c1_sdma_reqs, 1695 .sdma_reqs = omap2_i2c1_sdma_reqs,
1642 .main_clk = "i2c1_fck", 1696 .main_clk = "i2c1_fck",
@@ -1670,7 +1724,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = {
1670 1724
1671static struct omap_hwmod omap3xxx_i2c2_hwmod = { 1725static struct omap_hwmod omap3xxx_i2c2_hwmod = {
1672 .name = "i2c2", 1726 .name = "i2c2",
1673 .flags = HWMOD_16BIT_REG, 1727 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1674 .mpu_irqs = omap2_i2c2_mpu_irqs, 1728 .mpu_irqs = omap2_i2c2_mpu_irqs,
1675 .sdma_reqs = omap2_i2c2_sdma_reqs, 1729 .sdma_reqs = omap2_i2c2_sdma_reqs,
1676 .main_clk = "i2c2_fck", 1730 .main_clk = "i2c2_fck",
@@ -1715,7 +1769,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = {
1715 1769
1716static struct omap_hwmod omap3xxx_i2c3_hwmod = { 1770static struct omap_hwmod omap3xxx_i2c3_hwmod = {
1717 .name = "i2c3", 1771 .name = "i2c3",
1718 .flags = HWMOD_16BIT_REG, 1772 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
1719 .mpu_irqs = i2c3_mpu_irqs, 1773 .mpu_irqs = i2c3_mpu_irqs,
1720 .sdma_reqs = i2c3_sdma_reqs, 1774 .sdma_reqs = i2c3_sdma_reqs,
1721 .main_clk = "i2c3_fck", 1775 .main_clk = "i2c3_fck",
@@ -3072,7 +3126,35 @@ static struct omap_mmc_dev_attr mmc1_dev_attr = {
3072 .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, 3126 .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
3073}; 3127};
3074 3128
3075static struct omap_hwmod omap3xxx_mmc1_hwmod = { 3129/* See 35xx errata 2.1.1.128 in SPRZ278F */
3130static struct omap_mmc_dev_attr mmc1_pre_es3_dev_attr = {
3131 .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT |
3132 OMAP_HSMMC_BROKEN_MULTIBLOCK_READ),
3133};
3134
3135static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = {
3136 .name = "mmc1",
3137 .mpu_irqs = omap34xx_mmc1_mpu_irqs,
3138 .sdma_reqs = omap34xx_mmc1_sdma_reqs,
3139 .opt_clks = omap34xx_mmc1_opt_clks,
3140 .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks),
3141 .main_clk = "mmchs1_fck",
3142 .prcm = {
3143 .omap2 = {
3144 .module_offs = CORE_MOD,
3145 .prcm_reg_id = 1,
3146 .module_bit = OMAP3430_EN_MMC1_SHIFT,
3147 .idlest_reg_id = 1,
3148 .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT,
3149 },
3150 },
3151 .dev_attr = &mmc1_pre_es3_dev_attr,
3152 .slaves = omap3xxx_mmc1_slaves,
3153 .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves),
3154 .class = &omap34xx_mmc_class,
3155};
3156
3157static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = {
3076 .name = "mmc1", 3158 .name = "mmc1",
3077 .mpu_irqs = omap34xx_mmc1_mpu_irqs, 3159 .mpu_irqs = omap34xx_mmc1_mpu_irqs,
3078 .sdma_reqs = omap34xx_mmc1_sdma_reqs, 3160 .sdma_reqs = omap34xx_mmc1_sdma_reqs,
@@ -3115,7 +3197,34 @@ static struct omap_hwmod_ocp_if *omap3xxx_mmc2_slaves[] = {
3115 &omap3xxx_l4_core__mmc2, 3197 &omap3xxx_l4_core__mmc2,
3116}; 3198};
3117 3199
3118static struct omap_hwmod omap3xxx_mmc2_hwmod = { 3200/* See 35xx errata 2.1.1.128 in SPRZ278F */
3201static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = {
3202 .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ,
3203};
3204
3205static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = {
3206 .name = "mmc2",
3207 .mpu_irqs = omap34xx_mmc2_mpu_irqs,
3208 .sdma_reqs = omap34xx_mmc2_sdma_reqs,
3209 .opt_clks = omap34xx_mmc2_opt_clks,
3210 .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks),
3211 .main_clk = "mmchs2_fck",
3212 .prcm = {
3213 .omap2 = {
3214 .module_offs = CORE_MOD,
3215 .prcm_reg_id = 1,
3216 .module_bit = OMAP3430_EN_MMC2_SHIFT,
3217 .idlest_reg_id = 1,
3218 .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT,
3219 },
3220 },
3221 .dev_attr = &mmc2_pre_es3_dev_attr,
3222 .slaves = omap3xxx_mmc2_slaves,
3223 .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves),
3224 .class = &omap34xx_mmc_class,
3225};
3226
3227static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = {
3119 .name = "mmc2", 3228 .name = "mmc2",
3120 .mpu_irqs = omap34xx_mmc2_mpu_irqs, 3229 .mpu_irqs = omap34xx_mmc2_mpu_irqs,
3121 .sdma_reqs = omap34xx_mmc2_sdma_reqs, 3230 .sdma_reqs = omap34xx_mmc2_sdma_reqs,
@@ -3177,13 +3286,223 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
3177 .class = &omap34xx_mmc_class, 3286 .class = &omap34xx_mmc_class,
3178}; 3287};
3179 3288
3289/*
3290 * 'usb_host_hs' class
3291 * high-speed multi-port usb host controller
3292 */
3293static struct omap_hwmod_ocp_if omap3xxx_usb_host_hs__l3_main_2 = {
3294 .master = &omap3xxx_usb_host_hs_hwmod,
3295 .slave = &omap3xxx_l3_main_hwmod,
3296 .clk = "core_l3_ick",
3297 .user = OCP_USER_MPU,
3298};
3299
3300static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = {
3301 .rev_offs = 0x0000,
3302 .sysc_offs = 0x0010,
3303 .syss_offs = 0x0014,
3304 .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
3305 SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
3306 SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
3307 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
3308 MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
3309 .sysc_fields = &omap_hwmod_sysc_type1,
3310};
3311
3312static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
3313 .name = "usb_host_hs",
3314 .sysc = &omap3xxx_usb_host_hs_sysc,
3315};
3316
3317static struct omap_hwmod_ocp_if *omap3xxx_usb_host_hs_masters[] = {
3318 &omap3xxx_usb_host_hs__l3_main_2,
3319};
3320
3321static struct omap_hwmod_addr_space omap3xxx_usb_host_hs_addrs[] = {
3322 {
3323 .name = "uhh",
3324 .pa_start = 0x48064000,
3325 .pa_end = 0x480643ff,
3326 .flags = ADDR_TYPE_RT
3327 },
3328 {
3329 .name = "ohci",
3330 .pa_start = 0x48064400,
3331 .pa_end = 0x480647ff,
3332 },
3333 {
3334 .name = "ehci",
3335 .pa_start = 0x48064800,
3336 .pa_end = 0x48064cff,
3337 },
3338 {}
3339};
3340
3341static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_host_hs = {
3342 .master = &omap3xxx_l4_core_hwmod,
3343 .slave = &omap3xxx_usb_host_hs_hwmod,
3344 .clk = "usbhost_ick",
3345 .addr = omap3xxx_usb_host_hs_addrs,
3346 .user = OCP_USER_MPU | OCP_USER_SDMA,
3347};
3348
3349static struct omap_hwmod_ocp_if *omap3xxx_usb_host_hs_slaves[] = {
3350 &omap3xxx_l4_core__usb_host_hs,
3351};
3352
3353static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
3354 { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
3355};
3356
3357static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
3358 { .name = "ohci-irq", .irq = 76 },
3359 { .name = "ehci-irq", .irq = 77 },
3360 { .irq = -1 }
3361};
3362
3363static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
3364 .name = "usb_host_hs",
3365 .class = &omap3xxx_usb_host_hs_hwmod_class,
3366 .clkdm_name = "l3_init_clkdm",
3367 .mpu_irqs = omap3xxx_usb_host_hs_irqs,
3368 .main_clk = "usbhost_48m_fck",
3369 .prcm = {
3370 .omap2 = {
3371 .module_offs = OMAP3430ES2_USBHOST_MOD,
3372 .prcm_reg_id = 1,
3373 .module_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
3374 .idlest_reg_id = 1,
3375 .idlest_idle_bit = OMAP3430ES2_ST_USBHOST_IDLE_SHIFT,
3376 .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
3377 },
3378 },
3379 .opt_clks = omap3xxx_usb_host_hs_opt_clks,
3380 .opt_clks_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
3381 .slaves = omap3xxx_usb_host_hs_slaves,
3382 .slaves_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_slaves),
3383 .masters = omap3xxx_usb_host_hs_masters,
3384 .masters_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_masters),
3385
3386 /*
3387 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
3388 * id: i660
3389 *
3390 * Description:
3391 * In the following configuration :
3392 * - USBHOST module is set to smart-idle mode
3393 * - PRCM asserts idle_req to the USBHOST module ( This typically
3394 * happens when the system is going to a low power mode : all ports
3395 * have been suspended, the master part of the USBHOST module has
3396 * entered the standby state, and SW has cut the functional clocks)
3397 * - an USBHOST interrupt occurs before the module is able to answer
3398 * idle_ack, typically a remote wakeup IRQ.
3399 * Then the USB HOST module will enter a deadlock situation where it
3400 * is no more accessible nor functional.
3401 *
3402 * Workaround:
3403 * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
3404 */
3405
3406 /*
3407 * Errata: USB host EHCI may stall when entering smart-standby mode
3408 * Id: i571
3409 *
3410 * Description:
3411 * When the USBHOST module is set to smart-standby mode, and when it is
3412 * ready to enter the standby state (i.e. all ports are suspended and
3413 * all attached devices are in suspend mode), then it can wrongly assert
3414 * the Mstandby signal too early while there are still some residual OCP
3415 * transactions ongoing. If this condition occurs, the internal state
3416 * machine may go to an undefined state and the USB link may be stuck
3417 * upon the next resume.
3418 *
3419 * Workaround:
3420 * Don't use smart standby; use only force standby,
3421 * hence HWMOD_SWSUP_MSTANDBY
3422 */
3423
3424 /*
3425 * During system boot; If the hwmod framework resets the module
3426 * the module will have smart idle settings; which can lead to deadlock
3427 * (above Errata Id:i660); so, dont reset the module during boot;
3428 * Use HWMOD_INIT_NO_RESET.
3429 */
3430
3431 .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
3432 HWMOD_INIT_NO_RESET,
3433};
3434
3435/*
3436 * 'usb_tll_hs' class
3437 * usb_tll_hs module is the adapter on the usb_host_hs ports
3438 */
3439static struct omap_hwmod_class_sysconfig omap3xxx_usb_tll_hs_sysc = {
3440 .rev_offs = 0x0000,
3441 .sysc_offs = 0x0010,
3442 .syss_offs = 0x0014,
3443 .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
3444 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
3445 SYSC_HAS_AUTOIDLE),
3446 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
3447 .sysc_fields = &omap_hwmod_sysc_type1,
3448};
3449
3450static struct omap_hwmod_class omap3xxx_usb_tll_hs_hwmod_class = {
3451 .name = "usb_tll_hs",
3452 .sysc = &omap3xxx_usb_tll_hs_sysc,
3453};
3454
3455static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = {
3456 { .name = "tll-irq", .irq = 78 },
3457 { .irq = -1 }
3458};
3459
3460static struct omap_hwmod_addr_space omap3xxx_usb_tll_hs_addrs[] = {
3461 {
3462 .name = "tll",
3463 .pa_start = 0x48062000,
3464 .pa_end = 0x48062fff,
3465 .flags = ADDR_TYPE_RT
3466 },
3467 {}
3468};
3469
3470static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = {
3471 .master = &omap3xxx_l4_core_hwmod,
3472 .slave = &omap3xxx_usb_tll_hs_hwmod,
3473 .clk = "usbtll_ick",
3474 .addr = omap3xxx_usb_tll_hs_addrs,
3475 .user = OCP_USER_MPU | OCP_USER_SDMA,
3476};
3477
3478static struct omap_hwmod_ocp_if *omap3xxx_usb_tll_hs_slaves[] = {
3479 &omap3xxx_l4_core__usb_tll_hs,
3480};
3481
3482static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = {
3483 .name = "usb_tll_hs",
3484 .class = &omap3xxx_usb_tll_hs_hwmod_class,
3485 .clkdm_name = "l3_init_clkdm",
3486 .mpu_irqs = omap3xxx_usb_tll_hs_irqs,
3487 .main_clk = "usbtll_fck",
3488 .prcm = {
3489 .omap2 = {
3490 .module_offs = CORE_MOD,
3491 .prcm_reg_id = 3,
3492 .module_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
3493 .idlest_reg_id = 3,
3494 .idlest_idle_bit = OMAP3430ES2_ST_USBTLL_SHIFT,
3495 },
3496 },
3497 .slaves = omap3xxx_usb_tll_hs_slaves,
3498 .slaves_cnt = ARRAY_SIZE(omap3xxx_usb_tll_hs_slaves),
3499};
3500
3180static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { 3501static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
3181 &omap3xxx_l3_main_hwmod, 3502 &omap3xxx_l3_main_hwmod,
3182 &omap3xxx_l4_core_hwmod, 3503 &omap3xxx_l4_core_hwmod,
3183 &omap3xxx_l4_per_hwmod, 3504 &omap3xxx_l4_per_hwmod,
3184 &omap3xxx_l4_wkup_hwmod, 3505 &omap3xxx_l4_wkup_hwmod,
3185 &omap3xxx_mmc1_hwmod,
3186 &omap3xxx_mmc2_hwmod,
3187 &omap3xxx_mmc3_hwmod, 3506 &omap3xxx_mmc3_hwmod,
3188 &omap3xxx_mpu_hwmod, 3507 &omap3xxx_mpu_hwmod,
3189 3508
@@ -3198,12 +3517,12 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
3198 &omap3xxx_timer9_hwmod, 3517 &omap3xxx_timer9_hwmod,
3199 &omap3xxx_timer10_hwmod, 3518 &omap3xxx_timer10_hwmod,
3200 &omap3xxx_timer11_hwmod, 3519 &omap3xxx_timer11_hwmod,
3201 &omap3xxx_timer12_hwmod,
3202 3520
3203 &omap3xxx_wd_timer2_hwmod, 3521 &omap3xxx_wd_timer2_hwmod,
3204 &omap3xxx_uart1_hwmod, 3522 &omap3xxx_uart1_hwmod,
3205 &omap3xxx_uart2_hwmod, 3523 &omap3xxx_uart2_hwmod,
3206 &omap3xxx_uart3_hwmod, 3524 &omap3xxx_uart3_hwmod,
3525
3207 /* dss class */ 3526 /* dss class */
3208 &omap3xxx_dss_dispc_hwmod, 3527 &omap3xxx_dss_dispc_hwmod,
3209 &omap3xxx_dss_dsi1_hwmod, 3528 &omap3xxx_dss_dsi1_hwmod,
@@ -3245,6 +3564,12 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
3245 NULL, 3564 NULL,
3246}; 3565};
3247 3566
3567/* GP-only hwmods */
3568static __initdata struct omap_hwmod *omap3xxx_gp_hwmods[] = {
3569 &omap3xxx_timer12_hwmod,
3570 NULL
3571};
3572
3248/* 3430ES1-only hwmods */ 3573/* 3430ES1-only hwmods */
3249static __initdata struct omap_hwmod *omap3430es1_hwmods[] = { 3574static __initdata struct omap_hwmod *omap3430es1_hwmods[] = {
3250 &omap3430es1_dss_core_hwmod, 3575 &omap3430es1_dss_core_hwmod,
@@ -3255,6 +3580,22 @@ static __initdata struct omap_hwmod *omap3430es1_hwmods[] = {
3255static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = { 3580static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = {
3256 &omap3xxx_dss_core_hwmod, 3581 &omap3xxx_dss_core_hwmod,
3257 &omap3xxx_usbhsotg_hwmod, 3582 &omap3xxx_usbhsotg_hwmod,
3583 &omap3xxx_usb_host_hs_hwmod,
3584 &omap3xxx_usb_tll_hs_hwmod,
3585 NULL
3586};
3587
3588/* <= 3430ES3-only hwmods */
3589static struct omap_hwmod *omap3430_pre_es3_hwmods[] __initdata = {
3590 &omap3xxx_pre_es3_mmc1_hwmod,
3591 &omap3xxx_pre_es3_mmc2_hwmod,
3592 NULL
3593};
3594
3595/* 3430ES3+-only hwmods */
3596static struct omap_hwmod *omap3430_es3plus_hwmods[] __initdata = {
3597 &omap3xxx_es3plus_mmc1_hwmod,
3598 &omap3xxx_es3plus_mmc2_hwmod,
3258 NULL 3599 NULL
3259}; 3600};
3260 3601
@@ -3276,12 +3617,21 @@ static __initdata struct omap_hwmod *omap36xx_hwmods[] = {
3276 &omap36xx_sr2_hwmod, 3617 &omap36xx_sr2_hwmod,
3277 &omap3xxx_usbhsotg_hwmod, 3618 &omap3xxx_usbhsotg_hwmod,
3278 &omap3xxx_mailbox_hwmod, 3619 &omap3xxx_mailbox_hwmod,
3620 &omap3xxx_usb_host_hs_hwmod,
3621 &omap3xxx_usb_tll_hs_hwmod,
3622 &omap3xxx_es3plus_mmc1_hwmod,
3623 &omap3xxx_es3plus_mmc2_hwmod,
3279 NULL 3624 NULL
3280}; 3625};
3281 3626
3282static __initdata struct omap_hwmod *am35xx_hwmods[] = { 3627static __initdata struct omap_hwmod *am35xx_hwmods[] = {
3283 &omap3xxx_dss_core_hwmod, /* XXX ??? */ 3628 &omap3xxx_dss_core_hwmod, /* XXX ??? */
3284 &am35xx_usbhsotg_hwmod, 3629 &am35xx_usbhsotg_hwmod,
3630 &am35xx_uart4_hwmod,
3631 &omap3xxx_usb_host_hs_hwmod,
3632 &omap3xxx_usb_tll_hs_hwmod,
3633 &omap3xxx_es3plus_mmc1_hwmod,
3634 &omap3xxx_es3plus_mmc2_hwmod,
3285 NULL 3635 NULL
3286}; 3636};
3287 3637
@@ -3296,6 +3646,13 @@ int __init omap3xxx_hwmod_init(void)
3296 if (r < 0) 3646 if (r < 0)
3297 return r; 3647 return r;
3298 3648
3649 /* Register GP-only hwmods. */
3650 if (omap_type() == OMAP2_DEVICE_TYPE_GP) {
3651 r = omap_hwmod_register(omap3xxx_gp_hwmods);
3652 if (r < 0)
3653 return r;
3654 }
3655
3299 rev = omap_rev(); 3656 rev = omap_rev();
3300 3657
3301 /* 3658 /*
@@ -3334,6 +3691,21 @@ int __init omap3xxx_hwmod_init(void)
3334 h = omap3430es2plus_hwmods; 3691 h = omap3430es2plus_hwmods;
3335 }; 3692 };
3336 3693
3694 if (h) {
3695 r = omap_hwmod_register(h);
3696 if (r < 0)
3697 return r;
3698 }
3699
3700 h = NULL;
3701 if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
3702 rev == OMAP3430_REV_ES2_1) {
3703 h = omap3430_pre_es3_hwmods;
3704 } else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
3705 rev == OMAP3430_REV_ES3_1_2) {
3706 h = omap3430_es3plus_hwmods;
3707 };
3708
3337 if (h) 3709 if (h)
3338 r = omap_hwmod_register(h); 3710 r = omap_hwmod_register(h);
3339 3711
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index daaf165af69..f9f15108176 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -70,6 +70,8 @@ static struct omap_hwmod omap44xx_mmc2_hwmod;
70static struct omap_hwmod omap44xx_mpu_hwmod; 70static struct omap_hwmod omap44xx_mpu_hwmod;
71static struct omap_hwmod omap44xx_mpu_private_hwmod; 71static struct omap_hwmod omap44xx_mpu_private_hwmod;
72static struct omap_hwmod omap44xx_usb_otg_hs_hwmod; 72static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
73static struct omap_hwmod omap44xx_usb_host_hs_hwmod;
74static struct omap_hwmod omap44xx_usb_tll_hs_hwmod;
73 75
74/* 76/*
75 * Interconnects omap_hwmod structures 77 * Interconnects omap_hwmod structures
@@ -2246,6 +2248,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = {
2246 SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), 2248 SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
2247 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | 2249 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
2248 SIDLE_SMART_WKUP), 2250 SIDLE_SMART_WKUP),
2251 .clockact = CLOCKACT_TEST_ICLK,
2249 .sysc_fields = &omap_hwmod_sysc_type1, 2252 .sysc_fields = &omap_hwmod_sysc_type1,
2250}; 2253};
2251 2254
@@ -2300,7 +2303,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
2300 .name = "i2c1", 2303 .name = "i2c1",
2301 .class = &omap44xx_i2c_hwmod_class, 2304 .class = &omap44xx_i2c_hwmod_class,
2302 .clkdm_name = "l4_per_clkdm", 2305 .clkdm_name = "l4_per_clkdm",
2303 .flags = HWMOD_16BIT_REG, 2306 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
2304 .mpu_irqs = omap44xx_i2c1_irqs, 2307 .mpu_irqs = omap44xx_i2c1_irqs,
2305 .sdma_reqs = omap44xx_i2c1_sdma_reqs, 2308 .sdma_reqs = omap44xx_i2c1_sdma_reqs,
2306 .main_clk = "i2c1_fck", 2309 .main_clk = "i2c1_fck",
@@ -2356,7 +2359,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
2356 .name = "i2c2", 2359 .name = "i2c2",
2357 .class = &omap44xx_i2c_hwmod_class, 2360 .class = &omap44xx_i2c_hwmod_class,
2358 .clkdm_name = "l4_per_clkdm", 2361 .clkdm_name = "l4_per_clkdm",
2359 .flags = HWMOD_16BIT_REG, 2362 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
2360 .mpu_irqs = omap44xx_i2c2_irqs, 2363 .mpu_irqs = omap44xx_i2c2_irqs,
2361 .sdma_reqs = omap44xx_i2c2_sdma_reqs, 2364 .sdma_reqs = omap44xx_i2c2_sdma_reqs,
2362 .main_clk = "i2c2_fck", 2365 .main_clk = "i2c2_fck",
@@ -2412,7 +2415,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
2412 .name = "i2c3", 2415 .name = "i2c3",
2413 .class = &omap44xx_i2c_hwmod_class, 2416 .class = &omap44xx_i2c_hwmod_class,
2414 .clkdm_name = "l4_per_clkdm", 2417 .clkdm_name = "l4_per_clkdm",
2415 .flags = HWMOD_16BIT_REG, 2418 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
2416 .mpu_irqs = omap44xx_i2c3_irqs, 2419 .mpu_irqs = omap44xx_i2c3_irqs,
2417 .sdma_reqs = omap44xx_i2c3_sdma_reqs, 2420 .sdma_reqs = omap44xx_i2c3_sdma_reqs,
2418 .main_clk = "i2c3_fck", 2421 .main_clk = "i2c3_fck",
@@ -2468,7 +2471,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
2468 .name = "i2c4", 2471 .name = "i2c4",
2469 .class = &omap44xx_i2c_hwmod_class, 2472 .class = &omap44xx_i2c_hwmod_class,
2470 .clkdm_name = "l4_per_clkdm", 2473 .clkdm_name = "l4_per_clkdm",
2471 .flags = HWMOD_16BIT_REG, 2474 .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,
2472 .mpu_irqs = omap44xx_i2c4_irqs, 2475 .mpu_irqs = omap44xx_i2c4_irqs,
2473 .sdma_reqs = omap44xx_i2c4_sdma_reqs, 2476 .sdma_reqs = omap44xx_i2c4_sdma_reqs,
2474 .main_clk = "i2c4_fck", 2477 .main_clk = "i2c4_fck",
@@ -5276,6 +5279,207 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
5276 .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves), 5279 .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
5277}; 5280};
5278 5281
5282/*
5283 * 'usb_host_hs' class
5284 * high-speed multi-port usb host controller
5285 */
5286static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = {
5287 .master = &omap44xx_usb_host_hs_hwmod,
5288 .slave = &omap44xx_l3_main_2_hwmod,
5289 .clk = "l3_div_ck",
5290 .user = OCP_USER_MPU | OCP_USER_SDMA,
5291};
5292
5293static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = {
5294 .rev_offs = 0x0000,
5295 .sysc_offs = 0x0010,
5296 .syss_offs = 0x0014,
5297 .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
5298 SYSC_HAS_SOFTRESET),
5299 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
5300 SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
5301 MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
5302 .sysc_fields = &omap_hwmod_sysc_type2,
5303};
5304
5305static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = {
5306 .name = "usb_host_hs",
5307 .sysc = &omap44xx_usb_host_hs_sysc,
5308};
5309
5310static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = {
5311 &omap44xx_usb_host_hs__l3_main_2,
5312};
5313
5314static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = {
5315 {
5316 .name = "uhh",
5317 .pa_start = 0x4a064000,
5318 .pa_end = 0x4a0647ff,
5319 .flags = ADDR_TYPE_RT
5320 },
5321 {
5322 .name = "ohci",
5323 .pa_start = 0x4a064800,
5324 .pa_end = 0x4a064bff,
5325 },
5326 {
5327 .name = "ehci",
5328 .pa_start = 0x4a064c00,
5329 .pa_end = 0x4a064fff,
5330 },
5331 {}
5332};
5333
5334static struct omap_hwmod_irq_info omap44xx_usb_host_hs_irqs[] = {
5335 { .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START },
5336 { .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START },
5337 { .irq = -1 }
5338};
5339
5340static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = {
5341 .master = &omap44xx_l4_cfg_hwmod,
5342 .slave = &omap44xx_usb_host_hs_hwmod,
5343 .clk = "l4_div_ck",
5344 .addr = omap44xx_usb_host_hs_addrs,
5345 .user = OCP_USER_MPU | OCP_USER_SDMA,
5346};
5347
5348static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = {
5349 &omap44xx_l4_cfg__usb_host_hs,
5350};
5351
5352static struct omap_hwmod omap44xx_usb_host_hs_hwmod = {
5353 .name = "usb_host_hs",
5354 .class = &omap44xx_usb_host_hs_hwmod_class,
5355 .clkdm_name = "l3_init_clkdm",
5356 .main_clk = "usb_host_hs_fck",
5357 .prcm = {
5358 .omap4 = {
5359 .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET,
5360 .context_offs = OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET,
5361 .modulemode = MODULEMODE_SWCTRL,
5362 },
5363 },
5364 .mpu_irqs = omap44xx_usb_host_hs_irqs,
5365 .slaves = omap44xx_usb_host_hs_slaves,
5366 .slaves_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_slaves),
5367 .masters = omap44xx_usb_host_hs_masters,
5368 .masters_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_masters),
5369
5370 /*
5371 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
5372 * id: i660
5373 *
5374 * Description:
5375 * In the following configuration :
5376 * - USBHOST module is set to smart-idle mode
5377 * - PRCM asserts idle_req to the USBHOST module ( This typically
5378 * happens when the system is going to a low power mode : all ports
5379 * have been suspended, the master part of the USBHOST module has
5380 * entered the standby state, and SW has cut the functional clocks)
5381 * - an USBHOST interrupt occurs before the module is able to answer
5382 * idle_ack, typically a remote wakeup IRQ.
5383 * Then the USB HOST module will enter a deadlock situation where it
5384 * is no more accessible nor functional.
5385 *
5386 * Workaround:
5387 * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE
5388 */
5389
5390 /*
5391 * Errata: USB host EHCI may stall when entering smart-standby mode
5392 * Id: i571
5393 *
5394 * Description:
5395 * When the USBHOST module is set to smart-standby mode, and when it is
5396 * ready to enter the standby state (i.e. all ports are suspended and
5397 * all attached devices are in suspend mode), then it can wrongly assert
5398 * the Mstandby signal too early while there are still some residual OCP
5399 * transactions ongoing. If this condition occurs, the internal state
5400 * machine may go to an undefined state and the USB link may be stuck
5401 * upon the next resume.
5402 *
5403 * Workaround:
5404 * Don't use smart standby; use only force standby,
5405 * hence HWMOD_SWSUP_MSTANDBY
5406 */
5407
5408 /*
5409 * During system boot; If the hwmod framework resets the module
5410 * the module will have smart idle settings; which can lead to deadlock
5411 * (above Errata Id:i660); so, dont reset the module during boot;
5412 * Use HWMOD_INIT_NO_RESET.
5413 */
5414
5415 .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY |
5416 HWMOD_INIT_NO_RESET,
5417};
5418
5419/*
5420 * 'usb_tll_hs' class
5421 * usb_tll_hs module is the adapter on the usb_host_hs ports
5422 */
5423static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = {
5424 .rev_offs = 0x0000,
5425 .sysc_offs = 0x0010,
5426 .syss_offs = 0x0014,
5427 .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
5428 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
5429 SYSC_HAS_AUTOIDLE),
5430 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
5431 .sysc_fields = &omap_hwmod_sysc_type1,
5432};
5433
5434static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = {
5435 .name = "usb_tll_hs",
5436 .sysc = &omap44xx_usb_tll_hs_sysc,
5437};
5438
5439static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = {
5440 { .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START },
5441 { .irq = -1 }
5442};
5443
5444static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = {
5445 {
5446 .name = "tll",
5447 .pa_start = 0x4a062000,
5448 .pa_end = 0x4a063fff,
5449 .flags = ADDR_TYPE_RT
5450 },
5451 {}
5452};
5453
5454static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = {
5455 .master = &omap44xx_l4_cfg_hwmod,
5456 .slave = &omap44xx_usb_tll_hs_hwmod,
5457 .clk = "l4_div_ck",
5458 .addr = omap44xx_usb_tll_hs_addrs,
5459 .user = OCP_USER_MPU | OCP_USER_SDMA,
5460};
5461
5462static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = {
5463 &omap44xx_l4_cfg__usb_tll_hs,
5464};
5465
5466static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = {
5467 .name = "usb_tll_hs",
5468 .class = &omap44xx_usb_tll_hs_hwmod_class,
5469 .clkdm_name = "l3_init_clkdm",
5470 .main_clk = "usb_tll_hs_ick",
5471 .prcm = {
5472 .omap4 = {
5473 .clkctrl_offs = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET,
5474 .context_offs = OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET,
5475 .modulemode = MODULEMODE_HWCTRL,
5476 },
5477 },
5478 .mpu_irqs = omap44xx_usb_tll_hs_irqs,
5479 .slaves = omap44xx_usb_tll_hs_slaves,
5480 .slaves_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_slaves),
5481};
5482
5279static __initdata struct omap_hwmod *omap44xx_hwmods[] = { 5483static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
5280 5484
5281 /* dmm class */ 5485 /* dmm class */
@@ -5415,13 +5619,16 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
5415 &omap44xx_uart3_hwmod, 5619 &omap44xx_uart3_hwmod,
5416 &omap44xx_uart4_hwmod, 5620 &omap44xx_uart4_hwmod,
5417 5621
5622 /* usb host class */
5623 &omap44xx_usb_host_hs_hwmod,
5624 &omap44xx_usb_tll_hs_hwmod,
5625
5418 /* usb_otg_hs class */ 5626 /* usb_otg_hs class */
5419 &omap44xx_usb_otg_hs_hwmod, 5627 &omap44xx_usb_otg_hs_hwmod,
5420 5628
5421 /* wd_timer class */ 5629 /* wd_timer class */
5422 &omap44xx_wd_timer2_hwmod, 5630 &omap44xx_wd_timer2_hwmod,
5423 &omap44xx_wd_timer3_hwmod, 5631 &omap44xx_wd_timer3_hwmod,
5424
5425 NULL, 5632 NULL,
5426}; 5633};
5427 5634
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index 58775e3c847..4c90477e6f8 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -260,3 +260,38 @@ void am35x_set_mode(u8 musb_mode)
260 260
261 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); 261 omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
262} 262}
263
264void ti81xx_musb_phy_power(u8 on)
265{
266 void __iomem *scm_base = NULL;
267 u32 usbphycfg;
268
269 scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K);
270 if (!scm_base) {
271 pr_err("system control module ioremap failed\n");
272 return;
273 }
274
275 usbphycfg = __raw_readl(scm_base + USBCTRL0);
276
277 if (on) {
278 if (cpu_is_ti816x()) {
279 usbphycfg |= TI816X_USBPHY0_NORMAL_MODE;
280 usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC;
281 } else if (cpu_is_ti814x()) {
282 usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN
283 | USBPHY_DPINPUT | USBPHY_DMINPUT);
284 usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN
285 | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL);
286 }
287 } else {
288 if (cpu_is_ti816x())
289 usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE;
290 else if (cpu_is_ti814x())
291 usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
292
293 }
294 __raw_writel(usbphycfg, scm_base + USBCTRL0);
295
296 iounmap(scm_base);
297}
diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h
index 8affc66a92c..8fae534eb15 100644
--- a/arch/arm/mach-omap2/opp2xxx.h
+++ b/arch/arm/mach-omap2/opp2xxx.h
@@ -51,7 +51,7 @@ struct prcm_config {
51 unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ 51 unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */
52 unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ 52 unsigned long cm_clksel_mdm; /* modem dividers 2430 only */
53 unsigned long base_sdrc_rfr; /* base refresh timing for a set */ 53 unsigned long base_sdrc_rfr; /* base refresh timing for a set */
54 unsigned char flags; 54 unsigned short flags;
55}; 55};
56 56
57 57
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4e166add2f3..b737b11e449 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -21,6 +21,7 @@ extern void omap_sram_idle(void);
21extern int omap3_can_sleep(void); 21extern int omap3_can_sleep(void);
22extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 22extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
23extern int omap3_idle_init(void); 23extern int omap3_idle_init(void);
24extern int omap4_idle_init(void);
24 25
25#if defined(CONFIG_PM_OPP) 26#if defined(CONFIG_PM_OPP)
26extern int omap3_opp_init(void); 27extern int omap3_opp_init(void);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index ef8595c8029..b8822f8b289 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -30,7 +30,6 @@
30#include <linux/irq.h> 30#include <linux/irq.h>
31#include <linux/time.h> 31#include <linux/time.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/console.h>
34 33
35#include <asm/mach/time.h> 34#include <asm/mach/time.h>
36#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
@@ -127,27 +126,11 @@ static void omap2_enter_full_retention(void)
127 if (omap_irq_pending()) 126 if (omap_irq_pending())
128 goto no_sleep; 127 goto no_sleep;
129 128
130 /* Block console output in case it is on one of the OMAP UARTs */
131 if (!is_suspending())
132 if (!console_trylock())
133 goto no_sleep;
134
135 omap_uart_prepare_idle(0);
136 omap_uart_prepare_idle(1);
137 omap_uart_prepare_idle(2);
138
139 /* Jump to SRAM suspend code */ 129 /* Jump to SRAM suspend code */
140 omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), 130 omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
141 OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), 131 OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
142 OMAP_SDRC_REGADDR(SDRC_POWER)); 132 OMAP_SDRC_REGADDR(SDRC_POWER));
143 133
144 omap_uart_resume_idle(2);
145 omap_uart_resume_idle(1);
146 omap_uart_resume_idle(0);
147
148 if (!is_suspending())
149 console_unlock();
150
151no_sleep: 134no_sleep:
152 omap2_gpio_resume_after_idle(); 135 omap2_gpio_resume_after_idle();
153 136
@@ -239,8 +222,6 @@ static int omap2_can_sleep(void)
239{ 222{
240 if (omap2_fclks_active()) 223 if (omap2_fclks_active())
241 return 0; 224 return 0;
242 if (!omap_uart_can_sleep())
243 return 0;
244 if (osc_ck->usecount > 1) 225 if (osc_ck->usecount > 1)
245 return 0; 226 return 0;
246 if (omap_dma_running()) 227 if (omap_dma_running())
@@ -291,7 +272,6 @@ static int omap2_pm_suspend(void)
291 mir1 = omap_readl(0x480fe0a4); 272 mir1 = omap_readl(0x480fe0a4);
292 omap_writel(1 << 5, 0x480fe0ac); 273 omap_writel(1 << 5, 0x480fe0ac);
293 274
294 omap_uart_prepare_suspend();
295 omap2_enter_full_retention(); 275 omap2_enter_full_retention();
296 276
297 omap_writel(mir1, 0x480fe0a4); 277 omap_writel(mir1, 0x480fe0a4);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fa637dfdda5..fc698757892 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -28,7 +28,6 @@
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/console.h>
32#include <trace/events/power.h> 31#include <trace/events/power.h>
33 32
34#include <asm/suspend.h> 33#include <asm/suspend.h>
@@ -36,7 +35,6 @@
36#include <plat/sram.h> 35#include <plat/sram.h>
37#include "clockdomain.h" 36#include "clockdomain.h"
38#include "powerdomain.h" 37#include "powerdomain.h"
39#include <plat/serial.h>
40#include <plat/sdrc.h> 38#include <plat/sdrc.h>
41#include <plat/prcm.h> 39#include <plat/prcm.h>
42#include <plat/gpmc.h> 40#include <plat/gpmc.h>
@@ -54,15 +52,6 @@
54 52
55#ifdef CONFIG_SUSPEND 53#ifdef CONFIG_SUSPEND
56static suspend_state_t suspend_state = PM_SUSPEND_ON; 54static suspend_state_t suspend_state = PM_SUSPEND_ON;
57static inline bool is_suspending(void)
58{
59 return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled;
60}
61#else
62static inline bool is_suspending(void)
63{
64 return false;
65}
66#endif 55#endif
67 56
68/* pm34xx errata defined in pm.h */ 57/* pm34xx errata defined in pm.h */
@@ -195,7 +184,7 @@ static void omap3_save_secure_ram_context(void)
195 * that any peripheral wake-up events occurring while attempting to 184 * that any peripheral wake-up events occurring while attempting to
196 * clear the PM_WKST_x are detected and cleared. 185 * clear the PM_WKST_x are detected and cleared.
197 */ 186 */
198static int prcm_clear_mod_irqs(s16 module, u8 regs) 187static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits)
199{ 188{
200 u32 wkst, fclk, iclk, clken; 189 u32 wkst, fclk, iclk, clken;
201 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; 190 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
@@ -207,6 +196,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
207 196
208 wkst = omap2_prm_read_mod_reg(module, wkst_off); 197 wkst = omap2_prm_read_mod_reg(module, wkst_off);
209 wkst &= omap2_prm_read_mod_reg(module, grpsel_off); 198 wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
199 wkst &= ~ignore_bits;
210 if (wkst) { 200 if (wkst) {
211 iclk = omap2_cm_read_mod_reg(module, iclk_off); 201 iclk = omap2_cm_read_mod_reg(module, iclk_off);
212 fclk = omap2_cm_read_mod_reg(module, fclk_off); 202 fclk = omap2_cm_read_mod_reg(module, fclk_off);
@@ -222,6 +212,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
222 omap2_cm_set_mod_reg_bits(clken, module, fclk_off); 212 omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
223 omap2_prm_write_mod_reg(wkst, module, wkst_off); 213 omap2_prm_write_mod_reg(wkst, module, wkst_off);
224 wkst = omap2_prm_read_mod_reg(module, wkst_off); 214 wkst = omap2_prm_read_mod_reg(module, wkst_off);
215 wkst &= ~ignore_bits;
225 c++; 216 c++;
226 } 217 }
227 omap2_cm_write_mod_reg(iclk, module, iclk_off); 218 omap2_cm_write_mod_reg(iclk, module, iclk_off);
@@ -231,76 +222,35 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
231 return c; 222 return c;
232} 223}
233 224
234static int _prcm_int_handle_wakeup(void) 225static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
235{ 226{
236 int c; 227 int c;
237 228
238 c = prcm_clear_mod_irqs(WKUP_MOD, 1); 229 c = prcm_clear_mod_irqs(WKUP_MOD, 1,
239 c += prcm_clear_mod_irqs(CORE_MOD, 1); 230 ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK));
240 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
241 if (omap_rev() > OMAP3430_REV_ES1_0) {
242 c += prcm_clear_mod_irqs(CORE_MOD, 3);
243 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
244 }
245 231
246 return c; 232 return c ? IRQ_HANDLED : IRQ_NONE;
247} 233}
248 234
249/* 235static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
250 * PRCM Interrupt Handler
251 *
252 * The PRM_IRQSTATUS_MPU register indicates if there are any pending
253 * interrupts from the PRCM for the MPU. These bits must be cleared in
254 * order to clear the PRCM interrupt. The PRCM interrupt handler is
255 * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
256 * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
257 * register indicates that a wake-up event is pending for the MPU and
258 * this bit can only be cleared if the all the wake-up events latched
259 * in the various PM_WKST_x registers have been cleared. The interrupt
260 * handler is implemented using a do-while loop so that if a wake-up
261 * event occurred during the processing of the prcm interrupt handler
262 * (setting a bit in the corresponding PM_WKST_x register and thus
263 * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
264 * this would be handled.
265 */
266static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
267{ 236{
268 u32 irqenable_mpu, irqstatus_mpu; 237 int c;
269 int c = 0;
270
271 irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
272 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
273 irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
274 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
275 irqstatus_mpu &= irqenable_mpu;
276
277 do {
278 if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
279 OMAP3430_IO_ST_MASK)) {
280 c = _prcm_int_handle_wakeup();
281
282 /*
283 * Is the MPU PRCM interrupt handler racing with the
284 * IVA2 PRCM interrupt handler ?
285 */
286 WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
287 "but no wakeup sources are marked\n");
288 } else {
289 /* XXX we need to expand our PRCM interrupt handler */
290 WARN(1, "prcm: WARNING: PRCM interrupt received, but "
291 "no code to handle it (%08x)\n", irqstatus_mpu);
292 }
293
294 omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
295 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
296
297 irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
298 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
299 irqstatus_mpu &= irqenable_mpu;
300 238
301 } while (irqstatus_mpu); 239 /*
240 * Clear all except ST_IO and ST_IO_CHAIN for wkup module,
241 * these are handled in a separate handler to avoid acking
242 * IO events before parsing in mux code
243 */
244 c = prcm_clear_mod_irqs(WKUP_MOD, 1,
245 OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK);
246 c += prcm_clear_mod_irqs(CORE_MOD, 1, 0);
247 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0);
248 if (omap_rev() > OMAP3430_REV_ES1_0) {
249 c += prcm_clear_mod_irqs(CORE_MOD, 3, 0);
250 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0);
251 }
302 252
303 return IRQ_HANDLED; 253 return c ? IRQ_HANDLED : IRQ_NONE;
304} 254}
305 255
306static void omap34xx_save_context(u32 *save) 256static void omap34xx_save_context(u32 *save)
@@ -376,20 +326,11 @@ void omap_sram_idle(void)
376 omap3_enable_io_chain(); 326 omap3_enable_io_chain();
377 } 327 }
378 328
379 /* Block console output in case it is on one of the OMAP UARTs */
380 if (!is_suspending())
381 if (per_next_state < PWRDM_POWER_ON ||
382 core_next_state < PWRDM_POWER_ON)
383 if (!console_trylock())
384 goto console_still_active;
385
386 pwrdm_pre_transition(); 329 pwrdm_pre_transition();
387 330
388 /* PER */ 331 /* PER */
389 if (per_next_state < PWRDM_POWER_ON) { 332 if (per_next_state < PWRDM_POWER_ON) {
390 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; 333 per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
391 omap_uart_prepare_idle(2);
392 omap_uart_prepare_idle(3);
393 omap2_gpio_prepare_for_idle(per_going_off); 334 omap2_gpio_prepare_for_idle(per_going_off);
394 if (per_next_state == PWRDM_POWER_OFF) 335 if (per_next_state == PWRDM_POWER_OFF)
395 omap3_per_save_context(); 336 omap3_per_save_context();
@@ -397,8 +338,6 @@ void omap_sram_idle(void)
397 338
398 /* CORE */ 339 /* CORE */
399 if (core_next_state < PWRDM_POWER_ON) { 340 if (core_next_state < PWRDM_POWER_ON) {
400 omap_uart_prepare_idle(0);
401 omap_uart_prepare_idle(1);
402 if (core_next_state == PWRDM_POWER_OFF) { 341 if (core_next_state == PWRDM_POWER_OFF) {
403 omap3_core_save_context(); 342 omap3_core_save_context();
404 omap3_cm_save_context(); 343 omap3_cm_save_context();
@@ -447,8 +386,6 @@ void omap_sram_idle(void)
447 omap3_sram_restore_context(); 386 omap3_sram_restore_context();
448 omap2_sms_restore_context(); 387 omap2_sms_restore_context();
449 } 388 }
450 omap_uart_resume_idle(0);
451 omap_uart_resume_idle(1);
452 if (core_next_state == PWRDM_POWER_OFF) 389 if (core_next_state == PWRDM_POWER_OFF)
453 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, 390 omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
454 OMAP3430_GR_MOD, 391 OMAP3430_GR_MOD,
@@ -464,14 +401,8 @@ void omap_sram_idle(void)
464 omap2_gpio_resume_after_idle(); 401 omap2_gpio_resume_after_idle();
465 if (per_prev_state == PWRDM_POWER_OFF) 402 if (per_prev_state == PWRDM_POWER_OFF)
466 omap3_per_restore_context(); 403 omap3_per_restore_context();
467 omap_uart_resume_idle(2);
468 omap_uart_resume_idle(3);
469 } 404 }
470 405
471 if (!is_suspending())
472 console_unlock();
473
474console_still_active:
475 /* Disable IO-PAD and IO-CHAIN wakeup */ 406 /* Disable IO-PAD and IO-CHAIN wakeup */
476 if (omap3_has_io_wakeup() && 407 if (omap3_has_io_wakeup() &&
477 (per_next_state < PWRDM_POWER_ON || 408 (per_next_state < PWRDM_POWER_ON ||
@@ -485,21 +416,11 @@ console_still_active:
485 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); 416 clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
486} 417}
487 418
488int omap3_can_sleep(void)
489{
490 if (!omap_uart_can_sleep())
491 return 0;
492 return 1;
493}
494
495static void omap3_pm_idle(void) 419static void omap3_pm_idle(void)
496{ 420{
497 local_irq_disable(); 421 local_irq_disable();
498 local_fiq_disable(); 422 local_fiq_disable();
499 423
500 if (!omap3_can_sleep())
501 goto out;
502
503 if (omap_irq_pending() || need_resched()) 424 if (omap_irq_pending() || need_resched())
504 goto out; 425 goto out;
505 426
@@ -533,7 +454,6 @@ static int omap3_pm_suspend(void)
533 goto restore; 454 goto restore;
534 } 455 }
535 456
536 omap_uart_prepare_suspend();
537 omap3_intc_suspend(); 457 omap3_intc_suspend();
538 458
539 omap_sram_idle(); 459 omap_sram_idle();
@@ -580,22 +500,27 @@ static int omap3_pm_begin(suspend_state_t state)
580{ 500{
581 disable_hlt(); 501 disable_hlt();
582 suspend_state = state; 502 suspend_state = state;
583 omap_uart_enable_irqs(0); 503 omap_prcm_irq_prepare();
584 return 0; 504 return 0;
585} 505}
586 506
587static void omap3_pm_end(void) 507static void omap3_pm_end(void)
588{ 508{
589 suspend_state = PM_SUSPEND_ON; 509 suspend_state = PM_SUSPEND_ON;
590 omap_uart_enable_irqs(1);
591 enable_hlt(); 510 enable_hlt();
592 return; 511 return;
593} 512}
594 513
514static void omap3_pm_finish(void)
515{
516 omap_prcm_irq_complete();
517}
518
595static const struct platform_suspend_ops omap_pm_ops = { 519static const struct platform_suspend_ops omap_pm_ops = {
596 .begin = omap3_pm_begin, 520 .begin = omap3_pm_begin,
597 .end = omap3_pm_end, 521 .end = omap3_pm_end,
598 .enter = omap3_pm_enter, 522 .enter = omap3_pm_enter,
523 .finish = omap3_pm_finish,
599 .valid = suspend_valid_only_mem, 524 .valid = suspend_valid_only_mem,
600}; 525};
601#endif /* CONFIG_SUSPEND */ 526#endif /* CONFIG_SUSPEND */
@@ -701,10 +626,6 @@ static void __init prcm_setup_regs(void)
701 OMAP3430_GRPSEL_GPT1_MASK | 626 OMAP3430_GRPSEL_GPT1_MASK |
702 OMAP3430_GRPSEL_GPT12_MASK, 627 OMAP3430_GRPSEL_GPT12_MASK,
703 WKUP_MOD, OMAP3430_PM_MPUGRPSEL); 628 WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
704 /* For some reason IO doesn't generate wakeup event even if
705 * it is selected to mpu wakeup goup */
706 omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
707 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
708 629
709 /* Enable PM_WKEN to support DSS LPR */ 630 /* Enable PM_WKEN to support DSS LPR */
710 omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, 631 omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
@@ -881,12 +802,21 @@ static int __init omap3_pm_init(void)
881 * supervised mode for powerdomains */ 802 * supervised mode for powerdomains */
882 prcm_setup_regs(); 803 prcm_setup_regs();
883 804
884 ret = request_irq(INT_34XX_PRCM_MPU_IRQ, 805 ret = request_irq(omap_prcm_event_to_irq("wkup"),
885 (irq_handler_t)prcm_interrupt_handler, 806 _prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL);
886 IRQF_DISABLED, "prcm", NULL); 807
808 if (ret) {
809 pr_err("pm: Failed to request pm_wkup irq\n");
810 goto err1;
811 }
812
813 /* IO interrupt is shared with mux code */
814 ret = request_irq(omap_prcm_event_to_irq("io"),
815 _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io",
816 omap3_pm_init);
817
887 if (ret) { 818 if (ret) {
888 printk(KERN_ERR "request_irq failed to register for 0x%x\n", 819 pr_err("pm: Failed to request pm_io irq\n");
889 INT_34XX_PRCM_MPU_IRQ);
890 goto err1; 820 goto err1;
891 } 821 }
892 822
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index 8edb015f561..c264ef7219c 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * OMAP4 Power Management Routines 2 * OMAP4 Power Management Routines
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. 4 * Copyright (C) 2010-2011 Texas Instruments, Inc.
5 * Rajendra Nayak <rnayak@ti.com> 5 * Rajendra Nayak <rnayak@ti.com>
6 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -17,13 +18,16 @@
17#include <linux/slab.h> 18#include <linux/slab.h>
18 19
19#include "common.h" 20#include "common.h"
21#include "clockdomain.h"
20#include "powerdomain.h" 22#include "powerdomain.h"
23#include "pm.h"
21 24
22struct power_state { 25struct power_state {
23 struct powerdomain *pwrdm; 26 struct powerdomain *pwrdm;
24 u32 next_state; 27 u32 next_state;
25#ifdef CONFIG_SUSPEND 28#ifdef CONFIG_SUSPEND
26 u32 saved_state; 29 u32 saved_state;
30 u32 saved_logic_state;
27#endif 31#endif
28 struct list_head node; 32 struct list_head node;
29}; 33};
@@ -33,7 +37,50 @@ static LIST_HEAD(pwrst_list);
33#ifdef CONFIG_SUSPEND 37#ifdef CONFIG_SUSPEND
34static int omap4_pm_suspend(void) 38static int omap4_pm_suspend(void)
35{ 39{
36 do_wfi(); 40 struct power_state *pwrst;
41 int state, ret = 0;
42 u32 cpu_id = smp_processor_id();
43
44 /* Save current powerdomain state */
45 list_for_each_entry(pwrst, &pwrst_list, node) {
46 pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
47 pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
48 }
49
50 /* Set targeted power domain states by suspend */
51 list_for_each_entry(pwrst, &pwrst_list, node) {
52 omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
53 pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
54 }
55
56 /*
57 * For MPUSS to hit power domain retention(CSWR or OSWR),
58 * CPU0 and CPU1 power domains need to be in OFF or DORMANT state,
59 * since CPU power domain CSWR is not supported by hardware
60 * Only master CPU follows suspend path. All other CPUs follow
61 * CPU hotplug path in system wide suspend. On OMAP4, CPU power
62 * domain CSWR is not supported by hardware.
63 * More details can be found in OMAP4430 TRM section 4.3.4.2.
64 */
65 omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
66
67 /* Restore next powerdomain state */
68 list_for_each_entry(pwrst, &pwrst_list, node) {
69 state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
70 if (state > pwrst->next_state) {
71 pr_info("Powerdomain (%s) didn't enter "
72 "target state %d\n",
73 pwrst->pwrdm->name, pwrst->next_state);
74 ret = -1;
75 }
76 omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
77 pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
78 }
79 if (ret)
80 pr_crit("Could not enter target state in pm_suspend\n");
81 else
82 pr_info("Successfully put all powerdomains to target state\n");
83
37 return 0; 84 return 0;
38} 85}
39 86
@@ -73,6 +120,22 @@ static const struct platform_suspend_ops omap_pm_ops = {
73}; 120};
74#endif /* CONFIG_SUSPEND */ 121#endif /* CONFIG_SUSPEND */
75 122
123/*
124 * Enable hardware supervised mode for all clockdomains if it's
125 * supported. Initiate sleep transition for other clockdomains, if
126 * they are not used
127 */
128static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
129{
130 if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
131 clkdm_allow_idle(clkdm);
132 else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
133 atomic_read(&clkdm->usecount) == 0)
134 clkdm_sleep(clkdm);
135 return 0;
136}
137
138
76static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) 139static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
77{ 140{
78 struct power_state *pwrst; 141 struct power_state *pwrst;
@@ -80,14 +143,48 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
80 if (!pwrdm->pwrsts) 143 if (!pwrdm->pwrsts)
81 return 0; 144 return 0;
82 145
146 /*
147 * Skip CPU0 and CPU1 power domains. CPU1 is programmed
148 * through hotplug path and CPU0 explicitly programmed
149 * further down in the code path
150 */
151 if (!strncmp(pwrdm->name, "cpu", 3))
152 return 0;
153
154 /*
155 * FIXME: Remove this check when core retention is supported
156 * Only MPUSS power domain is added in the list.
157 */
158 if (strcmp(pwrdm->name, "mpu_pwrdm"))
159 return 0;
160
83 pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); 161 pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
84 if (!pwrst) 162 if (!pwrst)
85 return -ENOMEM; 163 return -ENOMEM;
164
86 pwrst->pwrdm = pwrdm; 165 pwrst->pwrdm = pwrdm;
87 pwrst->next_state = PWRDM_POWER_ON; 166 pwrst->next_state = PWRDM_POWER_RET;
88 list_add(&pwrst->node, &pwrst_list); 167 list_add(&pwrst->node, &pwrst_list);
89 168
90 return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); 169 return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
170}
171
172/**
173 * omap_default_idle - OMAP4 default ilde routine.'
174 *
175 * Implements OMAP4 memory, IO ordering requirements which can't be addressed
176 * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
177 * by secondary CPU with CONFIG_CPUIDLE.
178 */
179static void omap_default_idle(void)
180{
181 local_irq_disable();
182 local_fiq_disable();
183
184 omap_do_wfi();
185
186 local_fiq_enable();
187 local_irq_enable();
91} 188}
92 189
93/** 190/**
@@ -99,10 +196,17 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
99static int __init omap4_pm_init(void) 196static int __init omap4_pm_init(void)
100{ 197{
101 int ret; 198 int ret;
199 struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
200 struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
102 201
103 if (!cpu_is_omap44xx()) 202 if (!cpu_is_omap44xx())
104 return -ENODEV; 203 return -ENODEV;
105 204
205 if (omap_rev() == OMAP4430_REV_ES1_0) {
206 WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
207 return -ENODEV;
208 }
209
106 pr_err("Power Management for TI OMAP4.\n"); 210 pr_err("Power Management for TI OMAP4.\n");
107 211
108 ret = pwrdm_for_each(pwrdms_setup, NULL); 212 ret = pwrdm_for_each(pwrdms_setup, NULL);
@@ -111,10 +215,51 @@ static int __init omap4_pm_init(void)
111 goto err2; 215 goto err2;
112 } 216 }
113 217
218 /*
219 * The dynamic dependency between MPUSS -> MEMIF and
220 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
221 * expected. The hardware recommendation is to enable static
222 * dependencies for these to avoid system lock ups or random crashes.
223 */
224 mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
225 emif_clkdm = clkdm_lookup("l3_emif_clkdm");
226 l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
227 l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
228 l4_per_clkdm = clkdm_lookup("l4_per_clkdm");
229 ducati_clkdm = clkdm_lookup("ducati_clkdm");
230 if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
231 (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
232 goto err2;
233
234 ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
235 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
236 ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
237 ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm);
238 ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
239 ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
240 if (ret) {
241 pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 "
242 "wakeup dependency\n");
243 goto err2;
244 }
245
246 ret = omap4_mpuss_init();
247 if (ret) {
248 pr_err("Failed to initialise OMAP4 MPUSS\n");
249 goto err2;
250 }
251
252 (void) clkdm_for_each(clkdms_setup, NULL);
253
114#ifdef CONFIG_SUSPEND 254#ifdef CONFIG_SUSPEND
115 suspend_set_ops(&omap_pm_ops); 255 suspend_set_ops(&omap_pm_ops);
116#endif /* CONFIG_SUSPEND */ 256#endif /* CONFIG_SUSPEND */
117 257
258 /* Overwrite the default arch_idle() */
259 pm_idle = omap_default_idle;
260
261 omap4_idle_init();
262
118err2: 263err2:
119 return ret; 264 return ret;
120} 265}
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 0363dcb0ef9..5aa5435e3ff 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -4,7 +4,7 @@
4/* 4/*
5 * OMAP2/3 PRCM base and module definitions 5 * OMAP2/3 PRCM base and module definitions
6 * 6 *
7 * Copyright (C) 2007-2009 Texas Instruments, Inc. 7 * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc.
8 * Copyright (C) 2007-2009 Nokia Corporation 8 * Copyright (C) 2007-2009 Nokia Corporation
9 * 9 *
10 * Written by Paul Walmsley 10 * Written by Paul Walmsley
@@ -201,6 +201,8 @@
201#define OMAP3430_EN_MMC2_SHIFT 25 201#define OMAP3430_EN_MMC2_SHIFT 25
202#define OMAP3430_EN_MMC1_MASK (1 << 24) 202#define OMAP3430_EN_MMC1_MASK (1 << 24)
203#define OMAP3430_EN_MMC1_SHIFT 24 203#define OMAP3430_EN_MMC1_SHIFT 24
204#define OMAP3430_EN_UART4_MASK (1 << 23)
205#define OMAP3430_EN_UART4_SHIFT 23
204#define OMAP3430_EN_MCSPI4_MASK (1 << 21) 206#define OMAP3430_EN_MCSPI4_MASK (1 << 21)
205#define OMAP3430_EN_MCSPI4_SHIFT 21 207#define OMAP3430_EN_MCSPI4_SHIFT 21
206#define OMAP3430_EN_MCSPI3_MASK (1 << 20) 208#define OMAP3430_EN_MCSPI3_MASK (1 << 20)
@@ -408,6 +410,79 @@
408extern void __iomem *prm_base; 410extern void __iomem *prm_base;
409extern void __iomem *cm_base; 411extern void __iomem *cm_base;
410extern void __iomem *cm2_base; 412extern void __iomem *cm2_base;
413
414/**
415 * struct omap_prcm_irq - describes a PRCM interrupt bit
416 * @name: a short name describing the interrupt type, e.g. "wkup" or "io"
417 * @offset: the bit shift of the interrupt inside the IRQ{ENABLE,STATUS} regs
418 * @priority: should this interrupt be handled before @priority=false IRQs?
419 *
420 * Describes interrupt bits inside the PRM_IRQ{ENABLE,STATUS}_MPU* registers.
421 * On systems with multiple PRM MPU IRQ registers, the bitfields read from
422 * the registers are concatenated, so @offset could be > 31 on these systems -
423 * see omap_prm_irq_handler() for more details. I/O ring interrupts should
424 * have @priority set to true.
425 */
426struct omap_prcm_irq {
427 const char *name;
428 unsigned int offset;
429 bool priority;
430};
431
432/**
433 * struct omap_prcm_irq_setup - PRCM interrupt controller details
434 * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register
435 * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register
436 * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers
437 * @nr_irqs: number of entries in the @irqs array
438 * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs)
439 * @irq: MPU IRQ asserted when a PRCM interrupt arrives
440 * @read_pending_irqs: fn ptr to determine if any PRCM IRQs are pending
441 * @ocp_barrier: fn ptr to force buffered PRM writes to complete
442 * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs
443 * @restore_irqen: fn ptr to save and clear IRQENABLE regs
444 * @saved_mask: IRQENABLE regs are saved here during suspend
445 * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true
446 * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init
447 * @suspended: set to true after Linux suspend code has called our ->prepare()
448 * @suspend_save_flag: set to true after IRQ masks have been saved and disabled
449 *
450 * @saved_mask, @priority_mask, @base_irq, @suspended, and
451 * @suspend_save_flag are populated dynamically, and are not to be
452 * specified in static initializers.
453 */
454struct omap_prcm_irq_setup {
455 u16 ack;
456 u16 mask;
457 u8 nr_regs;
458 u8 nr_irqs;
459 const struct omap_prcm_irq *irqs;
460 int irq;
461 void (*read_pending_irqs)(unsigned long *events);
462 void (*ocp_barrier)(void);
463 void (*save_and_clear_irqen)(u32 *saved_mask);
464 void (*restore_irqen)(u32 *saved_mask);
465 u32 *saved_mask;
466 u32 *priority_mask;
467 int base_irq;
468 bool suspended;
469 bool suspend_save_flag;
470};
471
472/* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */
473#define OMAP_PRCM_IRQ(_name, _offset, _priority) { \
474 .name = _name, \
475 .offset = _offset, \
476 .priority = _priority \
477 }
478
479extern void omap_prcm_irq_cleanup(void);
480extern int omap_prcm_register_chain_handler(
481 struct omap_prcm_irq_setup *irq_setup);
482extern int omap_prcm_event_to_irq(const char *event);
483extern void omap_prcm_irq_prepare(void);
484extern void omap_prcm_irq_complete(void);
485
411# endif 486# endif
412 487
413#endif 488#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 9a08ba39732..c1c4d86a79a 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2/3 PRM module functions 2 * OMAP2/3 PRM module functions
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. 4 * Copyright (C) 2010-2011 Texas Instruments, Inc.
5 * Copyright (C) 2010 Nokia Corporation 5 * Copyright (C) 2010 Nokia Corporation
6 * Benoît Cousson 6 * Benoît Cousson
7 * Paul Walmsley 7 * Paul Walmsley
@@ -27,6 +27,24 @@
27#include "prm-regbits-24xx.h" 27#include "prm-regbits-24xx.h"
28#include "prm-regbits-34xx.h" 28#include "prm-regbits-34xx.h"
29 29
30static const struct omap_prcm_irq omap3_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0),
32 OMAP_PRCM_IRQ("io", 9, 1),
33};
34
35static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
36 .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
37 .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
38 .nr_regs = 1,
39 .irqs = omap3_prcm_irqs,
40 .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
41 .irq = INT_34XX_PRCM_MPU_IRQ,
42 .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
43 .ocp_barrier = &omap3xxx_prm_ocp_barrier,
44 .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
45 .restore_irqen = &omap3xxx_prm_restore_irqen,
46};
47
30u32 omap2_prm_read_mod_reg(s16 module, u16 idx) 48u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
31{ 49{
32 return __raw_readl(prm_base + module + idx); 50 return __raw_readl(prm_base + module + idx);
@@ -212,3 +230,80 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
212{ 230{
213 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); 231 return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
214} 232}
233
234/**
235 * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
236 * @events: ptr to a u32, preallocated by caller
237 *
238 * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
239 * MPU IRQs, and store the result into the u32 pointed to by @events.
240 * No return value.
241 */
242void omap3xxx_prm_read_pending_irqs(unsigned long *events)
243{
244 u32 mask, st;
245
246 /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
247 mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
248 st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
249
250 events[0] = mask & st;
251}
252
253/**
254 * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
255 *
256 * Force any buffered writes to the PRM IP block to complete. Needed
257 * by the PRM IRQ handler, which reads and writes directly to the IP
258 * block, to avoid race conditions after acknowledging or clearing IRQ
259 * bits. No return value.
260 */
261void omap3xxx_prm_ocp_barrier(void)
262{
263 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
264}
265
266/**
267 * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
268 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
269 *
270 * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
271 * must be allocated by the caller. Intended to be used in the PRM
272 * interrupt handler suspend callback. The OCP barrier is needed to
273 * ensure the write to disable PRM interrupts reaches the PRM before
274 * returning; otherwise, spurious interrupts might occur. No return
275 * value.
276 */
277void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
278{
279 saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
280 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
281 omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
282
283 /* OCP barrier */
284 omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
285}
286
287/**
288 * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
289 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
290 *
291 * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
292 * to be used in the PRM interrupt handler resume callback to restore
293 * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
294 * barrier should be needed here; any pending PRM interrupts will fire
295 * once the writes reach the PRM. No return value.
296 */
297void omap3xxx_prm_restore_irqen(u32 *saved_mask)
298{
299 omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
300 OMAP3_PRM_IRQENABLE_MPU_OFFSET);
301}
302
303static int __init omap3xxx_prcm_init(void)
304{
305 if (cpu_is_omap34xx())
306 return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
307 return 0;
308}
309subsys_initcall(omap3xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index cef533df086..70ac2a19dc5 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP2/3 Power/Reset Management (PRM) register definitions 2 * OMAP2/3 Power/Reset Management (PRM) register definitions
3 * 3 *
4 * Copyright (C) 2007-2009 Texas Instruments, Inc. 4 * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc.
5 * Copyright (C) 2008-2010 Nokia Corporation 5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Paul Walmsley 6 * Paul Walmsley
7 * 7 *
@@ -314,6 +314,13 @@ void omap3_prm_vp_clear_txdone(u8 vp_id);
314extern u32 omap3_prm_vcvp_read(u8 offset); 314extern u32 omap3_prm_vcvp_read(u8 offset);
315extern void omap3_prm_vcvp_write(u32 val, u8 offset); 315extern void omap3_prm_vcvp_write(u32 val, u8 offset);
316extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 316extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
317
318/* PRM interrupt-related functions */
319extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
320extern void omap3xxx_prm_ocp_barrier(void);
321extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
322extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
323
317#endif /* CONFIG_ARCH_OMAP4 */ 324#endif /* CONFIG_ARCH_OMAP4 */
318 325
319#endif 326#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index dd885eecf22..33dd655e6aa 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -27,6 +27,24 @@
27#include "prcm44xx.h" 27#include "prcm44xx.h"
28#include "prminst44xx.h" 28#include "prminst44xx.h"
29 29
30static const struct omap_prcm_irq omap4_prcm_irqs[] = {
31 OMAP_PRCM_IRQ("wkup", 0, 0),
32 OMAP_PRCM_IRQ("io", 9, 1),
33};
34
35static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
36 .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
37 .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET,
38 .nr_regs = 2,
39 .irqs = omap4_prcm_irqs,
40 .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs),
41 .irq = OMAP44XX_IRQ_PRCM,
42 .read_pending_irqs = &omap44xx_prm_read_pending_irqs,
43 .ocp_barrier = &omap44xx_prm_ocp_barrier,
44 .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen,
45 .restore_irqen = &omap44xx_prm_restore_irqen,
46};
47
30/* PRM low-level functions */ 48/* PRM low-level functions */
31 49
32/* Read a register in a CM/PRM instance in the PRM module */ 50/* Read a register in a CM/PRM instance in the PRM module */
@@ -121,3 +139,101 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
121 OMAP4430_PRM_DEVICE_INST, 139 OMAP4430_PRM_DEVICE_INST,
122 offset); 140 offset);
123} 141}
142
143static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
144{
145 u32 mask, st;
146
147 /* XXX read mask from RAM? */
148 mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs);
149 st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs);
150
151 return mask & st;
152}
153
154/**
155 * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
156 * @events: ptr to two consecutive u32s, preallocated by caller
157 *
158 * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
159 * MPU IRQs, and store the result into the two u32s pointed to by @events.
160 * No return value.
161 */
162void omap44xx_prm_read_pending_irqs(unsigned long *events)
163{
164 events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET,
165 OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
166
167 events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET,
168 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
169}
170
171/**
172 * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
173 *
174 * Force any buffered writes to the PRM IP block to complete. Needed
175 * by the PRM IRQ handler, which reads and writes directly to the IP
176 * block, to avoid race conditions after acknowledging or clearing IRQ
177 * bits. No return value.
178 */
179void omap44xx_prm_ocp_barrier(void)
180{
181 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
182 OMAP4_REVISION_PRM_OFFSET);
183}
184
185/**
186 * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
187 * @saved_mask: ptr to a u32 array to save IRQENABLE bits
188 *
189 * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
190 * @saved_mask. @saved_mask must be allocated by the caller.
191 * Intended to be used in the PRM interrupt handler suspend callback.
192 * The OCP barrier is needed to ensure the write to disable PRM
193 * interrupts reaches the PRM before returning; otherwise, spurious
194 * interrupts might occur. No return value.
195 */
196void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
197{
198 saved_mask[0] =
199 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
200 OMAP4_PRM_IRQSTATUS_MPU_OFFSET);
201 saved_mask[1] =
202 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
203 OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET);
204
205 omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST,
206 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
207 omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST,
208 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
209
210 /* OCP barrier */
211 omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
212 OMAP4_REVISION_PRM_OFFSET);
213}
214
215/**
216 * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
217 * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
218 *
219 * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
220 * @saved_mask. Intended to be used in the PRM interrupt handler resume
221 * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
222 * No OCP barrier should be needed here; any pending PRM interrupts will fire
223 * once the writes reach the PRM. No return value.
224 */
225void omap44xx_prm_restore_irqen(u32 *saved_mask)
226{
227 omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST,
228 OMAP4_PRM_IRQENABLE_MPU_OFFSET);
229 omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST,
230 OMAP4_PRM_IRQENABLE_MPU_2_OFFSET);
231}
232
233static int __init omap4xxx_prcm_init(void)
234{
235 if (cpu_is_omap44xx())
236 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
237 return 0;
238}
239subsys_initcall(omap4xxx_prcm_init);
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 3d66ccd849d..7978092946d 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * OMAP44xx PRM instance offset macros 2 * OMAP44xx PRM instance offset macros
3 * 3 *
4 * Copyright (C) 2009-2010 Texas Instruments, Inc. 4 * Copyright (C) 2009-2011 Texas Instruments, Inc.
5 * Copyright (C) 2009-2010 Nokia Corporation 5 * Copyright (C) 2009-2010 Nokia Corporation
6 * 6 *
7 * Paul Walmsley (paul@pwsan.com) 7 * Paul Walmsley (paul@pwsan.com)
@@ -763,6 +763,12 @@ extern u32 omap4_prm_vcvp_read(u8 offset);
763extern void omap4_prm_vcvp_write(u32 val, u8 offset); 763extern void omap4_prm_vcvp_write(u32 val, u8 offset);
764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); 764extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
765 765
766/* PRM interrupt-related functions */
767extern void omap44xx_prm_read_pending_irqs(unsigned long *events);
768extern void omap44xx_prm_ocp_barrier(void);
769extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
770extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
771
766# endif 772# endif
767 773
768#endif 774#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
new file mode 100644
index 00000000000..860118ab43e
--- /dev/null
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -0,0 +1,320 @@
1/*
2 * OMAP2+ common Power & Reset Management (PRM) IP block functions
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Tero Kristo <t-kristo@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 *
12 * For historical purposes, the API used to configure the PRM
13 * interrupt handler refers to it as the "PRCM interrupt." The
14 * underlying registers are located in the PRM on OMAP3/4.
15 *
16 * XXX This code should eventually be moved to a PRM driver.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/io.h>
23#include <linux/irq.h>
24#include <linux/interrupt.h>
25#include <linux/slab.h>
26
27#include <mach/system.h>
28#include <plat/common.h>
29#include <plat/prcm.h>
30#include <plat/irqs.h>
31
32#include "prm2xxx_3xxx.h"
33#include "prm44xx.h"
34
35/*
36 * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
37 * XXX this is technically not needed, since
38 * omap_prcm_register_chain_handler() could allocate this based on the
39 * actual amount of memory needed for the SoC
40 */
41#define OMAP_PRCM_MAX_NR_PENDING_REG 2
42
43/*
44 * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
45 * by the PRCM interrupt handler code. There will be one 'chip' per
46 * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have
47 * one "chip" and OMAP4 will have two.)
48 */
49static struct irq_chip_generic **prcm_irq_chips;
50
51/*
52 * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
53 * is currently running on. Defined and passed by initialization code
54 * that calls omap_prcm_register_chain_handler().
55 */
56static struct omap_prcm_irq_setup *prcm_irq_setup;
57
58/* Private functions */
59
60/*
61 * Move priority events from events to priority_events array
62 */
63static void omap_prcm_events_filter_priority(unsigned long *events,
64 unsigned long *priority_events)
65{
66 int i;
67
68 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
69 priority_events[i] =
70 events[i] & prcm_irq_setup->priority_mask[i];
71 events[i] ^= priority_events[i];
72 }
73}
74
75/*
76 * PRCM Interrupt Handler
77 *
78 * This is a common handler for the OMAP PRCM interrupts. Pending
79 * interrupts are detected by a call to prcm_pending_events and
80 * dispatched accordingly. Clearing of the wakeup events should be
81 * done by the SoC specific individual handlers.
82 */
83static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
84{
85 unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
86 unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
87 struct irq_chip *chip = irq_desc_get_chip(desc);
88 unsigned int virtirq;
89 int nr_irqs = prcm_irq_setup->nr_regs * 32;
90
91 /*
92 * If we are suspended, mask all interrupts from PRCM level,
93 * this does not ack them, and they will be pending until we
94 * re-enable the interrupts, at which point the
95 * omap_prcm_irq_handler will be executed again. The
96 * _save_and_clear_irqen() function must ensure that the PRM
97 * write to disable all IRQs has reached the PRM before
98 * returning, or spurious PRCM interrupts may occur during
99 * suspend.
100 */
101 if (prcm_irq_setup->suspended) {
102 prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
103 prcm_irq_setup->suspend_save_flag = true;
104 }
105
106 /*
107 * Loop until all pending irqs are handled, since
108 * generic_handle_irq() can cause new irqs to come
109 */
110 while (!prcm_irq_setup->suspended) {
111 prcm_irq_setup->read_pending_irqs(pending);
112
113 /* No bit set, then all IRQs are handled */
114 if (find_first_bit(pending, nr_irqs) >= nr_irqs)
115 break;
116
117 omap_prcm_events_filter_priority(pending, priority_pending);
118
119 /*
120 * Loop on all currently pending irqs so that new irqs
121 * cannot starve previously pending irqs
122 */
123
124 /* Serve priority events first */
125 for_each_set_bit(virtirq, priority_pending, nr_irqs)
126 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
127
128 /* Serve normal events next */
129 for_each_set_bit(virtirq, pending, nr_irqs)
130 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
131 }
132 if (chip->irq_ack)
133 chip->irq_ack(&desc->irq_data);
134 if (chip->irq_eoi)
135 chip->irq_eoi(&desc->irq_data);
136 chip->irq_unmask(&desc->irq_data);
137
138 prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
139}
140
141/* Public functions */
142
143/**
144 * omap_prcm_event_to_irq - given a PRCM event name, returns the
145 * corresponding IRQ on which the handler should be registered
146 * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
147 *
148 * Returns the Linux internal IRQ ID corresponding to @name upon success,
149 * or -ENOENT upon failure.
150 */
151int omap_prcm_event_to_irq(const char *name)
152{
153 int i;
154
155 if (!prcm_irq_setup || !name)
156 return -ENOENT;
157
158 for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
159 if (!strcmp(prcm_irq_setup->irqs[i].name, name))
160 return prcm_irq_setup->base_irq +
161 prcm_irq_setup->irqs[i].offset;
162
163 return -ENOENT;
164}
165
166/**
167 * omap_prcm_irq_cleanup - reverses memory allocated and other steps
168 * done by omap_prcm_register_chain_handler()
169 *
170 * No return value.
171 */
172void omap_prcm_irq_cleanup(void)
173{
174 int i;
175
176 if (!prcm_irq_setup) {
177 pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
178 return;
179 }
180
181 if (prcm_irq_chips) {
182 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
183 if (prcm_irq_chips[i])
184 irq_remove_generic_chip(prcm_irq_chips[i],
185 0xffffffff, 0, 0);
186 prcm_irq_chips[i] = NULL;
187 }
188 kfree(prcm_irq_chips);
189 prcm_irq_chips = NULL;
190 }
191
192 kfree(prcm_irq_setup->saved_mask);
193 prcm_irq_setup->saved_mask = NULL;
194
195 kfree(prcm_irq_setup->priority_mask);
196 prcm_irq_setup->priority_mask = NULL;
197
198 irq_set_chained_handler(prcm_irq_setup->irq, NULL);
199
200 if (prcm_irq_setup->base_irq > 0)
201 irq_free_descs(prcm_irq_setup->base_irq,
202 prcm_irq_setup->nr_regs * 32);
203 prcm_irq_setup->base_irq = 0;
204}
205
206void omap_prcm_irq_prepare(void)
207{
208 prcm_irq_setup->suspended = true;
209}
210
211void omap_prcm_irq_complete(void)
212{
213 prcm_irq_setup->suspended = false;
214
215 /* If we have not saved the masks, do not attempt to restore */
216 if (!prcm_irq_setup->suspend_save_flag)
217 return;
218
219 prcm_irq_setup->suspend_save_flag = false;
220
221 /*
222 * Re-enable all masked PRCM irq sources, this causes the PRCM
223 * interrupt to fire immediately if the events were masked
224 * previously in the chain handler
225 */
226 prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
227}
228
229/**
230 * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
231 * handler based on provided parameters
232 * @irq_setup: hardware data about the underlying PRM/PRCM
233 *
234 * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
235 * one generic IRQ chip per PRM interrupt status/enable register pair.
236 * Returns 0 upon success, -EINVAL if called twice or if invalid
237 * arguments are passed, or -ENOMEM on any other error.
238 */
239int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
240{
241 int nr_regs = irq_setup->nr_regs;
242 u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
243 int offset, i;
244 struct irq_chip_generic *gc;
245 struct irq_chip_type *ct;
246
247 if (!irq_setup)
248 return -EINVAL;
249
250 if (prcm_irq_setup) {
251 pr_err("PRCM: already initialized; won't reinitialize\n");
252 return -EINVAL;
253 }
254
255 if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
256 pr_err("PRCM: nr_regs too large\n");
257 return -EINVAL;
258 }
259
260 prcm_irq_setup = irq_setup;
261
262 prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
263 prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
264 prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
265 GFP_KERNEL);
266
267 if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
268 !prcm_irq_setup->priority_mask) {
269 pr_err("PRCM: kzalloc failed\n");
270 goto err;
271 }
272
273 memset(mask, 0, sizeof(mask));
274
275 for (i = 0; i < irq_setup->nr_irqs; i++) {
276 offset = irq_setup->irqs[i].offset;
277 mask[offset >> 5] |= 1 << (offset & 0x1f);
278 if (irq_setup->irqs[i].priority)
279 irq_setup->priority_mask[offset >> 5] |=
280 1 << (offset & 0x1f);
281 }
282
283 irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
284
285 irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
286 0);
287
288 if (irq_setup->base_irq < 0) {
289 pr_err("PRCM: failed to allocate irq descs: %d\n",
290 irq_setup->base_irq);
291 goto err;
292 }
293
294 for (i = 0; i <= irq_setup->nr_regs; i++) {
295 gc = irq_alloc_generic_chip("PRCM", 1,
296 irq_setup->base_irq + i * 32, prm_base,
297 handle_level_irq);
298
299 if (!gc) {
300 pr_err("PRCM: failed to allocate generic chip\n");
301 goto err;
302 }
303 ct = gc->chip_types;
304 ct->chip.irq_ack = irq_gc_ack_set_bit;
305 ct->chip.irq_mask = irq_gc_mask_clr_bit;
306 ct->chip.irq_unmask = irq_gc_mask_set_bit;
307
308 ct->regs.ack = irq_setup->ack + i * 4;
309 ct->regs.mask = irq_setup->mask + i * 4;
310
311 irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
312 prcm_irq_chips[i] = gc;
313 }
314
315 return 0;
316
317err:
318 omap_prcm_irq_cleanup();
319 return -ENOMEM;
320}
diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c
index ee3a8ad304c..7479d7ea137 100644
--- a/arch/arm/mach-omap2/sdram-nokia.c
+++ b/arch/arm/mach-omap2/sdram-nokia.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SDRC register values for Nokia boards 2 * SDRC register values for Nokia boards
3 * 3 *
4 * Copyright (C) 2008, 2010 Nokia Corporation 4 * Copyright (C) 2008, 2010-2011 Nokia Corporation
5 * 5 *
6 * Lauri Leukkunen <lauri.leukkunen@nokia.com> 6 * Lauri Leukkunen <lauri.leukkunen@nokia.com>
7 * 7 *
@@ -107,14 +107,37 @@ static const struct sdram_timings nokia_195dot2mhz_timings[] = {
107 }, 107 },
108}; 108};
109 109
110static const struct sdram_timings nokia_200mhz_timings[] = {
111 {
112 .casl = 3,
113 .tDAL = 30000,
114 .tDPL = 15000,
115 .tRRD = 10000,
116 .tRCD = 20000,
117 .tRP = 15000,
118 .tRAS = 40000,
119 .tRC = 55000,
120 .tRFC = 140000,
121 .tXSR = 200000,
122
123 .tREF = 7800,
124
125 .tXP = 2,
126 .tCKE = 4,
127 .tWTR = 2
128 },
129};
130
110static const struct { 131static const struct {
111 long rate; 132 long rate;
112 struct sdram_timings const *data; 133 struct sdram_timings const *data;
113} nokia_timings[] = { 134} nokia_timings[] = {
114 { 83000000, nokia_166mhz_timings }, 135 { 83000000, nokia_166mhz_timings },
115 { 97600000, nokia_97dot6mhz_timings }, 136 { 97600000, nokia_97dot6mhz_timings },
137 { 100000000, nokia_200mhz_timings },
116 { 166000000, nokia_166mhz_timings }, 138 { 166000000, nokia_166mhz_timings },
117 { 195200000, nokia_195dot2mhz_timings }, 139 { 195200000, nokia_195dot2mhz_timings },
140 { 200000000, nokia_200mhz_timings },
118}; 141};
119static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; 142static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1];
120 143
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 42c326732a2..247d89478f2 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -19,26 +19,21 @@
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/serial_reg.h>
23#include <linux/clk.h> 22#include <linux/clk.h>
24#include <linux/io.h> 23#include <linux/io.h>
25#include <linux/delay.h> 24#include <linux/delay.h>
26#include <linux/platform_device.h> 25#include <linux/platform_device.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/serial_8250.h>
29#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
30#include <linux/console.h> 28#include <linux/console.h>
31 29
32#ifdef CONFIG_SERIAL_OMAP
33#include <plat/omap-serial.h> 30#include <plat/omap-serial.h>
34#endif
35
36#include "common.h" 31#include "common.h"
37#include <plat/board.h> 32#include <plat/board.h>
38#include <plat/clock.h>
39#include <plat/dma.h> 33#include <plat/dma.h>
40#include <plat/omap_hwmod.h> 34#include <plat/omap_hwmod.h>
41#include <plat/omap_device.h> 35#include <plat/omap_device.h>
36#include <plat/omap-pm.h>
42 37
43#include "prm2xxx_3xxx.h" 38#include "prm2xxx_3xxx.h"
44#include "pm.h" 39#include "pm.h"
@@ -47,603 +42,226 @@
47#include "control.h" 42#include "control.h"
48#include "mux.h" 43#include "mux.h"
49 44
50#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
51#define UART_OMAP_WER 0x17 /* Wake-up enable register */
52
53#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
54#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
55
56/* 45/*
57 * NOTE: By default the serial timeout is disabled as it causes lost characters 46 * NOTE: By default the serial auto_suspend timeout is disabled as it causes
58 * over the serial ports. This means that the UART clocks will stay on until 47 * lost characters over the serial ports. This means that the UART clocks will
59 * disabled via sysfs. This also causes that any deeper omap sleep states are 48 * stay on until power/autosuspend_delay is set for the uart from sysfs.
60 * blocked. 49 * This also causes that any deeper omap sleep states are blocked.
61 */ 50 */
62#define DEFAULT_TIMEOUT 0 51#define DEFAULT_AUTOSUSPEND_DELAY -1
63 52
64#define MAX_UART_HWMOD_NAME_LEN 16 53#define MAX_UART_HWMOD_NAME_LEN 16
65 54
66struct omap_uart_state { 55struct omap_uart_state {
67 int num; 56 int num;
68 int can_sleep; 57 int can_sleep;
69 struct timer_list timer;
70 u32 timeout;
71
72 void __iomem *wk_st;
73 void __iomem *wk_en;
74 u32 wk_mask;
75 u32 padconf;
76 u32 dma_enabled;
77
78 struct clk *ick;
79 struct clk *fck;
80 int clocked;
81
82 int irq;
83 int regshift;
84 int irqflags;
85 void __iomem *membase;
86 resource_size_t mapbase;
87 58
88 struct list_head node; 59 struct list_head node;
89 struct omap_hwmod *oh; 60 struct omap_hwmod *oh;
90 struct platform_device *pdev; 61 struct platform_device *pdev;
91
92 u32 errata;
93#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
94 int context_valid;
95
96 /* Registers to be saved/restored for OFF-mode */
97 u16 dll;
98 u16 dlh;
99 u16 ier;
100 u16 sysc;
101 u16 scr;
102 u16 wer;
103 u16 mcr;
104#endif
105}; 62};
106 63
107static LIST_HEAD(uart_list); 64static LIST_HEAD(uart_list);
108static u8 num_uarts; 65static u8 num_uarts;
66static u8 console_uart_id = -1;
67static u8 no_console_suspend;
68static u8 uart_debug;
69
70#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */
71#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */
72#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */
73
74static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
75 {
76 .dma_enabled = false,
77 .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
78 .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
79 .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
80 .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
81 },
82};
109 83
110static inline unsigned int __serial_read_reg(struct uart_port *up, 84#ifdef CONFIG_PM
111 int offset) 85static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
112{
113 offset <<= up->regshift;
114 return (unsigned int)__raw_readb(up->membase + offset);
115}
116
117static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
118 int offset)
119{ 86{
120 offset <<= uart->regshift; 87 struct omap_device *od = to_omap_device(pdev);
121 return (unsigned int)__raw_readb(uart->membase + offset);
122}
123 88
124static inline void __serial_write_reg(struct uart_port *up, int offset, 89 if (!od)
125 int value) 90 return;
126{
127 offset <<= up->regshift;
128 __raw_writeb(value, up->membase + offset);
129}
130 91
131static inline void serial_write_reg(struct omap_uart_state *uart, int offset, 92 if (enable)
132 int value) 93 omap_hwmod_enable_wakeup(od->hwmods[0]);
133{ 94 else
134 offset <<= uart->regshift; 95 omap_hwmod_disable_wakeup(od->hwmods[0]);
135 __raw_writeb(value, uart->membase + offset);
136} 96}
137 97
138/* 98/*
139 * Internal UARTs need to be initialized for the 8250 autoconfig to work 99 * Errata i291: [UART]:Cannot Acknowledge Idle Requests
140 * properly. Note that the TX watermark initialization may not be needed 100 * in Smartidle Mode When Configured for DMA Operations.
141 * once the 8250.c watermark handling code is merged. 101 * WA: configure uart in force idle mode.
142 */ 102 */
143 103static void omap_uart_set_noidle(struct platform_device *pdev)
144static inline void __init omap_uart_reset(struct omap_uart_state *uart)
145{ 104{
146 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); 105 struct omap_device *od = to_omap_device(pdev);
147 serial_write_reg(uart, UART_OMAP_SCR, 0x08);
148 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
149}
150
151#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
152 106
153/* 107 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
154 * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
155 * The access to uart register after MDR1 Access
156 * causes UART to corrupt data.
157 *
158 * Need a delay =
159 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
160 * give 10 times as much
161 */
162static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
163 u8 fcr_val)
164{
165 u8 timeout = 255;
166
167 serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
168 udelay(2);
169 serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
170 UART_FCR_CLEAR_RCVR);
171 /*
172 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
173 * TX_FIFO_E bit is 1.
174 */
175 while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
176 (UART_LSR_THRE | UART_LSR_DR))) {
177 timeout--;
178 if (!timeout) {
179 /* Should *never* happen. we warn and carry on */
180 dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
181 serial_read_reg(uart, UART_LSR));
182 break;
183 }
184 udelay(1);
185 }
186} 108}
187 109
188static void omap_uart_save_context(struct omap_uart_state *uart) 110static void omap_uart_set_forceidle(struct platform_device *pdev)
189{ 111{
190 u16 lcr = 0; 112 struct omap_device *od = to_omap_device(pdev);
191 113
192 if (!enable_off_mode) 114 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
193 return;
194
195 lcr = serial_read_reg(uart, UART_LCR);
196 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
197 uart->dll = serial_read_reg(uart, UART_DLL);
198 uart->dlh = serial_read_reg(uart, UART_DLM);
199 serial_write_reg(uart, UART_LCR, lcr);
200 uart->ier = serial_read_reg(uart, UART_IER);
201 uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
202 uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
203 uart->wer = serial_read_reg(uart, UART_OMAP_WER);
204 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
205 uart->mcr = serial_read_reg(uart, UART_MCR);
206 serial_write_reg(uart, UART_LCR, lcr);
207
208 uart->context_valid = 1;
209} 115}
210 116
211static void omap_uart_restore_context(struct omap_uart_state *uart)
212{
213 u16 efr = 0;
214
215 if (!enable_off_mode)
216 return;
217
218 if (!uart->context_valid)
219 return;
220
221 uart->context_valid = 0;
222
223 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
224 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
225 else
226 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
227
228 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
229 efr = serial_read_reg(uart, UART_EFR);
230 serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
231 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
232 serial_write_reg(uart, UART_IER, 0x0);
233 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
234 serial_write_reg(uart, UART_DLL, uart->dll);
235 serial_write_reg(uart, UART_DLM, uart->dlh);
236 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
237 serial_write_reg(uart, UART_IER, uart->ier);
238 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
239 serial_write_reg(uart, UART_MCR, uart->mcr);
240 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
241 serial_write_reg(uart, UART_EFR, efr);
242 serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
243 serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
244 serial_write_reg(uart, UART_OMAP_WER, uart->wer);
245 serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
246
247 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
248 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
249 else
250 /* UART 16x mode */
251 serial_write_reg(uart, UART_OMAP_MDR1,
252 UART_OMAP_MDR1_16X_MODE);
253}
254#else 117#else
255static inline void omap_uart_save_context(struct omap_uart_state *uart) {} 118static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
256static inline void omap_uart_restore_context(struct omap_uart_state *uart) {} 119{}
257#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ 120static void omap_uart_set_noidle(struct platform_device *pdev) {}
258 121static void omap_uart_set_forceidle(struct platform_device *pdev) {}
259static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) 122#endif /* CONFIG_PM */
260{
261 if (uart->clocked)
262 return;
263
264 omap_device_enable(uart->pdev);
265 uart->clocked = 1;
266 omap_uart_restore_context(uart);
267}
268
269#ifdef CONFIG_PM
270
271static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
272{
273 if (!uart->clocked)
274 return;
275
276 omap_uart_save_context(uart);
277 uart->clocked = 0;
278 omap_device_idle(uart->pdev);
279}
280
281static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
282{
283 /* Set wake-enable bit */
284 if (uart->wk_en && uart->wk_mask) {
285 u32 v = __raw_readl(uart->wk_en);
286 v |= uart->wk_mask;
287 __raw_writel(v, uart->wk_en);
288 }
289
290 /* Ensure IOPAD wake-enables are set */
291 if (cpu_is_omap34xx() && uart->padconf) {
292 u16 v = omap_ctrl_readw(uart->padconf);
293 v |= OMAP3_PADCONF_WAKEUPENABLE0;
294 omap_ctrl_writew(v, uart->padconf);
295 }
296}
297
298static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
299{
300 /* Clear wake-enable bit */
301 if (uart->wk_en && uart->wk_mask) {
302 u32 v = __raw_readl(uart->wk_en);
303 v &= ~uart->wk_mask;
304 __raw_writel(v, uart->wk_en);
305 }
306
307 /* Ensure IOPAD wake-enables are cleared */
308 if (cpu_is_omap34xx() && uart->padconf) {
309 u16 v = omap_ctrl_readw(uart->padconf);
310 v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
311 omap_ctrl_writew(v, uart->padconf);
312 }
313}
314
315static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
316 int enable)
317{
318 u8 idlemode;
319
320 if (enable) {
321 /**
322 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
323 * in Smartidle Mode When Configured for DMA Operations.
324 */
325 if (uart->dma_enabled)
326 idlemode = HWMOD_IDLEMODE_FORCE;
327 else
328 idlemode = HWMOD_IDLEMODE_SMART;
329 } else {
330 idlemode = HWMOD_IDLEMODE_NO;
331 }
332
333 omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
334}
335
336static void omap_uart_block_sleep(struct omap_uart_state *uart)
337{
338 omap_uart_enable_clocks(uart);
339
340 omap_uart_smart_idle_enable(uart, 0);
341 uart->can_sleep = 0;
342 if (uart->timeout)
343 mod_timer(&uart->timer, jiffies + uart->timeout);
344 else
345 del_timer(&uart->timer);
346}
347
348static void omap_uart_allow_sleep(struct omap_uart_state *uart)
349{
350 if (device_may_wakeup(&uart->pdev->dev))
351 omap_uart_enable_wakeup(uart);
352 else
353 omap_uart_disable_wakeup(uart);
354
355 if (!uart->clocked)
356 return;
357
358 omap_uart_smart_idle_enable(uart, 1);
359 uart->can_sleep = 1;
360 del_timer(&uart->timer);
361}
362
363static void omap_uart_idle_timer(unsigned long data)
364{
365 struct omap_uart_state *uart = (struct omap_uart_state *)data;
366
367 omap_uart_allow_sleep(uart);
368}
369
370void omap_uart_prepare_idle(int num)
371{
372 struct omap_uart_state *uart;
373
374 list_for_each_entry(uart, &uart_list, node) {
375 if (num == uart->num && uart->can_sleep) {
376 omap_uart_disable_clocks(uart);
377 return;
378 }
379 }
380}
381
382void omap_uart_resume_idle(int num)
383{
384 struct omap_uart_state *uart;
385
386 list_for_each_entry(uart, &uart_list, node) {
387 if (num == uart->num && uart->can_sleep) {
388 omap_uart_enable_clocks(uart);
389
390 /* Check for IO pad wakeup */
391 if (cpu_is_omap34xx() && uart->padconf) {
392 u16 p = omap_ctrl_readw(uart->padconf);
393
394 if (p & OMAP3_PADCONF_WAKEUPEVENT0)
395 omap_uart_block_sleep(uart);
396 }
397
398 /* Check for normal UART wakeup */
399 if (__raw_readl(uart->wk_st) & uart->wk_mask)
400 omap_uart_block_sleep(uart);
401 return;
402 }
403 }
404}
405
406void omap_uart_prepare_suspend(void)
407{
408 struct omap_uart_state *uart;
409
410 list_for_each_entry(uart, &uart_list, node) {
411 omap_uart_allow_sleep(uart);
412 }
413}
414
415int omap_uart_can_sleep(void)
416{
417 struct omap_uart_state *uart;
418 int can_sleep = 1;
419
420 list_for_each_entry(uart, &uart_list, node) {
421 if (!uart->clocked)
422 continue;
423
424 if (!uart->can_sleep) {
425 can_sleep = 0;
426 continue;
427 }
428
429 /* This UART can now safely sleep. */
430 omap_uart_allow_sleep(uart);
431 }
432
433 return can_sleep;
434}
435 123
436/** 124#ifdef CONFIG_OMAP_MUX
437 * omap_uart_interrupt() 125static struct omap_device_pad default_uart1_pads[] __initdata = {
438 * 126 {
439 * This handler is used only to detect that *any* UART interrupt has 127 .name = "uart1_cts.uart1_cts",
440 * occurred. It does _nothing_ to handle the interrupt. Rather, 128 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
441 * any UART interrupt will trigger the inactivity timer so the 129 },
442 * UART will not idle or sleep for its timeout period. 130 {
443 * 131 .name = "uart1_rts.uart1_rts",
444 **/ 132 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
445/* static int first_interrupt; */ 133 },
446static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) 134 {
447{ 135 .name = "uart1_tx.uart1_tx",
448 struct omap_uart_state *uart = dev_id; 136 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
137 },
138 {
139 .name = "uart1_rx.uart1_rx",
140 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
141 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
142 .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
143 },
144};
449 145
450 omap_uart_block_sleep(uart); 146static struct omap_device_pad default_uart2_pads[] __initdata = {
147 {
148 .name = "uart2_cts.uart2_cts",
149 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
150 },
151 {
152 .name = "uart2_rts.uart2_rts",
153 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
154 },
155 {
156 .name = "uart2_tx.uart2_tx",
157 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
158 },
159 {
160 .name = "uart2_rx.uart2_rx",
161 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
162 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
163 .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
164 },
165};
451 166
452 return IRQ_NONE; 167static struct omap_device_pad default_uart3_pads[] __initdata = {
453} 168 {
169 .name = "uart3_cts_rctx.uart3_cts_rctx",
170 .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
171 },
172 {
173 .name = "uart3_rts_sd.uart3_rts_sd",
174 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
175 },
176 {
177 .name = "uart3_tx_irtx.uart3_tx_irtx",
178 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
179 },
180 {
181 .name = "uart3_rx_irrx.uart3_rx_irrx",
182 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
183 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
184 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
185 },
186};
454 187
455static void omap_uart_idle_init(struct omap_uart_state *uart) 188static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
456{ 189 {
457 int ret; 190 .name = "gpmc_wait2.uart4_tx",
458 191 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
459 uart->can_sleep = 0; 192 },
460 uart->timeout = DEFAULT_TIMEOUT; 193 {
461 setup_timer(&uart->timer, omap_uart_idle_timer, 194 .name = "gpmc_wait3.uart4_rx",
462 (unsigned long) uart); 195 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
463 if (uart->timeout) 196 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
464 mod_timer(&uart->timer, jiffies + uart->timeout); 197 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
465 omap_uart_smart_idle_enable(uart, 0); 198 },
466 199};
467 if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
468 u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
469 u32 wk_mask = 0;
470 u32 padconf = 0;
471
472 /* XXX These PRM accesses do not belong here */
473 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
474 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
475 switch (uart->num) {
476 case 0:
477 wk_mask = OMAP3430_ST_UART1_MASK;
478 padconf = 0x182;
479 break;
480 case 1:
481 wk_mask = OMAP3430_ST_UART2_MASK;
482 padconf = 0x17a;
483 break;
484 case 2:
485 wk_mask = OMAP3430_ST_UART3_MASK;
486 padconf = 0x19e;
487 break;
488 case 3:
489 wk_mask = OMAP3630_ST_UART4_MASK;
490 padconf = 0x0d2;
491 break;
492 }
493 uart->wk_mask = wk_mask;
494 uart->padconf = padconf;
495 } else if (cpu_is_omap24xx()) {
496 u32 wk_mask = 0;
497 u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
498
499 switch (uart->num) {
500 case 0:
501 wk_mask = OMAP24XX_ST_UART1_MASK;
502 break;
503 case 1:
504 wk_mask = OMAP24XX_ST_UART2_MASK;
505 break;
506 case 2:
507 wk_en = OMAP24XX_PM_WKEN2;
508 wk_st = OMAP24XX_PM_WKST2;
509 wk_mask = OMAP24XX_ST_UART3_MASK;
510 break;
511 }
512 uart->wk_mask = wk_mask;
513 if (cpu_is_omap2430()) {
514 uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
515 uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
516 } else if (cpu_is_omap2420()) {
517 uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
518 uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
519 }
520 } else {
521 uart->wk_en = NULL;
522 uart->wk_st = NULL;
523 uart->wk_mask = 0;
524 uart->padconf = 0;
525 }
526 200
527 uart->irqflags |= IRQF_SHARED; 201static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
528 ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt, 202 {
529 IRQF_SHARED, "serial idle", (void *)uart); 203 .name = "uart4_tx.uart4_tx",
530 WARN_ON(ret); 204 .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
531} 205 },
206 {
207 .name = "uart4_rx.uart4_rx",
208 .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
209 .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
210 .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
211 },
212};
532 213
533void omap_uart_enable_irqs(int enable) 214static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
534{ 215{
535 int ret; 216 switch (bdata->id) {
536 struct omap_uart_state *uart; 217 case 0:
537 218 bdata->pads = default_uart1_pads;
538 list_for_each_entry(uart, &uart_list, node) { 219 bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
539 if (enable) { 220 break;
540 pm_runtime_put_sync(&uart->pdev->dev); 221 case 1:
541 ret = request_threaded_irq(uart->irq, NULL, 222 bdata->pads = default_uart2_pads;
542 omap_uart_interrupt, 223 bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
543 IRQF_SHARED, 224 break;
544 "serial idle", 225 case 2:
545 (void *)uart); 226 bdata->pads = default_uart3_pads;
546 } else { 227 bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
547 pm_runtime_get_noresume(&uart->pdev->dev); 228 break;
548 free_irq(uart->irq, (void *)uart); 229 case 3:
230 if (cpu_is_omap44xx()) {
231 bdata->pads = default_omap4_uart4_pads;
232 bdata->pads_cnt =
233 ARRAY_SIZE(default_omap4_uart4_pads);
234 } else if (cpu_is_omap3630()) {
235 bdata->pads = default_omap36xx_uart4_pads;
236 bdata->pads_cnt =
237 ARRAY_SIZE(default_omap36xx_uart4_pads);
549 } 238 }
239 break;
240 default:
241 break;
550 } 242 }
551} 243}
552
553static ssize_t sleep_timeout_show(struct device *dev,
554 struct device_attribute *attr,
555 char *buf)
556{
557 struct platform_device *pdev = to_platform_device(dev);
558 struct omap_device *odev = to_omap_device(pdev);
559 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
560
561 return sprintf(buf, "%u\n", uart->timeout / HZ);
562}
563
564static ssize_t sleep_timeout_store(struct device *dev,
565 struct device_attribute *attr,
566 const char *buf, size_t n)
567{
568 struct platform_device *pdev = to_platform_device(dev);
569 struct omap_device *odev = to_omap_device(pdev);
570 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
571 unsigned int value;
572
573 if (sscanf(buf, "%u", &value) != 1) {
574 dev_err(dev, "sleep_timeout_store: Invalid value\n");
575 return -EINVAL;
576 }
577
578 uart->timeout = value * HZ;
579 if (uart->timeout)
580 mod_timer(&uart->timer, jiffies + uart->timeout);
581 else
582 /* A zero value means disable timeout feature */
583 omap_uart_block_sleep(uart);
584
585 return n;
586}
587
588static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
589 sleep_timeout_store);
590#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
591#else 244#else
592static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} 245static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
593static void omap_uart_block_sleep(struct omap_uart_state *uart) 246#endif
594{
595 /* Needed to enable UART clocks when built without CONFIG_PM */
596 omap_uart_enable_clocks(uart);
597}
598#define DEV_CREATE_FILE(dev, attr)
599#endif /* CONFIG_PM */
600
601#ifndef CONFIG_SERIAL_OMAP
602/*
603 * Override the default 8250 read handler: mem_serial_in()
604 * Empty RX fifo read causes an abort on omap3630 and omap4
605 * This function makes sure that an empty rx fifo is not read on these silicons
606 * (OMAP1/2/3430 are not affected)
607 */
608static unsigned int serial_in_override(struct uart_port *up, int offset)
609{
610 if (UART_RX == offset) {
611 unsigned int lsr;
612 lsr = __serial_read_reg(up, UART_LSR);
613 if (!(lsr & UART_LSR_DR))
614 return -EPERM;
615 }
616
617 return __serial_read_reg(up, offset);
618}
619 247
620static void serial_out_override(struct uart_port *up, int offset, int value) 248char *cmdline_find_option(char *str)
621{ 249{
622 unsigned int status, tmout = 10000; 250 extern char *saved_command_line;
623 251
624 status = __serial_read_reg(up, UART_LSR); 252 return strstr(saved_command_line, str);
625 while (!(status & UART_LSR_THRE)) {
626 /* Wait up to 10ms for the character(s) to be sent. */
627 if (--tmout == 0)
628 break;
629 udelay(1);
630 status = __serial_read_reg(up, UART_LSR);
631 }
632 __serial_write_reg(up, offset, value);
633} 253}
634#endif
635 254
636static int __init omap_serial_early_init(void) 255static int __init omap_serial_early_init(void)
637{ 256{
638 int i = 0;
639
640 do { 257 do {
641 char oh_name[MAX_UART_HWMOD_NAME_LEN]; 258 char oh_name[MAX_UART_HWMOD_NAME_LEN];
642 struct omap_hwmod *oh; 259 struct omap_hwmod *oh;
643 struct omap_uart_state *uart; 260 struct omap_uart_state *uart;
261 char uart_name[MAX_UART_HWMOD_NAME_LEN];
644 262
645 snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, 263 snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
646 "uart%d", i + 1); 264 "uart%d", num_uarts + 1);
647 oh = omap_hwmod_lookup(oh_name); 265 oh = omap_hwmod_lookup(oh_name);
648 if (!oh) 266 if (!oh)
649 break; 267 break;
@@ -653,21 +271,35 @@ static int __init omap_serial_early_init(void)
653 return -ENODEV; 271 return -ENODEV;
654 272
655 uart->oh = oh; 273 uart->oh = oh;
656 uart->num = i++; 274 uart->num = num_uarts++;
657 list_add_tail(&uart->node, &uart_list); 275 list_add_tail(&uart->node, &uart_list);
658 num_uarts++; 276 snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
659 277 "%s%d", OMAP_SERIAL_NAME, uart->num);
660 /* 278
661 * NOTE: omap_hwmod_setup*() has not yet been called, 279 if (cmdline_find_option(uart_name)) {
662 * so no hwmod functions will work yet. 280 console_uart_id = uart->num;
663 */ 281
664 282 if (console_loglevel >= 10) {
665 /* 283 uart_debug = true;
666 * During UART early init, device need to be probed 284 pr_info("%s used as console in debug mode"
667 * to determine SoC specific init before omap_device 285 " uart%d clocks will not be"
668 * is ready. Therefore, don't allow idle here 286 " gated", uart_name, uart->num);
669 */ 287 }
670 uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; 288
289 if (cmdline_find_option("no_console_suspend"))
290 no_console_suspend = true;
291
292 /*
293 * omap-uart can be used for earlyprintk logs
294 * So if omap-uart is used as console then prevent
295 * uart reset and idle to get logs from omap-uart
296 * until uart console driver is available to take
297 * care for console messages.
298 * Idling or resetting omap-uart while printing logs
299 * early boot logs can stall the boot-up.
300 */
301 oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
302 }
671 } while (1); 303 } while (1);
672 304
673 return 0; 305 return 0;
@@ -677,6 +309,7 @@ core_initcall(omap_serial_early_init);
677/** 309/**
678 * omap_serial_init_port() - initialize single serial port 310 * omap_serial_init_port() - initialize single serial port
679 * @bdata: port specific board data pointer 311 * @bdata: port specific board data pointer
312 * @info: platform specific data pointer
680 * 313 *
681 * This function initialies serial driver for given port only. 314 * This function initialies serial driver for given port only.
682 * Platforms can call this function instead of omap_serial_init() 315 * Platforms can call this function instead of omap_serial_init()
@@ -685,7 +318,8 @@ core_initcall(omap_serial_early_init);
685 * Don't mix calls to omap_serial_init_port() and omap_serial_init(), 318 * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
686 * use only one of the two. 319 * use only one of the two.
687 */ 320 */
688void __init omap_serial_init_port(struct omap_board_data *bdata) 321void __init omap_serial_init_port(struct omap_board_data *bdata,
322 struct omap_uart_port_info *info)
689{ 323{
690 struct omap_uart_state *uart; 324 struct omap_uart_state *uart;
691 struct omap_hwmod *oh; 325 struct omap_hwmod *oh;
@@ -693,15 +327,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
693 void *pdata = NULL; 327 void *pdata = NULL;
694 u32 pdata_size = 0; 328 u32 pdata_size = 0;
695 char *name; 329 char *name;
696#ifndef CONFIG_SERIAL_OMAP
697 struct plat_serial8250_port ports[2] = {
698 {},
699 {.flags = 0},
700 };
701 struct plat_serial8250_port *p = &ports[0];
702#else
703 struct omap_uart_port_info omap_up; 330 struct omap_uart_port_info omap_up;
704#endif
705 331
706 if (WARN_ON(!bdata)) 332 if (WARN_ON(!bdata))
707 return; 333 return;
@@ -713,66 +339,34 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
713 list_for_each_entry(uart, &uart_list, node) 339 list_for_each_entry(uart, &uart_list, node)
714 if (bdata->id == uart->num) 340 if (bdata->id == uart->num)
715 break; 341 break;
342 if (!info)
343 info = omap_serial_default_info;
716 344
717 oh = uart->oh; 345 oh = uart->oh;
718 uart->dma_enabled = 0;
719#ifndef CONFIG_SERIAL_OMAP
720 name = "serial8250";
721
722 /*
723 * !! 8250 driver does not use standard IORESOURCE* It
724 * has it's own custom pdata that can be taken from
725 * the hwmod resource data. But, this needs to be
726 * done after the build.
727 *
728 * ?? does it have to be done before the register ??
729 * YES, because platform_device_data_add() copies
730 * pdata, it does not use a pointer.
731 */
732 p->flags = UPF_BOOT_AUTOCONF;
733 p->iotype = UPIO_MEM;
734 p->regshift = 2;
735 p->uartclk = OMAP24XX_BASE_BAUD * 16;
736 p->irq = oh->mpu_irqs[0].irq;
737 p->mapbase = oh->slaves[0]->addr->pa_start;
738 p->membase = omap_hwmod_get_mpu_rt_va(oh);
739 p->irqflags = IRQF_SHARED;
740 p->private_data = uart;
741
742 /*
743 * omap44xx, ti816x: Never read empty UART fifo
744 * omap3xxx: Never read empty UART fifo on UARTs
745 * with IP rev >=0x52
746 */
747 uart->regshift = p->regshift;
748 uart->membase = p->membase;
749 if (cpu_is_omap44xx() || cpu_is_ti816x())
750 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
751 else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
752 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
753 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
754
755 if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
756 p->serial_in = serial_in_override;
757 p->serial_out = serial_out_override;
758 }
759
760 pdata = &ports[0];
761 pdata_size = 2 * sizeof(struct plat_serial8250_port);
762#else
763
764 name = DRIVER_NAME; 346 name = DRIVER_NAME;
765 347
766 omap_up.dma_enabled = uart->dma_enabled; 348 omap_up.dma_enabled = info->dma_enabled;
767 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; 349 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
768 omap_up.mapbase = oh->slaves[0]->addr->pa_start; 350 omap_up.flags = UPF_BOOT_AUTOCONF;
769 omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); 351 omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
770 omap_up.irqflags = IRQF_SHARED; 352 omap_up.set_forceidle = omap_uart_set_forceidle;
771 omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; 353 omap_up.set_noidle = omap_uart_set_noidle;
354 omap_up.enable_wakeup = omap_uart_enable_wakeup;
355 omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
356 omap_up.dma_rx_timeout = info->dma_rx_timeout;
357 omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
358 omap_up.autosuspend_timeout = info->autosuspend_timeout;
359
360 /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */
361 if (!cpu_is_omap2420() && !cpu_is_ti816x())
362 omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;
363
364 /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */
365 if (cpu_is_omap34xx() || cpu_is_omap3630())
366 omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;
772 367
773 pdata = &omap_up; 368 pdata = &omap_up;
774 pdata_size = sizeof(struct omap_uart_port_info); 369 pdata_size = sizeof(struct omap_uart_port_info);
775#endif
776 370
777 if (WARN_ON(!oh)) 371 if (WARN_ON(!oh))
778 return; 372 return;
@@ -782,64 +376,29 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
782 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", 376 WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
783 name, oh->name); 377 name, oh->name);
784 378
785 omap_device_disable_idle_on_suspend(pdev); 379 if ((console_uart_id == bdata->id) && no_console_suspend)
380 omap_device_disable_idle_on_suspend(pdev);
381
786 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); 382 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
787 383
788 uart->irq = oh->mpu_irqs[0].irq;
789 uart->regshift = 2;
790 uart->mapbase = oh->slaves[0]->addr->pa_start;
791 uart->membase = omap_hwmod_get_mpu_rt_va(oh);
792 uart->pdev = pdev; 384 uart->pdev = pdev;
793 385
794 oh->dev_attr = uart; 386 oh->dev_attr = uart;
795 387
796 console_lock(); /* in case the earlycon is on the UART */ 388 if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
797 389 && !uart_debug)
798 /*
799 * Because of early UART probing, UART did not get idled
800 * on init. Now that omap_device is ready, ensure full idle
801 * before doing omap_device_enable().
802 */
803 omap_hwmod_idle(uart->oh);
804
805 omap_device_enable(uart->pdev);
806 omap_uart_idle_init(uart);
807 omap_uart_reset(uart);
808 omap_hwmod_enable_wakeup(uart->oh);
809 omap_device_idle(uart->pdev);
810
811 /*
812 * Need to block sleep long enough for interrupt driven
813 * driver to start. Console driver is in polling mode
814 * so device needs to be kept enabled while polling driver
815 * is in use.
816 */
817 if (uart->timeout)
818 uart->timeout = (30 * HZ);
819 omap_uart_block_sleep(uart);
820 uart->timeout = DEFAULT_TIMEOUT;
821
822 console_unlock();
823
824 if ((cpu_is_omap34xx() && uart->padconf) ||
825 (uart->wk_en && uart->wk_mask)) {
826 device_init_wakeup(&pdev->dev, true); 390 device_init_wakeup(&pdev->dev, true);
827 DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
828 }
829
830 /* Enable the MDR1 errata for OMAP3 */
831 if (cpu_is_omap34xx() && !cpu_is_ti816x())
832 uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
833} 391}
834 392
835/** 393/**
836 * omap_serial_init() - initialize all supported serial ports 394 * omap_serial_board_init() - initialize all supported serial ports
395 * @info: platform specific data pointer
837 * 396 *
838 * Initializes all available UARTs as serial ports. Platforms 397 * Initializes all available UARTs as serial ports. Platforms
839 * can call this function when they want to have default behaviour 398 * can call this function when they want to have default behaviour
840 * for serial ports (e.g initialize them all as serial ports). 399 * for serial ports (e.g initialize them all as serial ports).
841 */ 400 */
842void __init omap_serial_init(void) 401void __init omap_serial_board_init(struct omap_uart_port_info *info)
843{ 402{
844 struct omap_uart_state *uart; 403 struct omap_uart_state *uart;
845 struct omap_board_data bdata; 404 struct omap_board_data bdata;
@@ -849,7 +408,25 @@ void __init omap_serial_init(void)
849 bdata.flags = 0; 408 bdata.flags = 0;
850 bdata.pads = NULL; 409 bdata.pads = NULL;
851 bdata.pads_cnt = 0; 410 bdata.pads_cnt = 0;
852 omap_serial_init_port(&bdata);
853 411
412 if (cpu_is_omap44xx() || cpu_is_omap34xx())
413 omap_serial_fill_default_pads(&bdata);
414
415 if (!info)
416 omap_serial_init_port(&bdata, NULL);
417 else
418 omap_serial_init_port(&bdata, &info[uart->num]);
854 } 419 }
855} 420}
421
422/**
423 * omap_serial_init() - initialize all supported serial ports
424 *
425 * Initializes all available UARTs.
426 * Platforms can call this function when they want to have default behaviour
427 * for serial ports (e.g initialize them all as serial ports).
428 */
429void __init omap_serial_init(void)
430{
431 omap_serial_board_init(NULL);
432}
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
new file mode 100644
index 00000000000..abd28340049
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -0,0 +1,379 @@
1/*
2 * OMAP44xx sleep code.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Santosh Shilimkar <santosh.shilimkar@ti.com>
6 *
7 * This program is free software,you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/linkage.h>
13#include <asm/system.h>
14#include <asm/smp_scu.h>
15#include <asm/memory.h>
16#include <asm/hardware/cache-l2x0.h>
17
18#include <plat/omap44xx.h>
19#include <mach/omap-secure.h>
20
21#include "common.h"
22#include "omap4-sar-layout.h"
23
24#if defined(CONFIG_SMP) && defined(CONFIG_PM)
25
26.macro DO_SMC
27 dsb
28 smc #0
29 dsb
30.endm
31
32ppa_zero_params:
33 .word 0x0
34
35ppa_por_params:
36 .word 1, 0
37
38/*
39 * =============================
40 * == CPU suspend finisher ==
41 * =============================
42 *
43 * void omap4_finish_suspend(unsigned long cpu_state)
44 *
45 * This function code saves the CPU context and performs the CPU
46 * power down sequence. Calling WFI effectively changes the CPU
47 * power domains states to the desired target power state.
48 *
49 * @cpu_state : contains context save state (r0)
50 * 0 - No context lost
51 * 1 - CPUx L1 and logic lost: MPUSS CSWR
52 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
53 * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF
54 * @return: This function never returns for CPU OFF and DORMANT power states.
55 * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up
56 * from this follows a full CPU reset path via ROM code to CPU restore code.
57 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
58 * It returns to the caller for CPU INACTIVE and ON power states or in case
59 * CPU failed to transition to targeted OFF/DORMANT state.
60 */
61ENTRY(omap4_finish_suspend)
62 stmfd sp!, {lr}
63 cmp r0, #0x0
64 beq do_WFI @ No lowpower state, jump to WFI
65
66 /*
67 * Flush all data from the L1 data cache before disabling
68 * SCTLR.C bit.
69 */
70 bl omap4_get_sar_ram_base
71 ldr r9, [r0, #OMAP_TYPE_OFFSET]
72 cmp r9, #0x1 @ Check for HS device
73 bne skip_secure_l1_clean
74 mov r0, #SCU_PM_NORMAL
75 mov r1, #0xFF @ clean seucre L1
76 stmfd r13!, {r4-r12, r14}
77 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
78 DO_SMC
79 ldmfd r13!, {r4-r12, r14}
80skip_secure_l1_clean:
81 bl v7_flush_dcache_all
82
83 /*
84 * Clear the SCTLR.C bit to prevent further data cache
85 * allocation. Clearing SCTLR.C would make all the data accesses
86 * strongly ordered and would not hit the cache.
87 */
88 mrc p15, 0, r0, c1, c0, 0
89 bic r0, r0, #(1 << 2) @ Disable the C bit
90 mcr p15, 0, r0, c1, c0, 0
91 isb
92
93 /*
94 * Invalidate L1 data cache. Even though only invalidate is
95 * necessary exported flush API is used here. Doing clean
96 * on already clean cache would be almost NOP.
97 */
98 bl v7_flush_dcache_all
99
100 /*
101 * Switch the CPU from Symmetric Multiprocessing (SMP) mode
102 * to AsymmetricMultiprocessing (AMP) mode by programming
103 * the SCU power status to DORMANT or OFF mode.
104 * This enables the CPU to be taken out of coherency by
105 * preventing the CPU from receiving cache, TLB, or BTB
106 * maintenance operations broadcast by other CPUs in the cluster.
107 */
108 bl omap4_get_sar_ram_base
109 mov r8, r0
110 ldr r9, [r8, #OMAP_TYPE_OFFSET]
111 cmp r9, #0x1 @ Check for HS device
112 bne scu_gp_set
113 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
114 ands r0, r0, #0x0f
115 ldreq r0, [r8, #SCU_OFFSET0]
116 ldrne r0, [r8, #SCU_OFFSET1]
117 mov r1, #0x00
118 stmfd r13!, {r4-r12, r14}
119 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
120 DO_SMC
121 ldmfd r13!, {r4-r12, r14}
122 b skip_scu_gp_set
123scu_gp_set:
124 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
125 ands r0, r0, #0x0f
126 ldreq r1, [r8, #SCU_OFFSET0]
127 ldrne r1, [r8, #SCU_OFFSET1]
128 bl omap4_get_scu_base
129 bl scu_power_mode
130skip_scu_gp_set:
131 mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data
132 tst r0, #(1 << 18)
133 mrcne p15, 0, r0, c1, c0, 1
134 bicne r0, r0, #(1 << 6) @ Disable SMP bit
135 mcrne p15, 0, r0, c1, c0, 1
136 isb
137 dsb
138#ifdef CONFIG_CACHE_L2X0
139 /*
140 * Clean and invalidate the L2 cache.
141 * Common cache-l2x0.c functions can't be used here since it
142 * uses spinlocks. We are out of coherency here with data cache
143 * disabled. The spinlock implementation uses exclusive load/store
144 * instruction which can fail without data cache being enabled.
145 * OMAP4 hardware doesn't support exclusive monitor which can
146 * overcome exclusive access issue. Because of this, CPU can
147 * lead to deadlock.
148 */
149 bl omap4_get_sar_ram_base
150 mov r8, r0
151 mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR
152 ands r5, r5, #0x0f
153 ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR
154 ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory.
155 cmp r0, #3
156 bne do_WFI
157#ifdef CONFIG_PL310_ERRATA_727915
158 mov r0, #0x03
159 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
160 DO_SMC
161#endif
162 bl omap4_get_l2cache_base
163 mov r2, r0
164 ldr r0, =0xffff
165 str r0, [r2, #L2X0_CLEAN_INV_WAY]
166wait:
167 ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
168 ldr r1, =0xffff
169 ands r0, r0, r1
170 bne wait
171#ifdef CONFIG_PL310_ERRATA_727915
172 mov r0, #0x00
173 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
174 DO_SMC
175#endif
176l2x_sync:
177 bl omap4_get_l2cache_base
178 mov r2, r0
179 mov r0, #0x0
180 str r0, [r2, #L2X0_CACHE_SYNC]
181sync:
182 ldr r0, [r2, #L2X0_CACHE_SYNC]
183 ands r0, r0, #0x1
184 bne sync
185#endif
186
187do_WFI:
188 bl omap_do_wfi
189
190 /*
191 * CPU is here when it failed to enter OFF/DORMANT or
192 * no low power state was attempted.
193 */
194 mrc p15, 0, r0, c1, c0, 0
195 tst r0, #(1 << 2) @ Check C bit enabled?
196 orreq r0, r0, #(1 << 2) @ Enable the C bit
197 mcreq p15, 0, r0, c1, c0, 0
198 isb
199
200 /*
201 * Ensure the CPU power state is set to NORMAL in
202 * SCU power state so that CPU is back in coherency.
203 * In non-coherent mode CPU can lock-up and lead to
204 * system deadlock.
205 */
206 mrc p15, 0, r0, c1, c0, 1
207 tst r0, #(1 << 6) @ Check SMP bit enabled?
208 orreq r0, r0, #(1 << 6)
209 mcreq p15, 0, r0, c1, c0, 1
210 isb
211 bl omap4_get_sar_ram_base
212 mov r8, r0
213 ldr r9, [r8, #OMAP_TYPE_OFFSET]
214 cmp r9, #0x1 @ Check for HS device
215 bne scu_gp_clear
216 mov r0, #SCU_PM_NORMAL
217 mov r1, #0x00
218 stmfd r13!, {r4-r12, r14}
219 ldr r12, =OMAP4_MON_SCU_PWR_INDEX
220 DO_SMC
221 ldmfd r13!, {r4-r12, r14}
222 b skip_scu_gp_clear
223scu_gp_clear:
224 bl omap4_get_scu_base
225 mov r1, #SCU_PM_NORMAL
226 bl scu_power_mode
227skip_scu_gp_clear:
228 isb
229 dsb
230 ldmfd sp!, {pc}
231ENDPROC(omap4_finish_suspend)
232
233/*
234 * ============================
235 * == CPU resume entry point ==
236 * ============================
237 *
238 * void omap4_cpu_resume(void)
239 *
240 * ROM code jumps to this function while waking up from CPU
241 * OFF or DORMANT state. Physical address of the function is
242 * stored in the SAR RAM while entering to OFF or DORMANT mode.
243 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET.
244 */
245ENTRY(omap4_cpu_resume)
246 /*
247 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
248 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
249 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
250 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
251 * OMAP443X GP devices- SMP bit isn't accessible.
252 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
253 */
254 ldr r8, =OMAP44XX_SAR_RAM_BASE
255 ldr r9, [r8, #OMAP_TYPE_OFFSET]
256 cmp r9, #0x1 @ Skip if GP device
257 bne skip_ns_smp_enable
258 mrc p15, 0, r0, c0, c0, 5
259 ands r0, r0, #0x0f
260 beq skip_ns_smp_enable
261ppa_actrl_retry:
262 mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX
263 adr r3, ppa_zero_params @ Pointer to parameters
264 mov r1, #0x0 @ Process ID
265 mov r2, #0x4 @ Flag
266 mov r6, #0xff
267 mov r12, #0x00 @ Secure Service ID
268 DO_SMC
269 cmp r0, #0x0 @ API returns 0 on success.
270 beq enable_smp_bit
271 b ppa_actrl_retry
272enable_smp_bit:
273 mrc p15, 0, r0, c1, c0, 1
274 tst r0, #(1 << 6) @ Check SMP bit enabled?
275 orreq r0, r0, #(1 << 6)
276 mcreq p15, 0, r0, c1, c0, 1
277 isb
278skip_ns_smp_enable:
279#ifdef CONFIG_CACHE_L2X0
280 /*
281 * Restore the L2 AUXCTRL and enable the L2 cache.
282 * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL
283 * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL
284 * register r0 contains value to be programmed.
285 * L2 cache is already invalidate by ROM code as part
286 * of MPUSS OFF wakeup path.
287 */
288 ldr r2, =OMAP44XX_L2CACHE_BASE
289 ldr r0, [r2, #L2X0_CTRL]
290 and r0, #0x0f
291 cmp r0, #1
292 beq skip_l2en @ Skip if already enabled
293 ldr r3, =OMAP44XX_SAR_RAM_BASE
294 ldr r1, [r3, #OMAP_TYPE_OFFSET]
295 cmp r1, #0x1 @ Check for HS device
296 bne set_gp_por
297 ldr r0, =OMAP4_PPA_L2_POR_INDEX
298 ldr r1, =OMAP44XX_SAR_RAM_BASE
299 ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
300 adr r3, ppa_por_params
301 str r4, [r3, #0x04]
302 mov r1, #0x0 @ Process ID
303 mov r2, #0x4 @ Flag
304 mov r6, #0xff
305 mov r12, #0x00 @ Secure Service ID
306 DO_SMC
307 b set_aux_ctrl
308set_gp_por:
309 ldr r1, =OMAP44XX_SAR_RAM_BASE
310 ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET]
311 ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH
312 DO_SMC
313set_aux_ctrl:
314 ldr r1, =OMAP44XX_SAR_RAM_BASE
315 ldr r0, [r1, #L2X0_AUXCTRL_OFFSET]
316 ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL
317 DO_SMC
318 mov r0, #0x1
319 ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache
320 DO_SMC
321skip_l2en:
322#endif
323
324 b cpu_resume @ Jump to generic resume
325ENDPROC(omap4_cpu_resume)
326#endif
327
328#ifndef CONFIG_OMAP4_ERRATA_I688
329ENTRY(omap_bus_sync)
330 mov pc, lr
331ENDPROC(omap_bus_sync)
332#endif
333
334ENTRY(omap_do_wfi)
335 stmfd sp!, {lr}
336 /* Drain interconnect write buffers. */
337 bl omap_bus_sync
338
339 /*
340 * Execute an ISB instruction to ensure that all of the
341 * CP15 register changes have been committed.
342 */
343 isb
344
345 /*
346 * Execute a barrier instruction to ensure that all cache,
347 * TLB and branch predictor maintenance operations issued
348 * by any CPU in the cluster have completed.
349 */
350 dsb
351 dmb
352
353 /*
354 * Execute a WFI instruction and wait until the
355 * STANDBYWFI output is asserted to indicate that the
356 * CPU is in idle and low power state. CPU can specualatively
357 * prefetch the instructions so add NOPs after WFI. Sixteen
358 * NOPs as per Cortex-A9 pipeline.
359 */
360 wfi @ Wait For Interrupt
361 nop
362 nop
363 nop
364 nop
365 nop
366 nop
367 nop
368 nop
369 nop
370 nop
371 nop
372 nop
373 nop
374 nop
375 nop
376 nop
377
378 ldmfd sp!, {pc}
379ENDPROC(omap_do_wfi)
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 89ae29847c5..771dc781b74 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -28,51 +28,28 @@
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/irqs.h> 29#include <mach/irqs.h>
30#include <plat/usb.h> 30#include <plat/usb.h>
31#include <plat/omap_device.h>
31 32
32#include "mux.h" 33#include "mux.h"
33 34
34#ifdef CONFIG_MFD_OMAP_USB_HOST 35#ifdef CONFIG_MFD_OMAP_USB_HOST
35 36
36#define OMAP_USBHS_DEVICE "usbhs-omap" 37#define OMAP_USBHS_DEVICE "usbhs_omap"
37 38#define USBHS_UHH_HWMODNAME "usb_host_hs"
38static struct resource usbhs_resources[] = { 39#define USBHS_TLL_HWMODNAME "usb_tll_hs"
39 {
40 .name = "uhh",
41 .flags = IORESOURCE_MEM,
42 },
43 {
44 .name = "tll",
45 .flags = IORESOURCE_MEM,
46 },
47 {
48 .name = "ehci",
49 .flags = IORESOURCE_MEM,
50 },
51 {
52 .name = "ehci-irq",
53 .flags = IORESOURCE_IRQ,
54 },
55 {
56 .name = "ohci",
57 .flags = IORESOURCE_MEM,
58 },
59 {
60 .name = "ohci-irq",
61 .flags = IORESOURCE_IRQ,
62 }
63};
64
65static struct platform_device usbhs_device = {
66 .name = OMAP_USBHS_DEVICE,
67 .id = 0,
68 .num_resources = ARRAY_SIZE(usbhs_resources),
69 .resource = usbhs_resources,
70};
71 40
72static struct usbhs_omap_platform_data usbhs_data; 41static struct usbhs_omap_platform_data usbhs_data;
73static struct ehci_hcd_omap_platform_data ehci_data; 42static struct ehci_hcd_omap_platform_data ehci_data;
74static struct ohci_hcd_omap_platform_data ohci_data; 43static struct ohci_hcd_omap_platform_data ohci_data;
75 44
45static struct omap_device_pm_latency omap_uhhtll_latency[] = {
46 {
47 .deactivate_func = omap_device_idle_hwmods,
48 .activate_func = omap_device_enable_hwmods,
49 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
50 },
51};
52
76/* MUX settings for EHCI pins */ 53/* MUX settings for EHCI pins */
77/* 54/*
78 * setup_ehci_io_mux - initialize IO pad mux for USBHOST 55 * setup_ehci_io_mux - initialize IO pad mux for USBHOST
@@ -508,7 +485,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
508 485
509void __init usbhs_init(const struct usbhs_omap_board_data *pdata) 486void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
510{ 487{
511 int i; 488 struct omap_hwmod *oh[2];
489 struct omap_device *od;
490 int bus_id = -1;
491 int i;
512 492
513 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { 493 for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
514 usbhs_data.port_mode[i] = pdata->port_mode[i]; 494 usbhs_data.port_mode[i] = pdata->port_mode[i];
@@ -523,44 +503,34 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
523 usbhs_data.ohci_data = &ohci_data; 503 usbhs_data.ohci_data = &ohci_data;
524 504
525 if (cpu_is_omap34xx()) { 505 if (cpu_is_omap34xx()) {
526 usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
527 usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
528 usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
529 usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
530 usbhs_resources[2].start = OMAP34XX_EHCI_BASE;
531 usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
532 usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
533 usbhs_resources[4].start = OMAP34XX_OHCI_BASE;
534 usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1;
535 usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
536 setup_ehci_io_mux(pdata->port_mode); 506 setup_ehci_io_mux(pdata->port_mode);
537 setup_ohci_io_mux(pdata->port_mode); 507 setup_ohci_io_mux(pdata->port_mode);
538 } else if (cpu_is_omap44xx()) { 508 } else if (cpu_is_omap44xx()) {
539 usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
540 usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
541 usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
542 usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
543 usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
544 usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
545 usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
546 usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
547 usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
548 usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
549 setup_4430ehci_io_mux(pdata->port_mode); 509 setup_4430ehci_io_mux(pdata->port_mode);
550 setup_4430ohci_io_mux(pdata->port_mode); 510 setup_4430ohci_io_mux(pdata->port_mode);
551 } 511 }
552 512
553 if (platform_device_add_data(&usbhs_device, 513 oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
554 &usbhs_data, sizeof(usbhs_data)) < 0) { 514 if (!oh[0]) {
555 printk(KERN_ERR "USBHS platform_device_add_data failed\n"); 515 pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
556 goto init_end; 516 return;
557 } 517 }
558 518
559 if (platform_device_register(&usbhs_device) < 0) 519 oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
560 printk(KERN_ERR "USBHS platform_device_register failed\n"); 520 if (!oh[1]) {
521 pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
522 return;
523 }
561 524
562init_end: 525 od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
563 return; 526 (void *)&usbhs_data, sizeof(usbhs_data),
527 omap_uhhtll_latency,
528 ARRAY_SIZE(omap_uhhtll_latency), false);
529 if (IS_ERR(od)) {
530 pr_err("Could not build hwmod devices %s,%s\n",
531 USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
532 return;
533 }
564} 534}
565 535
566#else 536#else
@@ -570,5 +540,3 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
570} 540}
571 541
572#endif 542#endif
573
574
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 267975086a7..8d5ed775dd5 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -93,6 +93,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
93 if (cpu_is_omap3517() || cpu_is_omap3505()) { 93 if (cpu_is_omap3517() || cpu_is_omap3505()) {
94 oh_name = "am35x_otg_hs"; 94 oh_name = "am35x_otg_hs";
95 name = "musb-am35x"; 95 name = "musb-am35x";
96 } else if (cpu_is_ti81xx()) {
97 oh_name = "usb_otg_hs";
98 name = "musb-ti81xx";
96 } else { 99 } else {
97 oh_name = "usb_otg_hs"; 100 oh_name = "usb_otg_hs";
98 name = "musb-omap2430"; 101 name = "musb-omap2430";
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index 474559d5b07..c005e2f5e38 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -31,6 +31,14 @@
31 * VDD data 31 * VDD data
32 */ 32 */
33 33
34/* OMAP3-common voltagedomain data */
35
36static struct voltagedomain omap3_voltdm_wkup = {
37 .name = "wakeup",
38};
39
40/* 34xx/36xx voltagedomain data */
41
34static const struct omap_vfsm_instance omap3_vdd1_vfsm = { 42static const struct omap_vfsm_instance omap3_vdd1_vfsm = {
35 .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET, 43 .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
36 .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK, 44 .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
@@ -63,10 +71,6 @@ static struct voltagedomain omap3_voltdm_core = {
63 .vp = &omap3_vp_core, 71 .vp = &omap3_vp_core,
64}; 72};
65 73
66static struct voltagedomain omap3_voltdm_wkup = {
67 .name = "wakeup",
68};
69
70static struct voltagedomain *voltagedomains_omap3[] __initdata = { 74static struct voltagedomain *voltagedomains_omap3[] __initdata = {
71 &omap3_voltdm_mpu, 75 &omap3_voltdm_mpu,
72 &omap3_voltdm_core, 76 &omap3_voltdm_core,
@@ -74,11 +78,30 @@ static struct voltagedomain *voltagedomains_omap3[] __initdata = {
74 NULL, 78 NULL,
75}; 79};
76 80
81/* AM35xx voltagedomain data */
82
83static struct voltagedomain am35xx_voltdm_mpu = {
84 .name = "mpu_iva",
85};
86
87static struct voltagedomain am35xx_voltdm_core = {
88 .name = "core",
89};
90
91static struct voltagedomain *voltagedomains_am35xx[] __initdata = {
92 &am35xx_voltdm_mpu,
93 &am35xx_voltdm_core,
94 &omap3_voltdm_wkup,
95 NULL,
96};
97
98
77static const char *sys_clk_name __initdata = "sys_ck"; 99static const char *sys_clk_name __initdata = "sys_ck";
78 100
79void __init omap3xxx_voltagedomains_init(void) 101void __init omap3xxx_voltagedomains_init(void)
80{ 102{
81 struct voltagedomain *voltdm; 103 struct voltagedomain *voltdm;
104 struct voltagedomain **voltdms;
82 int i; 105 int i;
83 106
84 /* 107 /*
@@ -93,8 +116,13 @@ void __init omap3xxx_voltagedomains_init(void)
93 omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data; 116 omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
94 } 117 }
95 118
96 for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++) 119 if (cpu_is_omap3517() || cpu_is_omap3505())
120 voltdms = voltagedomains_am35xx;
121 else
122 voltdms = voltagedomains_omap3;
123
124 for (i = 0; voltdm = voltdms[i], voltdm; i++)
97 voltdm->sys_clk.name = sys_clk_name; 125 voltdm->sys_clk.name = sys_clk_name;
98 126
99 voltdm_init(voltagedomains_omap3); 127 voltdm_init(voltdms);
100}; 128};
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index 5ceafdccc45..3638e5c12b7 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -14,8 +14,8 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/mbus.h> 15#include <linux/mbus.h>
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/errno.h>
18#include <mach/hardware.h> 17#include <mach/hardware.h>
18#include <plat/addr-map.h>
19#include "common.h" 19#include "common.h"
20 20
21/* 21/*
@@ -41,7 +41,6 @@
41/* 41/*
42 * Generic Address Decode Windows bit settings 42 * Generic Address Decode Windows bit settings
43 */ 43 */
44#define TARGET_DDR 0
45#define TARGET_DEV_BUS 1 44#define TARGET_DEV_BUS 1
46#define TARGET_PCI 3 45#define TARGET_PCI 3
47#define TARGET_PCIE 4 46#define TARGET_PCIE 4
@@ -57,27 +56,10 @@
57#define ATTR_DEV_BOOT 0xf 56#define ATTR_DEV_BOOT 0xf
58#define ATTR_SRAM 0x0 57#define ATTR_SRAM 0x0
59 58
60/*
61 * Helpers to get DDR bank info
62 */
63#define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x))
64#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3))
65#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3))
66
67/*
68 * CPU Address Decode Windows registers
69 */
70#define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x))
71#define CPU_WIN_CTRL(n) ORION5X_BRIDGE_REG(0x000 | ((n) << 4))
72#define CPU_WIN_BASE(n) ORION5X_BRIDGE_REG(0x004 | ((n) << 4))
73#define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
74#define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
75
76
77struct mbus_dram_target_info orion5x_mbus_dram_info;
78static int __initdata win_alloc_count; 59static int __initdata win_alloc_count;
79 60
80static int __init orion5x_cpu_win_can_remap(int win) 61static int __init cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
62 const int win)
81{ 63{
82 u32 dev, rev; 64 u32 dev, rev;
83 65
@@ -91,116 +73,82 @@ static int __init orion5x_cpu_win_can_remap(int win)
91 return 0; 73 return 0;
92} 74}
93 75
94static int __init setup_cpu_win(int win, u32 base, u32 size, 76/*
95 u8 target, u8 attr, int remap) 77 * Description of the windows needed by the platform code
96{ 78 */
97 if (win >= 8) { 79static struct __initdata orion_addr_map_cfg addr_map_cfg = {
98 printk(KERN_ERR "setup_cpu_win: trying to allocate " 80 .num_wins = 8,
99 "window %d\n", win); 81 .cpu_win_can_remap = cpu_win_can_remap,
100 return -ENOSPC; 82 .bridge_virt_base = ORION5X_BRIDGE_VIRT_BASE,
101 } 83};
102
103 writel(base & 0xffff0000, CPU_WIN_BASE(win));
104 writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1,
105 CPU_WIN_CTRL(win));
106
107 if (orion5x_cpu_win_can_remap(win)) {
108 if (remap < 0)
109 remap = base;
110
111 writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
112 writel(0, CPU_WIN_REMAP_HI(win));
113 }
114 return 0;
115}
116
117void __init orion5x_setup_cpu_mbus_bridge(void)
118{
119 int i;
120 int cs;
121 84
85static const struct __initdata orion_addr_map_info addr_map_info[] = {
122 /* 86 /*
123 * First, disable and clear windows. 87 * Setup windows for PCI+PCIe IO+MEM space.
124 */ 88 */
125 for (i = 0; i < 8; i++) { 89 { 0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
126 writel(0, CPU_WIN_BASE(i)); 90 TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE
127 writel(0, CPU_WIN_CTRL(i)); 91 },
128 if (orion5x_cpu_win_can_remap(i)) { 92 { 1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
129 writel(0, CPU_WIN_REMAP_LO(i)); 93 TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE
130 writel(0, CPU_WIN_REMAP_HI(i)); 94 },
131 } 95 { 2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
132 } 96 TARGET_PCIE, ATTR_PCIE_MEM, -1
97 },
98 { 3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
99 TARGET_PCI, ATTR_PCI_MEM, -1
100 },
101 /* End marker */
102 { -1, 0, 0, 0, 0, 0 }
103};
133 104
105void __init orion5x_setup_cpu_mbus_bridge(void)
106{
134 /* 107 /*
135 * Setup windows for PCI+PCIe IO+MEM space. 108 * Disable, clear and configure windows.
136 */ 109 */
137 setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE, 110 orion_config_wins(&addr_map_cfg, addr_map_info);
138 TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE);
139 setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
140 TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE);
141 setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
142 TARGET_PCIE, ATTR_PCIE_MEM, -1);
143 setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
144 TARGET_PCI, ATTR_PCI_MEM, -1);
145 win_alloc_count = 4; 111 win_alloc_count = 4;
146 112
147 /* 113 /*
148 * Setup MBUS dram target info. 114 * Setup MBUS dram target info.
149 */ 115 */
150 orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR; 116 orion_setup_cpu_mbus_target(&addr_map_cfg, ORION5X_DDR_WINDOW_CPU_BASE);
151
152 for (i = 0, cs = 0; i < 4; i++) {
153 u32 base = readl(DDR_BASE_CS(i));
154 u32 size = readl(DDR_SIZE_CS(i));
155
156 /*
157 * Chip select enabled?
158 */
159 if (size & 1) {
160 struct mbus_dram_window *w;
161
162 w = &orion5x_mbus_dram_info.cs[cs++];
163 w->cs_index = i;
164 w->mbus_attr = 0xf & ~(1 << i);
165 w->base = base & 0xffff0000;
166 w->size = (size | 0x0000ffff) + 1;
167 }
168 }
169 orion5x_mbus_dram_info.num_cs = cs;
170} 117}
171 118
172void __init orion5x_setup_dev_boot_win(u32 base, u32 size) 119void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
173{ 120{
174 setup_cpu_win(win_alloc_count++, base, size, 121 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
175 TARGET_DEV_BUS, ATTR_DEV_BOOT, -1); 122 TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
176} 123}
177 124
178void __init orion5x_setup_dev0_win(u32 base, u32 size) 125void __init orion5x_setup_dev0_win(u32 base, u32 size)
179{ 126{
180 setup_cpu_win(win_alloc_count++, base, size, 127 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
181 TARGET_DEV_BUS, ATTR_DEV_CS0, -1); 128 TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
182} 129}
183 130
184void __init orion5x_setup_dev1_win(u32 base, u32 size) 131void __init orion5x_setup_dev1_win(u32 base, u32 size)
185{ 132{
186 setup_cpu_win(win_alloc_count++, base, size, 133 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
187 TARGET_DEV_BUS, ATTR_DEV_CS1, -1); 134 TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
188} 135}
189 136
190void __init orion5x_setup_dev2_win(u32 base, u32 size) 137void __init orion5x_setup_dev2_win(u32 base, u32 size)
191{ 138{
192 setup_cpu_win(win_alloc_count++, base, size, 139 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
193 TARGET_DEV_BUS, ATTR_DEV_CS2, -1); 140 TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
194} 141}
195 142
196void __init orion5x_setup_pcie_wa_win(u32 base, u32 size) 143void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
197{ 144{
198 setup_cpu_win(win_alloc_count++, base, size, 145 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++, base, size,
199 TARGET_PCIE, ATTR_PCIE_WA, -1); 146 TARGET_PCIE, ATTR_PCIE_WA, -1);
200} 147}
201 148
202int __init orion5x_setup_sram_win(void) 149void __init orion5x_setup_sram_win(void)
203{ 150{
204 return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE, 151 orion_setup_cpu_win(&addr_map_cfg, win_alloc_count++,
205 ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1); 152 ORION5X_SRAM_PHYS_BASE, ORION5X_SRAM_SIZE,
153 TARGET_SRAM, ATTR_SRAM, -1);
206} 154}
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 41127e80cc1..0e28bae20bd 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -15,7 +15,6 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/serial_8250.h> 17#include <linux/serial_8250.h>
18#include <linux/mbus.h>
19#include <linux/mv643xx_i2c.h> 18#include <linux/mv643xx_i2c.h>
20#include <linux/ata_platform.h> 19#include <linux/ata_platform.h>
21#include <linux/delay.h> 20#include <linux/delay.h>
@@ -32,6 +31,7 @@
32#include <plat/orion_nand.h> 31#include <plat/orion_nand.h>
33#include <plat/time.h> 32#include <plat/time.h>
34#include <plat/common.h> 33#include <plat/common.h>
34#include <plat/addr-map.h>
35#include "common.h" 35#include "common.h"
36 36
37/***************************************************************************** 37/*****************************************************************************
@@ -72,8 +72,7 @@ void __init orion5x_map_io(void)
72 ****************************************************************************/ 72 ****************************************************************************/
73void __init orion5x_ehci0_init(void) 73void __init orion5x_ehci0_init(void)
74{ 74{
75 orion_ehci_init(&orion5x_mbus_dram_info, 75 orion_ehci_init(ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL);
76 ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL);
77} 76}
78 77
79 78
@@ -82,8 +81,7 @@ void __init orion5x_ehci0_init(void)
82 ****************************************************************************/ 81 ****************************************************************************/
83void __init orion5x_ehci1_init(void) 82void __init orion5x_ehci1_init(void)
84{ 83{
85 orion_ehci_1_init(&orion5x_mbus_dram_info, 84 orion_ehci_1_init(ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
86 ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
87} 85}
88 86
89 87
@@ -92,7 +90,7 @@ void __init orion5x_ehci1_init(void)
92 ****************************************************************************/ 90 ****************************************************************************/
93void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) 91void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
94{ 92{
95 orion_ge00_init(eth_data, &orion5x_mbus_dram_info, 93 orion_ge00_init(eth_data,
96 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, 94 ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
97 IRQ_ORION5X_ETH_ERR, orion5x_tclk); 95 IRQ_ORION5X_ETH_ERR, orion5x_tclk);
98} 96}
@@ -122,8 +120,7 @@ void __init orion5x_i2c_init(void)
122 ****************************************************************************/ 120 ****************************************************************************/
123void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) 121void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
124{ 122{
125 orion_sata_init(sata_data, &orion5x_mbus_dram_info, 123 orion_sata_init(sata_data, ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
126 ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
127} 124}
128 125
129 126
@@ -159,8 +156,7 @@ void __init orion5x_uart1_init(void)
159 ****************************************************************************/ 156 ****************************************************************************/
160void __init orion5x_xor_init(void) 157void __init orion5x_xor_init(void)
161{ 158{
162 orion_xor0_init(&orion5x_mbus_dram_info, 159 orion_xor0_init(ORION5X_XOR_PHYS_BASE,
163 ORION5X_XOR_PHYS_BASE,
164 ORION5X_XOR_PHYS_BASE + 0x200, 160 ORION5X_XOR_PHYS_BASE + 0x200,
165 IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1); 161 IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1);
166} 162}
@@ -170,12 +166,7 @@ void __init orion5x_xor_init(void)
170 ****************************************************************************/ 166 ****************************************************************************/
171static void __init orion5x_crypto_init(void) 167static void __init orion5x_crypto_init(void)
172{ 168{
173 int ret; 169 orion5x_setup_sram_win();
174
175 ret = orion5x_setup_sram_win();
176 if (ret)
177 return;
178
179 orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE, 170 orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
180 SZ_8K, IRQ_ORION5X_CESA); 171 SZ_8K, IRQ_ORION5X_CESA);
181} 172}
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index 37ef18de61b..d2513ac79ff 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -20,14 +20,13 @@ extern struct sys_timer orion5x_timer;
20 * functions to map its interfaces and by the machine-setup to map its on- 20 * functions to map its interfaces and by the machine-setup to map its on-
21 * board devices. Details in /mach-orion/addr-map.c 21 * board devices. Details in /mach-orion/addr-map.c
22 */ 22 */
23extern struct mbus_dram_target_info orion5x_mbus_dram_info;
24void orion5x_setup_cpu_mbus_bridge(void); 23void orion5x_setup_cpu_mbus_bridge(void);
25void orion5x_setup_dev_boot_win(u32 base, u32 size); 24void orion5x_setup_dev_boot_win(u32 base, u32 size);
26void orion5x_setup_dev0_win(u32 base, u32 size); 25void orion5x_setup_dev0_win(u32 base, u32 size);
27void orion5x_setup_dev1_win(u32 base, u32 size); 26void orion5x_setup_dev1_win(u32 base, u32 size);
28void orion5x_setup_dev2_win(u32 base, u32 size); 27void orion5x_setup_dev2_win(u32 base, u32 size);
29void orion5x_setup_pcie_wa_win(u32 base, u32 size); 28void orion5x_setup_pcie_wa_win(u32 base, u32 size);
30int orion5x_setup_sram_win(void); 29void orion5x_setup_sram_win(void);
31 30
32void orion5x_ehci0_init(void); 31void orion5x_ehci0_init(void);
33void orion5x_ehci1_init(void); 32void orion5x_ehci1_init(void);
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
index 0a28bbc7689..2745f5d95b3 100644
--- a/arch/arm/mach-orion5x/include/mach/orion5x.h
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -69,7 +69,7 @@
69 ******************************************************************************/ 69 ******************************************************************************/
70 70
71#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000) 71#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000)
72 72#define ORION5X_DDR_WINDOW_CPU_BASE (ORION5X_DDR_VIRT_BASE | 0x1500)
73#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) 73#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
74#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) 74#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
75#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) 75#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
index b6ddd7a5db6..5b70026f478 100644
--- a/arch/arm/mach-orion5x/mpp.c
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/mbus.h>
14#include <linux/io.h> 13#include <linux/io.h>
15#include <mach/hardware.h> 14#include <mach/hardware.h>
16#include <plat/mpp.h> 15#include <plat/mpp.h>
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index bc4a920e26e..a494c470e3e 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -18,6 +18,7 @@
18#include <asm/irq.h> 18#include <asm/irq.h>
19#include <asm/mach/pci.h> 19#include <asm/mach/pci.h>
20#include <plat/pcie.h> 20#include <plat/pcie.h>
21#include <plat/addr-map.h>
21#include "common.h" 22#include "common.h"
22 23
23/***************************************************************************** 24/*****************************************************************************
@@ -145,7 +146,7 @@ static int __init pcie_setup(struct pci_sys_data *sys)
145 /* 146 /*
146 * Generic PCIe unit setup. 147 * Generic PCIe unit setup.
147 */ 148 */
148 orion_pcie_setup(PCIE_BASE, &orion5x_mbus_dram_info); 149 orion_pcie_setup(PCIE_BASE);
149 150
150 /* 151 /*
151 * Check whether to apply Orion-1/Orion-NAS PCIe config 152 * Check whether to apply Orion-1/Orion-NAS PCIe config
@@ -477,7 +478,7 @@ static int __init pci_setup(struct pci_sys_data *sys)
477 /* 478 /*
478 * Point PCI unit MBUS decode windows to DRAM space. 479 * Point PCI unit MBUS decode windows to DRAM space.
479 */ 480 */
480 orion5x_setup_pci_wins(&orion5x_mbus_dram_info); 481 orion5x_setup_pci_wins(&orion_mbus_dram_info);
481 482
482 /* 483 /*
483 * Master + Slave enable 484 * Master + Slave enable
diff --git a/arch/arm/mach-picoxcell/Makefile b/arch/arm/mach-picoxcell/Makefile
index c550b636348..e5ec4a8d9bc 100644
--- a/arch/arm/mach-picoxcell/Makefile
+++ b/arch/arm/mach-picoxcell/Makefile
@@ -1,3 +1,2 @@
1obj-y := common.o 1obj-y := common.o
2obj-y += time.o 2obj-y += time.o
3obj-y += io.o
diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c
index ad871bd7b1a..a2e8ae8b582 100644
--- a/arch/arm/mach-picoxcell/common.c
+++ b/arch/arm/mach-picoxcell/common.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * All enquiries to support@picochip.com 8 * All enquiries to support@picochip.com
9 */ 9 */
10#include <linux/delay.h>
10#include <linux/irq.h> 11#include <linux/irq.h>
11#include <linux/irqdomain.h> 12#include <linux/irqdomain.h>
12#include <linux/of.h> 13#include <linux/of.h>
@@ -16,15 +17,49 @@
16 17
17#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
18#include <asm/hardware/vic.h> 19#include <asm/hardware/vic.h>
20#include <asm/mach/map.h>
19 21
20#include <mach/map.h> 22#include <mach/map.h>
21#include <mach/picoxcell_soc.h> 23#include <mach/picoxcell_soc.h>
22 24
23#include "common.h" 25#include "common.h"
24 26
27#define WDT_CTRL_REG_EN_MASK (1 << 0)
28#define WDT_CTRL_REG_OFFS (0x00)
29#define WDT_TIMEOUT_REG_OFFS (0x04)
30static void __iomem *wdt_regs;
31
32/*
33 * The machine restart method can be called from an atomic context so we won't
34 * be able to ioremap the regs then.
35 */
36static void picoxcell_setup_restart(void)
37{
38 struct device_node *np = of_find_compatible_node(NULL, NULL,
39 "snps,dw-apb-wdg");
40 if (WARN(!np, "unable to setup watchdog restart"))
41 return;
42
43 wdt_regs = of_iomap(np, 0);
44 WARN(!wdt_regs, "failed to remap watchdog regs");
45}
46
47static struct map_desc io_map __initdata = {
48 .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
49 .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE),
50 .length = PICOXCELL_PERIPH_LENGTH,
51 .type = MT_DEVICE,
52};
53
54static void __init picoxcell_map_io(void)
55{
56 iotable_init(&io_map, 1);
57}
58
25static void __init picoxcell_init_machine(void) 59static void __init picoxcell_init_machine(void)
26{ 60{
27 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 61 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
62 picoxcell_setup_restart();
28} 63}
29 64
30static const char *picoxcell_dt_match[] = { 65static const char *picoxcell_dt_match[] = {
@@ -43,12 +78,27 @@ static void __init picoxcell_init_irq(void)
43 of_irq_init(vic_of_match); 78 of_irq_init(vic_of_match);
44} 79}
45 80
81static void picoxcell_wdt_restart(char mode, const char *cmd)
82{
83 /*
84 * Configure the watchdog to reset with the shortest possible timeout
85 * and give it chance to do the reset.
86 */
87 if (wdt_regs) {
88 writel_relaxed(WDT_CTRL_REG_EN_MASK, wdt_regs + WDT_CTRL_REG_OFFS);
89 writel_relaxed(0, wdt_regs + WDT_TIMEOUT_REG_OFFS);
90 /* No sleeping, possibly atomic. */
91 mdelay(500);
92 }
93}
94
46DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") 95DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
47 .map_io = picoxcell_map_io, 96 .map_io = picoxcell_map_io,
48 .nr_irqs = ARCH_NR_IRQS, 97 .nr_irqs = NR_IRQS_LEGACY,
49 .init_irq = picoxcell_init_irq, 98 .init_irq = picoxcell_init_irq,
50 .handle_irq = vic_handle_irq, 99 .handle_irq = vic_handle_irq,
51 .timer = &picoxcell_timer, 100 .timer = &picoxcell_timer,
52 .init_machine = picoxcell_init_machine, 101 .init_machine = picoxcell_init_machine,
53 .dt_compat = picoxcell_dt_match, 102 .dt_compat = picoxcell_dt_match,
103 .restart = picoxcell_wdt_restart,
54MACHINE_END 104MACHINE_END
diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h
index 5263f0fa095..83d55ab956a 100644
--- a/arch/arm/mach-picoxcell/common.h
+++ b/arch/arm/mach-picoxcell/common.h
@@ -13,6 +13,5 @@
13#include <asm/mach/time.h> 13#include <asm/mach/time.h>
14 14
15extern struct sys_timer picoxcell_timer; 15extern struct sys_timer picoxcell_timer;
16extern void picoxcell_map_io(void);
17 16
18#endif /* __PICOXCELL_COMMON_H__ */ 17#endif /* __PICOXCELL_COMMON_H__ */
diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h
index 4d13ed97091..59eac1ee282 100644
--- a/arch/arm/mach-picoxcell/include/mach/irqs.h
+++ b/arch/arm/mach-picoxcell/include/mach/irqs.h
@@ -1,8 +1,6 @@
1/* 1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles 2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 * 3 *
4 * This file contains the hardware definitions of the picoXcell SoC devices.
5 *
6 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 5 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 6 * the Free Software Foundation; either version 2 of the License, or
@@ -16,10 +14,7 @@
16#ifndef __MACH_IRQS_H 14#ifndef __MACH_IRQS_H
17#define __MACH_IRQS_H 15#define __MACH_IRQS_H
18 16
19#define ARCH_NR_IRQS 64 17/* We dynamically allocate our irq_desc's. */
20#define NR_IRQS (128 + ARCH_NR_IRQS) 18#define NR_IRQS 0
21
22#define IRQ_VIC0_BASE 0
23#define IRQ_VIC1_BASE 32
24 19
25#endif /* __MACH_IRQS_H */ 20#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-picoxcell/include/mach/memory.h b/arch/arm/mach-picoxcell/include/mach/memory.h
deleted file mode 100644
index 40a8c178f10..00000000000
--- a/arch/arm/mach-picoxcell/include/mach/memory.h
+++ /dev/null
@@ -1 +0,0 @@
1/* empty */
diff --git a/arch/arm/mach-picoxcell/io.c b/arch/arm/mach-picoxcell/io.c
deleted file mode 100644
index 39e9b9e8cc3..00000000000
--- a/arch/arm/mach-picoxcell/io.c
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * Copyright (c) 2011 Picochip Ltd., Jamie Iles
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * All enquiries to support@picochip.com
9 */
10#include <linux/io.h>
11#include <linux/mm.h>
12#include <linux/module.h>
13#include <linux/of.h>
14
15#include <asm/mach/map.h>
16
17#include <mach/map.h>
18#include <mach/picoxcell_soc.h>
19
20#include "common.h"
21
22void __init picoxcell_map_io(void)
23{
24 struct map_desc io_map = {
25 .virtual = PHYS_TO_IO(PICOXCELL_PERIPH_BASE),
26 .pfn = __phys_to_pfn(PICOXCELL_PERIPH_BASE),
27 .length = PICOXCELL_PERIPH_LENGTH,
28 .type = MT_DEVICE,
29 };
30
31 iotable_init(&io_map, 1);
32}
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index 4cb069fd9af..ccdac4b6a46 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -138,7 +138,7 @@ static void am200_cleanup(struct metronomefb_par *par)
138{ 138{
139 int i; 139 int i;
140 140
141 free_irq(IRQ_GPIO(RDY_GPIO_PIN), par); 141 free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par);
142 142
143 for (i = 0; i < ARRAY_SIZE(gpios); i++) 143 for (i = 0; i < ARRAY_SIZE(gpios); i++)
144 gpio_free(gpios[i]); 144 gpio_free(gpios[i]);
@@ -292,7 +292,7 @@ static int am200_setup_irq(struct fb_info *info)
292{ 292{
293 int ret; 293 int ret;
294 294
295 ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq, 295 ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am200_handle_irq,
296 IRQF_DISABLED|IRQF_TRIGGER_FALLING, 296 IRQF_DISABLED|IRQF_TRIGGER_FALLING,
297 "AM200", info->par); 297 "AM200", info->par);
298 if (ret) 298 if (ret)
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
index fa8bad235d9..76c4b949403 100644
--- a/arch/arm/mach-pxa/am300epd.c
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -176,7 +176,7 @@ static void am300_cleanup(struct broadsheetfb_par *par)
176{ 176{
177 int i; 177 int i;
178 178
179 free_irq(IRQ_GPIO(RDY_GPIO_PIN), par); 179 free_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), par);
180 180
181 for (i = 0; i < ARRAY_SIZE(gpios); i++) 181 for (i = 0; i < ARRAY_SIZE(gpios); i++)
182 gpio_free(gpios[i]); 182 gpio_free(gpios[i]);
@@ -240,7 +240,7 @@ static int am300_setup_irq(struct fb_info *info)
240 int ret; 240 int ret;
241 struct broadsheetfb_par *par = info->par; 241 struct broadsheetfb_par *par = info->par;
242 242
243 ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq, 243 ret = request_irq(PXA_GPIO_TO_IRQ(RDY_GPIO_PIN), am300_handle_irq,
244 IRQF_DISABLED|IRQF_TRIGGER_RISING, 244 IRQF_DISABLED|IRQF_TRIGGER_RISING,
245 "AM300", par); 245 "AM300", par);
246 if (ret) 246 if (ret)
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index 82514f5c38f..c35456f02ac 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -13,6 +13,7 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15 15
16#include <linux/export.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -179,7 +180,7 @@ static unsigned long balloon3_ac97_pin_config[] __initdata = {
179}; 180};
180 181
181static struct ucb1400_pdata vpac270_ucb1400_pdata = { 182static struct ucb1400_pdata vpac270_ucb1400_pdata = {
182 .irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ), 183 .irq = PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ),
183}; 184};
184 185
185 186
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index c2f0be040d2..c91727d1fe0 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -50,8 +50,8 @@ static struct resource capc7117_ide_resources[] = {
50 .flags = IORESOURCE_MEM 50 .flags = IORESOURCE_MEM
51 }, 51 },
52 [2] = { 52 [2] = {
53 .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)), 53 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)),
54 .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)), 54 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO76)),
55 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING 55 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING
56 } 56 }
57}; 57};
@@ -80,7 +80,7 @@ static void __init capc7117_ide_init(void)
80static struct plat_serial8250_port ti16c752_platform_data[] = { 80static struct plat_serial8250_port ti16c752_platform_data[] = {
81 [0] = { 81 [0] = {
82 .mapbase = 0x14000000, 82 .mapbase = 0x14000000,
83 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO78)), 83 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO78)),
84 .irqflags = IRQF_TRIGGER_RISING, 84 .irqflags = IRQF_TRIGGER_RISING,
85 .flags = TI16C752_FLAGS, 85 .flags = TI16C752_FLAGS,
86 .iotype = UPIO_MEM, 86 .iotype = UPIO_MEM,
@@ -89,7 +89,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = {
89 }, 89 },
90 [1] = { 90 [1] = {
91 .mapbase = 0x14000040, 91 .mapbase = 0x14000040,
92 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO79)), 92 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO79)),
93 .irqflags = IRQF_TRIGGER_RISING, 93 .irqflags = IRQF_TRIGGER_RISING,
94 .flags = TI16C752_FLAGS, 94 .flags = TI16C752_FLAGS,
95 .iotype = UPIO_MEM, 95 .iotype = UPIO_MEM,
@@ -98,7 +98,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = {
98 }, 98 },
99 [2] = { 99 [2] = {
100 .mapbase = 0x14000080, 100 .mapbase = 0x14000080,
101 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO80)), 101 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO80)),
102 .irqflags = IRQF_TRIGGER_RISING, 102 .irqflags = IRQF_TRIGGER_RISING,
103 .flags = TI16C752_FLAGS, 103 .flags = TI16C752_FLAGS,
104 .iotype = UPIO_MEM, 104 .iotype = UPIO_MEM,
@@ -107,7 +107,7 @@ static struct plat_serial8250_port ti16c752_platform_data[] = {
107 }, 107 },
108 [3] = { 108 [3] = {
109 .mapbase = 0x140000c0, 109 .mapbase = 0x140000c0,
110 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO81)), 110 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO81)),
111 .irqflags = IRQF_TRIGGER_RISING, 111 .irqflags = IRQF_TRIGGER_RISING,
112 .flags = TI16C752_FLAGS, 112 .flags = TI16C752_FLAGS,
113 .iotype = UPIO_MEM, 113 .iotype = UPIO_MEM,
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 13518a70539..431ef56700c 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -33,7 +33,7 @@
33/* GPIO IRQ usage */ 33/* GPIO IRQ usage */
34#define GPIO83_MMC_IRQ (83) 34#define GPIO83_MMC_IRQ (83)
35 35
36#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) 36#define CMX270_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO83_MMC_IRQ)
37 37
38/* MMC power enable */ 38/* MMC power enable */
39#define GPIO105_MMC_POWER (105) 39#define GPIO105_MMC_POWER (105)
@@ -380,7 +380,7 @@ static struct spi_board_info cm_x270_spi_devices[] __initdata = {
380 .modalias = "libertas_spi", 380 .modalias = "libertas_spi",
381 .max_speed_hz = 13000000, 381 .max_speed_hz = 13000000,
382 .bus_num = 2, 382 .bus_num = 2,
383 .irq = gpio_to_irq(95), 383 .irq = PXA_GPIO_TO_IRQ(95),
384 .chip_select = 0, 384 .chip_select = 0,
385 .controller_data = &cm_x270_libertas_chip, 385 .controller_data = &cm_x270_libertas_chip,
386 .platform_data = &cm_x270_libertas_pdata, 386 .platform_data = &cm_x270_libertas_pdata,
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index ec170a552c2..8fa4ad27edf 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -58,8 +58,8 @@ extern void cmx270_init(void);
58#define CMX255_GPIO_IT8152_IRQ (0) 58#define CMX255_GPIO_IT8152_IRQ (0)
59#define CMX270_GPIO_IT8152_IRQ (22) 59#define CMX270_GPIO_IT8152_IRQ (22)
60 60
61#define CMX255_ETHIRQ IRQ_GPIO(GPIO22_ETHIRQ) 61#define CMX255_ETHIRQ PXA_GPIO_TO_IRQ(GPIO22_ETHIRQ)
62#define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ) 62#define CMX270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO10_ETHIRQ)
63 63
64#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE) 64#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
65static struct resource cmx255_dm9000_resource[] = { 65static struct resource cmx255_dm9000_resource[] = {
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 7236974da0b..4b981b82d2a 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -64,7 +64,7 @@
64#define GPIO82_MMC_IRQ (82) 64#define GPIO82_MMC_IRQ (82)
65#define GPIO85_MMC_WP (85) 65#define GPIO85_MMC_WP (85)
66 66
67#define CM_X300_MMC_IRQ IRQ_GPIO(GPIO82_MMC_IRQ) 67#define CM_X300_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO82_MMC_IRQ)
68 68
69#define GPIO95_RTC_CS (95) 69#define GPIO95_RTC_CS (95)
70#define GPIO96_RTC_WR (96) 70#define GPIO96_RTC_WR (96)
@@ -229,8 +229,8 @@ static struct resource dm9000_resources[] = {
229 .flags = IORESOURCE_MEM, 229 .flags = IORESOURCE_MEM,
230 }, 230 },
231 [2] = { 231 [2] = {
232 .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), 232 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)),
233 .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)), 233 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO99)),
234 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 234 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
235 } 235 }
236}; 236};
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index 6a685165c9f..29d5d541f60 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -218,8 +218,8 @@ static struct resource colibri_pxa270_dm9000_resources[] = {
218 .flags = IORESOURCE_MEM, 218 .flags = IORESOURCE_MEM,
219 }, 219 },
220 { 220 {
221 .start = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ), 221 .start = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ),
222 .end = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ), 222 .end = PXA_GPIO_TO_IRQ(GPIO114_COLIBRI_PXA270_ETH_IRQ),
223 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, 223 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
224 }, 224 },
225}; 225};
@@ -249,7 +249,7 @@ static pxa2xx_audio_ops_t colibri_pxa270_ac97_pdata = {
249}; 249};
250 250
251static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = { 251static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = {
252 .irq = gpio_to_irq(GPIO113_COLIBRI_PXA270_TS_IRQ), 252 .irq = PXA_GPIO_TO_IRQ(GPIO113_COLIBRI_PXA270_TS_IRQ),
253}; 253};
254 254
255static struct platform_device colibri_pxa270_ucb1400_device = { 255static struct platform_device colibri_pxa270_ucb1400_device = {
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index c01059a61f3..0846d210cb0 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -78,8 +78,8 @@ static struct resource colibri_asix_resource[] = {
78 .flags = IORESOURCE_MEM, 78 .flags = IORESOURCE_MEM,
79 }, 79 },
80 [1] = { 80 [1] = {
81 .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 81 .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
82 .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 82 .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
83 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, 83 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
84 } 84 }
85}; 85};
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 5028f2300d5..6ad3359063a 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -115,8 +115,8 @@ static struct resource colibri_asix_resource[] = {
115 .flags = IORESOURCE_MEM, 115 .flags = IORESOURCE_MEM,
116 }, 116 },
117 [1] = { 117 [1] = {
118 .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 118 .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
119 .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 119 .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO),
120 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, 120 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
121 } 121 }
122}; 122};
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 9d4dc5970b9..66600f05e43 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -531,7 +531,7 @@ static struct spi_board_info corgi_spi_devices[] = {
531 .chip_select = 0, 531 .chip_select = 0,
532 .platform_data = &corgi_ads7846_info, 532 .platform_data = &corgi_ads7846_info,
533 .controller_data= &corgi_ads7846_chip, 533 .controller_data= &corgi_ads7846_chip,
534 .irq = gpio_to_irq(CORGI_GPIO_TP_INT), 534 .irq = PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
535 }, { 535 }, {
536 .modalias = "corgi-lcd", 536 .modalias = "corgi-lcd",
537 .max_speed_hz = 50000, 537 .max_speed_hz = 50000,
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 29034778bfd..39e265cfc86 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/gpio-pxa.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/apm-emulation.h> 21#include <linux/apm-emulation.h>
@@ -40,7 +41,9 @@ static struct gpio charger_gpios[] = {
40 { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, 41 { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
41 { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, 42 { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
42 { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" }, 43 { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" },
44 { CORGI_GPIO_AC_IN, GPIOF_IN, "Charger Detection" },
43 { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" }, 45 { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" },
46 { CORGI_GPIO_WAKEUP, GPIOF_IN, "System wakeup notification" },
44}; 47};
45 48
46static void corgi_charger_init(void) 49static void corgi_charger_init(void)
@@ -90,7 +93,12 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm)
90{ 93{
91 int is_resume = 0; 94 int is_resume = 0;
92 95
93 dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR); 96 dev_dbg(sharpsl_pm.dev, "PEDR = %x, GPIO_AC_IN = %d, "
97 "GPIO_CHRG_FULL = %d, GPIO_KEY_INT = %d, GPIO_WAKEUP = %d\n",
98 PEDR, gpio_get_value(CORGI_GPIO_AC_IN),
99 gpio_get_value(CORGI_GPIO_CHRG_FULL),
100 gpio_get_value(CORGI_GPIO_KEY_INT),
101 gpio_get_value(CORGI_GPIO_WAKEUP));
94 102
95 if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) { 103 if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
96 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { 104 if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
@@ -124,14 +132,21 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm)
124 132
125static unsigned long corgi_charger_wakeup(void) 133static unsigned long corgi_charger_wakeup(void)
126{ 134{
127 return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) ); 135 unsigned long ret;
136
137 ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN))
138 | (!gpio_get_value(CORGI_GPIO_KEY_INT)
139 << GPIO_bit(CORGI_GPIO_KEY_INT))
140 | (!gpio_get_value(CORGI_GPIO_WAKEUP)
141 << GPIO_bit(CORGI_GPIO_WAKEUP));
142 return ret;
128} 143}
129 144
130unsigned long corgipm_read_devdata(int type) 145unsigned long corgipm_read_devdata(int type)
131{ 146{
132 switch(type) { 147 switch(type) {
133 case SHARPSL_STATUS_ACIN: 148 case SHARPSL_STATUS_ACIN:
134 return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0); 149 return !gpio_get_value(CORGI_GPIO_AC_IN);
135 case SHARPSL_STATUS_LOCK: 150 case SHARPSL_STATUS_LOCK:
136 return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); 151 return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
137 case SHARPSL_STATUS_CHRGFULL: 152 case SHARPSL_STATUS_CHRGFULL:
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 2e0425404de..18fd177073f 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -415,9 +415,29 @@ static struct resource pxa_rtc_resources[] = {
415 }, 415 },
416}; 416};
417 417
418static struct resource sa1100_rtc_resources[] = {
419 [0] = {
420 .start = 0x40900000,
421 .end = 0x409000ff,
422 .flags = IORESOURCE_MEM,
423 },
424 [1] = {
425 .start = IRQ_RTC1Hz,
426 .end = IRQ_RTC1Hz,
427 .flags = IORESOURCE_IRQ,
428 },
429 [2] = {
430 .start = IRQ_RTCAlrm,
431 .end = IRQ_RTCAlrm,
432 .flags = IORESOURCE_IRQ,
433 },
434};
435
418struct platform_device sa1100_device_rtc = { 436struct platform_device sa1100_device_rtc = {
419 .name = "sa1100-rtc", 437 .name = "sa1100-rtc",
420 .id = -1, 438 .id = -1,
439 .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
440 .resource = sa1100_rtc_resources,
421}; 441};
422 442
423struct platform_device pxa_device_rtc = { 443struct platform_device pxa_device_rtc = {
@@ -1051,6 +1071,36 @@ struct platform_device pxa3xx_device_ssp4 = {
1051}; 1071};
1052#endif /* CONFIG_PXA3xx || CONFIG_PXA95x */ 1072#endif /* CONFIG_PXA3xx || CONFIG_PXA95x */
1053 1073
1074struct resource pxa_resource_gpio[] = {
1075 {
1076 .start = 0x40e00000,
1077 .end = 0x40e0ffff,
1078 .flags = IORESOURCE_MEM,
1079 }, {
1080 .start = IRQ_GPIO0,
1081 .end = IRQ_GPIO0,
1082 .name = "gpio0",
1083 .flags = IORESOURCE_IRQ,
1084 }, {
1085 .start = IRQ_GPIO1,
1086 .end = IRQ_GPIO1,
1087 .name = "gpio1",
1088 .flags = IORESOURCE_IRQ,
1089 }, {
1090 .start = IRQ_GPIO_2_x,
1091 .end = IRQ_GPIO_2_x,
1092 .name = "gpio_mux",
1093 .flags = IORESOURCE_IRQ,
1094 },
1095};
1096
1097struct platform_device pxa_device_gpio = {
1098 .name = "pxa-gpio",
1099 .id = -1,
1100 .num_resources = ARRAY_SIZE(pxa_resource_gpio),
1101 .resource = pxa_resource_gpio,
1102};
1103
1054/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1. 1104/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
1055 * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */ 1105 * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
1056void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) 1106void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
index 2fd5a8b3575..1475db10725 100644
--- a/arch/arm/mach-pxa/devices.h
+++ b/arch/arm/mach-pxa/devices.h
@@ -16,6 +16,7 @@ extern struct platform_device pxa_device_ficp;
16extern struct platform_device sa1100_device_rtc; 16extern struct platform_device sa1100_device_rtc;
17extern struct platform_device pxa_device_rtc; 17extern struct platform_device pxa_device_rtc;
18extern struct platform_device pxa_device_ac97; 18extern struct platform_device pxa_device_ac97;
19extern struct platform_device pxa_device_gpio;
19 20
20extern struct platform_device pxa27x_device_i2c_power; 21extern struct platform_device pxa27x_device_i2c_power;
21extern struct platform_device pxa27x_device_ohci; 22extern struct platform_device pxa27x_device_ohci;
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index bd396ba67af..d80c0ba9a09 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -70,7 +70,7 @@
70/* common GPIOs */ 70/* common GPIOs */
71#define GPIO11_NAND_CS (11) 71#define GPIO11_NAND_CS (11)
72#define GPIO41_ETHIRQ (41) 72#define GPIO41_ETHIRQ (41)
73#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) 73#define EM_X270_ETHIRQ PXA_GPIO_TO_IRQ(GPIO41_ETHIRQ)
74#define GPIO115_WLAN_PWEN (115) 74#define GPIO115_WLAN_PWEN (115)
75#define GPIO19_WLAN_STRAP (19) 75#define GPIO19_WLAN_STRAP (19)
76#define GPIO9_USB_VBUS_EN (9) 76#define GPIO9_USB_VBUS_EN (9)
@@ -805,7 +805,7 @@ static struct spi_board_info em_x270_spi_devices[] __initdata = {
805 .modalias = "libertas_spi", 805 .modalias = "libertas_spi",
806 .max_speed_hz = 13000000, 806 .max_speed_hz = 13000000,
807 .bus_num = 2, 807 .bus_num = 2,
808 .irq = IRQ_GPIO(116), 808 .irq = PXA_GPIO_TO_IRQ(116),
809 .chip_select = 0, 809 .chip_select = 0,
810 .controller_data = &em_x270_libertas_chip, 810 .controller_data = &em_x270_libertas_chip,
811 .platform_data = &em_x270_libertas_pdata, 811 .platform_data = &em_x270_libertas_pdata,
@@ -1203,7 +1203,7 @@ static struct da903x_platform_data em_x270_da9030_info = {
1203 1203
1204static struct i2c_board_info em_x270_i2c_pmic_info = { 1204static struct i2c_board_info em_x270_i2c_pmic_info = {
1205 I2C_BOARD_INFO("da9030", 0x49), 1205 I2C_BOARD_INFO("da9030", 0x49),
1206 .irq = IRQ_GPIO(0), 1206 .irq = PXA_GPIO_TO_IRQ(0),
1207 .platform_data = &em_x270_da9030_info, 1207 .platform_data = &em_x270_da9030_info,
1208}; 1208};
1209 1209
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 69473db9775..f79a610c62f 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -119,8 +119,8 @@ struct resource eseries_tmio_resources[] = {
119 .flags = IORESOURCE_MEM, 119 .flags = IORESOURCE_MEM,
120 }, 120 },
121 [1] = { 121 [1] = {
122 .start = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ), 122 .start = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ),
123 .end = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ), 123 .end = PXA_GPIO_TO_IRQ(GPIO_ESERIES_TMIO_IRQ),
124 .flags = IORESOURCE_IRQ, 124 .flags = IORESOURCE_IRQ,
125 }, 125 },
126}; 126};
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index ce16bdae96d..fb9b62dcf4c 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -252,8 +252,8 @@ static struct resource asic3_resources[] = {
252 .flags = IORESOURCE_MEM, 252 .flags = IORESOURCE_MEM,
253 }, 253 },
254 [1] = { 254 [1] = {
255 .start = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ), 255 .start = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ),
256 .end = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ), 256 .end = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ),
257 .flags = IORESOURCE_IRQ, 257 .flags = IORESOURCE_IRQ,
258 }, 258 },
259 /* SD part */ 259 /* SD part */
@@ -263,8 +263,8 @@ static struct resource asic3_resources[] = {
263 .flags = IORESOURCE_MEM, 263 .flags = IORESOURCE_MEM,
264 }, 264 },
265 [3] = { 265 [3] = {
266 .start = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ), 266 .start = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
267 .end = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ), 267 .end = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
268 .flags = IORESOURCE_IRQ, 268 .flags = IORESOURCE_IRQ,
269 }, 269 },
270}; 270};
@@ -587,7 +587,7 @@ static struct spi_board_info tsc2046_board_info[] __initdata = {
587 .modalias = "ads7846", 587 .modalias = "ads7846",
588 .bus_num = 2, 588 .bus_num = 2,
589 .max_speed_hz = 2600000, /* 100 kHz sample rate */ 589 .max_speed_hz = 2600000, /* 100 kHz sample rate */
590 .irq = gpio_to_irq(GPIO58_HX4700_TSC2046_nPENIRQ), 590 .irq = PXA_GPIO_TO_IRQ(GPIO58_HX4700_TSC2046_nPENIRQ),
591 .platform_data = &tsc2046_info, 591 .platform_data = &tsc2046_info,
592 .controller_data = &tsc2046_chip, 592 .controller_data = &tsc2046_chip,
593 }, 593 },
@@ -635,15 +635,15 @@ static struct resource power_supply_resources[] = {
635 .name = "ac", 635 .name = "ac",
636 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | 636 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
637 IORESOURCE_IRQ_LOWEDGE, 637 IORESOURCE_IRQ_LOWEDGE,
638 .start = gpio_to_irq(GPIOD9_nAC_IN), 638 .start = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN),
639 .end = gpio_to_irq(GPIOD9_nAC_IN), 639 .end = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN),
640 }, 640 },
641 [1] = { 641 [1] = {
642 .name = "usb", 642 .name = "usb",
643 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | 643 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
644 IORESOURCE_IRQ_LOWEDGE, 644 IORESOURCE_IRQ_LOWEDGE,
645 .start = gpio_to_irq(GPIOD14_nUSBC_DETECT), 645 .start = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT),
646 .end = gpio_to_irq(GPIOD14_nUSBC_DETECT), 646 .end = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT),
647 }, 647 },
648}; 648};
649 649
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index e239b82c99d..67400192ed3 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -86,7 +86,7 @@ static struct spi_board_info mcp251x_board_info[] = {
86 .chip_select = 0, 86 .chip_select = 0,
87 .platform_data = &mcp251x_info, 87 .platform_data = &mcp251x_info,
88 .controller_data = &mcp251x_chip_info1, 88 .controller_data = &mcp251x_chip_info1,
89 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1) 89 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1)
90 }, 90 },
91 { 91 {
92 .modalias = "mcp2515", 92 .modalias = "mcp2515",
@@ -95,7 +95,7 @@ static struct spi_board_info mcp251x_board_info[] = {
95 .chip_select = 1, 95 .chip_select = 1,
96 .platform_data = &mcp251x_info, 96 .platform_data = &mcp251x_info,
97 .controller_data = &mcp251x_chip_info2, 97 .controller_data = &mcp251x_chip_info2,
98 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2) 98 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2)
99 }, 99 },
100 { 100 {
101 .modalias = "mcp2515", 101 .modalias = "mcp2515",
@@ -104,7 +104,7 @@ static struct spi_board_info mcp251x_board_info[] = {
104 .chip_select = 0, 104 .chip_select = 0,
105 .platform_data = &mcp251x_info, 105 .platform_data = &mcp251x_info,
106 .controller_data = &mcp251x_chip_info3, 106 .controller_data = &mcp251x_chip_info3,
107 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3) 107 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3)
108 }, 108 },
109 { 109 {
110 .modalias = "mcp2515", 110 .modalias = "mcp2515",
@@ -113,7 +113,7 @@ static struct spi_board_info mcp251x_board_info[] = {
113 .chip_select = 1, 113 .chip_select = 1,
114 .platform_data = &mcp251x_info, 114 .platform_data = &mcp251x_info,
115 .controller_data = &mcp251x_chip_info4, 115 .controller_data = &mcp251x_chip_info4,
116 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ4) 116 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4)
117 } 117 }
118}; 118};
119 119
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index fbabd84e110..8af1840e12c 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -75,8 +75,8 @@ static struct resource smc91x_resources[] = {
75 .flags = IORESOURCE_MEM, 75 .flags = IORESOURCE_MEM,
76 }, 76 },
77 [1] = { 77 [1] = {
78 .start = IRQ_GPIO(4), 78 .start = PXA_GPIO_TO_IRQ(4),
79 .end = IRQ_GPIO(4), 79 .end = PXA_GPIO_TO_IRQ(4),
80 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 80 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
81 } 81 }
82}; 82};
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
index 6d7eab3d086..f02fa1e6ba8 100644
--- a/arch/arm/mach-pxa/include/mach/balloon3.h
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -172,9 +172,9 @@ enum balloon3_features {
172/* Balloon3 Interrupts */ 172/* Balloon3 Interrupts */
173#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x)) 173#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x))
174 174
175#define BALLOON3_AUX_NIRQ IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ) 175#define BALLOON3_AUX_NIRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ)
176#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ) 176#define BALLOON3_CODEC_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ)
177#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD) 177#define BALLOON3_S0_CD_IRQ PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD)
178 178
179#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16) 179#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16)
180 180
diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h
index 5dfd1195a5a..f3c3493b468 100644
--- a/arch/arm/mach-pxa/include/mach/corgi.h
+++ b/arch/arm/mach-pxa/include/mach/corgi.h
@@ -66,18 +66,18 @@
66/* 66/*
67 * Corgi Interrupts 67 * Corgi Interrupts
68 */ 68 */
69#define CORGI_IRQ_GPIO_KEY_INT IRQ_GPIO(0) 69#define CORGI_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(0)
70#define CORGI_IRQ_GPIO_AC_IN IRQ_GPIO(1) 70#define CORGI_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1)
71#define CORGI_IRQ_GPIO_WAKEUP IRQ_GPIO(3) 71#define CORGI_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(3)
72#define CORGI_IRQ_GPIO_AK_INT IRQ_GPIO(4) 72#define CORGI_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(4)
73#define CORGI_IRQ_GPIO_TP_INT IRQ_GPIO(5) 73#define CORGI_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5)
74#define CORGI_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) 74#define CORGI_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9)
75#define CORGI_IRQ_GPIO_nSD_INT IRQ_GPIO(10) 75#define CORGI_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(10)
76#define CORGI_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(11) 76#define CORGI_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(11)
77#define CORGI_IRQ_GPIO_CF_CD IRQ_GPIO(14) 77#define CORGI_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14)
78#define CORGI_IRQ_GPIO_CHRG_FULL IRQ_GPIO(16) /* Battery fully charged */ 78#define CORGI_IRQ_GPIO_CHRG_FULL PXA_GPIO_TO_IRQ(16) /* Battery fully charged */
79#define CORGI_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) 79#define CORGI_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17)
80#define CORGI_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(58+(a)) /* Keyboard Sense lines */ 80#define CORGI_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(58+(a)) /* Keyboard Sense lines */
81 81
82 82
83/* 83/*
@@ -98,7 +98,7 @@
98 CORGI_SCP_MIC_BIAS ) 98 CORGI_SCP_MIC_BIAS )
99#define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R ) 99#define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R )
100 100
101#define CORGI_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO) 101#define CORGI_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
102#define CORGI_GPIO_LED_GREEN (CORGI_SCOOP_GPIO_BASE + 0) 102#define CORGI_GPIO_LED_GREEN (CORGI_SCOOP_GPIO_BASE + 0)
103#define CORGI_GPIO_SWA (CORGI_SCOOP_GPIO_BASE + 1) /* Hinge Switch A */ 103#define CORGI_GPIO_SWA (CORGI_SCOOP_GPIO_BASE + 1) /* Hinge Switch A */
104#define CORGI_GPIO_SWB (CORGI_SCOOP_GPIO_BASE + 2) /* Hinge Switch B */ 104#define CORGI_GPIO_SWB (CORGI_SCOOP_GPIO_BASE + 2) /* Hinge Switch B */
diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h
index 747ab1a71f2..2628e7b7211 100644
--- a/arch/arm/mach-pxa/include/mach/csb726.h
+++ b/arch/arm/mach-pxa/include/mach/csb726.h
@@ -19,8 +19,8 @@
19#define CSB726_FLASH_SIZE (64 * 1024 * 1024) 19#define CSB726_FLASH_SIZE (64 * 1024 * 1024)
20#define CSB726_FLASH_uMON (8 * 1024 * 1024) 20#define CSB726_FLASH_uMON (8 * 1024 * 1024)
21 21
22#define CSB726_IRQ_LAN gpio_to_irq(CSB726_GPIO_IRQ_LAN) 22#define CSB726_IRQ_LAN PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_LAN)
23#define CSB726_IRQ_SM501 gpio_to_irq(CSB726_GPIO_IRQ_SM501) 23#define CSB726_IRQ_SM501 PXA_GPIO_TO_IRQ(CSB726_GPIO_IRQ_SM501)
24 24
25#endif 25#endif
26 26
diff --git a/arch/arm/mach-pxa/include/mach/gpio-pxa.h b/arch/arm/mach-pxa/include/mach/gpio-pxa.h
deleted file mode 100644
index 41b4c93a96c..00000000000
--- a/arch/arm/mach-pxa/include/mach/gpio-pxa.h
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * Written by Philipp Zabel <philipp.zabel@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19#ifndef __MACH_PXA_GPIO_PXA_H
20#define __MACH_PXA_GPIO_PXA_H
21
22#include <mach/irqs.h>
23#include <mach/hardware.h>
24
25#define GPIO_REGS_VIRT io_p2v(0x40E00000)
26
27#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
28#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
29
30/* GPIO Pin Level Registers */
31#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00)
32#define GPLR1 GPIO_REG(BANK_OFF(1) + 0x00)
33#define GPLR2 GPIO_REG(BANK_OFF(2) + 0x00)
34#define GPLR3 GPIO_REG(BANK_OFF(3) + 0x00)
35
36/* GPIO Pin Direction Registers */
37#define GPDR0 GPIO_REG(BANK_OFF(0) + 0x0c)
38#define GPDR1 GPIO_REG(BANK_OFF(1) + 0x0c)
39#define GPDR2 GPIO_REG(BANK_OFF(2) + 0x0c)
40#define GPDR3 GPIO_REG(BANK_OFF(3) + 0x0c)
41
42/* GPIO Pin Output Set Registers */
43#define GPSR0 GPIO_REG(BANK_OFF(0) + 0x18)
44#define GPSR1 GPIO_REG(BANK_OFF(1) + 0x18)
45#define GPSR2 GPIO_REG(BANK_OFF(2) + 0x18)
46#define GPSR3 GPIO_REG(BANK_OFF(3) + 0x18)
47
48/* GPIO Pin Output Clear Registers */
49#define GPCR0 GPIO_REG(BANK_OFF(0) + 0x24)
50#define GPCR1 GPIO_REG(BANK_OFF(1) + 0x24)
51#define GPCR2 GPIO_REG(BANK_OFF(2) + 0x24)
52#define GPCR3 GPIO_REG(BANK_OFF(3) + 0x24)
53
54/* GPIO Rising Edge Detect Registers */
55#define GRER0 GPIO_REG(BANK_OFF(0) + 0x30)
56#define GRER1 GPIO_REG(BANK_OFF(1) + 0x30)
57#define GRER2 GPIO_REG(BANK_OFF(2) + 0x30)
58#define GRER3 GPIO_REG(BANK_OFF(3) + 0x30)
59
60/* GPIO Falling Edge Detect Registers */
61#define GFER0 GPIO_REG(BANK_OFF(0) + 0x3c)
62#define GFER1 GPIO_REG(BANK_OFF(1) + 0x3c)
63#define GFER2 GPIO_REG(BANK_OFF(2) + 0x3c)
64#define GFER3 GPIO_REG(BANK_OFF(3) + 0x3c)
65
66/* GPIO Edge Detect Status Registers */
67#define GEDR0 GPIO_REG(BANK_OFF(0) + 0x48)
68#define GEDR1 GPIO_REG(BANK_OFF(1) + 0x48)
69#define GEDR2 GPIO_REG(BANK_OFF(2) + 0x48)
70#define GEDR3 GPIO_REG(BANK_OFF(3) + 0x48)
71
72/* GPIO Alternate Function Select Registers */
73#define GAFR0_L GPIO_REG(0x0054)
74#define GAFR0_U GPIO_REG(0x0058)
75#define GAFR1_L GPIO_REG(0x005C)
76#define GAFR1_U GPIO_REG(0x0060)
77#define GAFR2_L GPIO_REG(0x0064)
78#define GAFR2_U GPIO_REG(0x0068)
79#define GAFR3_L GPIO_REG(0x006C)
80#define GAFR3_U GPIO_REG(0x0070)
81
82/* More handy macros. The argument is a literal GPIO number. */
83
84#define GPIO_bit(x) (1 << ((x) & 0x1f))
85
86#define GPLR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x00)
87#define GPDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x0c)
88#define GPSR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x18)
89#define GPCR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x24)
90#define GRER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x30)
91#define GFER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x3c)
92#define GEDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x48)
93#define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2))
94
95
96#define NR_BUILTIN_GPIO PXA_GPIO_IRQ_NUM
97
98#define gpio_to_bank(gpio) ((gpio) >> 5)
99
100#ifdef CONFIG_CPU_PXA26x
101/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
102 * as well as their Alternate Function value being '1' for GPIO in GAFRx.
103 */
104static inline int __gpio_is_inverted(unsigned gpio)
105{
106 return cpu_is_pxa25x() && gpio > 85;
107}
108#else
109static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
110#endif
111
112/*
113 * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
114 * function of a GPIO, and GPDRx cannot be altered once configured. It
115 * is attributed as "occupied" here (I know this terminology isn't
116 * accurate, you are welcome to propose a better one :-)
117 */
118static inline int __gpio_is_occupied(unsigned gpio)
119{
120 if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
121 int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
122 int dir = GPDR(gpio) & GPIO_bit(gpio);
123
124 if (__gpio_is_inverted(gpio))
125 return af != 1 || dir == 0;
126 else
127 return af != 0 || dir != 0;
128 } else
129 return GPDR(gpio) & GPIO_bit(gpio);
130}
131
132#include <plat/gpio-pxa.h>
133#endif /* __MACH_PXA_GPIO_PXA_H */
diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h
index 004cade7bb1..0248e433bc9 100644
--- a/arch/arm/mach-pxa/include/mach/gpio.h
+++ b/arch/arm/mach-pxa/include/mach/gpio.h
@@ -25,24 +25,8 @@
25#define __ASM_ARCH_PXA_GPIO_H 25#define __ASM_ARCH_PXA_GPIO_H
26 26
27#include <asm-generic/gpio.h> 27#include <asm-generic/gpio.h>
28/* The defines for the driver are needed for the accelerated accessors */
29#include "gpio-pxa.h"
30 28
31#define gpio_to_irq(gpio) IRQ_GPIO(gpio) 29#include <mach/irqs.h>
30#include <mach/hardware.h>
32 31
33static inline int irq_to_gpio(unsigned int irq)
34{
35 int gpio;
36
37 if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1)
38 return irq - IRQ_GPIO0;
39
40 gpio = irq - PXA_GPIO_IRQ_BASE;
41 if (gpio >= 2 && gpio < NR_BUILTIN_GPIO)
42 return gpio;
43
44 return -1;
45}
46
47#include <plat/gpio.h>
48#endif 32#endif
diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h
index 9b898680b20..dba14b6503a 100644
--- a/arch/arm/mach-pxa/include/mach/gumstix.h
+++ b/arch/arm/mach-pxa/include/mach/gumstix.h
@@ -24,7 +24,7 @@ has detected a cable insertion; driven low otherwise. */
24#define GPIO_GUMSTIX_USB_GPIOx 41 24#define GPIO_GUMSTIX_USB_GPIOx 41
25 25
26/* usb state change */ 26/* usb state change */
27#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn) 27#define GUMSTIX_USB_INTR_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_USB_GPIOn)
28 28
29#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN) 29#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
30#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT) 30#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
@@ -35,7 +35,7 @@ has detected a cable insertion; driven low otherwise. */
35 */ 35 */
36#define GUMSTIX_GPIO_nSD_WP 22 /* SD Write Protect */ 36#define GUMSTIX_GPIO_nSD_WP 22 /* SD Write Protect */
37#define GUMSTIX_GPIO_nSD_DETECT 11 /* MMC/SD Card Detect */ 37#define GUMSTIX_GPIO_nSD_DETECT 11 /* MMC/SD Card Detect */
38#define GUMSTIX_IRQ_GPIO_nSD_DETECT IRQ_GPIO(GUMSTIX_GPIO_nSD_DETECT) 38#define GUMSTIX_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(GUMSTIX_GPIO_nSD_DETECT)
39 39
40/* 40/*
41 * SMC Ethernet definitions 41 * SMC Ethernet definitions
@@ -49,10 +49,10 @@ has detected a cable insertion; driven low otherwise. */
49 49
50#define GPIO_GUMSTIX_ETH0 36 50#define GPIO_GUMSTIX_ETH0 36
51#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN) 51#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN)
52#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0) 52#define GUMSTIX_ETH0_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH0)
53#define GPIO_GUMSTIX_ETH1 27 53#define GPIO_GUMSTIX_ETH1 27
54#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN) 54#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN)
55#define GUMSTIX_ETH1_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH1) 55#define GUMSTIX_ETH1_IRQ PXA_GPIO_TO_IRQ(GPIO_GUMSTIX_ETH1)
56 56
57 57
58/* CF reset line */ 58/* CF reset line */
@@ -63,18 +63,18 @@ has detected a cable insertion; driven low otherwise. */
63#define GPIO4_nSTSCHG GPIO4_nBVD1 63#define GPIO4_nSTSCHG GPIO4_nBVD1
64#define GPIO11_nCD 11 64#define GPIO11_nCD 11
65#define GPIO26_PRDY_nBSY 26 65#define GPIO26_PRDY_nBSY 26
66#define GUMSTIX_S0_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG) 66#define GUMSTIX_S0_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO4_nSTSCHG)
67#define GUMSTIX_S0_nCD_IRQ IRQ_GPIO(GPIO11_nCD) 67#define GUMSTIX_S0_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO11_nCD)
68#define GUMSTIX_S0_PRDY_nBSY_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY) 68#define GUMSTIX_S0_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO26_PRDY_nBSY)
69 69
70/* CF slot 1 */ 70/* CF slot 1 */
71#define GPIO18_nBVD1 18 71#define GPIO18_nBVD1 18
72#define GPIO18_nSTSCHG GPIO18_nBVD1 72#define GPIO18_nSTSCHG GPIO18_nBVD1
73#define GPIO36_nCD 36 73#define GPIO36_nCD 36
74#define GPIO27_PRDY_nBSY 27 74#define GPIO27_PRDY_nBSY 27
75#define GUMSTIX_S1_nSTSCHG_IRQ IRQ_GPIO(GPIO18_nSTSCHG) 75#define GUMSTIX_S1_nSTSCHG_IRQ PXA_GPIO_TO_IRQ(GPIO18_nSTSCHG)
76#define GUMSTIX_S1_nCD_IRQ IRQ_GPIO(GPIO36_nCD) 76#define GUMSTIX_S1_nCD_IRQ PXA_GPIO_TO_IRQ(GPIO36_nCD)
77#define GUMSTIX_S1_PRDY_nBSY_IRQ IRQ_GPIO(GPIO27_PRDY_nBSY) 77#define GUMSTIX_S1_PRDY_nBSY_IRQ PXA_GPIO_TO_IRQ(GPIO27_PRDY_nBSY)
78 78
79/* CF GPIO line modes */ 79/* CF GPIO line modes */
80#define GPIO4_nSTSCHG_MD (GPIO4_nSTSCHG | GPIO_IN) 80#define GPIO4_nSTSCHG_MD (GPIO4_nSTSCHG | GPIO_IN)
diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h
index 37408449ec2..8bc02913517 100644
--- a/arch/arm/mach-pxa/include/mach/hx4700.h
+++ b/arch/arm/mach-pxa/include/mach/hx4700.h
@@ -15,7 +15,7 @@
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/mfd/asic3.h> 16#include <linux/mfd/asic3.h>
17 17
18#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO 18#define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO
19#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) 19#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
20#define HX4700_NR_IRQS (IRQ_BOARD_START + 70) 20#define HX4700_NR_IRQS (IRQ_BOARD_START + 70)
21 21
diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h
index 5eff96fcc94..22a96f87232 100644
--- a/arch/arm/mach-pxa/include/mach/idp.h
+++ b/arch/arm/mach-pxa/include/mach/idp.h
@@ -131,28 +131,26 @@
131#define PCC_VS2 (1 << 1) 131#define PCC_VS2 (1 << 1)
132#define PCC_VS1 (1 << 0) 132#define PCC_VS1 (1 << 0)
133 133
134#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x)))
135
136/* A listing of interrupts used by external hardware devices */ 134/* A listing of interrupts used by external hardware devices */
137 135
138#define TOUCH_PANEL_IRQ IRQ_GPIO(5) 136#define TOUCH_PANEL_IRQ PXA_GPIO_TO_IRQ(5)
139#define IDE_IRQ IRQ_GPIO(21) 137#define IDE_IRQ PXA_GPIO_TO_IRQ(21)
140 138
141#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING 139#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
142 140
143#define ETHERNET_IRQ IRQ_GPIO(4) 141#define ETHERNET_IRQ PXA_GPIO_TO_IRQ(4)
144#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING 142#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING
145 143
146#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING 144#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING
147 145
148#define PCMCIA_S0_CD_VALID IRQ_GPIO(7) 146#define PCMCIA_S0_CD_VALID PXA_GPIO_TO_IRQ(7)
149#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH 147#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
150 148
151#define PCMCIA_S1_CD_VALID IRQ_GPIO(8) 149#define PCMCIA_S1_CD_VALID PXA_GPIO_TO_IRQ(8)
152#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH 150#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
153 151
154#define PCMCIA_S0_RDYINT IRQ_GPIO(19) 152#define PCMCIA_S0_RDYINT PXA_GPIO_TO_IRQ(19)
155#define PCMCIA_S1_RDYINT IRQ_GPIO(22) 153#define PCMCIA_S1_RDYINT PXA_GPIO_TO_IRQ(22)
156 154
157 155
158/* 156/*
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 7cc5a781e99..32975adf3ca 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -88,10 +88,8 @@
88#define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */ 88#define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */
89 89
90#define PXA_GPIO_IRQ_BASE PXA_IRQ(96) 90#define PXA_GPIO_IRQ_BASE PXA_IRQ(96)
91#define PXA_GPIO_IRQ_NUM (192) 91#define PXA_NR_BUILTIN_GPIO (192)
92 92#define PXA_GPIO_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
93#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
94#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x))
95 93
96/* 94/*
97 * The following interrupts are for board specific purposes. Since 95 * The following interrupts are for board specific purposes. Since
@@ -100,7 +98,7 @@
100 * By default, no board IRQ is reserved. It should be finished in 98 * By default, no board IRQ is reserved. It should be finished in
101 * custom board since sparse IRQ is already enabled. 99 * custom board since sparse IRQ is already enabled.
102 */ 100 */
103#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM) 101#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO)
104 102
105#define NR_IRQS (IRQ_BOARD_START) 103#define NR_IRQS (IRQ_BOARD_START)
106 104
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h
index b6238cbd8ae..8066be54e9f 100644
--- a/arch/arm/mach-pxa/include/mach/littleton.h
+++ b/arch/arm/mach-pxa/include/mach/littleton.h
@@ -1,13 +1,11 @@
1#ifndef __ASM_ARCH_LITTLETON_H 1#ifndef __ASM_ARCH_LITTLETON_H
2#define __ASM_ARCH_LITTLETON_H 2#define __ASM_ARCH_LITTLETON_H
3 3
4#include <mach/gpio-pxa.h>
5
6#define LITTLETON_ETH_PHYS 0x30000000 4#define LITTLETON_ETH_PHYS 0x30000000
7 5
8#define LITTLETON_GPIO_LCD_CS (17) 6#define LITTLETON_GPIO_LCD_CS (17)
9 7
10#define EXT0_GPIO_BASE (NR_BUILTIN_GPIO) 8#define EXT0_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
11#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x)) 9#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x))
12 10
13#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8) 11#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8)
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index 7cbfc5d3f9d..ba6a6e1d29e 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -78,7 +78,7 @@
78 * CPLD EGPIOs 78 * CPLD EGPIOs
79 */ 79 */
80 80
81#define MAGICIAN_EGPIO_BASE NR_BUILTIN_GPIO 81#define MAGICIAN_EGPIO_BASE PXA_NR_BUILTIN_GPIO
82#define MAGICIAN_EGPIO(reg,bit) \ 82#define MAGICIAN_EGPIO(reg,bit) \
83 (MAGICIAN_EGPIO_BASE + 8*reg + bit) 83 (MAGICIAN_EGPIO_BASE + 8*reg + bit)
84 84
diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
index ae536e86d8e..2c447133657 100644
--- a/arch/arm/mach-pxa/include/mach/palmld.h
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -68,10 +68,10 @@
68/* 20, 53 and 86 are usb related too */ 68/* 20, 53 and 86 are usb related too */
69 69
70/* INTERRUPTS */ 70/* INTERRUPTS */
71#define IRQ_GPIO_PALMLD_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMLD_GPIO_RESET) 71#define IRQ_GPIO_PALMLD_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_GPIO_RESET)
72#define IRQ_GPIO_PALMLD_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMLD_SD_DETECT_N) 72#define IRQ_GPIO_PALMLD_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_SD_DETECT_N)
73#define IRQ_GPIO_PALMLD_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMLD_WM9712_IRQ) 73#define IRQ_GPIO_PALMLD_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_WM9712_IRQ)
74#define IRQ_GPIO_PALMLD_IDE_IRQ IRQ_GPIO(GPIO_NR_PALMLD_IDE_IRQ) 74#define IRQ_GPIO_PALMLD_IDE_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMLD_IDE_IRQ)
75 75
76 76
77/** HERE ARE INIT VALUES **/ 77/** HERE ARE INIT VALUES **/
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
index 6baf7469d4e..0bd4f036c72 100644
--- a/arch/arm/mach-pxa/include/mach/palmt5.h
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -48,10 +48,10 @@
48#define GPIO_NR_PALMT5_BT_RESET 83 48#define GPIO_NR_PALMT5_BT_RESET 83
49 49
50/* INTERRUPTS */ 50/* INTERRUPTS */
51#define IRQ_GPIO_PALMT5_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMT5_SD_DETECT_N) 51#define IRQ_GPIO_PALMT5_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_SD_DETECT_N)
52#define IRQ_GPIO_PALMT5_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMT5_WM9712_IRQ) 52#define IRQ_GPIO_PALMT5_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_WM9712_IRQ)
53#define IRQ_GPIO_PALMT5_USB_DETECT IRQ_GPIO(GPIO_NR_PALMT5_USB_DETECT) 53#define IRQ_GPIO_PALMT5_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_USB_DETECT)
54#define IRQ_GPIO_PALMT5_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMT5_GPIO_RESET) 54#define IRQ_GPIO_PALMT5_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMT5_GPIO_RESET)
55 55
56/** HERE ARE INIT VALUES **/ 56/** HERE ARE INIT VALUES **/
57 57
diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h
index 3f9dd3fd463..c383a21680b 100644
--- a/arch/arm/mach-pxa/include/mach/palmtc.h
+++ b/arch/arm/mach-pxa/include/mach/palmtc.h
@@ -52,8 +52,8 @@
52#define GPIO_NR_PALMTC_IR_DISABLE 45 52#define GPIO_NR_PALMTC_IR_DISABLE 45
53 53
54/* IRQs */ 54/* IRQs */
55#define IRQ_GPIO_PALMTC_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTC_SD_DETECT_N) 55#define IRQ_GPIO_PALMTC_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_SD_DETECT_N)
56#define IRQ_GPIO_PALMTC_WLAN_READY IRQ_GPIO(GPIO_NR_PALMTC_WLAN_READY) 56#define IRQ_GPIO_PALMTC_WLAN_READY PXA_GPIO_TO_IRQ(GPIO_NR_PALMTC_WLAN_READY)
57 57
58/* UCB1400 GPIOs */ 58/* UCB1400 GPIOs */
59#define GPIO_NR_PALMTC_POWER_DETECT (0x80 | 0x00) 59#define GPIO_NR_PALMTC_POWER_DETECT (0x80 | 0x00)
diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h
index 7074a6ed46c..f2e53038025 100644
--- a/arch/arm/mach-pxa/include/mach/palmtx.h
+++ b/arch/arm/mach-pxa/include/mach/palmtx.h
@@ -62,10 +62,10 @@
62#define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79 62#define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79
63 63
64/* INTERRUPTS */ 64/* INTERRUPTS */
65#define IRQ_GPIO_PALMTX_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N) 65#define IRQ_GPIO_PALMTX_SD_DETECT_N PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_SD_DETECT_N)
66#define IRQ_GPIO_PALMTX_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ) 66#define IRQ_GPIO_PALMTX_WM9712_IRQ PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_WM9712_IRQ)
67#define IRQ_GPIO_PALMTX_USB_DETECT IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT) 67#define IRQ_GPIO_PALMTX_USB_DETECT PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_USB_DETECT)
68#define IRQ_GPIO_PALMTX_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET) 68#define IRQ_GPIO_PALMTX_GPIO_RESET PXA_GPIO_TO_IRQ(GPIO_NR_PALMTX_GPIO_RESET)
69 69
70/** HERE ARE INIT VALUES **/ 70/** HERE ARE INIT VALUES **/
71 71
diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
index 4bac588478a..6bf28de228b 100644
--- a/arch/arm/mach-pxa/include/mach/pcm027.h
+++ b/arch/arm/mach-pxa/include/mach/pcm027.h
@@ -34,7 +34,7 @@
34 34
35/* I2C RTC */ 35/* I2C RTC */
36#define PCM027_RTC_IRQ_GPIO 0 36#define PCM027_RTC_IRQ_GPIO 0
37#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO) 37#define PCM027_RTC_IRQ PXA_GPIO_TO_IRQ(PCM027_RTC_IRQ_GPIO)
38#define PCM027_RTC_IRQ_EDGE IRQ_TYPE_EDGE_FALLING 38#define PCM027_RTC_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
39#define ADR_PCM027_RTC 0x51 /* I2C address */ 39#define ADR_PCM027_RTC 0x51 /* I2C address */
40 40
@@ -43,21 +43,21 @@
43 43
44/* Ethernet chip (SMSC91C111) */ 44/* Ethernet chip (SMSC91C111) */
45#define PCM027_ETH_IRQ_GPIO 52 45#define PCM027_ETH_IRQ_GPIO 52
46#define PCM027_ETH_IRQ IRQ_GPIO(PCM027_ETH_IRQ_GPIO) 46#define PCM027_ETH_IRQ PXA_GPIO_TO_IRQ(PCM027_ETH_IRQ_GPIO)
47#define PCM027_ETH_IRQ_EDGE IRQ_TYPE_EDGE_RISING 47#define PCM027_ETH_IRQ_EDGE IRQ_TYPE_EDGE_RISING
48#define PCM027_ETH_PHYS PXA_CS5_PHYS 48#define PCM027_ETH_PHYS PXA_CS5_PHYS
49#define PCM027_ETH_SIZE (1*1024*1024) 49#define PCM027_ETH_SIZE (1*1024*1024)
50 50
51/* CAN controller SJA1000 (unsupported yet) */ 51/* CAN controller SJA1000 (unsupported yet) */
52#define PCM027_CAN_IRQ_GPIO 114 52#define PCM027_CAN_IRQ_GPIO 114
53#define PCM027_CAN_IRQ IRQ_GPIO(PCM027_CAN_IRQ_GPIO) 53#define PCM027_CAN_IRQ PXA_GPIO_TO_IRQ(PCM027_CAN_IRQ_GPIO)
54#define PCM027_CAN_IRQ_EDGE IRQ_TYPE_EDGE_FALLING 54#define PCM027_CAN_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
55#define PCM027_CAN_PHYS 0x22000000 55#define PCM027_CAN_PHYS 0x22000000
56#define PCM027_CAN_SIZE 0x100 56#define PCM027_CAN_SIZE 0x100
57 57
58/* SPI GPIO expander (unsupported yet) */ 58/* SPI GPIO expander (unsupported yet) */
59#define PCM027_EGPIO_IRQ_GPIO 27 59#define PCM027_EGPIO_IRQ_GPIO 27
60#define PCM027_EGPIO_IRQ IRQ_GPIO(PCM027_EGPIO_IRQ_GPIO) 60#define PCM027_EGPIO_IRQ PXA_GPIO_TO_IRQ(PCM027_EGPIO_IRQ_GPIO)
61#define PCM027_EGPIO_IRQ_EDGE IRQ_TYPE_EDGE_FALLING 61#define PCM027_EGPIO_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
62#define PCM027_EGPIO_CS 24 62#define PCM027_EGPIO_CS 24
63/* 63/*
diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
index 8a4383b776d..d72791695b2 100644
--- a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
+++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
@@ -28,14 +28,14 @@
28 28
29/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */ 29/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
30#define PCM990_CTRL_INT_IRQ_GPIO 9 30#define PCM990_CTRL_INT_IRQ_GPIO 9
31#define PCM990_CTRL_INT_IRQ IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO) 31#define PCM990_CTRL_INT_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_INT_IRQ_GPIO)
32#define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING 32#define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING
33#define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */ 33#define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */
34#define PCM990_CTRL_BASE 0xea000000 34#define PCM990_CTRL_BASE 0xea000000
35#define PCM990_CTRL_SIZE (1*1024*1024) 35#define PCM990_CTRL_SIZE (1*1024*1024)
36 36
37#define PCM990_CTRL_PWR_IRQ_GPIO 14 37#define PCM990_CTRL_PWR_IRQ_GPIO 14
38#define PCM990_CTRL_PWR_IRQ IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO) 38#define PCM990_CTRL_PWR_IRQ PXA_GPIO_TO_IRQ(PCM990_CTRL_PWR_IRQ_GPIO)
39#define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING 39#define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING
40 40
41/* visible CPLD (U7) registers */ 41/* visible CPLD (U7) registers */
@@ -132,7 +132,7 @@
132 * IDE 132 * IDE
133 */ 133 */
134#define PCM990_IDE_IRQ_GPIO 13 134#define PCM990_IDE_IRQ_GPIO 13
135#define PCM990_IDE_IRQ IRQ_GPIO(PCM990_IDE_IRQ_GPIO) 135#define PCM990_IDE_IRQ PXA_GPIO_TO_IRQ(PCM990_IDE_IRQ_GPIO)
136#define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING 136#define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING
137#define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */ 137#define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */
138#define PCM990_IDE_PLD_BASE 0xee000000 138#define PCM990_IDE_PLD_BASE 0xee000000
@@ -188,11 +188,11 @@
188 * Compact Flash 188 * Compact Flash
189 */ 189 */
190#define PCM990_CF_IRQ_GPIO 11 190#define PCM990_CF_IRQ_GPIO 11
191#define PCM990_CF_IRQ IRQ_GPIO(PCM990_CF_IRQ_GPIO) 191#define PCM990_CF_IRQ PXA_GPIO_TO_IRQ(PCM990_CF_IRQ_GPIO)
192#define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING 192#define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING
193 193
194#define PCM990_CF_CD_GPIO 12 194#define PCM990_CF_CD_GPIO 12
195#define PCM990_CF_CD IRQ_GPIO(PCM990_CF_CD_GPIO) 195#define PCM990_CF_CD PXA_GPIO_TO_IRQ(PCM990_CF_CD_GPIO)
196#define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING 196#define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING
197 197
198#define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */ 198#define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */
@@ -258,14 +258,14 @@
258 * Wolfson AC97 Touch 258 * Wolfson AC97 Touch
259 */ 259 */
260#define PCM990_AC97_IRQ_GPIO 10 260#define PCM990_AC97_IRQ_GPIO 10
261#define PCM990_AC97_IRQ IRQ_GPIO(PCM990_AC97_IRQ_GPIO) 261#define PCM990_AC97_IRQ PXA_GPIO_TO_IRQ(PCM990_AC97_IRQ_GPIO)
262#define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING 262#define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING
263 263
264/* 264/*
265 * MMC phyCORE 265 * MMC phyCORE
266 */ 266 */
267#define PCM990_MMC0_IRQ_GPIO 9 267#define PCM990_MMC0_IRQ_GPIO 9
268#define PCM990_MMC0_IRQ IRQ_GPIO(PCM990_MMC0_IRQ_GPIO) 268#define PCM990_MMC0_IRQ PXA_GPIO_TO_IRQ(PCM990_MMC0_IRQ_GPIO)
269#define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING 269#define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
270 270
271/* 271/*
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index 83d1cfd00fc..f32ff75dcca 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -47,18 +47,18 @@
47#define POODLE_GPIO_DISCHARGE_ON (42) /* Enable battery discharge */ 47#define POODLE_GPIO_DISCHARGE_ON (42) /* Enable battery discharge */
48 48
49/* PXA GPIOs */ 49/* PXA GPIOs */
50#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO(0) 50#define POODLE_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(0)
51#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO(1) 51#define POODLE_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(1)
52#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO(4) 52#define POODLE_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(4)
53#define POODLE_IRQ_GPIO_CO IRQ_GPIO(16) 53#define POODLE_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(16)
54#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO(5) 54#define POODLE_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(5)
55#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO(11) 55#define POODLE_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(11)
56#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO(10) 56#define POODLE_IRQ_GPIO_GA_INT PXA_GPIO_TO_IRQ(10)
57#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO(17) 57#define POODLE_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(17)
58#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO(14) 58#define POODLE_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(14)
59#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO(8) 59#define POODLE_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(8)
60#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9) 60#define POODLE_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(9)
61#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(13) 61#define POODLE_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(13)
62 62
63/* SCOOP GPIOs */ 63/* SCOOP GPIOs */
64#define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11 64#define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11
@@ -71,7 +71,7 @@
71#define POODLE_SCOOP_IO_DIR ( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT ) 71#define POODLE_SCOOP_IO_DIR ( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
72#define POODLE_SCOOP_IO_OUT ( 0 ) 72#define POODLE_SCOOP_IO_OUT ( 0 )
73 73
74#define POODLE_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO) 74#define POODLE_SCOOP_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
75#define POODLE_GPIO_CHARGE_ON (POODLE_SCOOP_GPIO_BASE + 0) 75#define POODLE_GPIO_CHARGE_ON (POODLE_SCOOP_GPIO_BASE + 0)
76#define POODLE_GPIO_CP401 (POODLE_SCOOP_GPIO_BASE + 2) 76#define POODLE_GPIO_CP401 (POODLE_SCOOP_GPIO_BASE + 2)
77#define POODLE_GPIO_VPEN (POODLE_SCOOP_GPIO_BASE + 7) 77#define POODLE_GPIO_VPEN (POODLE_SCOOP_GPIO_BASE + 7)
diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h
index 685749a51c4..0bfe6507c95 100644
--- a/arch/arm/mach-pxa/include/mach/spitz.h
+++ b/arch/arm/mach-pxa/include/mach/spitz.h
@@ -108,7 +108,7 @@
108#define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON) 108#define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
109#define SPITZ_SCP_SUS_SET 0 109#define SPITZ_SCP_SUS_SET 0
110 110
111#define SPITZ_SCP_GPIO_BASE (NR_BUILTIN_GPIO) 111#define SPITZ_SCP_GPIO_BASE (PXA_NR_BUILTIN_GPIO)
112#define SPITZ_GPIO_LED_GREEN (SPITZ_SCP_GPIO_BASE + 0) 112#define SPITZ_GPIO_LED_GREEN (SPITZ_SCP_GPIO_BASE + 0)
113#define SPITZ_GPIO_JK_B (SPITZ_SCP_GPIO_BASE + 1) 113#define SPITZ_GPIO_JK_B (SPITZ_SCP_GPIO_BASE + 1)
114#define SPITZ_GPIO_CHRG_ON (SPITZ_SCP_GPIO_BASE + 2) 114#define SPITZ_GPIO_CHRG_ON (SPITZ_SCP_GPIO_BASE + 2)
@@ -140,7 +140,7 @@
140 SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS) 140 SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
141#define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1) 141#define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1)
142 142
143#define SPITZ_SCP2_GPIO_BASE (NR_BUILTIN_GPIO + 12) 143#define SPITZ_SCP2_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12)
144#define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0) 144#define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0)
145#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1) 145#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1)
146#define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2) 146#define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2)
@@ -152,7 +152,7 @@
152#define SPITZ_GPIO_MIC_BIAS (SPITZ_SCP2_GPIO_BASE + 8) 152#define SPITZ_GPIO_MIC_BIAS (SPITZ_SCP2_GPIO_BASE + 8)
153 153
154/* Akita IO Expander GPIOs */ 154/* Akita IO Expander GPIOs */
155#define AKITA_IOEXP_GPIO_BASE (NR_BUILTIN_GPIO + 12) 155#define AKITA_IOEXP_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12)
156#define AKITA_GPIO_RESERVED_0 (AKITA_IOEXP_GPIO_BASE + 0) 156#define AKITA_GPIO_RESERVED_0 (AKITA_IOEXP_GPIO_BASE + 0)
157#define AKITA_GPIO_RESERVED_1 (AKITA_IOEXP_GPIO_BASE + 1) 157#define AKITA_GPIO_RESERVED_1 (AKITA_IOEXP_GPIO_BASE + 1)
158#define AKITA_GPIO_MIC_BIAS (AKITA_IOEXP_GPIO_BASE + 2) 158#define AKITA_GPIO_MIC_BIAS (AKITA_IOEXP_GPIO_BASE + 2)
@@ -164,23 +164,23 @@
164 164
165/* Spitz IRQ Definitions */ 165/* Spitz IRQ Definitions */
166 166
167#define SPITZ_IRQ_GPIO_KEY_INT IRQ_GPIO(SPITZ_GPIO_KEY_INT) 167#define SPITZ_IRQ_GPIO_KEY_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_KEY_INT)
168#define SPITZ_IRQ_GPIO_AC_IN IRQ_GPIO(SPITZ_GPIO_AC_IN) 168#define SPITZ_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_AC_IN)
169#define SPITZ_IRQ_GPIO_AK_INT IRQ_GPIO(SPITZ_GPIO_AK_INT) 169#define SPITZ_IRQ_GPIO_AK_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_AK_INT)
170#define SPITZ_IRQ_GPIO_HP_IN IRQ_GPIO(SPITZ_GPIO_HP_IN) 170#define SPITZ_IRQ_GPIO_HP_IN PXA_GPIO_TO_IRQ(SPITZ_GPIO_HP_IN)
171#define SPITZ_IRQ_GPIO_TP_INT IRQ_GPIO(SPITZ_GPIO_TP_INT) 171#define SPITZ_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT)
172#define SPITZ_IRQ_GPIO_SYNC IRQ_GPIO(SPITZ_GPIO_SYNC) 172#define SPITZ_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(SPITZ_GPIO_SYNC)
173#define SPITZ_IRQ_GPIO_ON_KEY IRQ_GPIO(SPITZ_GPIO_ON_KEY) 173#define SPITZ_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(SPITZ_GPIO_ON_KEY)
174#define SPITZ_IRQ_GPIO_SWA IRQ_GPIO(SPITZ_GPIO_SWA) 174#define SPITZ_IRQ_GPIO_SWA PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWA)
175#define SPITZ_IRQ_GPIO_SWB IRQ_GPIO(SPITZ_GPIO_SWB) 175#define SPITZ_IRQ_GPIO_SWB PXA_GPIO_TO_IRQ(SPITZ_GPIO_SWB)
176#define SPITZ_IRQ_GPIO_BAT_COVER IRQ_GPIO(SPITZ_GPIO_BAT_COVER) 176#define SPITZ_IRQ_GPIO_BAT_COVER PXA_GPIO_TO_IRQ(SPITZ_GPIO_BAT_COVER)
177#define SPITZ_IRQ_GPIO_FATAL_BAT IRQ_GPIO(SPITZ_GPIO_FATAL_BAT) 177#define SPITZ_IRQ_GPIO_FATAL_BAT PXA_GPIO_TO_IRQ(SPITZ_GPIO_FATAL_BAT)
178#define SPITZ_IRQ_GPIO_CO IRQ_GPIO(SPITZ_GPIO_CO) 178#define SPITZ_IRQ_GPIO_CO PXA_GPIO_TO_IRQ(SPITZ_GPIO_CO)
179#define SPITZ_IRQ_GPIO_CF_IRQ IRQ_GPIO(SPITZ_GPIO_CF_IRQ) 179#define SPITZ_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_IRQ)
180#define SPITZ_IRQ_GPIO_CF_CD IRQ_GPIO(SPITZ_GPIO_CF_CD) 180#define SPITZ_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF_CD)
181#define SPITZ_IRQ_GPIO_CF2_IRQ IRQ_GPIO(SPITZ_GPIO_CF2_IRQ) 181#define SPITZ_IRQ_GPIO_CF2_IRQ PXA_GPIO_TO_IRQ(SPITZ_GPIO_CF2_IRQ)
182#define SPITZ_IRQ_GPIO_nSD_INT IRQ_GPIO(SPITZ_GPIO_nSD_INT) 182#define SPITZ_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_INT)
183#define SPITZ_IRQ_GPIO_nSD_DETECT IRQ_GPIO(SPITZ_GPIO_nSD_DETECT) 183#define SPITZ_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(SPITZ_GPIO_nSD_DETECT)
184 184
185/* 185/*
186 * Shared data structures 186 * Shared data structures
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index 1272c4b56ce..2bb0e862598 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -24,7 +24,7 @@
24/* 24/*
25 * SCOOP2 internal GPIOs 25 * SCOOP2 internal GPIOs
26 */ 26 */
27#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO 27#define TOSA_SCOOP_GPIO_BASE PXA_NR_BUILTIN_GPIO
28#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11 28#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
29#define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1) 29#define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1)
30#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) 30#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
@@ -42,7 +42,7 @@
42/* 42/*
43 * SCOOP2 jacket GPIOs 43 * SCOOP2 jacket GPIOs
44 */ 44 */
45#define TOSA_SCOOP_JC_GPIO_BASE (NR_BUILTIN_GPIO + 12) 45#define TOSA_SCOOP_JC_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 12)
46#define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0) 46#define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0)
47#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1) 47#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
48#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) 48#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
@@ -59,7 +59,7 @@
59/* 59/*
60 * TC6393XB GPIOs 60 * TC6393XB GPIOs
61 */ 61 */
62#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12) 62#define TOSA_TC6393XB_GPIO_BASE (PXA_NR_BUILTIN_GPIO + 2 * 12)
63 63
64#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0) 64#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0)
65#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1) 65#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1)
@@ -141,30 +141,30 @@
141/* 141/*
142 * Interrupts 142 * Interrupts
143 */ 143 */
144#define TOSA_IRQ_GPIO_WAKEUP IRQ_GPIO(TOSA_GPIO_WAKEUP) 144#define TOSA_IRQ_GPIO_WAKEUP PXA_GPIO_TO_IRQ(TOSA_GPIO_WAKEUP)
145#define TOSA_IRQ_GPIO_AC_IN IRQ_GPIO(TOSA_GPIO_AC_IN) 145#define TOSA_IRQ_GPIO_AC_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN)
146#define TOSA_IRQ_GPIO_RECORD_BTN IRQ_GPIO(TOSA_GPIO_RECORD_BTN) 146#define TOSA_IRQ_GPIO_RECORD_BTN PXA_GPIO_TO_IRQ(TOSA_GPIO_RECORD_BTN)
147#define TOSA_IRQ_GPIO_SYNC IRQ_GPIO(TOSA_GPIO_SYNC) 147#define TOSA_IRQ_GPIO_SYNC PXA_GPIO_TO_IRQ(TOSA_GPIO_SYNC)
148#define TOSA_IRQ_GPIO_USB_IN IRQ_GPIO(TOSA_GPIO_USB_IN) 148#define TOSA_IRQ_GPIO_USB_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_USB_IN)
149#define TOSA_IRQ_GPIO_JACKET_DETECT IRQ_GPIO(TOSA_GPIO_JACKET_DETECT) 149#define TOSA_IRQ_GPIO_JACKET_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_JACKET_DETECT)
150#define TOSA_IRQ_GPIO_nSD_INT IRQ_GPIO(TOSA_GPIO_nSD_INT) 150#define TOSA_IRQ_GPIO_nSD_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_INT)
151#define TOSA_IRQ_GPIO_nSD_DETECT IRQ_GPIO(TOSA_GPIO_nSD_DETECT) 151#define TOSA_IRQ_GPIO_nSD_DETECT PXA_GPIO_TO_IRQ(TOSA_GPIO_nSD_DETECT)
152#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG) 152#define TOSA_IRQ_GPIO_BAT1_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_CRG)
153#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD) 153#define TOSA_IRQ_GPIO_CF_CD PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_CD)
154#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG) 154#define TOSA_IRQ_GPIO_BAT0_CRG PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_CRG)
155#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT) 155#define TOSA_IRQ_GPIO_TC6393XB_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TC6393XB_INT)
156#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW) 156#define TOSA_IRQ_GPIO_BAT0_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT0_LOW)
157#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN) 157#define TOSA_IRQ_GPIO_EAR_IN PXA_GPIO_TO_IRQ(TOSA_GPIO_EAR_IN)
158#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ) 158#define TOSA_IRQ_GPIO_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_CF_IRQ)
159#define TOSA_IRQ_GPIO_ON_KEY IRQ_GPIO(TOSA_GPIO_ON_KEY) 159#define TOSA_IRQ_GPIO_ON_KEY PXA_GPIO_TO_IRQ(TOSA_GPIO_ON_KEY)
160#define TOSA_IRQ_GPIO_VGA_LINE IRQ_GPIO(TOSA_GPIO_VGA_LINE) 160#define TOSA_IRQ_GPIO_VGA_LINE PXA_GPIO_TO_IRQ(TOSA_GPIO_VGA_LINE)
161#define TOSA_IRQ_GPIO_TP_INT IRQ_GPIO(TOSA_GPIO_TP_INT) 161#define TOSA_IRQ_GPIO_TP_INT PXA_GPIO_TO_IRQ(TOSA_GPIO_TP_INT)
162#define TOSA_IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(TOSA_GPIO_JC_CF_IRQ) 162#define TOSA_IRQ_GPIO_JC_CF_IRQ PXA_GPIO_TO_IRQ(TOSA_GPIO_JC_CF_IRQ)
163#define TOSA_IRQ_GPIO_BAT_LOCKED IRQ_GPIO(TOSA_GPIO_BAT_LOCKED) 163#define TOSA_IRQ_GPIO_BAT_LOCKED PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT_LOCKED)
164#define TOSA_IRQ_GPIO_BAT1_LOW IRQ_GPIO(TOSA_GPIO_BAT1_LOW) 164#define TOSA_IRQ_GPIO_BAT1_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_BAT1_LOW)
165#define TOSA_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a)) 165#define TOSA_IRQ_GPIO_KEY_SENSE(a) PXA_GPIO_TO_IRQ(69+(a))
166 166
167#define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW) 167#define TOSA_IRQ_GPIO_MAIN_BAT_LOW PXA_GPIO_TO_IRQ(TOSA_GPIO_MAIN_BAT_LOW)
168 168
169#define TOSA_KEY_SYNC KEY_102ND /* ??? */ 169#define TOSA_KEY_SYNC KEY_102ND /* ??? */
170 170
diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h
index 903e1a2e664..d2ca01053f6 100644
--- a/arch/arm/mach-pxa/include/mach/trizeps4.h
+++ b/arch/arm/mach-pxa/include/mach/trizeps4.h
@@ -43,30 +43,30 @@
43 43
44/* Ethernet Controller Davicom DM9000 */ 44/* Ethernet Controller Davicom DM9000 */
45#define GPIO_DM9000 101 45#define GPIO_DM9000 101
46#define TRIZEPS4_ETH_IRQ IRQ_GPIO(GPIO_DM9000) 46#define TRIZEPS4_ETH_IRQ PXA_GPIO_TO_IRQ(GPIO_DM9000)
47 47
48/* UCB1400 audio / TS-controller */ 48/* UCB1400 audio / TS-controller */
49#define GPIO_UCB1400 1 49#define GPIO_UCB1400 1
50#define TRIZEPS4_UCB1400_IRQ IRQ_GPIO(GPIO_UCB1400) 50#define TRIZEPS4_UCB1400_IRQ PXA_GPIO_TO_IRQ(GPIO_UCB1400)
51 51
52/* PCMCIA socket Compact Flash */ 52/* PCMCIA socket Compact Flash */
53#define GPIO_PCD 11 /* PCMCIA Card Detect */ 53#define GPIO_PCD 11 /* PCMCIA Card Detect */
54#define TRIZEPS4_CD_IRQ IRQ_GPIO(GPIO_PCD) 54#define TRIZEPS4_CD_IRQ PXA_GPIO_TO_IRQ(GPIO_PCD)
55#define GPIO_PRDY 13 /* READY / nINT */ 55#define GPIO_PRDY 13 /* READY / nINT */
56#define TRIZEPS4_READY_NINT IRQ_GPIO(GPIO_PRDY) 56#define TRIZEPS4_READY_NINT PXA_GPIO_TO_IRQ(GPIO_PRDY)
57 57
58/* MMC socket */ 58/* MMC socket */
59#define GPIO_MMC_DET 12 59#define GPIO_MMC_DET 12
60#define TRIZEPS4_MMC_IRQ IRQ_GPIO(GPIO_MMC_DET) 60#define TRIZEPS4_MMC_IRQ PXA_GPIO_TO_IRQ(GPIO_MMC_DET)
61 61
62/* DOC NAND chip */ 62/* DOC NAND chip */
63#define GPIO_DOC_LOCK 94 63#define GPIO_DOC_LOCK 94
64#define GPIO_DOC_IRQ 93 64#define GPIO_DOC_IRQ 93
65#define TRIZEPS4_DOC_IRQ IRQ_GPIO(GPIO_DOC_IRQ) 65#define TRIZEPS4_DOC_IRQ PXA_GPIO_TO_IRQ(GPIO_DOC_IRQ)
66 66
67/* SPI interface */ 67/* SPI interface */
68#define GPIO_SPI 53 68#define GPIO_SPI 53
69#define TRIZEPS4_SPI_IRQ IRQ_GPIO(GPIO_SPI) 69#define TRIZEPS4_SPI_IRQ PXA_GPIO_TO_IRQ(GPIO_SPI)
70 70
71/* LEDS using tx2 / rx2 */ 71/* LEDS using tx2 / rx2 */
72#define GPIO_SYS_BUSY_LED 46 72#define GPIO_SYS_BUSY_LED 46
@@ -74,7 +74,7 @@
74 74
75/* Off-module PIC on ConXS board */ 75/* Off-module PIC on ConXS board */
76#define GPIO_PIC 0 76#define GPIO_PIC 0
77#define TRIZEPS4_PIC_IRQ IRQ_GPIO(GPIO_PIC) 77#define TRIZEPS4_PIC_IRQ PXA_GPIO_TO_IRQ(GPIO_PIC)
78 78
79#ifdef CONFIG_MACH_TRIZEPS_CONXS 79#ifdef CONFIG_MACH_TRIZEPS_CONXS
80/* for CONXS base board define these registers */ 80/* for CONXS base board define these registers */
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 532c5d3a97d..5dae15ea671 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -22,7 +22,6 @@
22 22
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <mach/irqs.h> 24#include <mach/irqs.h>
25#include <mach/gpio-pxa.h>
26 25
27#include "generic.h" 26#include "generic.h"
28 27
@@ -92,44 +91,6 @@ static struct irq_chip pxa_internal_irq_chip = {
92 .irq_unmask = pxa_unmask_irq, 91 .irq_unmask = pxa_unmask_irq,
93}; 92};
94 93
95/*
96 * GPIO IRQs for GPIO 0 and 1
97 */
98static int pxa_set_low_gpio_type(struct irq_data *d, unsigned int type)
99{
100 int gpio = d->irq - IRQ_GPIO0;
101
102 if (__gpio_is_occupied(gpio)) {
103 pr_err("%s failed: GPIO is configured\n", __func__);
104 return -EINVAL;
105 }
106
107 if (type & IRQ_TYPE_EDGE_RISING)
108 GRER0 |= GPIO_bit(gpio);
109 else
110 GRER0 &= ~GPIO_bit(gpio);
111
112 if (type & IRQ_TYPE_EDGE_FALLING)
113 GFER0 |= GPIO_bit(gpio);
114 else
115 GFER0 &= ~GPIO_bit(gpio);
116
117 return 0;
118}
119
120static void pxa_ack_low_gpio(struct irq_data *d)
121{
122 GEDR0 = (1 << (d->irq - IRQ_GPIO0));
123}
124
125static struct irq_chip pxa_low_gpio_chip = {
126 .name = "GPIO-l",
127 .irq_ack = pxa_ack_low_gpio,
128 .irq_mask = pxa_mask_irq,
129 .irq_unmask = pxa_unmask_irq,
130 .irq_set_type = pxa_set_low_gpio_type,
131};
132
133asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs) 94asmlinkage void __exception_irq_entry icip_handle_irq(struct pt_regs *regs)
134{ 95{
135 uint32_t icip, icmr, mask; 96 uint32_t icip, icmr, mask;
@@ -160,26 +121,7 @@ asmlinkage void __exception_irq_entry ichp_handle_irq(struct pt_regs *regs)
160 } while (1); 121 } while (1);
161} 122}
162 123
163static void __init pxa_init_low_gpio_irq(set_wake_t fn) 124void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int))
164{
165 int irq;
166
167 /* clear edge detection on GPIO 0 and 1 */
168 GFER0 &= ~0x3;
169 GRER0 &= ~0x3;
170 GEDR0 = 0x3;
171
172 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
173 irq_set_chip_and_handler(irq, &pxa_low_gpio_chip,
174 handle_edge_irq);
175 irq_set_chip_data(irq, irq_base(0));
176 set_irq_flags(irq, IRQF_VALID);
177 }
178
179 pxa_low_gpio_chip.irq_set_wake = fn;
180}
181
182void __init pxa_init_irq(int irq_nr, set_wake_t fn)
183{ 125{
184 int irq, i, n; 126 int irq, i, n;
185 127
@@ -209,7 +151,6 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
209 __raw_writel(1, irq_base(0) + ICCR); 151 __raw_writel(1, irq_base(0) + ICCR);
210 152
211 pxa_internal_irq_chip.irq_set_wake = fn; 153 pxa_internal_irq_chip.irq_set_wake = fn;
212 pxa_init_low_gpio_irq(fn);
213} 154}
214 155
215#ifdef CONFIG_PM 156#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index c337c7eed51..1fb86edb857 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -124,8 +124,8 @@ static struct resource smc91x_resources[] = {
124 .flags = IORESOURCE_MEM, 124 .flags = IORESOURCE_MEM,
125 }, 125 },
126 [1] = { 126 [1] = {
127 .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), 127 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)),
128 .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)), 128 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO90)),
129 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, 129 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
130 } 130 }
131}; 131};
@@ -396,7 +396,7 @@ static struct i2c_board_info littleton_i2c_info[] = {
396 .type = "da9034", 396 .type = "da9034",
397 .addr = 0x34, 397 .addr = 0x34,
398 .platform_data = &littleton_da9034_info, 398 .platform_data = &littleton_da9034_info,
399 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO18)), 399 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO18)),
400 }, 400 },
401 [1] = { 401 [1] = {
402 .type = "max7320", 402 .type = "max7320",
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index 6119c015f39..cee9ce2fc0b 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -152,8 +152,8 @@ static void __init lpd270_init_irq(void)
152 handle_level_irq); 152 handle_level_irq);
153 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 153 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
154 } 154 }
155 irq_set_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); 155 irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lpd270_irq_handler);
156 irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); 156 irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING);
157} 157}
158 158
159 159
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 4b7a5287165..6ebd276aebe 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -170,8 +170,8 @@ static void __init lubbock_init_irq(void)
170 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 170 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
171 } 171 }
172 172
173 irq_set_chained_handler(IRQ_GPIO(0), lubbock_irq_handler); 173 irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lubbock_irq_handler);
174 irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); 174 irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING);
175} 175}
176 176
177#ifdef CONFIG_PM 177#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 4e6774fff42..3d6baf91396 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -184,8 +184,8 @@ static struct resource egpio_resources[] = {
184 .flags = IORESOURCE_MEM, 184 .flags = IORESOURCE_MEM,
185 }, 185 },
186 [1] = { 186 [1] = {
187 .start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), 187 .start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
188 .end = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ), 188 .end = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
189 .flags = IORESOURCE_IRQ, 189 .flags = IORESOURCE_IRQ,
190 }, 190 },
191}; 191};
@@ -468,8 +468,8 @@ static struct resource pasic3_resources[] = {
468 }, 468 },
469 /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */ 469 /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
470 [1] = { 470 [1] = {
471 .start = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), 471 .start = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
472 .end = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ), 472 .end = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
473 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 473 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
474 } 474 }
475}; 475};
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index ca14555d5e1..1aebaf71946 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -178,8 +178,8 @@ static void __init mainstone_init_irq(void)
178 MST_INTMSKENA = 0; 178 MST_INTMSKENA = 0;
179 MST_INTSETCLR = 0; 179 MST_INTSETCLR = 0;
180 180
181 irq_set_chained_handler(IRQ_GPIO(0), mainstone_irq_handler); 181 irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), mainstone_irq_handler);
182 irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING); 182 irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING);
183} 183}
184 184
185#ifdef CONFIG_PM 185#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 43a5f6861ca..f14775536b8 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -13,6 +13,7 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/gpio-pxa.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/init.h> 19#include <linux/init.h>
@@ -20,7 +21,6 @@
20 21
21#include <mach/pxa2xx-regs.h> 22#include <mach/pxa2xx-regs.h>
22#include <mach/mfp-pxa2xx.h> 23#include <mach/mfp-pxa2xx.h>
23#include <mach/gpio-pxa.h>
24 24
25#include "generic.h" 25#include "generic.h"
26 26
@@ -29,6 +29,10 @@
29#define GAFR_L(x) __GAFR(0, x) 29#define GAFR_L(x) __GAFR(0, x)
30#define GAFR_U(x) __GAFR(1, x) 30#define GAFR_U(x) __GAFR(1, x)
31 31
32#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
33#define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5))
34#define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c)
35
32#define PWER_WE35 (1 << 24) 36#define PWER_WE35 (1 << 24)
33 37
34struct gpio_desc { 38struct gpio_desc {
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 924a3b5f8da..e80a3db735c 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -53,6 +53,7 @@
53#include <mach/pxa27x-udc.h> 53#include <mach/pxa27x-udc.h>
54#include <mach/camera.h> 54#include <mach/camera.h>
55#include <mach/audio.h> 55#include <mach/audio.h>
56#include <mach/smemc.h>
56#include <media/soc_camera.h> 57#include <media/soc_camera.h>
57 58
58#include <mach/mioa701.h> 59#include <mach/mioa701.h>
@@ -390,24 +391,19 @@ static struct pxamci_platform_data mioa701_mci_info = {
390}; 391};
391 392
392/* FlashRAM */ 393/* FlashRAM */
393static struct resource strataflash_resource = { 394static struct resource docg3_resource = {
394 .start = PXA_CS0_PHYS, 395 .start = PXA_CS0_PHYS,
395 .end = PXA_CS0_PHYS + SZ_64M - 1, 396 .end = PXA_CS0_PHYS + SZ_8K - 1,
396 .flags = IORESOURCE_MEM, 397 .flags = IORESOURCE_MEM,
397}; 398};
398 399
399static struct physmap_flash_data strataflash_data = { 400static struct platform_device docg3 = {
400 .width = 2, 401 .name = "docg3",
401 /* .set_vpp = mioa701_set_vpp, */
402};
403
404static struct platform_device strataflash = {
405 .name = "physmap-flash",
406 .id = -1, 402 .id = -1,
407 .resource = &strataflash_resource, 403 .resource = &docg3_resource,
408 .num_resources = 1, 404 .num_resources = 1,
409 .dev = { 405 .dev = {
410 .platform_data = &strataflash_data, 406 .platform_data = NULL,
411 }, 407 },
412}; 408};
413 409
@@ -541,15 +537,15 @@ static struct pda_power_pdata power_pdata = {
541static struct resource power_resources[] = { 537static struct resource power_resources[] = {
542 [0] = { 538 [0] = {
543 .name = "ac", 539 .name = "ac",
544 .start = gpio_to_irq(GPIO96_AC_DETECT), 540 .start = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
545 .end = gpio_to_irq(GPIO96_AC_DETECT), 541 .end = PXA_GPIO_TO_IRQ(GPIO96_AC_DETECT),
546 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | 542 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
547 IORESOURCE_IRQ_LOWEDGE, 543 IORESOURCE_IRQ_LOWEDGE,
548 }, 544 },
549 [1] = { 545 [1] = {
550 .name = "usb", 546 .name = "usb",
551 .start = gpio_to_irq(GPIO13_nUSB_DETECT), 547 .start = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT),
552 .end = gpio_to_irq(GPIO13_nUSB_DETECT), 548 .end = PXA_GPIO_TO_IRQ(GPIO13_nUSB_DETECT),
553 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | 549 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
554 IORESOURCE_IRQ_LOWEDGE, 550 IORESOURCE_IRQ_LOWEDGE,
555 }, 551 },
@@ -685,7 +681,7 @@ static struct platform_device *devices[] __initdata = {
685 &pxa2xx_pcm, 681 &pxa2xx_pcm,
686 &mioa701_sound, 682 &mioa701_sound,
687 &power_dev, 683 &power_dev,
688 &strataflash, 684 &docg3,
689 &gpio_vbus, 685 &gpio_vbus,
690 &mioa701_camera, 686 &mioa701_camera,
691 &mioa701_board, 687 &mioa701_board,
@@ -720,6 +716,15 @@ static void __init mioa701_machine_init(void)
720 RTTR = 32768 - 1; /* Reset crazy WinCE value */ 716 RTTR = 32768 - 1; /* Reset crazy WinCE value */
721 UP2OCR = UP2OCR_HXOE; 717 UP2OCR = UP2OCR_HXOE;
722 718
719 /*
720 * Set up the flash memory : DiskOnChip G3 on first static memory bank
721 */
722 __raw_writel(0x7ff02dd8, MSC0);
723 __raw_writel(0x0001c391, MCMEM0);
724 __raw_writel(0x0001c391, MCATT0);
725 __raw_writel(0x0001c391, MCIO0);
726
727
723 pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config)); 728 pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
724 pxa_set_ffuart_info(NULL); 729 pxa_set_ffuart_info(NULL);
725 pxa_set_btuart_info(NULL); 730 pxa_set_btuart_info(NULL);
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
index 90928d6e1a5..83570a79e7d 100644
--- a/arch/arm/mach-pxa/mxm8x10.c
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -417,8 +417,8 @@ static struct resource dm9k_resources[] = {
417 .flags = IORESOURCE_MEM 417 .flags = IORESOURCE_MEM
418 }, 418 },
419 [2] = { 419 [2] = {
420 .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)), 420 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)),
421 .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)), 421 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO9)),
422 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE 422 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
423 } 423 }
424}; 424};
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 6d38c6548b3..abab4e2b122 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -378,7 +378,7 @@ struct pxacamera_platform_data pcm990_pxacamera_platform_data = {
378#include <linux/i2c/pca953x.h> 378#include <linux/i2c/pca953x.h>
379 379
380static struct pca953x_platform_data pca9536_data = { 380static struct pca953x_platform_data pca9536_data = {
381 .gpio_base = NR_BUILTIN_GPIO, 381 .gpio_base = PXA_NR_BUILTIN_GPIO,
382}; 382};
383 383
384static int gpio_bus_switch = -EINVAL; 384static int gpio_bus_switch = -EINVAL;
@@ -406,9 +406,9 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
406 int ret; 406 int ret;
407 407
408 if (gpio_bus_switch < 0) { 408 if (gpio_bus_switch < 0) {
409 ret = gpio_request(NR_BUILTIN_GPIO, "camera"); 409 ret = gpio_request(PXA_NR_BUILTIN_GPIO, "camera");
410 if (!ret) { 410 if (!ret) {
411 gpio_bus_switch = NR_BUILTIN_GPIO; 411 gpio_bus_switch = PXA_NR_BUILTIN_GPIO;
412 gpio_direction_output(gpio_bus_switch, 0); 412 gpio_direction_output(gpio_bus_switch, 0);
413 } 413 }
414 } 414 }
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index b260ce872d2..69036e42ca3 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -166,8 +166,8 @@ static struct resource locomo_resources[] = {
166 .flags = IORESOURCE_MEM, 166 .flags = IORESOURCE_MEM,
167 }, 167 },
168 [1] = { 168 [1] = {
169 .start = IRQ_GPIO(10), 169 .start = PXA_GPIO_TO_IRQ(10),
170 .end = IRQ_GPIO(10), 170 .end = PXA_GPIO_TO_IRQ(10),
171 .flags = IORESOURCE_IRQ, 171 .flags = IORESOURCE_IRQ,
172 }, 172 },
173}; 173};
@@ -212,7 +212,7 @@ static struct spi_board_info poodle_spi_devices[] = {
212 .bus_num = 1, 212 .bus_num = 1,
213 .platform_data = &poodle_ads7846_info, 213 .platform_data = &poodle_ads7846_info,
214 .controller_data= &poodle_ads7846_chip, 214 .controller_data= &poodle_ads7846_chip,
215 .irq = gpio_to_irq(POODLE_GPIO_TP_INT), 215 .irq = PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
216 }, 216 },
217}; 217};
218 218
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index f05f9486b0c..adf058fa97e 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -17,6 +17,7 @@
17 * need be. 17 * need be.
18 */ 18 */
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/gpio-pxa.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/kernel.h> 22#include <linux/kernel.h>
22#include <linux/init.h> 23#include <linux/init.h>
@@ -208,6 +209,8 @@ static struct clk_lookup pxa25x_clkregs[] = {
208 INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), 209 INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
209 INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), 210 INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
210 INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), 211 INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
212 INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
213 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
211}; 214};
212 215
213static struct clk_lookup pxa25x_hwuart_clkreg = 216static struct clk_lookup pxa25x_hwuart_clkreg =
@@ -287,7 +290,7 @@ static inline void pxa25x_init_pm(void) {}
287 290
288static int pxa25x_set_wake(struct irq_data *d, unsigned int on) 291static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
289{ 292{
290 int gpio = irq_to_gpio(d->irq); 293 int gpio = pxa_irq_to_gpio(d->irq);
291 uint32_t mask = 0; 294 uint32_t mask = 0;
292 295
293 if (gpio >= 0 && gpio < 85) 296 if (gpio >= 0 && gpio < 85)
@@ -312,14 +315,12 @@ set_pwer:
312void __init pxa25x_init_irq(void) 315void __init pxa25x_init_irq(void)
313{ 316{
314 pxa_init_irq(32, pxa25x_set_wake); 317 pxa_init_irq(32, pxa25x_set_wake);
315 pxa_init_gpio(IRQ_GPIO_2_x, 2, 84, pxa25x_set_wake);
316} 318}
317 319
318#ifdef CONFIG_CPU_PXA26x 320#ifdef CONFIG_CPU_PXA26x
319void __init pxa26x_init_irq(void) 321void __init pxa26x_init_irq(void)
320{ 322{
321 pxa_init_irq(32, pxa25x_set_wake); 323 pxa_init_irq(32, pxa25x_set_wake);
322 pxa_init_gpio(IRQ_GPIO_2_x, 2, 89, pxa25x_set_wake);
323} 324}
324#endif 325#endif
325 326
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index bc5a98ebaa7..180bd8675d4 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -12,6 +12,7 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/gpio-pxa.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/init.h> 18#include <linux/init.h>
@@ -229,6 +230,8 @@ static struct clk_lookup pxa27x_clkregs[] = {
229 INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), 230 INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
230 INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), 231 INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
231 INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), 232 INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
233 INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL),
234 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
232}; 235};
233 236
234#ifdef CONFIG_PM 237#ifdef CONFIG_PM
@@ -355,7 +358,7 @@ static inline void pxa27x_init_pm(void) {}
355 */ 358 */
356static int pxa27x_set_wake(struct irq_data *d, unsigned int on) 359static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
357{ 360{
358 int gpio = irq_to_gpio(d->irq); 361 int gpio = pxa_irq_to_gpio(d->irq);
359 uint32_t mask; 362 uint32_t mask;
360 363
361 if (gpio >= 0 && gpio < 128) 364 if (gpio >= 0 && gpio < 128)
@@ -386,7 +389,6 @@ static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
386void __init pxa27x_init_irq(void) 389void __init pxa27x_init_irq(void)
387{ 390{
388 pxa_init_irq(34, pxa27x_set_wake); 391 pxa_init_irq(34, pxa27x_set_wake);
389 pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake);
390} 392}
391 393
392static struct map_desc pxa27x_io_desc[] __initdata = { 394static struct map_desc pxa27x_io_desc[] __initdata = {
@@ -422,6 +424,7 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
422} 424}
423 425
424static struct platform_device *devices[] __initdata = { 426static struct platform_device *devices[] __initdata = {
427 &pxa_device_gpio,
425 &pxa27x_device_udc, 428 &pxa27x_device_udc,
426 &pxa_device_pmu, 429 &pxa_device_pmu,
427 &pxa_device_i2s, 430 &pxa_device_i2s,
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 40bb16501d8..0388eda7878 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -89,6 +89,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0);
89static struct clk_lookup common_clkregs[] = { 89static struct clk_lookup common_clkregs[] = {
90 INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), 90 INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL),
91 INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), 91 INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
92 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
92}; 93};
93 94
94static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); 95static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 8d614ecd8e9..d487e1ff4c9 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -83,6 +83,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0);
83static struct clk_lookup pxa320_clkregs[] = { 83static struct clk_lookup pxa320_clkregs[] = {
84 INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), 84 INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL),
85 INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), 85 INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
86 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
86}; 87};
87 88
88static int __init pxa320_init(void) 89static int __init pxa320_init(void)
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 0737c59b88a..f107c71c758 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -25,7 +25,6 @@
25#include <asm/mach/map.h> 25#include <asm/mach/map.h>
26#include <asm/suspend.h> 26#include <asm/suspend.h>
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/gpio-pxa.h>
29#include <mach/pxa3xx-regs.h> 28#include <mach/pxa3xx-regs.h>
30#include <mach/reset.h> 29#include <mach/reset.h>
31#include <mach/ohci.h> 30#include <mach/ohci.h>
@@ -56,6 +55,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0);
56static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0); 55static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0);
57static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0); 56static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0);
58static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); 57static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0);
58static DEFINE_PXA3_CKEN(pxa3xx_gpio, GPIO, 13000000, 0);
59 59
60static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops); 60static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
61static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops); 61static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops);
@@ -67,6 +67,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
67 INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), 67 INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
68 /* Power I2C clock is always on */ 68 /* Power I2C clock is always on */
69 INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), 69 INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
70 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
70 INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), 71 INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
71 INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), 72 INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
72 INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), 73 INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
@@ -88,6 +89,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
88 INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL), 89 INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
89 INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL), 90 INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
90 INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL), 91 INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
92 INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL),
91}; 93};
92 94
93#ifdef CONFIG_PM 95#ifdef CONFIG_PM
@@ -365,7 +367,8 @@ static struct irq_chip pxa_ext_wakeup_chip = {
365 .irq_set_type = pxa_set_ext_wakeup_type, 367 .irq_set_type = pxa_set_ext_wakeup_type,
366}; 368};
367 369
368static void __init pxa_init_ext_wakeup_irq(set_wake_t fn) 370static void __init pxa_init_ext_wakeup_irq(int (*fn)(struct irq_data *,
371 unsigned int))
369{ 372{
370 int irq; 373 int irq;
371 374
@@ -388,7 +391,6 @@ void __init pxa3xx_init_irq(void)
388 391
389 pxa_init_irq(56, pxa3xx_set_wake); 392 pxa_init_irq(56, pxa3xx_set_wake);
390 pxa_init_ext_wakeup_irq(pxa3xx_set_wake); 393 pxa_init_ext_wakeup_irq(pxa3xx_set_wake);
391 pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
392} 394}
393 395
394static struct map_desc pxa3xx_io_desc[] __initdata = { 396static struct map_desc pxa3xx_io_desc[] __initdata = {
@@ -417,6 +419,7 @@ void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
417} 419}
418 420
419static struct platform_device *devices[] __initdata = { 421static struct platform_device *devices[] __initdata = {
422 &pxa_device_gpio,
420 &pxa27x_device_udc, 423 &pxa27x_device_udc,
421 &pxa_device_pmu, 424 &pxa_device_pmu,
422 &pxa_device_i2s, 425 &pxa_device_i2s,
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
index 51371b39d2a..fccc644702e 100644
--- a/arch/arm/mach-pxa/pxa95x.c
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -20,7 +20,6 @@
20#include <linux/syscore_ops.h> 20#include <linux/syscore_ops.h>
21 21
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <mach/gpio-pxa.h>
24#include <mach/pxa3xx-regs.h> 23#include <mach/pxa3xx-regs.h>
25#include <mach/pxa930.h> 24#include <mach/pxa930.h>
26#include <mach/reset.h> 25#include <mach/reset.h>
@@ -212,11 +211,13 @@ static DEFINE_PXA3_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
212static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0); 211static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
213static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0); 212static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
214static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0); 213static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0);
214static DEFINE_PXA3_CKEN(pxa95x_gpio, GPIO, 13000000, 0);
215 215
216static struct clk_lookup pxa95x_clkregs[] = { 216static struct clk_lookup pxa95x_clkregs[] = {
217 INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"), 217 INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
218 /* Power I2C clock is always on */ 218 /* Power I2C clock is always on */
219 INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), 219 INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
220 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
220 INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL), 221 INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
221 INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL), 222 INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
222 INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL), 223 INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
@@ -230,12 +231,12 @@ static struct clk_lookup pxa95x_clkregs[] = {
230 INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL), 231 INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL),
231 INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL), 232 INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
232 INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL), 233 INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
234 INIT_CLKREG(&clk_pxa95x_gpio, "pxa-gpio", NULL),
233}; 235};
234 236
235void __init pxa95x_init_irq(void) 237void __init pxa95x_init_irq(void)
236{ 238{
237 pxa_init_irq(96, NULL); 239 pxa_init_irq(96, NULL);
238 pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
239} 240}
240 241
241/* 242/*
@@ -248,6 +249,7 @@ void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
248} 249}
249 250
250static struct platform_device *devices[] __initdata = { 251static struct platform_device *devices[] __initdata = {
252 &pxa_device_gpio,
251 &sa1100_device_rtc, 253 &sa1100_device_rtc,
252 &pxa_device_rtc, 254 &pxa_device_rtc,
253 &pxa27x_device_ssp1, 255 &pxa27x_device_ssp1,
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 4962b167662..22818c7694a 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -292,8 +292,8 @@ static struct resource smc91x_resources[] = {
292 .flags = IORESOURCE_MEM, 292 .flags = IORESOURCE_MEM,
293 }, 293 },
294 { 294 {
295 .start = gpio_to_irq(GPIO_ETH_IRQ), 295 .start = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ),
296 .end = gpio_to_irq(GPIO_ETH_IRQ), 296 .end = PXA_GPIO_TO_IRQ(GPIO_ETH_IRQ),
297 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, 297 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
298 } 298 }
299}; 299};
@@ -672,7 +672,7 @@ static struct lis3lv02d_platform_data lis3_pdata = {
672 .chip_select = 1, \ 672 .chip_select = 1, \
673 .controller_data = (void *) GPIO_ACCEL_CS, \ 673 .controller_data = (void *) GPIO_ACCEL_CS, \
674 .platform_data = &lis3_pdata, \ 674 .platform_data = &lis3_pdata, \
675 .irq = gpio_to_irq(GPIO_ACCEL_IRQ), \ 675 .irq = PXA_GPIO_TO_IRQ(GPIO_ACCEL_IRQ), \
676} 676}
677 677
678#define SPI_DAC7512 \ 678#define SPI_DAC7512 \
@@ -956,7 +956,7 @@ static struct eeti_ts_platform_data eeti_ts_pdata = {
956static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { 956static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
957 .type = "eeti_ts", 957 .type = "eeti_ts",
958 .addr = 0x0a, 958 .addr = 0x0a,
959 .irq = gpio_to_irq(GPIO_TOUCH_IRQ), 959 .irq = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ),
960 .platform_data = &eeti_ts_pdata, 960 .platform_data = &eeti_ts_pdata,
961}; 961};
962 962
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 878707056e6..0fe354efb93 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -96,8 +96,8 @@ static struct resource smc91x_resources[] = {
96 .flags = IORESOURCE_MEM, 96 .flags = IORESOURCE_MEM,
97 }, 97 },
98 [1] = { 98 [1] = {
99 .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), 99 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
100 .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)), 100 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO97)),
101 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 101 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
102 } 102 }
103}; 103};
@@ -502,7 +502,7 @@ static struct i2c_board_info saar_i2c_info[] = {
502 .type = "da9034", 502 .type = "da9034",
503 .addr = 0x34, 503 .addr = 0x34,
504 .platform_data = &saar_da9034_info, 504 .platform_data = &saar_da9034_info,
505 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), 505 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)),
506 }, 506 },
507}; 507};
508 508
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
index b6dbaca460c..febc809ed5a 100644
--- a/arch/arm/mach-pxa/saarb.c
+++ b/arch/arm/mach-pxa/saarb.c
@@ -92,7 +92,7 @@ static struct i2c_board_info saarb_i2c_info[] = {
92 .type = "88PM860x", 92 .type = "88PM860x",
93 .addr = 0x34, 93 .addr = 0x34,
94 .platform_data = &saarb_pm8607_info, 94 .platform_data = &saarb_pm8607_info,
95 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), 95 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)),
96 }, 96 },
97}; 97};
98 98
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 785880f67b6..8d5168d253a 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -907,24 +907,24 @@ static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
907 gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock); 907 gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock);
908 908
909 /* Register interrupt handlers */ 909 /* Register interrupt handlers */
910 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) { 910 if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) {
911 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin)); 911 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin));
912 } 912 }
913 913
914 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) { 914 if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) {
915 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock)); 915 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock));
916 } 916 }
917 917
918 if (sharpsl_pm.machinfo->gpio_fatal) { 918 if (sharpsl_pm.machinfo->gpio_fatal) {
919 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) { 919 if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) {
920 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal)); 920 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal));
921 } 921 }
922 } 922 }
923 923
924 if (sharpsl_pm.machinfo->batfull_irq) { 924 if (sharpsl_pm.machinfo->batfull_irq) {
925 /* Register interrupt handler. */ 925 /* Register interrupt handler. */
926 if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) { 926 if (request_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
927 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull)); 927 dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull));
928 } 928 }
929 } 929 }
930 930
@@ -953,14 +953,14 @@ static int sharpsl_pm_remove(struct platform_device *pdev)
953 953
954 led_trigger_unregister_simple(sharpsl_charge_led_trigger); 954 led_trigger_unregister_simple(sharpsl_charge_led_trigger);
955 955
956 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); 956 free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
957 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); 957 free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
958 958
959 if (sharpsl_pm.machinfo->gpio_fatal) 959 if (sharpsl_pm.machinfo->gpio_fatal)
960 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr); 960 free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
961 961
962 if (sharpsl_pm.machinfo->batfull_irq) 962 if (sharpsl_pm.machinfo->batfull_irq)
963 free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); 963 free_irq(PXA_GPIO_TO_IRQ(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
964 964
965 gpio_free(sharpsl_pm.machinfo->gpio_batlock); 965 gpio_free(sharpsl_pm.machinfo->gpio_batlock);
966 gpio_free(sharpsl_pm.machinfo->gpio_batfull); 966 gpio_free(sharpsl_pm.machinfo->gpio_batfull);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index a7f81a3fd13..abf355d0c92 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -552,7 +552,7 @@ static struct spi_board_info spitz_spi_devices[] = {
552 .chip_select = 0, 552 .chip_select = 0,
553 .platform_data = &spitz_ads7846_info, 553 .platform_data = &spitz_ads7846_info,
554 .controller_data = &spitz_ads7846_chip, 554 .controller_data = &spitz_ads7846_chip,
555 .irq = gpio_to_irq(SPITZ_GPIO_TP_INT), 555 .irq = PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
556 }, { 556 }, {
557 .modalias = "corgi-lcd", 557 .modalias = "corgi-lcd",
558 .max_speed_hz = 50000, 558 .max_speed_hz = 50000,
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 094279aefe9..34cbdac5152 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/gpio.h> 17#include <linux/gpio.h>
18#include <linux/gpio-pxa.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/apm-emulation.h> 21#include <linux/apm-emulation.h>
@@ -41,6 +42,7 @@ static int spitz_last_ac_status;
41static struct gpio spitz_charger_gpios[] = { 42static struct gpio spitz_charger_gpios[] = {
42 { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" }, 43 { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" },
43 { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" }, 44 { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" },
45 { SPITZ_GPIO_AC_IN, GPIOF_IN, "Charger Detection" },
44 { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" }, 46 { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
45 { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" }, 47 { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" },
46 { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" }, 48 { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
@@ -169,14 +171,19 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm)
169 171
170static unsigned long spitz_charger_wakeup(void) 172static unsigned long spitz_charger_wakeup(void)
171{ 173{
172 return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC)); 174 unsigned long ret;
175 ret = (!gpio_get_value(SPITZ_GPIO_KEY_INT)
176 << GPIO_bit(SPITZ_GPIO_KEY_INT))
177 | (!gpio_get_value(SPITZ_GPIO_SYNC)
178 << GPIO_bit(SPITZ_GPIO_SYNC));
179 return ret;
173} 180}
174 181
175unsigned long spitzpm_read_devdata(int type) 182unsigned long spitzpm_read_devdata(int type)
176{ 183{
177 switch (type) { 184 switch (type) {
178 case SHARPSL_STATUS_ACIN: 185 case SHARPSL_STATUS_ACIN:
179 return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0); 186 return !gpio_get_value(SPITZ_GPIO_AC_IN);
180 case SHARPSL_STATUS_LOCK: 187 case SHARPSL_STATUS_LOCK:
181 return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock); 188 return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
182 case SHARPSL_STATUS_CHRGFULL: 189 case SHARPSL_STATUS_CHRGFULL:
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 80d7f23ad0f..d8a2467de92 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -376,7 +376,7 @@ static struct spi_board_info spi_board_info[] __initdata = {
376 .bus_num = 1, 376 .bus_num = 1,
377 .chip_select = 0, 377 .chip_select = 0,
378 .controller_data = &staccel_chip_info, 378 .controller_data = &staccel_chip_info,
379 .irq = IRQ_GPIO(96), 379 .irq = PXA_GPIO_TO_IRQ(96),
380 }, { 380 }, {
381 .modalias = "cc2420", 381 .modalias = "cc2420",
382 .max_speed_hz = 6500000, 382 .max_speed_hz = 6500000,
@@ -546,7 +546,7 @@ static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = {
546 .type = "da9030", 546 .type = "da9030",
547 .addr = 0x49, 547 .addr = 0x49,
548 .platform_data = &imote2_da9030_pdata, 548 .platform_data = &imote2_da9030_pdata,
549 .irq = gpio_to_irq(1), 549 .irq = PXA_GPIO_TO_IRQ(1),
550 }, 550 },
551}; 551};
552 552
@@ -560,18 +560,18 @@ static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
560 /* Through a nand gate - Also beware, on V2 sensor board the 560 /* Through a nand gate - Also beware, on V2 sensor board the
561 * pull up resistors are missing. 561 * pull up resistors are missing.
562 */ 562 */
563 .irq = IRQ_GPIO(99), 563 .irq = PXA_GPIO_TO_IRQ(99),
564 }, { /* ITS400 Sensor board only */ 564 }, { /* ITS400 Sensor board only */
565 .type = "tsl2561", 565 .type = "tsl2561",
566 .addr = 0x49, 566 .addr = 0x49,
567 /* Through a nand gate - Also beware, on V2 sensor board the 567 /* Through a nand gate - Also beware, on V2 sensor board the
568 * pull up resistors are missing. 568 * pull up resistors are missing.
569 */ 569 */
570 .irq = IRQ_GPIO(99), 570 .irq = PXA_GPIO_TO_IRQ(99),
571 }, { /* ITS400 Sensor board only */ 571 }, { /* ITS400 Sensor board only */
572 .type = "tmp175", 572 .type = "tmp175",
573 .addr = 0x4A, 573 .addr = 0x4A,
574 .irq = IRQ_GPIO(96), 574 .irq = PXA_GPIO_TO_IRQ(96),
575 }, { /* IMB400 Multimedia board */ 575 }, { /* IMB400 Multimedia board */
576 .type = "wm8940", 576 .type = "wm8940",
577 .addr = 0x1A, 577 .addr = 0x1A,
@@ -661,8 +661,8 @@ static struct resource smc91x_resources[] = {
661 .flags = IORESOURCE_MEM, 661 .flags = IORESOURCE_MEM,
662 }, 662 },
663 [1] = { 663 [1] = {
664 .start = IRQ_GPIO(40), 664 .start = PXA_GPIO_TO_IRQ(40),
665 .end = IRQ_GPIO(40), 665 .end = PXA_GPIO_TO_IRQ(40),
666 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 666 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
667 } 667 }
668}; 668};
@@ -707,7 +707,7 @@ static int stargate2_mci_init(struct device *dev,
707 } 707 }
708 gpio_direction_input(SG2_GPIO_nSD_DETECT); 708 gpio_direction_input(SG2_GPIO_nSD_DETECT);
709 709
710 err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), 710 err = request_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT),
711 stargate2_detect_int, 711 stargate2_detect_int,
712 IRQ_TYPE_EDGE_BOTH, 712 IRQ_TYPE_EDGE_BOTH,
713 "MMC card detect", 713 "MMC card detect",
@@ -738,7 +738,7 @@ static void stargate2_mci_setpower(struct device *dev, unsigned int vdd)
738 738
739static void stargate2_mci_exit(struct device *dev, void *data) 739static void stargate2_mci_exit(struct device *dev, void *data)
740{ 740{
741 free_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), data); 741 free_irq(PXA_GPIO_TO_IRQ(SG2_GPIO_nSD_DETECT), data);
742 gpio_free(SG2_SD_POWER_ENABLE); 742 gpio_free(SG2_SD_POWER_ENABLE);
743 gpio_free(SG2_GPIO_nSD_DETECT); 743 gpio_free(SG2_GPIO_nSD_DETECT);
744} 744}
@@ -913,7 +913,7 @@ static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
913 .type = "da9030", 913 .type = "da9030",
914 .addr = 0x49, 914 .addr = 0x49,
915 .platform_data = &stargate2_da9030_pdata, 915 .platform_data = &stargate2_da9030_pdata,
916 .irq = gpio_to_irq(1), 916 .irq = PXA_GPIO_TO_IRQ(1),
917 }, 917 },
918}; 918};
919 919
@@ -938,18 +938,18 @@ static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
938 /* Through a nand gate - Also beware, on V2 sensor board the 938 /* Through a nand gate - Also beware, on V2 sensor board the
939 * pull up resistors are missing. 939 * pull up resistors are missing.
940 */ 940 */
941 .irq = IRQ_GPIO(99), 941 .irq = PXA_GPIO_TO_IRQ(99),
942 }, { /* ITS400 Sensor board only */ 942 }, { /* ITS400 Sensor board only */
943 .type = "tsl2561", 943 .type = "tsl2561",
944 .addr = 0x49, 944 .addr = 0x49,
945 /* Through a nand gate - Also beware, on V2 sensor board the 945 /* Through a nand gate - Also beware, on V2 sensor board the
946 * pull up resistors are missing. 946 * pull up resistors are missing.
947 */ 947 */
948 .irq = IRQ_GPIO(99), 948 .irq = PXA_GPIO_TO_IRQ(99),
949 }, { /* ITS400 Sensor board only */ 949 }, { /* ITS400 Sensor board only */
950 .type = "tmp175", 950 .type = "tmp175",
951 .addr = 0x4A, 951 .addr = 0x4A,
952 .irq = IRQ_GPIO(96), 952 .irq = PXA_GPIO_TO_IRQ(96),
953 }, 953 },
954}; 954};
955 955
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 4fa36a3e383..9fb38e80e07 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -85,8 +85,8 @@ static struct resource smc91x_resources[] = {
85 .flags = IORESOURCE_MEM, 85 .flags = IORESOURCE_MEM,
86 }, 86 },
87 [1] = { 87 [1] = {
88 .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), 88 .start = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)),
89 .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)), 89 .end = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO47)),
90 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 90 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
91 } 91 }
92}; 92};
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c
index 8a22879f0bb..f7d9305cfd7 100644
--- a/arch/arm/mach-pxa/tavorevb3.c
+++ b/arch/arm/mach-pxa/tavorevb3.c
@@ -101,7 +101,7 @@ static struct i2c_board_info evb3_i2c_info[] = {
101 .type = "88PM860x", 101 .type = "88PM860x",
102 .addr = 0x34, 102 .addr = 0x34,
103 .platform_data = &evb3_pm8607_info, 103 .platform_data = &evb3_pm8607_info,
104 .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)), 104 .irq = PXA_GPIO_TO_IRQ(mfp_to_gpio(MFP_PIN_GPIO83)),
105 }, 105 },
106}; 106};
107 107
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index dfe40f8705a..7ce5c436cc4 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -404,8 +404,8 @@ static struct pda_power_pdata tosa_power_data = {
404static struct resource tosa_power_resource[] = { 404static struct resource tosa_power_resource[] = {
405 { 405 {
406 .name = "ac", 406 .name = "ac",
407 .start = gpio_to_irq(TOSA_GPIO_AC_IN), 407 .start = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
408 .end = gpio_to_irq(TOSA_GPIO_AC_IN), 408 .end = PXA_GPIO_TO_IRQ(TOSA_GPIO_AC_IN),
409 .flags = IORESOURCE_IRQ | 409 .flags = IORESOURCE_IRQ |
410 IORESOURCE_IRQ_HIGHEDGE | 410 IORESOURCE_IRQ_HIGHEDGE |
411 IORESOURCE_IRQ_LOWEDGE, 411 IORESOURCE_IRQ_LOWEDGE,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index afe2b749552..023d6ca789d 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -422,8 +422,8 @@ static struct resource smc91x_resources[] = {
422 .flags = IORESOURCE_MEM, 422 .flags = IORESOURCE_MEM,
423 }, 423 },
424 [1] = { 424 [1] = {
425 .start = gpio_to_irq(VIPER_ETH_GPIO), 425 .start = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO),
426 .end = gpio_to_irq(VIPER_ETH_GPIO), 426 .end = PXA_GPIO_TO_IRQ(VIPER_ETH_GPIO),
427 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 427 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
428 }, 428 },
429 [2] = { 429 [2] = {
@@ -546,7 +546,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
546 /* External UARTs */ 546 /* External UARTs */
547 { 547 {
548 .mapbase = VIPER_UARTA_PHYS, 548 .mapbase = VIPER_UARTA_PHYS,
549 .irq = gpio_to_irq(VIPER_UARTA_GPIO), 549 .irq = PXA_GPIO_TO_IRQ(VIPER_UARTA_GPIO),
550 .irqflags = IRQF_TRIGGER_RISING, 550 .irqflags = IRQF_TRIGGER_RISING,
551 .uartclk = 1843200, 551 .uartclk = 1843200,
552 .regshift = 1, 552 .regshift = 1,
@@ -556,7 +556,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
556 }, 556 },
557 { 557 {
558 .mapbase = VIPER_UARTB_PHYS, 558 .mapbase = VIPER_UARTB_PHYS,
559 .irq = gpio_to_irq(VIPER_UARTB_GPIO), 559 .irq = PXA_GPIO_TO_IRQ(VIPER_UARTB_GPIO),
560 .irqflags = IRQF_TRIGGER_RISING, 560 .irqflags = IRQF_TRIGGER_RISING,
561 .uartclk = 1843200, 561 .uartclk = 1843200,
562 .regshift = 1, 562 .regshift = 1,
@@ -596,8 +596,8 @@ static struct resource isp116x_resources[] = {
596 .flags = IORESOURCE_MEM, 596 .flags = IORESOURCE_MEM,
597 }, 597 },
598 [2] = { 598 [2] = {
599 .start = gpio_to_irq(VIPER_USB_GPIO), 599 .start = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO),
600 .end = gpio_to_irq(VIPER_USB_GPIO), 600 .end = PXA_GPIO_TO_IRQ(VIPER_USB_GPIO),
601 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 601 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
602 }, 602 },
603}; 603};
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index fed5fb08871..1f5cfa96f6d 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -395,8 +395,8 @@ static struct resource vpac270_dm9000_resources[] = {
395 .flags = IORESOURCE_MEM, 395 .flags = IORESOURCE_MEM,
396 }, 396 },
397 [2] = { 397 [2] = {
398 .start = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), 398 .start = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ),
399 .end = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ), 399 .end = PXA_GPIO_TO_IRQ(GPIO114_VPAC270_ETH_IRQ),
400 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 400 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
401 }, 401 },
402}; 402};
@@ -433,7 +433,7 @@ static pxa2xx_audio_ops_t vpac270_ac97_pdata = {
433}; 433};
434 434
435static struct ucb1400_pdata vpac270_ucb1400_pdata = { 435static struct ucb1400_pdata vpac270_ucb1400_pdata = {
436 .irq = IRQ_GPIO(GPIO113_VPAC270_TS_IRQ), 436 .irq = PXA_GPIO_TO_IRQ(GPIO113_VPAC270_TS_IRQ),
437}; 437};
438 438
439static struct platform_device vpac270_ucb1400_device = { 439static struct platform_device vpac270_ucb1400_device = {
@@ -610,8 +610,8 @@ static struct resource vpac270_ide_resources[] = {
610 .flags = IORESOURCE_DMA 610 .flags = IORESOURCE_DMA
611 }, 611 },
612 [3] = { /* IDE IRQ pin */ 612 [3] = { /* IDE IRQ pin */
613 .start = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), 613 .start = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ),
614 .end = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ), 614 .end = PXA_GPIO_TO_IRQ(GPIO36_VPAC270_IDE_IRQ),
615 .flags = IORESOURCE_IRQ 615 .flags = IORESOURCE_IRQ
616 } 616 }
617}; 617};
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index d75f66ab8c3..b6476848b56 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -573,7 +573,7 @@ static struct spi_board_info spi_board_info[] __initdata = {
573 .modalias = "libertas_spi", 573 .modalias = "libertas_spi",
574 .platform_data = &z2_lbs_pdata, 574 .platform_data = &z2_lbs_pdata,
575 .controller_data = &z2_lbs_chip_info, 575 .controller_data = &z2_lbs_chip_info,
576 .irq = gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ), 576 .irq = PXA_GPIO_TO_IRQ(GPIO36_ZIPITZ2_WIFI_IRQ),
577 .max_speed_hz = 13000000, 577 .max_speed_hz = 13000000,
578 .bus_num = 1, 578 .bus_num = 1,
579 .chip_select = 0, 579 .chip_select = 0,
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 9db35a7fcfc..a4dd1c34705 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -233,7 +233,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
233 /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */ 233 /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */
234 { /* COM1 */ 234 { /* COM1 */
235 .mapbase = 0x10000000, 235 .mapbase = 0x10000000,
236 .irq = gpio_to_irq(ZEUS_UARTA_GPIO), 236 .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTA_GPIO),
237 .irqflags = IRQF_TRIGGER_RISING, 237 .irqflags = IRQF_TRIGGER_RISING,
238 .uartclk = 14745600, 238 .uartclk = 14745600,
239 .regshift = 1, 239 .regshift = 1,
@@ -242,7 +242,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
242 }, 242 },
243 { /* COM2 */ 243 { /* COM2 */
244 .mapbase = 0x10800000, 244 .mapbase = 0x10800000,
245 .irq = gpio_to_irq(ZEUS_UARTB_GPIO), 245 .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTB_GPIO),
246 .irqflags = IRQF_TRIGGER_RISING, 246 .irqflags = IRQF_TRIGGER_RISING,
247 .uartclk = 14745600, 247 .uartclk = 14745600,
248 .regshift = 1, 248 .regshift = 1,
@@ -251,7 +251,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
251 }, 251 },
252 { /* COM3 */ 252 { /* COM3 */
253 .mapbase = 0x11000000, 253 .mapbase = 0x11000000,
254 .irq = gpio_to_irq(ZEUS_UARTC_GPIO), 254 .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTC_GPIO),
255 .irqflags = IRQF_TRIGGER_RISING, 255 .irqflags = IRQF_TRIGGER_RISING,
256 .uartclk = 14745600, 256 .uartclk = 14745600,
257 .regshift = 1, 257 .regshift = 1,
@@ -260,7 +260,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
260 }, 260 },
261 { /* COM4 */ 261 { /* COM4 */
262 .mapbase = 0x11800000, 262 .mapbase = 0x11800000,
263 .irq = gpio_to_irq(ZEUS_UARTD_GPIO), 263 .irq = PXA_GPIO_TO_IRQ(ZEUS_UARTD_GPIO),
264 .irqflags = IRQF_TRIGGER_RISING, 264 .irqflags = IRQF_TRIGGER_RISING,
265 .uartclk = 14745600, 265 .uartclk = 14745600,
266 .regshift = 1, 266 .regshift = 1,
@@ -321,8 +321,8 @@ static struct resource zeus_dm9k0_resource[] = {
321 .flags = IORESOURCE_MEM 321 .flags = IORESOURCE_MEM
322 }, 322 },
323 [2] = { 323 [2] = {
324 .start = gpio_to_irq(ZEUS_ETH0_GPIO), 324 .start = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO),
325 .end = gpio_to_irq(ZEUS_ETH0_GPIO), 325 .end = PXA_GPIO_TO_IRQ(ZEUS_ETH0_GPIO),
326 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, 326 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
327 }, 327 },
328}; 328};
@@ -339,8 +339,8 @@ static struct resource zeus_dm9k1_resource[] = {
339 .flags = IORESOURCE_MEM, 339 .flags = IORESOURCE_MEM,
340 }, 340 },
341 [2] = { 341 [2] = {
342 .start = gpio_to_irq(ZEUS_ETH1_GPIO), 342 .start = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO),
343 .end = gpio_to_irq(ZEUS_ETH1_GPIO), 343 .end = PXA_GPIO_TO_IRQ(ZEUS_ETH1_GPIO),
344 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, 344 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
345 }, 345 },
346}; 346};
@@ -423,7 +423,7 @@ static struct spi_board_info zeus_spi_board_info[] = {
423 [0] = { 423 [0] = {
424 .modalias = "mcp2515", 424 .modalias = "mcp2515",
425 .platform_data = &zeus_mcp2515_pdata, 425 .platform_data = &zeus_mcp2515_pdata,
426 .irq = gpio_to_irq(ZEUS_CAN_GPIO), 426 .irq = PXA_GPIO_TO_IRQ(ZEUS_CAN_GPIO),
427 .max_speed_hz = 1*1000*1000, 427 .max_speed_hz = 1*1000*1000,
428 .bus_num = 3, 428 .bus_num = 3,
429 .mode = SPI_MODE_0, 429 .mode = SPI_MODE_0,
@@ -753,7 +753,7 @@ static struct i2c_board_info __initdata zeus_i2c_devices[] = {
753 { 753 {
754 I2C_BOARD_INFO("pca9535", 0x20), 754 I2C_BOARD_INFO("pca9535", 0x20),
755 .platform_data = &zeus_pca953x_pdata[2], 755 .platform_data = &zeus_pca953x_pdata[2],
756 .irq = gpio_to_irq(ZEUS_EXTGPIO_GPIO), 756 .irq = PXA_GPIO_TO_IRQ(ZEUS_EXTGPIO_GPIO),
757 }, 757 },
758 { I2C_BOARD_INFO("lm75a", 0x48) }, 758 { I2C_BOARD_INFO("lm75a", 0x48) },
759 { I2C_BOARD_INFO("24c01", 0x50) }, 759 { I2C_BOARD_INFO("24c01", 0x50) },
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 7678b1bf790..98eec80623e 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -408,8 +408,8 @@ static void __init zylonite_init(void)
408 * Note: We depend that the bootloader set 408 * Note: We depend that the bootloader set
409 * the correct value to MSC register for SMC91x. 409 * the correct value to MSC register for SMC91x.
410 */ 410 */
411 smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq); 411 smc91x_resources[1].start = PXA_GPIO_TO_IRQ(gpio_eth_irq);
412 smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq); 412 smc91x_resources[1].end = PXA_GPIO_TO_IRQ(gpio_eth_irq);
413 platform_device_register(&smc91x_device); 413 platform_device_register(&smc91x_device);
414 414
415 pxa_set_ac97_info(NULL); 415 pxa_set_ac97_info(NULL);
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 93c64d8d7de..86e59c043de 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -231,12 +231,12 @@ static struct i2c_board_info zylonite_i2c_board_info[] = {
231 .type = "pca9539", 231 .type = "pca9539",
232 .addr = 0x74, 232 .addr = 0x74,
233 .platform_data = &gpio_exp[0], 233 .platform_data = &gpio_exp[0],
234 .irq = IRQ_GPIO(18), 234 .irq = PXA_GPIO_TO_IRQ(18),
235 }, { 235 }, {
236 .type = "pca9539", 236 .type = "pca9539",
237 .addr = 0x75, 237 .addr = 0x75,
238 .platform_data = &gpio_exp[1], 238 .platform_data = &gpio_exp[1],
239 .irq = IRQ_GPIO(19), 239 .irq = PXA_GPIO_TO_IRQ(19),
240 }, 240 },
241}; 241};
242 242
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index c6133c6ec18..feeaf73933d 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -165,22 +165,6 @@ static struct map_desc bast_iodesc[] __initdata = {
165#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 165#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
166#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 166#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
167 167
168static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
169 [0] = {
170 .name = "uclk",
171 .divisor = 1,
172 .min_baud = 0,
173 .max_baud = 0,
174 },
175 [1] = {
176 .name = "pclk",
177 .divisor = 1,
178 .min_baud = 0,
179 .max_baud = 0,
180 }
181};
182
183
184static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { 168static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
185 [0] = { 169 [0] = {
186 .hwport = 0, 170 .hwport = 0,
@@ -188,8 +172,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
188 .ucon = UCON, 172 .ucon = UCON,
189 .ulcon = ULCON, 173 .ulcon = ULCON,
190 .ufcon = UFCON, 174 .ufcon = UFCON,
191 .clocks = bast_serial_clocks,
192 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
193 }, 175 },
194 [1] = { 176 [1] = {
195 .hwport = 1, 177 .hwport = 1,
@@ -197,8 +179,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
197 .ucon = UCON, 179 .ucon = UCON,
198 .ulcon = ULCON, 180 .ulcon = ULCON,
199 .ufcon = UFCON, 181 .ufcon = UFCON,
200 .clocks = bast_serial_clocks,
201 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
202 }, 182 },
203 /* port 2 is not actually used */ 183 /* port 2 is not actually used */
204 [2] = { 184 [2] = {
@@ -207,8 +187,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
207 .ucon = UCON, 187 .ucon = UCON,
208 .ulcon = ULCON, 188 .ulcon = ULCON,
209 .ufcon = UFCON, 189 .ufcon = UFCON,
210 .clocks = bast_serial_clocks,
211 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
212 } 190 }
213}; 191};
214 192
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index cc7032b5c65..dbe668a803e 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -110,23 +110,6 @@ static struct map_desc vr1000_iodesc[] __initdata = {
110#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 110#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
111#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 111#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
112 112
113/* uart clock source(s) */
114
115static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
116 [0] = {
117 .name = "uclk",
118 .divisor = 1,
119 .min_baud = 0,
120 .max_baud = 0,
121 },
122 [1] = {
123 .name = "pclk",
124 .divisor = 1,
125 .min_baud = 0,
126 .max_baud = 0.
127 }
128};
129
130static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { 113static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
131 [0] = { 114 [0] = {
132 .hwport = 0, 115 .hwport = 0,
@@ -134,8 +117,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
134 .ucon = UCON, 117 .ucon = UCON,
135 .ulcon = ULCON, 118 .ulcon = ULCON,
136 .ufcon = UFCON, 119 .ufcon = UFCON,
137 .clocks = vr1000_serial_clocks,
138 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
139 }, 120 },
140 [1] = { 121 [1] = {
141 .hwport = 1, 122 .hwport = 1,
@@ -143,8 +124,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
143 .ucon = UCON, 124 .ucon = UCON,
144 .ulcon = ULCON, 125 .ulcon = ULCON,
145 .ufcon = UFCON, 126 .ufcon = UFCON,
146 .clocks = vr1000_serial_clocks,
147 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
148 }, 127 },
149 /* port 2 is not actually used */ 128 /* port 2 is not actually used */
150 [2] = { 129 [2] = {
@@ -153,9 +132,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
153 .ucon = UCON, 132 .ucon = UCON,
154 .ulcon = ULCON, 133 .ulcon = ULCON,
155 .ufcon = UFCON, 134 .ufcon = UFCON,
156 .clocks = vr1000_serial_clocks,
157 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
158
159 } 135 }
160}; 136};
161 137
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index eea559ec7a5..061b6bb1a55 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -124,12 +124,18 @@ static struct clk s3c2410_armclk = {
124 .id = -1, 124 .id = -1,
125}; 125};
126 126
127static struct clk_lookup s3c2410_clk_lookup[] = {
128 CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
129 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
130};
131
127void __init s3c2410_init_clocks(int xtal) 132void __init s3c2410_init_clocks(int xtal)
128{ 133{
129 s3c24xx_register_baseclocks(xtal); 134 s3c24xx_register_baseclocks(xtal);
130 s3c2410_setup_clocks(); 135 s3c2410_setup_clocks();
131 s3c2410_baseclk_add(); 136 s3c2410_baseclk_add();
132 s3c24xx_register_clock(&s3c2410_armclk); 137 s3c24xx_register_clock(&s3c2410_armclk);
138 clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
133} 139}
134 140
135struct bus_type s3c2410_subsys = { 141struct bus_type s3c2410_subsys = {
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 51688164080..d10b695a906 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = {
659 &clk_armclk, 659 &clk_armclk,
660}; 660};
661 661
662static struct clk_lookup s3c2412_clk_lookup[] = {
663 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
664 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
665 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
666};
667
662int __init s3c2412_baseclk_add(void) 668int __init s3c2412_baseclk_add(void)
663{ 669{
664 unsigned long clkcon = __raw_readl(S3C2410_CLKCON); 670 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
@@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void)
751 s3c2412_clkcon_enable(clkp, 0); 757 s3c2412_clkcon_enable(clkp, 0);
752 } 758 }
753 759
760 clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
754 s3c_pwmclk_init(); 761 s3c_pwmclk_init();
755 return 0; 762 return 0;
756} 763}
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
index 7b805b279ca..ca0cd227f87 100644
--- a/arch/arm/mach-s3c2416/Makefile
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_S3C2416_PM) += pm.o
15#obj-$(CONFIG_S3C2416_DMA) += dma.o 15#obj-$(CONFIG_S3C2416_DMA) += dma.o
16 16
17# Device setup 17# Device setup
18obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o
19obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 18obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
20 19
21# Machine support 20# Machine support
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index afbbe8bc21d..59f54d1d7f8 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -90,39 +90,38 @@ static struct clksrc_clk hsmmc_div[] = {
90 }, 90 },
91}; 91};
92 92
93static struct clksrc_clk hsmmc_mux[] = { 93static struct clksrc_clk hsmmc_mux0 = {
94 [0] = { 94 .clk = {
95 .clk = { 95 .name = "hsmmc-if",
96 .name = "hsmmc-if", 96 .devname = "s3c-sdhci.0",
97 .devname = "s3c-sdhci.0", 97 .ctrlbit = (1 << 6),
98 .ctrlbit = (1 << 6), 98 .enable = s3c2443_clkcon_enable_s,
99 .enable = s3c2443_clkcon_enable_s,
100 },
101 .sources = &(struct clksrc_sources) {
102 .nr_sources = 2,
103 .sources = (struct clk *[]) {
104 [0] = &hsmmc_div[0].clk,
105 [1] = NULL, /* to fix */
106 },
107 },
108 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
109 }, 99 },
110 [1] = { 100 .sources = &(struct clksrc_sources) {
111 .clk = { 101 .nr_sources = 2,
112 .name = "hsmmc-if", 102 .sources = (struct clk * []) {
113 .devname = "s3c-sdhci.1", 103 [0] = &hsmmc_div[0].clk,
114 .ctrlbit = (1 << 12), 104 [1] = NULL, /* to fix */
115 .enable = s3c2443_clkcon_enable_s,
116 }, 105 },
117 .sources = &(struct clksrc_sources) { 106 },
118 .nr_sources = 2, 107 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
119 .sources = (struct clk *[]) { 108};
120 [0] = &hsmmc_div[1].clk, 109
121 [1] = NULL, /* to fix */ 110static struct clksrc_clk hsmmc_mux1 = {
122 }, 111 .clk = {
112 .name = "hsmmc-if",
113 .devname = "s3c-sdhci.1",
114 .ctrlbit = (1 << 12),
115 .enable = s3c2443_clkcon_enable_s,
116 },
117 .sources = &(struct clksrc_sources) {
118 .nr_sources = 2,
119 .sources = (struct clk * []) {
120 [0] = &hsmmc_div[1].clk,
121 [1] = NULL, /* to fix */
123 }, 122 },
124 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
125 }, 123 },
124 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
126}; 125};
127 126
128static struct clk hsmmc0_clk = { 127static struct clk hsmmc0_clk = {
@@ -144,8 +143,14 @@ static struct clksrc_clk *clksrcs[] __initdata = {
144 &hsspi_mux, 143 &hsspi_mux,
145 &hsmmc_div[0], 144 &hsmmc_div[0],
146 &hsmmc_div[1], 145 &hsmmc_div[1],
147 &hsmmc_mux[0], 146 &hsmmc_mux0,
148 &hsmmc_mux[1], 147 &hsmmc_mux1,
148};
149
150static struct clk_lookup s3c2416_clk_lookup[] = {
151 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
152 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
153 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
149}; 154};
150 155
151void __init s3c2416_init_clocks(int xtal) 156void __init s3c2416_init_clocks(int xtal)
@@ -167,6 +172,7 @@ void __init s3c2416_init_clocks(int xtal)
167 s3c_register_clksrc(clksrcs[ptr], 1); 172 s3c_register_clksrc(clksrcs[ptr], 1);
168 173
169 s3c24xx_register_clock(&hsmmc0_clk); 174 s3c24xx_register_clock(&hsmmc0_clk);
175 clkdev_add_table(s3c2416_clk_lookup, ARRAY_SIZE(s3c2416_clk_lookup));
170 176
171 s3c_pwmclk_init(); 177 s3c_pwmclk_init();
172 178
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
index 66b71736609..eebe1e72b93 100644
--- a/arch/arm/mach-s3c2416/mach-smdk2416.c
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -50,6 +50,7 @@
50#include <plat/nand.h> 50#include <plat/nand.h>
51#include <plat/sdhci.h> 51#include <plat/sdhci.h>
52#include <plat/udc.h> 52#include <plat/udc.h>
53#include <linux/platform_data/s3c-hsudc.h>
53 54
54#include <plat/regs-fb-v4.h> 55#include <plat/regs-fb-v4.h>
55#include <plat/fb.h> 56#include <plat/fb.h>
diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c
deleted file mode 100644
index cee53955eb0..00000000000
--- a/arch/arm/mach-s3c2416/setup-sdhci.c
+++ /dev/null
@@ -1,24 +0,0 @@
1/* linux/arch/arm/mach-s3c2416/setup-sdhci.c
2 *
3 * Copyright 2010 Promwad Innovation Company
4 * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
5 *
6 * S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * Based on mach-s3c64xx/setup-sdhci.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/types.h>
16
17/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
18
19char *s3c2416_hsmmc_clksrcs[4] = {
20 [0] = "hsmmc",
21 [1] = "hsmmc",
22 [2] = "hsmmc-if",
23 /* [3] = "48m", - note not successfully used yet */
24};
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index d8957592fdc..bedbc87a342 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -33,6 +33,7 @@
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/clk.h> 34#include <linux/clk.h>
35#include <linux/io.h> 35#include <linux/io.h>
36#include <linux/serial_core.h>
36 37
37#include <mach/hardware.h> 38#include <mach/hardware.h>
38#include <linux/atomic.h> 39#include <linux/atomic.h>
@@ -42,6 +43,7 @@
42 43
43#include <plat/clock.h> 44#include <plat/clock.h>
44#include <plat/cpu.h> 45#include <plat/cpu.h>
46#include <plat/regs-serial.h>
45 47
46/* S3C2440 extended clock support */ 48/* S3C2440 extended clock support */
47 49
@@ -107,6 +109,46 @@ static struct clk s3c2440_clk_ac97 = {
107 .ctrlbit = S3C2440_CLKCON_CAMERA, 109 .ctrlbit = S3C2440_CLKCON_CAMERA,
108}; 110};
109 111
112static unsigned long s3c2440_fclk_n_getrate(struct clk *clk)
113{
114 unsigned long ucon0, ucon1, ucon2, divisor;
115
116 /* the fun of calculating the uart divisors on the s3c2440 */
117 ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
118 ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
119 ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
120
121 ucon0 &= S3C2440_UCON0_DIVMASK;
122 ucon1 &= S3C2440_UCON1_DIVMASK;
123 ucon2 &= S3C2440_UCON2_DIVMASK;
124
125 if (ucon0 != 0)
126 divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
127 else if (ucon1 != 0)
128 divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
129 else if (ucon2 != 0)
130 divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
131 else
132 /* manual calims 44, seems to be 9 */
133 divisor = 9;
134
135 return clk_get_rate(clk->parent) / divisor;
136}
137
138static struct clk s3c2440_clk_fclk_n = {
139 .name = "fclk_n",
140 .parent = &clk_f,
141 .ops = &(struct clk_ops) {
142 .get_rate = s3c2440_fclk_n_getrate,
143 },
144};
145
146static struct clk_lookup s3c2440_clk_lookup[] = {
147 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
148 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
149 CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
150};
151
110static int s3c2440_clk_add(struct device *dev) 152static int s3c2440_clk_add(struct device *dev)
111{ 153{
112 struct clk *clock_upll; 154 struct clk *clock_upll;
@@ -125,10 +167,12 @@ static int s3c2440_clk_add(struct device *dev)
125 s3c2440_clk_cam.parent = clock_h; 167 s3c2440_clk_cam.parent = clock_h;
126 s3c2440_clk_ac97.parent = clock_p; 168 s3c2440_clk_ac97.parent = clock_p;
127 s3c2440_clk_cam_upll.parent = clock_upll; 169 s3c2440_clk_cam_upll.parent = clock_upll;
170 s3c24xx_register_clock(&s3c2440_clk_fclk_n);
128 171
129 s3c24xx_register_clock(&s3c2440_clk_ac97); 172 s3c24xx_register_clock(&s3c2440_clk_ac97);
130 s3c24xx_register_clock(&s3c2440_clk_cam); 173 s3c24xx_register_clock(&s3c2440_clk_cam);
131 s3c24xx_register_clock(&s3c2440_clk_cam_upll); 174 s3c24xx_register_clock(&s3c2440_clk_cam_upll);
175 clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
132 176
133 clk_disable(&s3c2440_clk_ac97); 177 clk_disable(&s3c2440_clk_ac97);
134 clk_disable(&s3c2440_clk_cam); 178 clk_disable(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 121ff8d2c88..24569550de1 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -98,22 +98,6 @@ static struct map_desc anubis_iodesc[] __initdata = {
98#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 98#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
99#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 99#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
100 100
101static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
102 [0] = {
103 .name = "uclk",
104 .divisor = 1,
105 .min_baud = 0,
106 .max_baud = 0,
107 },
108 [1] = {
109 .name = "pclk",
110 .divisor = 1,
111 .min_baud = 0,
112 .max_baud = 0,
113 }
114};
115
116
117static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { 101static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
118 [0] = { 102 [0] = {
119 .hwport = 0, 103 .hwport = 0,
@@ -121,8 +105,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
121 .ucon = UCON, 105 .ucon = UCON,
122 .ulcon = ULCON, 106 .ulcon = ULCON,
123 .ufcon = UFCON, 107 .ufcon = UFCON,
124 .clocks = anubis_serial_clocks, 108 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
125 .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
126 }, 109 },
127 [1] = { 110 [1] = {
128 .hwport = 2, 111 .hwport = 2,
@@ -130,8 +113,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
130 .ucon = UCON, 113 .ucon = UCON,
131 .ulcon = ULCON, 114 .ulcon = ULCON,
132 .ufcon = UFCON, 115 .ufcon = UFCON,
133 .clocks = anubis_serial_clocks, 116 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
134 .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
135 }, 117 },
136}; 118};
137 119
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index b7e334f07da..d6a9763110c 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -59,22 +59,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = {
59#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) 59#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
60#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) 60#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
61 61
62static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
63 [0] = {
64 .name = "uclk",
65 .divisor = 1,
66 .min_baud = 0,
67 .max_baud = 0,
68 },
69 [1] = {
70 .name = "pclk",
71 .divisor = 1,
72 .min_baud = 0,
73 .max_baud = 0,
74 }
75};
76
77
78static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { 62static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
79 [0] = { 63 [0] = {
80 .hwport = 0, 64 .hwport = 0,
@@ -82,8 +66,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
82 .ucon = UCON, 66 .ucon = UCON,
83 .ulcon = ULCON, 67 .ulcon = ULCON,
84 .ufcon = UFCON, 68 .ufcon = UFCON,
85 .clocks = at2440evb_serial_clocks, 69 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
86 .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
87 }, 70 },
88 [1] = { 71 [1] = {
89 .hwport = 1, 72 .hwport = 1,
@@ -91,8 +74,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
91 .ucon = UCON, 74 .ucon = UCON,
92 .ulcon = ULCON, 75 .ulcon = ULCON,
93 .ufcon = UFCON, 76 .ufcon = UFCON,
94 .clocks = at2440evb_serial_clocks, 77 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
95 .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
96 }, 78 },
97}; 79};
98 80
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
index 437322ffd88..adbbb85bc4c 100644
--- a/arch/arm/mach-s3c2440/mach-mini2440.c
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -169,6 +169,24 @@ static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
169 .lcdcon5 = (S3C2410_LCDCON5_FRM565 | 169 .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
170 S3C2410_LCDCON5_HWSWP), 170 S3C2410_LCDCON5_HWSWP),
171 }, 171 },
172 /* mini2440 + 3.5" TFT (LCD-W35i, LQ035Q1DG06 type) + touchscreen*/
173 [3] = {
174 _LCD_DECLARE(
175 /* clock */
176 7,
177 /* xres, margin_right, margin_left, hsync */
178 320, 68, 66, 4,
179 /* yres, margin_top, margin_bottom, vsync */
180 240, 4, 4, 9,
181 /* refresh rate */
182 60),
183 .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
184 S3C2410_LCDCON5_INVVDEN |
185 S3C2410_LCDCON5_INVVFRAME |
186 S3C2410_LCDCON5_INVVLINE |
187 S3C2410_LCDCON5_INVVCLK |
188 S3C2410_LCDCON5_HWSWP),
189 },
172}; 190};
173 191
174/* todo - put into gpio header */ 192/* todo - put into gpio header */
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index e795715fba3..4c480ef734f 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -102,21 +102,6 @@ static struct map_desc osiris_iodesc[] __initdata = {
102#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 102#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
103#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 103#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
104 104
105static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
106 [0] = {
107 .name = "uclk",
108 .divisor = 1,
109 .min_baud = 0,
110 .max_baud = 0,
111 },
112 [1] = {
113 .name = "pclk",
114 .divisor = 1,
115 .min_baud = 0,
116 .max_baud = 0,
117 }
118};
119
120static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { 105static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
121 [0] = { 106 [0] = {
122 .hwport = 0, 107 .hwport = 0,
@@ -124,8 +109,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
124 .ucon = UCON, 109 .ucon = UCON,
125 .ulcon = ULCON, 110 .ulcon = ULCON,
126 .ufcon = UFCON, 111 .ufcon = UFCON,
127 .clocks = osiris_serial_clocks, 112 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
128 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
129 }, 113 },
130 [1] = { 114 [1] = {
131 .hwport = 1, 115 .hwport = 1,
@@ -133,8 +117,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
133 .ucon = UCON, 117 .ucon = UCON,
134 .ulcon = ULCON, 118 .ulcon = ULCON,
135 .ufcon = UFCON, 119 .ufcon = UFCON,
136 .clocks = osiris_serial_clocks, 120 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
137 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
138 }, 121 },
139 [2] = { 122 [2] = {
140 .hwport = 2, 123 .hwport = 2,
@@ -142,8 +125,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
142 .ucon = UCON, 125 .ucon = UCON,
143 .ulcon = ULCON, 126 .ulcon = ULCON,
144 .ufcon = UFCON, 127 .ufcon = UFCON,
145 .clocks = osiris_serial_clocks, 128 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
146 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
147 } 129 }
148}; 130};
149 131
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 332d7533bd9..80077f6472e 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -70,15 +70,6 @@
70static struct map_desc rx1950_iodesc[] __initdata = { 70static struct map_desc rx1950_iodesc[] __initdata = {
71}; 71};
72 72
73static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
74 [0] = {
75 .name = "fclk",
76 .divisor = 0x0a,
77 .min_baud = 0,
78 .max_baud = 0,
79 },
80};
81
82static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { 73static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
83 [0] = { 74 [0] = {
84 .hwport = 0, 75 .hwport = 0,
@@ -86,8 +77,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
86 .ucon = 0x3c5, 77 .ucon = 0x3c5,
87 .ulcon = 0x03, 78 .ulcon = 0x03,
88 .ufcon = 0x51, 79 .ufcon = 0x51,
89 .clocks = rx1950_serial_clocks, 80 .clk_sel = S3C2410_UCON_CLKSEL3,
90 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
91 }, 81 },
92 [1] = { 82 [1] = {
93 .hwport = 1, 83 .hwport = 1,
@@ -95,8 +85,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
95 .ucon = 0x3c5, 85 .ucon = 0x3c5,
96 .ulcon = 0x03, 86 .ulcon = 0x03,
97 .ufcon = 0x51, 87 .ufcon = 0x51,
98 .clocks = rx1950_serial_clocks, 88 .clk_sel = S3C2410_UCON_CLKSEL3,
99 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
100 }, 89 },
101 /* IR port */ 90 /* IR port */
102 [2] = { 91 [2] = {
@@ -105,8 +94,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
105 .ucon = 0x3c5, 94 .ucon = 0x3c5,
106 .ulcon = 0x43, 95 .ulcon = 0x43,
107 .ufcon = 0xf1, 96 .ufcon = 0xf1,
108 .clocks = rx1950_serial_clocks, 97 .clk_sel = S3C2410_UCON_CLKSEL3,
109 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
110 }, 98 },
111}; 99};
112 100
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 80a0972873c..20103bafbd4 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -69,16 +69,6 @@ static struct map_desc rx3715_iodesc[] __initdata = {
69 }, 69 },
70}; 70};
71 71
72
73static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
74 [0] = {
75 .name = "fclk",
76 .divisor = 0,
77 .min_baud = 0,
78 .max_baud = 0,
79 }
80};
81
82static struct s3c2410_uartcfg rx3715_uartcfgs[] = { 72static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
83 [0] = { 73 [0] = {
84 .hwport = 0, 74 .hwport = 0,
@@ -86,8 +76,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
86 .ucon = 0x3c5, 76 .ucon = 0x3c5,
87 .ulcon = 0x03, 77 .ulcon = 0x03,
88 .ufcon = 0x51, 78 .ufcon = 0x51,
89 .clocks = rx3715_serial_clocks, 79 .clk_sel = S3C2410_UCON_CLKSEL3,
90 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
91 }, 80 },
92 [1] = { 81 [1] = {
93 .hwport = 1, 82 .hwport = 1,
@@ -95,8 +84,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
95 .ucon = 0x3c5, 84 .ucon = 0x3c5,
96 .ulcon = 0x03, 85 .ulcon = 0x03,
97 .ufcon = 0x00, 86 .ufcon = 0x00,
98 .clocks = rx3715_serial_clocks, 87 .clk_sel = S3C2410_UCON_CLKSEL3,
99 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
100 }, 88 },
101 /* IR port */ 89 /* IR port */
102 [2] = { 90 [2] = {
@@ -105,8 +93,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
105 .ucon = 0x3c5, 93 .ucon = 0x3c5,
106 .ulcon = 0x43, 94 .ulcon = 0x43,
107 .ufcon = 0x51, 95 .ufcon = 0x51,
108 .clocks = rx3715_serial_clocks, 96 .clk_sel = S3C2410_UCON_CLKSEL3,
109 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
110 } 97 }
111}; 98};
112 99
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 381586c7b1b..dd20c66cd70 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -78,6 +78,11 @@ config S3C64XX_SETUP_SDHCI_GPIO
78 help 78 help
79 Common setup code for S3C64XX SDHCI GPIO configurations 79 Common setup code for S3C64XX SDHCI GPIO configurations
80 80
81config S3C64XX_SETUP_SPI
82 bool
83 help
84 Common setup code for SPI GPIO configurations
85
81# S36400 Macchine support 86# S36400 Macchine support
82 87
83config MACH_SMDK6400 88config MACH_SMDK6400
@@ -189,7 +194,7 @@ config SMDK6410_WM1190_EV1
189 depends on MACH_SMDK6410 194 depends on MACH_SMDK6410
190 select REGULATOR 195 select REGULATOR
191 select REGULATOR_WM8350 196 select REGULATOR_WM8350
192 select S3C24XX_GPIO_EXTRA64 197 select SAMSUNG_GPIO_EXTRA64
193 select MFD_WM8350_I2C 198 select MFD_WM8350_I2C
194 select MFD_WM8350_CONFIG_MODE_0 199 select MFD_WM8350_CONFIG_MODE_0
195 select MFD_WM8350_CONFIG_MODE_3 200 select MFD_WM8350_CONFIG_MODE_3
@@ -207,7 +212,7 @@ config SMDK6410_WM1192_EV1
207 depends on MACH_SMDK6410 212 depends on MACH_SMDK6410
208 select REGULATOR 213 select REGULATOR
209 select REGULATOR_WM831X 214 select REGULATOR_WM831X
210 select S3C24XX_GPIO_EXTRA64 215 select SAMSUNG_GPIO_EXTRA64
211 select MFD_WM831X 216 select MFD_WM831X
212 select MFD_WM831X_I2C 217 select MFD_WM831X_I2C
213 help 218 help
@@ -277,6 +282,7 @@ config MACH_WLF_CRAGG_6410
277 select S3C64XX_SETUP_IDE 282 select S3C64XX_SETUP_IDE
278 select S3C64XX_SETUP_FB_24BPP 283 select S3C64XX_SETUP_FB_24BPP
279 select S3C64XX_SETUP_KEYPAD 284 select S3C64XX_SETUP_KEYPAD
285 select S3C64XX_SETUP_SPI
280 select SAMSUNG_DEV_ADC 286 select SAMSUNG_DEV_ADC
281 select SAMSUNG_DEV_KEYPAD 287 select SAMSUNG_DEV_KEYPAD
282 select S3C_DEV_USB_HOST 288 select S3C_DEV_USB_HOST
@@ -287,8 +293,8 @@ config MACH_WLF_CRAGG_6410
287 select S3C_DEV_I2C1 293 select S3C_DEV_I2C1
288 select S3C_DEV_WDT 294 select S3C_DEV_WDT
289 select S3C_DEV_RTC 295 select S3C_DEV_RTC
290 select S3C64XX_DEV_SPI 296 select S3C64XX_DEV_SPI0
291 select S3C24XX_GPIO_EXTRA128 297 select SAMSUNG_GPIO_EXTRA128
292 select I2C 298 select I2C
293 help 299 help
294 Machine support for the Wolfson Cragganmore S3C6410 variant. 300 Machine support for the Wolfson Cragganmore S3C6410 variant.
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index f37016cebbe..1822ac2eba3 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -40,8 +40,8 @@ obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
40obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o 40obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
41obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o 41obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
42obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o 42obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
43obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
44obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 43obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
44obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
45 45
46# Machine support 46# Machine support
47 47
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 625219b9cef..31bb27dc4ae 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -184,18 +184,6 @@ static struct clk init_clocks_off[] = {
184 .enable = s3c64xx_pclk_ctrl, 184 .enable = s3c64xx_pclk_ctrl,
185 .ctrlbit = S3C_CLKCON_PCLK_SPI1, 185 .ctrlbit = S3C_CLKCON_PCLK_SPI1,
186 }, { 186 }, {
187 .name = "spi_48m",
188 .devname = "s3c64xx-spi.0",
189 .parent = &clk_48m,
190 .enable = s3c64xx_sclk_ctrl,
191 .ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
192 }, {
193 .name = "spi_48m",
194 .devname = "s3c64xx-spi.1",
195 .parent = &clk_48m,
196 .enable = s3c64xx_sclk_ctrl,
197 .ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
198 }, {
199 .name = "48m", 187 .name = "48m",
200 .devname = "s3c-sdhci.0", 188 .devname = "s3c-sdhci.0",
201 .parent = &clk_48m, 189 .parent = &clk_48m,
@@ -226,6 +214,22 @@ static struct clk init_clocks_off[] = {
226 }, 214 },
227}; 215};
228 216
217static struct clk clk_48m_spi0 = {
218 .name = "spi_48m",
219 .devname = "s3c64xx-spi.0",
220 .parent = &clk_48m,
221 .enable = s3c64xx_sclk_ctrl,
222 .ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
223};
224
225static struct clk clk_48m_spi1 = {
226 .name = "spi_48m",
227 .devname = "s3c64xx-spi.1",
228 .parent = &clk_48m,
229 .enable = s3c64xx_sclk_ctrl,
230 .ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
231};
232
229static struct clk init_clocks[] = { 233static struct clk init_clocks[] = {
230 { 234 {
231 .name = "lcd", 235 .name = "lcd",
@@ -243,24 +247,6 @@ static struct clk init_clocks[] = {
243 .enable = s3c64xx_hclk_ctrl, 247 .enable = s3c64xx_hclk_ctrl,
244 .ctrlbit = S3C_CLKCON_HCLK_UHOST, 248 .ctrlbit = S3C_CLKCON_HCLK_UHOST,
245 }, { 249 }, {
246 .name = "hsmmc",
247 .devname = "s3c-sdhci.0",
248 .parent = &clk_h,
249 .enable = s3c64xx_hclk_ctrl,
250 .ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
251 }, {
252 .name = "hsmmc",
253 .devname = "s3c-sdhci.1",
254 .parent = &clk_h,
255 .enable = s3c64xx_hclk_ctrl,
256 .ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
257 }, {
258 .name = "hsmmc",
259 .devname = "s3c-sdhci.2",
260 .parent = &clk_h,
261 .enable = s3c64xx_hclk_ctrl,
262 .ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
263 }, {
264 .name = "otg", 250 .name = "otg",
265 .parent = &clk_h, 251 .parent = &clk_h,
266 .enable = s3c64xx_hclk_ctrl, 252 .enable = s3c64xx_hclk_ctrl,
@@ -310,6 +296,29 @@ static struct clk init_clocks[] = {
310 } 296 }
311}; 297};
312 298
299static struct clk clk_hsmmc0 = {
300 .name = "hsmmc",
301 .devname = "s3c-sdhci.0",
302 .parent = &clk_h,
303 .enable = s3c64xx_hclk_ctrl,
304 .ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
305};
306
307static struct clk clk_hsmmc1 = {
308 .name = "hsmmc",
309 .devname = "s3c-sdhci.1",
310 .parent = &clk_h,
311 .enable = s3c64xx_hclk_ctrl,
312 .ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
313};
314
315static struct clk clk_hsmmc2 = {
316 .name = "hsmmc",
317 .devname = "s3c-sdhci.2",
318 .parent = &clk_h,
319 .enable = s3c64xx_hclk_ctrl,
320 .ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
321};
313 322
314static struct clk clk_fout_apll = { 323static struct clk clk_fout_apll = {
315 .name = "fout_apll", 324 .name = "fout_apll",
@@ -578,36 +587,6 @@ static struct clksrc_sources clkset_camif = {
578static struct clksrc_clk clksrcs[] = { 587static struct clksrc_clk clksrcs[] = {
579 { 588 {
580 .clk = { 589 .clk = {
581 .name = "mmc_bus",
582 .devname = "s3c-sdhci.0",
583 .ctrlbit = S3C_CLKCON_SCLK_MMC0,
584 .enable = s3c64xx_sclk_ctrl,
585 },
586 .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
587 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
588 .sources = &clkset_spi_mmc,
589 }, {
590 .clk = {
591 .name = "mmc_bus",
592 .devname = "s3c-sdhci.1",
593 .ctrlbit = S3C_CLKCON_SCLK_MMC1,
594 .enable = s3c64xx_sclk_ctrl,
595 },
596 .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
597 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
598 .sources = &clkset_spi_mmc,
599 }, {
600 .clk = {
601 .name = "mmc_bus",
602 .devname = "s3c-sdhci.2",
603 .ctrlbit = S3C_CLKCON_SCLK_MMC2,
604 .enable = s3c64xx_sclk_ctrl,
605 },
606 .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
607 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
608 .sources = &clkset_spi_mmc,
609 }, {
610 .clk = {
611 .name = "usb-bus-host", 590 .name = "usb-bus-host",
612 .ctrlbit = S3C_CLKCON_SCLK_UHOST, 591 .ctrlbit = S3C_CLKCON_SCLK_UHOST,
613 .enable = s3c64xx_sclk_ctrl, 592 .enable = s3c64xx_sclk_ctrl,
@@ -617,35 +596,6 @@ static struct clksrc_clk clksrcs[] = {
617 .sources = &clkset_uhost, 596 .sources = &clkset_uhost,
618 }, { 597 }, {
619 .clk = { 598 .clk = {
620 .name = "uclk1",
621 .ctrlbit = S3C_CLKCON_SCLK_UART,
622 .enable = s3c64xx_sclk_ctrl,
623 },
624 .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
625 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
626 .sources = &clkset_uart,
627 }, {
628/* Where does UCLK0 come from? */
629 .clk = {
630 .name = "spi-bus",
631 .devname = "s3c64xx-spi.0",
632 .ctrlbit = S3C_CLKCON_SCLK_SPI0,
633 .enable = s3c64xx_sclk_ctrl,
634 },
635 .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
636 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
637 .sources = &clkset_spi_mmc,
638 }, {
639 .clk = {
640 .name = "spi-bus",
641 .devname = "s3c64xx-spi.1",
642 .enable = s3c64xx_sclk_ctrl,
643 },
644 .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
645 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
646 .sources = &clkset_spi_mmc,
647 }, {
648 .clk = {
649 .name = "audio-bus", 599 .name = "audio-bus",
650 .devname = "samsung-i2s.0", 600 .devname = "samsung-i2s.0",
651 .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, 601 .ctrlbit = S3C_CLKCON_SCLK_AUDIO0,
@@ -695,6 +645,78 @@ static struct clksrc_clk clksrcs[] = {
695 }, 645 },
696}; 646};
697 647
648/* Where does UCLK0 come from? */
649static struct clksrc_clk clk_sclk_uclk = {
650 .clk = {
651 .name = "uclk1",
652 .ctrlbit = S3C_CLKCON_SCLK_UART,
653 .enable = s3c64xx_sclk_ctrl,
654 },
655 .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
656 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
657 .sources = &clkset_uart,
658};
659
660static struct clksrc_clk clk_sclk_mmc0 = {
661 .clk = {
662 .name = "mmc_bus",
663 .devname = "s3c-sdhci.0",
664 .ctrlbit = S3C_CLKCON_SCLK_MMC0,
665 .enable = s3c64xx_sclk_ctrl,
666 },
667 .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
668 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
669 .sources = &clkset_spi_mmc,
670};
671
672static struct clksrc_clk clk_sclk_mmc1 = {
673 .clk = {
674 .name = "mmc_bus",
675 .devname = "s3c-sdhci.1",
676 .ctrlbit = S3C_CLKCON_SCLK_MMC1,
677 .enable = s3c64xx_sclk_ctrl,
678 },
679 .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
680 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
681 .sources = &clkset_spi_mmc,
682};
683
684static struct clksrc_clk clk_sclk_mmc2 = {
685 .clk = {
686 .name = "mmc_bus",
687 .devname = "s3c-sdhci.2",
688 .ctrlbit = S3C_CLKCON_SCLK_MMC2,
689 .enable = s3c64xx_sclk_ctrl,
690 },
691 .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
692 .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
693 .sources = &clkset_spi_mmc,
694};
695
696static struct clksrc_clk clk_sclk_spi0 = {
697 .clk = {
698 .name = "spi-bus",
699 .devname = "s3c64xx-spi.0",
700 .ctrlbit = S3C_CLKCON_SCLK_SPI0,
701 .enable = s3c64xx_sclk_ctrl,
702 },
703 .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
704 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
705 .sources = &clkset_spi_mmc,
706};
707
708static struct clksrc_clk clk_sclk_spi1 = {
709 .clk = {
710 .name = "spi-bus",
711 .devname = "s3c64xx-spi.1",
712 .ctrlbit = S3C_CLKCON_SCLK_SPI1,
713 .enable = s3c64xx_sclk_ctrl,
714 },
715 .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
716 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
717 .sources = &clkset_spi_mmc,
718};
719
698/* Clock initialisation code */ 720/* Clock initialisation code */
699 721
700static struct clksrc_clk *init_parents[] = { 722static struct clksrc_clk *init_parents[] = {
@@ -703,6 +725,39 @@ static struct clksrc_clk *init_parents[] = {
703 &clk_mout_mpll, 725 &clk_mout_mpll,
704}; 726};
705 727
728static struct clksrc_clk *clksrc_cdev[] = {
729 &clk_sclk_uclk,
730 &clk_sclk_mmc0,
731 &clk_sclk_mmc1,
732 &clk_sclk_mmc2,
733 &clk_sclk_spi0,
734 &clk_sclk_spi1,
735};
736
737static struct clk *clk_cdev[] = {
738 &clk_hsmmc0,
739 &clk_hsmmc1,
740 &clk_hsmmc2,
741 &clk_48m_spi0,
742 &clk_48m_spi1,
743};
744
745static struct clk_lookup s3c64xx_clk_lookup[] = {
746 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
747 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
748 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
749 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
750 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
751 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
752 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
753 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
754 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
755 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
756 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_48m_spi0),
757 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
758 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_48m_spi1),
759};
760
706#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) 761#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
707 762
708void __init_or_cpufreq s3c64xx_setup_clocks(void) 763void __init_or_cpufreq s3c64xx_setup_clocks(void)
@@ -811,6 +866,8 @@ static struct clk *clks[] __initdata = {
811void __init s3c64xx_register_clocks(unsigned long xtal, 866void __init s3c64xx_register_clocks(unsigned long xtal,
812 unsigned armclk_divlimit) 867 unsigned armclk_divlimit)
813{ 868{
869 unsigned int cnt;
870
814 armclk_mask = armclk_divlimit; 871 armclk_mask = armclk_divlimit;
815 872
816 s3c24xx_register_baseclocks(xtal); 873 s3c24xx_register_baseclocks(xtal);
@@ -821,7 +878,15 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
821 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 878 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
822 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 879 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
823 880
881 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
882 for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++)
883 s3c_disable_clocks(clk_cdev[cnt], 1);
884
824 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); 885 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
825 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 886 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
887 for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
888 s3c_register_clksrc(clksrc_cdev[cnt], 1);
889 clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
890
826 s3c_pwmclk_init(); 891 s3c_pwmclk_init();
827} 892}
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c
deleted file mode 100644
index 3341fd11872..00000000000
--- a/arch/arm/mach-s3c64xx/dev-spi.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/* linux/arch/arm/plat-s3c64xx/dev-spi.c
2 *
3 * Copyright (C) 2009 Samsung Electronics Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/string.h>
13#include <linux/export.h>
14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h>
16#include <linux/gpio.h>
17
18#include <mach/dma.h>
19#include <mach/map.h>
20#include <mach/spi-clocks.h>
21#include <mach/irqs.h>
22
23#include <plat/s3c64xx-spi.h>
24#include <plat/gpio-cfg.h>
25#include <plat/devs.h>
26
27static char *spi_src_clks[] = {
28 [S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
29 [S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
30 [S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
31};
32
33/* SPI Controller platform_devices */
34
35/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
36 * The emulated CS is toggled by board specific mechanism, as it can
37 * be either some immediate GPIO or some signal out of some other
38 * chip in between ... or some yet another way.
39 * We simply do not assume anything about CS.
40 */
41static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
42{
43 unsigned int base;
44
45 switch (pdev->id) {
46 case 0:
47 base = S3C64XX_GPC(0);
48 break;
49
50 case 1:
51 base = S3C64XX_GPC(4);
52 break;
53
54 default:
55 dev_err(&pdev->dev, "Invalid SPI Controller number!");
56 return -EINVAL;
57 }
58
59 s3c_gpio_cfgall_range(base, 3,
60 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
61
62 return 0;
63}
64
65static struct resource s3c64xx_spi0_resource[] = {
66 [0] = {
67 .start = S3C64XX_PA_SPI0,
68 .end = S3C64XX_PA_SPI0 + 0x100 - 1,
69 .flags = IORESOURCE_MEM,
70 },
71 [1] = {
72 .start = DMACH_SPI0_TX,
73 .end = DMACH_SPI0_TX,
74 .flags = IORESOURCE_DMA,
75 },
76 [2] = {
77 .start = DMACH_SPI0_RX,
78 .end = DMACH_SPI0_RX,
79 .flags = IORESOURCE_DMA,
80 },
81 [3] = {
82 .start = IRQ_SPI0,
83 .end = IRQ_SPI0,
84 .flags = IORESOURCE_IRQ,
85 },
86};
87
88static struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
89 .cfg_gpio = s3c64xx_spi_cfg_gpio,
90 .fifo_lvl_mask = 0x7f,
91 .rx_lvl_offset = 13,
92 .tx_st_done = 21,
93};
94
95static u64 spi_dmamask = DMA_BIT_MASK(32);
96
97struct platform_device s3c64xx_device_spi0 = {
98 .name = "s3c64xx-spi",
99 .id = 0,
100 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
101 .resource = s3c64xx_spi0_resource,
102 .dev = {
103 .dma_mask = &spi_dmamask,
104 .coherent_dma_mask = DMA_BIT_MASK(32),
105 .platform_data = &s3c64xx_spi0_pdata,
106 },
107};
108EXPORT_SYMBOL(s3c64xx_device_spi0);
109
110static struct resource s3c64xx_spi1_resource[] = {
111 [0] = {
112 .start = S3C64XX_PA_SPI1,
113 .end = S3C64XX_PA_SPI1 + 0x100 - 1,
114 .flags = IORESOURCE_MEM,
115 },
116 [1] = {
117 .start = DMACH_SPI1_TX,
118 .end = DMACH_SPI1_TX,
119 .flags = IORESOURCE_DMA,
120 },
121 [2] = {
122 .start = DMACH_SPI1_RX,
123 .end = DMACH_SPI1_RX,
124 .flags = IORESOURCE_DMA,
125 },
126 [3] = {
127 .start = IRQ_SPI1,
128 .end = IRQ_SPI1,
129 .flags = IORESOURCE_IRQ,
130 },
131};
132
133static struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
134 .cfg_gpio = s3c64xx_spi_cfg_gpio,
135 .fifo_lvl_mask = 0x7f,
136 .rx_lvl_offset = 13,
137 .tx_st_done = 21,
138};
139
140struct platform_device s3c64xx_device_spi1 = {
141 .name = "s3c64xx-spi",
142 .id = 1,
143 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
144 .resource = s3c64xx_spi1_resource,
145 .dev = {
146 .dma_mask = &spi_dmamask,
147 .coherent_dma_mask = DMA_BIT_MASK(32),
148 .platform_data = &s3c64xx_spi1_pdata,
149 },
150};
151EXPORT_SYMBOL(s3c64xx_device_spi1);
152
153void __init s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
154{
155 struct s3c64xx_spi_info *pd;
156
157 /* Reject invalid configuration */
158 if (!num_cs || src_clk_nr < 0
159 || src_clk_nr > S3C64XX_SPI_SRCCLK_48M) {
160 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
161 return;
162 }
163
164 switch (cntrlr) {
165 case 0:
166 pd = &s3c64xx_spi0_pdata;
167 break;
168 case 1:
169 pd = &s3c64xx_spi1_pdata;
170 break;
171 default:
172 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
173 __func__, cntrlr);
174 return;
175 }
176
177 pd->num_cs = num_cs;
178 pd->src_clk_nr = src_clk_nr;
179 pd->src_clk_name = spi_src_clks[src_clk_nr];
180}
diff --git a/arch/arm/mach-s3c64xx/include/mach/crag6410.h b/arch/arm/mach-s3c64xx/include/mach/crag6410.h
index be9074e17df..5d55ab018b6 100644
--- a/arch/arm/mach-s3c64xx/include/mach/crag6410.h
+++ b/arch/arm/mach-s3c64xx/include/mach/crag6410.h
@@ -15,9 +15,11 @@
15 15
16#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START 16#define BANFF_PMIC_IRQ_BASE IRQ_BOARD_START
17#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64) 17#define GLENFARCLAS_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
18#define CODEC_IRQ_BASE (IRQ_BOARD_START + 128)
18 19
19#define PCA935X_GPIO_BASE GPIO_BOARD_START 20#define PCA935X_GPIO_BASE GPIO_BOARD_START
20#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8) 21#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
21#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 16) 22#define GLENFARCLAS_PMIC_GPIO_BASE (GPIO_BOARD_START + 32)
23#define BANFF_PMIC_GPIO_BASE (GPIO_BOARD_START + 64)
22 24
23#endif 25#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio.h
index 6e34c2f6e67..8b540c42d5d 100644
--- a/arch/arm/mach-s3c64xx/include/mach/gpio.h
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio.h
@@ -88,6 +88,6 @@ enum s3c_gpio_number {
88/* define the number of gpios we need to the one after the GPQ() range */ 88/* define the number of gpios we need to the one after the GPQ() range */
89#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) 89#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
90 90
91#define BOARD_NR_GPIOS 16 91#define BOARD_NR_GPIOS (16 + CONFIG_SAMSUNG_GPIO_EXTRA)
92 92
93#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS) 93#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS)
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
index 443f85b3c20..96d60e0d937 100644
--- a/arch/arm/mach-s3c64xx/include/mach/irqs.h
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -169,7 +169,7 @@
169#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1) 169#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
170 170
171#ifdef CONFIG_MACH_WLF_CRAGG_6410 171#ifdef CONFIG_MACH_WLF_CRAGG_6410
172#define IRQ_BOARD_NR 128 172#define IRQ_BOARD_NR 160
173#elif defined(CONFIG_SMDK6410_WM1190_EV1) 173#elif defined(CONFIG_SMDK6410_WM1190_EV1)
174#define IRQ_BOARD_NR 64 174#define IRQ_BOARD_NR 64
175#elif defined(CONFIG_SMDK6410_WM1192_EV1) 175#elif defined(CONFIG_SMDK6410_WM1192_EV1)
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index 23a1d71e4d5..8e2097bb208 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -115,6 +115,8 @@
115#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG 115#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
116#define S3C_PA_RTC S3C64XX_PA_RTC 116#define S3C_PA_RTC S3C64XX_PA_RTC
117#define S3C_PA_WDT S3C64XX_PA_WATCHDOG 117#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
118#define S3C_PA_SPI0 S3C64XX_PA_SPI0
119#define S3C_PA_SPI1 S3C64XX_PA_SPI1
118 120
119#define SAMSUNG_PA_ADC S3C64XX_PA_ADC 121#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
120#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON 122#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index f208154b138..cd3c97e2ee7 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -14,13 +14,43 @@
14 14
15#include <linux/mfd/wm831x/irq.h> 15#include <linux/mfd/wm831x/irq.h>
16#include <linux/mfd/wm831x/gpio.h> 16#include <linux/mfd/wm831x/gpio.h>
17#include <linux/mfd/wm8994/pdata.h>
17 18
19#include <sound/wm5100.h>
18#include <sound/wm8996.h> 20#include <sound/wm8996.h>
19#include <sound/wm8962.h> 21#include <sound/wm8962.h>
20#include <sound/wm9081.h> 22#include <sound/wm9081.h>
21 23
22#include <mach/crag6410.h> 24#include <mach/crag6410.h>
23 25
26static struct wm5100_pdata wm5100_pdata = {
27 .ldo_ena = S3C64XX_GPN(7),
28 .irq_flags = IRQF_TRIGGER_HIGH,
29 .gpio_base = CODEC_GPIO_BASE,
30
31 .in_mode = {
32 WM5100_IN_DIFF,
33 WM5100_IN_DIFF,
34 WM5100_IN_DIFF,
35 WM5100_IN_SE,
36 },
37
38 .hp_pol = CODEC_GPIO_BASE + 3,
39 .jack_modes = {
40 { WM5100_MICDET_MICBIAS3, 0, 0 },
41 { WM5100_MICDET_MICBIAS2, 1, 1 },
42 },
43
44 .gpio_defaults = {
45 0,
46 0,
47 0,
48 0,
49 0x2, /* IRQ: CMOS output */
50 0x3, /* CLKOUT: CMOS output */
51 },
52};
53
24static struct wm8996_retune_mobile_config wm8996_retune[] = { 54static struct wm8996_retune_mobile_config wm8996_retune[] = {
25 { 55 {
26 .name = "Sub LPF", 56 .name = "Sub LPF",
@@ -72,7 +102,6 @@ static struct wm8962_pdata wm8962_pdata __initdata = {
72 0x8000 | WM8962_GPIO_FN_DMICDAT, 102 0x8000 | WM8962_GPIO_FN_DMICDAT,
73 WM8962_GPIO_FN_IRQ, /* Open drain mode */ 103 WM8962_GPIO_FN_IRQ, /* Open drain mode */
74 }, 104 },
75 .irq_active_low = true,
76}; 105};
77 106
78static struct wm9081_pdata wm9081_pdata __initdata = { 107static struct wm9081_pdata wm9081_pdata __initdata = {
@@ -91,6 +120,7 @@ static const struct i2c_board_info wm1254_devs[] = {
91 120
92static const struct i2c_board_info wm1255_devs[] = { 121static const struct i2c_board_info wm1255_devs[] = {
93 { I2C_BOARD_INFO("wm5100", 0x1a), 122 { I2C_BOARD_INFO("wm5100", 0x1a),
123 .platform_data = &wm5100_pdata,
94 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, 124 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
95 }, 125 },
96 { I2C_BOARD_INFO("wm9081", 0x6c), 126 { I2C_BOARD_INFO("wm9081", 0x6c),
@@ -104,6 +134,24 @@ static const struct i2c_board_info wm1259_devs[] = {
104 }, 134 },
105}; 135};
106 136
137static struct wm8994_pdata wm8994_pdata = {
138 .gpio_base = CODEC_GPIO_BASE,
139 .gpio_defaults = {
140 0x3, /* IRQ out, active high, CMOS */
141 },
142 .irq_base = CODEC_IRQ_BASE,
143 .ldo = {
144 { .supply = "WALLVDD" },
145 { .supply = "WALLVDD" },
146 },
147};
148
149static const struct i2c_board_info wm1277_devs[] = {
150 { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */
151 .platform_data = &wm8994_pdata,
152 .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
153 },
154};
107 155
108static __devinitdata const struct { 156static __devinitdata const struct {
109 u8 id; 157 u8 id;
@@ -125,6 +173,8 @@ static __devinitdata const struct {
125 { .id = 0x3b, .name = "1255-EV1 Kilchoman", 173 { .id = 0x3b, .name = "1255-EV1 Kilchoman",
126 .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) }, 174 .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) },
127 { .id = 0x3c, .name = "1273-EV1 Longmorn" }, 175 { .id = 0x3c, .name = "1273-EV1 Longmorn" },
176 { .id = 0x3d, .name = "1277-EV1 Littlemill",
177 .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs) },
128}; 178};
129 179
130static __devinit int wlf_gf_module_probe(struct i2c_client *i2c, 180static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
@@ -154,8 +204,8 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
154 "Failed to register dev: %d\n", ret); 204 "Failed to register dev: %d\n", ret);
155 } 205 }
156 } else { 206 } else {
157 dev_warn(&i2c->dev, "Unknown module ID %d revision %d\n", 207 dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
158 id, rev); 208 id, rev + 1);
159 } 209 }
160 210
161 return 0; 211 return 0;
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index fb786b6a2ea..680fd758ff2 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -37,6 +37,8 @@
37#include <linux/mfd/wm831x/irq.h> 37#include <linux/mfd/wm831x/irq.h>
38#include <linux/mfd/wm831x/gpio.h> 38#include <linux/mfd/wm831x/gpio.h>
39 39
40#include <sound/wm1250-ev1.h>
41
40#include <asm/hardware/vic.h> 42#include <asm/hardware/vic.h>
41#include <asm/mach/arch.h> 43#include <asm/mach/arch.h>
42#include <asm/mach-types.h> 44#include <asm/mach-types.h>
@@ -289,6 +291,11 @@ static struct platform_device speyside_wm8962_device = {
289 .id = -1, 291 .id = -1,
290}; 292};
291 293
294static struct platform_device littlemill_device = {
295 .name = "littlemill",
296 .id = -1,
297};
298
292static struct regulator_consumer_supply wallvdd_consumers[] = { 299static struct regulator_consumer_supply wallvdd_consumers[] = {
293 REGULATOR_SUPPLY("SPKVDD1", "1-001a"), 300 REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
294 REGULATOR_SUPPLY("SPKVDD2", "1-001a"), 301 REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
@@ -341,6 +348,7 @@ static struct platform_device *crag6410_devices[] __initdata = {
341 &crag6410_backlight_device, 348 &crag6410_backlight_device,
342 &speyside_device, 349 &speyside_device,
343 &speyside_wm8962_device, 350 &speyside_wm8962_device,
351 &littlemill_device,
344 &lowland_device, 352 &lowland_device,
345 &wallvdd_device, 353 &wallvdd_device,
346}; 354};
@@ -374,6 +382,10 @@ static struct regulator_init_data vddarm __initdata = {
374 .driver_data = &vddarm_pdata, 382 .driver_data = &vddarm_pdata,
375}; 383};
376 384
385static struct regulator_consumer_supply vddint_consumers[] __initdata = {
386 REGULATOR_SUPPLY("vddint", NULL),
387};
388
377static struct regulator_init_data vddint __initdata = { 389static struct regulator_init_data vddint __initdata = {
378 .constraints = { 390 .constraints = {
379 .name = "VDDINT", 391 .name = "VDDINT",
@@ -382,6 +394,9 @@ static struct regulator_init_data vddint __initdata = {
382 .always_on = 1, 394 .always_on = 1,
383 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, 395 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
384 }, 396 },
397 .num_consumer_supplies = ARRAY_SIZE(vddint_consumers),
398 .consumer_supplies = vddint_consumers,
399 .supply_regulator = "WALLVDD",
385}; 400};
386 401
387static struct regulator_init_data vddmem __initdata = { 402static struct regulator_init_data vddmem __initdata = {
@@ -502,7 +517,8 @@ static struct wm831x_touch_pdata touch_pdata __initdata = {
502static struct wm831x_pdata crag_pmic_pdata __initdata = { 517static struct wm831x_pdata crag_pmic_pdata __initdata = {
503 .wm831x_num = 1, 518 .wm831x_num = 1,
504 .irq_base = BANFF_PMIC_IRQ_BASE, 519 .irq_base = BANFF_PMIC_IRQ_BASE,
505 .gpio_base = GPIO_BOARD_START + 8, 520 .gpio_base = BANFF_PMIC_GPIO_BASE,
521 .soft_shutdown = true,
506 522
507 .backup = &banff_backup_pdata, 523 .backup = &banff_backup_pdata,
508 524
@@ -607,6 +623,7 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
607 .wm831x_num = 2, 623 .wm831x_num = 2,
608 .irq_base = GLENFARCLAS_PMIC_IRQ_BASE, 624 .irq_base = GLENFARCLAS_PMIC_IRQ_BASE,
609 .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE, 625 .gpio_base = GLENFARCLAS_PMIC_GPIO_BASE,
626 .soft_shutdown = true,
610 627
611 .gpio_defaults = { 628 .gpio_defaults = {
612 /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */ 629 /* GPIO1-3: IRQ inputs, rising edge triggered, CMOS */
@@ -624,6 +641,16 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = {
624 .disable_touch = true, 641 .disable_touch = true,
625}; 642};
626 643
644static struct wm1250_ev1_pdata wm1250_ev1_pdata = {
645 .gpios = {
646 [WM1250_EV1_GPIO_CLK_ENA] = S3C64XX_GPN(12),
647 [WM1250_EV1_GPIO_CLK_SEL0] = S3C64XX_GPL(12),
648 [WM1250_EV1_GPIO_CLK_SEL1] = S3C64XX_GPL(13),
649 [WM1250_EV1_GPIO_OSR] = S3C64XX_GPL(14),
650 [WM1250_EV1_GPIO_MASTER] = S3C64XX_GPL(8),
651 },
652};
653
627static struct i2c_board_info i2c_devs1[] __initdata = { 654static struct i2c_board_info i2c_devs1[] __initdata = {
628 { I2C_BOARD_INFO("wm8311", 0x34), 655 { I2C_BOARD_INFO("wm8311", 0x34),
629 .irq = S3C_EINT(0), 656 .irq = S3C_EINT(0),
@@ -633,7 +660,13 @@ static struct i2c_board_info i2c_devs1[] __initdata = {
633 { I2C_BOARD_INFO("wlf-gf-module", 0x25) }, 660 { I2C_BOARD_INFO("wlf-gf-module", 0x25) },
634 { I2C_BOARD_INFO("wlf-gf-module", 0x26) }, 661 { I2C_BOARD_INFO("wlf-gf-module", 0x26) },
635 662
636 { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, 663 { I2C_BOARD_INFO("wm1250-ev1", 0x27),
664 .platform_data = &wm1250_ev1_pdata },
665};
666
667static struct s3c2410_platform_i2c i2c1_pdata = {
668 .frequency = 400000,
669 .bus_num = 1,
637}; 670};
638 671
639static void __init crag6410_map_io(void) 672static void __init crag6410_map_io(void)
@@ -694,7 +727,7 @@ static void __init crag6410_machine_init(void)
694 s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata); 727 s3c_sdhci2_set_platdata(&crag6410_hsmmc2_pdata);
695 728
696 s3c_i2c0_set_platdata(&i2c0_pdata); 729 s3c_i2c0_set_platdata(&i2c0_pdata);
697 s3c_i2c1_set_platdata(NULL); 730 s3c_i2c1_set_platdata(&i2c1_pdata);
698 s3c_fb_set_platdata(&crag6410_lcd_pdata); 731 s3c_fb_set_platdata(&crag6410_lcd_pdata);
699 732
700 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); 733 i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
index 7d3e81b9dd0..055dac90e0e 100644
--- a/arch/arm/mach-s3c64xx/pm.c
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -346,10 +346,23 @@ int __init s3c64xx_pm_init(void)
346 346
347static __init int s3c64xx_pm_initcall(void) 347static __init int s3c64xx_pm_initcall(void)
348{ 348{
349 u32 val;
350
349 pm_cpu_prep = s3c64xx_pm_prepare; 351 pm_cpu_prep = s3c64xx_pm_prepare;
350 pm_cpu_sleep = s3c64xx_cpu_suspend; 352 pm_cpu_sleep = s3c64xx_cpu_suspend;
351 pm_uart_udivslot = 1; 353 pm_uart_udivslot = 1;
352 354
355 /*
356 * Unconditionally disable power domains that contain only
357 * blocks which have no mainline driver support.
358 */
359 val = __raw_readl(S3C64XX_NORMAL_CFG);
360 val &= ~(S3C64XX_NORMALCFG_DOMAIN_G_ON |
361 S3C64XX_NORMALCFG_DOMAIN_V_ON |
362 S3C64XX_NORMALCFG_DOMAIN_I_ON |
363 S3C64XX_NORMALCFG_DOMAIN_P_ON);
364 __raw_writel(val, S3C64XX_NORMAL_CFG);
365
353#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK 366#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
354 gpio_request(S3C64XX_GPN(12), "DEBUG_LED0"); 367 gpio_request(S3C64XX_GPN(12), "DEBUG_LED0");
355 gpio_request(S3C64XX_GPN(13), "DEBUG_LED1"); 368 gpio_request(S3C64XX_GPN(13), "DEBUG_LED1");
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c
deleted file mode 100644
index c75a71b2116..00000000000
--- a/arch/arm/mach-s3c64xx/setup-sdhci.c
+++ /dev/null
@@ -1,24 +0,0 @@
1/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Copyright 2008 Simtec Electronics
5 * Ben Dooks <ben@simtec.co.uk>
6 * http://armlinux.simtec.co.uk/
7 *
8 * S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/types.h>
16
17/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
18
19char *s3c64xx_hsmmc_clksrcs[4] = {
20 [0] = "hsmmc",
21 [1] = "hsmmc",
22 [2] = "mmc_bus",
23 /* [3] = "48m", - note not successfully used yet */
24};
diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c
new file mode 100644
index 00000000000..d9592ad7a82
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-spi.c
@@ -0,0 +1,45 @@
1/* linux/arch/arm/mach-s3c64xx/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16
17#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
19 .fifo_lvl_mask = 0x7f,
20 .rx_lvl_offset = 13,
21 .tx_st_done = 21,
22};
23
24int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
25{
26 s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3,
27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
28 return 0;
29}
30#endif
31
32#ifdef CONFIG_S3C64XX_DEV_SPI1
33struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
34 .fifo_lvl_mask = 0x7f,
35 .rx_lvl_offset = 13,
36 .tx_st_done = 21,
37};
38
39int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
40{
41 s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
42 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
43 return 0;
44}
45#endif
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 18690c5f99e..c87f6108eeb 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -36,6 +36,16 @@ config S5P64X0_SETUP_I2C1
36 help 36 help
37 Common setup code for i2c bus 1. 37 Common setup code for i2c bus 1.
38 38
39config S5P64X0_SETUP_SPI
40 bool
41 help
42 Common setup code for SPI GPIO configurations
43
44config S5P64X0_SETUP_SDHCI_GPIO
45 bool
46 help
47 Common setup code for SDHCI gpio.
48
39# machine support 49# machine support
40 50
41config MACH_SMDK6440 51config MACH_SMDK6440
@@ -45,13 +55,16 @@ config MACH_SMDK6440
45 select S3C_DEV_I2C1 55 select S3C_DEV_I2C1
46 select S3C_DEV_RTC 56 select S3C_DEV_RTC
47 select S3C_DEV_WDT 57 select S3C_DEV_WDT
48 select S3C64XX_DEV_SPI 58 select S3C_DEV_HSMMC
59 select S3C_DEV_HSMMC1
60 select S3C_DEV_HSMMC2
49 select SAMSUNG_DEV_ADC 61 select SAMSUNG_DEV_ADC
50 select SAMSUNG_DEV_BACKLIGHT 62 select SAMSUNG_DEV_BACKLIGHT
51 select SAMSUNG_DEV_PWM 63 select SAMSUNG_DEV_PWM
52 select SAMSUNG_DEV_TS 64 select SAMSUNG_DEV_TS
53 select S5P64X0_SETUP_FB_24BPP 65 select S5P64X0_SETUP_FB_24BPP
54 select S5P64X0_SETUP_I2C1 66 select S5P64X0_SETUP_I2C1
67 select S5P64X0_SETUP_SDHCI_GPIO
55 help 68 help
56 Machine support for the Samsung SMDK6440 69 Machine support for the Samsung SMDK6440
57 70
@@ -62,14 +75,28 @@ config MACH_SMDK6450
62 select S3C_DEV_I2C1 75 select S3C_DEV_I2C1
63 select S3C_DEV_RTC 76 select S3C_DEV_RTC
64 select S3C_DEV_WDT 77 select S3C_DEV_WDT
65 select S3C64XX_DEV_SPI 78 select S3C_DEV_HSMMC
79 select S3C_DEV_HSMMC1
80 select S3C_DEV_HSMMC2
66 select SAMSUNG_DEV_ADC 81 select SAMSUNG_DEV_ADC
67 select SAMSUNG_DEV_BACKLIGHT 82 select SAMSUNG_DEV_BACKLIGHT
68 select SAMSUNG_DEV_PWM 83 select SAMSUNG_DEV_PWM
69 select SAMSUNG_DEV_TS 84 select SAMSUNG_DEV_TS
70 select S5P64X0_SETUP_FB_24BPP 85 select S5P64X0_SETUP_FB_24BPP
71 select S5P64X0_SETUP_I2C1 86 select S5P64X0_SETUP_I2C1
87 select S5P64X0_SETUP_SDHCI_GPIO
72 help 88 help
73 Machine support for the Samsung SMDK6450 89 Machine support for the Samsung SMDK6450
74 90
91menu "Use 8-bit SDHCI bus width"
92
93config S5P64X0_SD_CH1_8BIT
94 bool "SDHCI Channel 1 (Slot 1)"
95 depends on MACH_SMDK6450 || MACH_SMDK6440
96 help
97 Support SDHCI Channel 1 8-bit bus.
98 If selected, Channel 2 is disabled.
99
100endmenu
101
75endif 102endif
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index d3f7409999f..12bb951187a 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -28,8 +28,9 @@ obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
28# device support 28# device support
29 29
30obj-y += dev-audio.o 30obj-y += dev-audio.o
31obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
32 31
33obj-y += setup-i2c0.o 32obj-y += setup-i2c0.o
34obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o 33obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
35obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o 34obj-$(CONFIG_S5P64X0_SETUP_FB_24BPP) += setup-fb-24bpp.o
35obj-$(CONFIG_S5P64X0_SETUP_SPI) += setup-spi.o
36obj-$(CONFIG_S5P64X0_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index eb4ffe331e1..ee1e8e7f563 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -269,18 +269,6 @@ static struct clk init_clocks_off[] = {
269 .enable = s5p64x0_pclk_ctrl, 269 .enable = s5p64x0_pclk_ctrl,
270 .ctrlbit = (1 << 31), 270 .ctrlbit = (1 << 31),
271 }, { 271 }, {
272 .name = "sclk_spi_48",
273 .devname = "s3c64xx-spi.0",
274 .parent = &clk_48m,
275 .enable = s5p64x0_sclk_ctrl,
276 .ctrlbit = (1 << 22),
277 }, {
278 .name = "sclk_spi_48",
279 .devname = "s3c64xx-spi.1",
280 .parent = &clk_48m,
281 .enable = s5p64x0_sclk_ctrl,
282 .ctrlbit = (1 << 23),
283 }, {
284 .name = "mmc_48m", 272 .name = "mmc_48m",
285 .devname = "s3c-sdhci.0", 273 .devname = "s3c-sdhci.0",
286 .parent = &clk_48m, 274 .parent = &clk_48m,
@@ -392,65 +380,6 @@ static struct clksrc_sources clkset_audio = {
392static struct clksrc_clk clksrcs[] = { 380static struct clksrc_clk clksrcs[] = {
393 { 381 {
394 .clk = { 382 .clk = {
395 .name = "sclk_mmc",
396 .devname = "s3c-sdhci.0",
397 .ctrlbit = (1 << 24),
398 .enable = s5p64x0_sclk_ctrl,
399 },
400 .sources = &clkset_group1,
401 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
402 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
403 }, {
404 .clk = {
405 .name = "sclk_mmc",
406 .devname = "s3c-sdhci.1",
407 .ctrlbit = (1 << 25),
408 .enable = s5p64x0_sclk_ctrl,
409 },
410 .sources = &clkset_group1,
411 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
412 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
413 }, {
414 .clk = {
415 .name = "sclk_mmc",
416 .devname = "s3c-sdhci.2",
417 .ctrlbit = (1 << 26),
418 .enable = s5p64x0_sclk_ctrl,
419 },
420 .sources = &clkset_group1,
421 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
422 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
423 }, {
424 .clk = {
425 .name = "uclk1",
426 .ctrlbit = (1 << 5),
427 .enable = s5p64x0_sclk_ctrl,
428 },
429 .sources = &clkset_uart,
430 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
431 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
432 }, {
433 .clk = {
434 .name = "sclk_spi",
435 .devname = "s3c64xx-spi.0",
436 .ctrlbit = (1 << 20),
437 .enable = s5p64x0_sclk_ctrl,
438 },
439 .sources = &clkset_group1,
440 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
441 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
442 }, {
443 .clk = {
444 .name = "sclk_spi",
445 .devname = "s3c64xx-spi.1",
446 .ctrlbit = (1 << 21),
447 .enable = s5p64x0_sclk_ctrl,
448 },
449 .sources = &clkset_group1,
450 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
451 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
452 }, {
453 .clk = {
454 .name = "sclk_post", 383 .name = "sclk_post",
455 .ctrlbit = (1 << 10), 384 .ctrlbit = (1 << 10),
456 .enable = s5p64x0_sclk_ctrl, 385 .enable = s5p64x0_sclk_ctrl,
@@ -488,6 +417,77 @@ static struct clksrc_clk clksrcs[] = {
488 }, 417 },
489}; 418};
490 419
420static struct clksrc_clk clk_sclk_mmc0 = {
421 .clk = {
422 .name = "sclk_mmc",
423 .devname = "s3c-sdhci.0",
424 .ctrlbit = (1 << 24),
425 .enable = s5p64x0_sclk_ctrl,
426 },
427 .sources = &clkset_group1,
428 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
429 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
430};
431
432static struct clksrc_clk clk_sclk_mmc1 = {
433 .clk = {
434 .name = "sclk_mmc",
435 .devname = "s3c-sdhci.1",
436 .ctrlbit = (1 << 25),
437 .enable = s5p64x0_sclk_ctrl,
438 },
439 .sources = &clkset_group1,
440 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
441 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
442};
443
444static struct clksrc_clk clk_sclk_mmc2 = {
445 .clk = {
446 .name = "sclk_mmc",
447 .devname = "s3c-sdhci.2",
448 .ctrlbit = (1 << 26),
449 .enable = s5p64x0_sclk_ctrl,
450 },
451 .sources = &clkset_group1,
452 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
453 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
454};
455
456static struct clksrc_clk clk_sclk_uclk = {
457 .clk = {
458 .name = "uclk1",
459 .ctrlbit = (1 << 5),
460 .enable = s5p64x0_sclk_ctrl,
461 },
462 .sources = &clkset_uart,
463 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
464 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
465};
466
467static struct clksrc_clk clk_sclk_spi0 = {
468 .clk = {
469 .name = "sclk_spi",
470 .devname = "s3c64xx-spi.0",
471 .ctrlbit = (1 << 20),
472 .enable = s5p64x0_sclk_ctrl,
473 },
474 .sources = &clkset_group1,
475 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
476 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
477};
478
479static struct clksrc_clk clk_sclk_spi1 = {
480 .clk = {
481 .name = "sclk_spi",
482 .devname = "s3c64xx-spi.1",
483 .ctrlbit = (1 << 21),
484 .enable = s5p64x0_sclk_ctrl,
485 },
486 .sources = &clkset_group1,
487 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
488 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
489};
490
491/* Clock initialization code */ 491/* Clock initialization code */
492static struct clksrc_clk *sysclks[] = { 492static struct clksrc_clk *sysclks[] = {
493 &clk_mout_apll, 493 &clk_mout_apll,
@@ -506,6 +506,26 @@ static struct clk dummy_apb_pclk = {
506 .id = -1, 506 .id = -1,
507}; 507};
508 508
509static struct clksrc_clk *clksrc_cdev[] = {
510 &clk_sclk_uclk,
511 &clk_sclk_spi0,
512 &clk_sclk_spi1,
513 &clk_sclk_mmc0,
514 &clk_sclk_mmc1,
515 &clk_sclk_mmc2
516};
517
518static struct clk_lookup s5p6440_clk_lookup[] = {
519 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
520 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
521 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
522 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
523 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
524 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
525 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
526 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
527};
528
509void __init_or_cpufreq s5p6440_setup_clocks(void) 529void __init_or_cpufreq s5p6440_setup_clocks(void)
510{ 530{
511 struct clk *xtal_clk; 531 struct clk *xtal_clk;
@@ -584,9 +604,12 @@ void __init s5p6440_register_clocks(void)
584 604
585 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 605 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
586 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 606 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
607 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
608 s3c_register_clksrc(clksrc_cdev[ptr], 1);
587 609
588 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 610 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
589 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 611 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
612 clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
590 613
591 s3c24xx_register_clock(&dummy_apb_pclk); 614 s3c24xx_register_clock(&dummy_apb_pclk);
592 615
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index bb7ee912090..dae6a13f43b 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -414,65 +414,6 @@ static struct clksrc_clk clk_sclk_audio0 = {
414static struct clksrc_clk clksrcs[] = { 414static struct clksrc_clk clksrcs[] = {
415 { 415 {
416 .clk = { 416 .clk = {
417 .name = "sclk_mmc",
418 .devname = "s3c-sdhci.0",
419 .ctrlbit = (1 << 24),
420 .enable = s5p64x0_sclk_ctrl,
421 },
422 .sources = &clkset_group2,
423 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
424 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
425 }, {
426 .clk = {
427 .name = "sclk_mmc",
428 .devname = "s3c-sdhci.1",
429 .ctrlbit = (1 << 25),
430 .enable = s5p64x0_sclk_ctrl,
431 },
432 .sources = &clkset_group2,
433 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
434 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
435 }, {
436 .clk = {
437 .name = "sclk_mmc",
438 .devname = "s3c-sdhci.2",
439 .ctrlbit = (1 << 26),
440 .enable = s5p64x0_sclk_ctrl,
441 },
442 .sources = &clkset_group2,
443 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
444 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
445 }, {
446 .clk = {
447 .name = "uclk1",
448 .ctrlbit = (1 << 5),
449 .enable = s5p64x0_sclk_ctrl,
450 },
451 .sources = &clkset_uart,
452 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
453 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
454 }, {
455 .clk = {
456 .name = "sclk_spi",
457 .devname = "s3c64xx-spi.0",
458 .ctrlbit = (1 << 20),
459 .enable = s5p64x0_sclk_ctrl,
460 },
461 .sources = &clkset_group2,
462 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
463 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
464 }, {
465 .clk = {
466 .name = "sclk_spi",
467 .devname = "s3c64xx-spi.1",
468 .ctrlbit = (1 << 21),
469 .enable = s5p64x0_sclk_ctrl,
470 },
471 .sources = &clkset_group2,
472 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
473 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
474 }, {
475 .clk = {
476 .name = "sclk_fimc", 417 .name = "sclk_fimc",
477 .ctrlbit = (1 << 10), 418 .ctrlbit = (1 << 10),
478 .enable = s5p64x0_sclk_ctrl, 419 .enable = s5p64x0_sclk_ctrl,
@@ -537,6 +478,97 @@ static struct clksrc_clk clksrcs[] = {
537 }, 478 },
538}; 479};
539 480
481static struct clksrc_clk clk_sclk_mmc0 = {
482 .clk = {
483 .name = "sclk_mmc",
484 .devname = "s3c-sdhci.0",
485 .ctrlbit = (1 << 24),
486 .enable = s5p64x0_sclk_ctrl,
487 },
488 .sources = &clkset_group2,
489 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
490 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
491};
492
493static struct clksrc_clk clk_sclk_mmc1 = {
494 .clk = {
495 .name = "sclk_mmc",
496 .devname = "s3c-sdhci.1",
497 .ctrlbit = (1 << 25),
498 .enable = s5p64x0_sclk_ctrl,
499 },
500 .sources = &clkset_group2,
501 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
502 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
503};
504
505static struct clksrc_clk clk_sclk_mmc2 = {
506 .clk = {
507 .name = "sclk_mmc",
508 .devname = "s3c-sdhci.2",
509 .ctrlbit = (1 << 26),
510 .enable = s5p64x0_sclk_ctrl,
511 },
512 .sources = &clkset_group2,
513 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
514 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
515};
516
517static struct clksrc_clk clk_sclk_uclk = {
518 .clk = {
519 .name = "uclk1",
520 .ctrlbit = (1 << 5),
521 .enable = s5p64x0_sclk_ctrl,
522 },
523 .sources = &clkset_uart,
524 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
525 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
526};
527
528static struct clksrc_clk clk_sclk_spi0 = {
529 .clk = {
530 .name = "sclk_spi",
531 .devname = "s3c64xx-spi.0",
532 .ctrlbit = (1 << 20),
533 .enable = s5p64x0_sclk_ctrl,
534 },
535 .sources = &clkset_group2,
536 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
537 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
538};
539
540static struct clksrc_clk clk_sclk_spi1 = {
541 .clk = {
542 .name = "sclk_spi",
543 .devname = "s3c64xx-spi.1",
544 .ctrlbit = (1 << 21),
545 .enable = s5p64x0_sclk_ctrl,
546 },
547 .sources = &clkset_group2,
548 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
549 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
550};
551
552static struct clksrc_clk *clksrc_cdev[] = {
553 &clk_sclk_uclk,
554 &clk_sclk_spi0,
555 &clk_sclk_spi1,
556 &clk_sclk_mmc0,
557 &clk_sclk_mmc1,
558 &clk_sclk_mmc2,
559};
560
561static struct clk_lookup s5p6450_clk_lookup[] = {
562 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
563 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
564 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
565 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
566 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
567 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
568 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
569 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
570};
571
540/* Clock initialization code */ 572/* Clock initialization code */
541static struct clksrc_clk *sysclks[] = { 573static struct clksrc_clk *sysclks[] = {
542 &clk_mout_apll, 574 &clk_mout_apll,
@@ -635,9 +667,12 @@ void __init s5p6450_register_clocks(void)
635 667
636 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 668 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
637 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 669 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
670 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
671 s3c_register_clksrc(clksrc_cdev[ptr], 1);
638 672
639 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 673 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
640 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 674 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
675 clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
641 676
642 s3c24xx_register_clock(&dummy_apb_pclk); 677 s3c24xx_register_clock(&dummy_apb_pclk);
643 678
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 28d0b918cd4..52b89a37644 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -40,6 +40,7 @@
40#include <plat/clock.h> 40#include <plat/clock.h>
41#include <plat/devs.h> 41#include <plat/devs.h>
42#include <plat/pm.h> 42#include <plat/pm.h>
43#include <plat/sdhci.h>
43#include <plat/adc-core.h> 44#include <plat/adc-core.h>
44#include <plat/fb-core.h> 45#include <plat/fb-core.h>
45#include <plat/gpio-cfg.h> 46#include <plat/gpio-cfg.h>
@@ -181,6 +182,10 @@ void __init s5p6440_map_io(void)
181 s3c_adc_setname("s3c64xx-adc"); 182 s3c_adc_setname("s3c64xx-adc");
182 s3c_fb_setname("s5p64x0-fb"); 183 s3c_fb_setname("s5p64x0-fb");
183 184
185 s5p64x0_default_sdhci0();
186 s5p64x0_default_sdhci1();
187 s5p6440_default_sdhci2();
188
184 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc)); 189 iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
185 init_consistent_dma_size(SZ_8M); 190 init_consistent_dma_size(SZ_8M);
186} 191}
@@ -191,6 +196,10 @@ void __init s5p6450_map_io(void)
191 s3c_adc_setname("s3c64xx-adc"); 196 s3c_adc_setname("s3c64xx-adc");
192 s3c_fb_setname("s5p64x0-fb"); 197 s3c_fb_setname("s5p64x0-fb");
193 198
199 s5p64x0_default_sdhci0();
200 s5p64x0_default_sdhci1();
201 s5p6450_default_sdhci2();
202
194 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc)); 203 iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
195 init_consistent_dma_size(SZ_8M); 204 init_consistent_dma_size(SZ_8M);
196} 205}
@@ -282,36 +291,7 @@ int __init s5p64x0_init(void)
282 return device_register(&s5p64x0_dev); 291 return device_register(&s5p64x0_dev);
283} 292}
284 293
285static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
286 [0] = {
287 .name = "pclk_low",
288 .divisor = 1,
289 .min_baud = 0,
290 .max_baud = 0,
291 },
292 [1] = {
293 .name = "uclk1",
294 .divisor = 1,
295 .min_baud = 0,
296 .max_baud = 0,
297 },
298};
299
300/* uart registration process */ 294/* uart registration process */
301
302void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
303{
304 struct s3c2410_uartcfg *tcfg = cfg;
305 u32 ucnt;
306
307 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
308 if (!tcfg->clocks) {
309 tcfg->clocks = s5p64x0_serial_clocks;
310 tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
311 }
312 }
313}
314
315void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) 295void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
316{ 296{
317 int uart; 297 int uart;
@@ -321,13 +301,11 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
321 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; 301 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
322 } 302 }
323 303
324 s5p64x0_common_init_uarts(cfg, no);
325 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); 304 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
326} 305}
327 306
328void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) 307void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
329{ 308{
330 s5p64x0_common_init_uarts(cfg, no);
331 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); 309 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
332} 310}
333 311
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
deleted file mode 100644
index 1fd9c79c7db..00000000000
--- a/arch/arm/mach-s5p64x0/dev-spi.c
+++ /dev/null
@@ -1,224 +0,0 @@
1/* linux/arch/arm/mach-s5p64x0/dev-spi.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
7 * Jaswinder Singh <jassi.brar@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h>
16#include <linux/gpio.h>
17
18#include <mach/dma.h>
19#include <mach/map.h>
20#include <mach/irqs.h>
21#include <mach/regs-clock.h>
22#include <mach/spi-clocks.h>
23
24#include <plat/cpu.h>
25#include <plat/s3c64xx-spi.h>
26#include <plat/gpio-cfg.h>
27
28static char *s5p64x0_spi_src_clks[] = {
29 [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
30 [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
31};
32
33/* SPI Controller platform_devices */
34
35/* Since we emulate multi-cs capability, we do not touch the CS.
36 * The emulated CS is toggled by board specific mechanism, as it can
37 * be either some immediate GPIO or some signal out of some other
38 * chip in between ... or some yet another way.
39 * We simply do not assume anything about CS.
40 */
41static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
42{
43 unsigned int base;
44
45 switch (pdev->id) {
46 case 0:
47 base = S5P6440_GPC(0);
48 break;
49
50 case 1:
51 base = S5P6440_GPC(4);
52 break;
53
54 default:
55 dev_err(&pdev->dev, "Invalid SPI Controller number!");
56 return -EINVAL;
57 }
58
59 s3c_gpio_cfgall_range(base, 3,
60 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
61
62 return 0;
63}
64
65static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
66{
67 unsigned int base;
68
69 switch (pdev->id) {
70 case 0:
71 base = S5P6450_GPC(0);
72 break;
73
74 case 1:
75 base = S5P6450_GPC(4);
76 break;
77
78 default:
79 dev_err(&pdev->dev, "Invalid SPI Controller number!");
80 return -EINVAL;
81 }
82
83 s3c_gpio_cfgall_range(base, 3,
84 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
85
86 return 0;
87}
88
89static struct resource s5p64x0_spi0_resource[] = {
90 [0] = {
91 .start = S5P64X0_PA_SPI0,
92 .end = S5P64X0_PA_SPI0 + 0x100 - 1,
93 .flags = IORESOURCE_MEM,
94 },
95 [1] = {
96 .start = DMACH_SPI0_TX,
97 .end = DMACH_SPI0_TX,
98 .flags = IORESOURCE_DMA,
99 },
100 [2] = {
101 .start = DMACH_SPI0_RX,
102 .end = DMACH_SPI0_RX,
103 .flags = IORESOURCE_DMA,
104 },
105 [3] = {
106 .start = IRQ_SPI0,
107 .end = IRQ_SPI0,
108 .flags = IORESOURCE_IRQ,
109 },
110};
111
112static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
113 .cfg_gpio = s5p6440_spi_cfg_gpio,
114 .fifo_lvl_mask = 0x1ff,
115 .rx_lvl_offset = 15,
116 .tx_st_done = 25,
117};
118
119static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
120 .cfg_gpio = s5p6450_spi_cfg_gpio,
121 .fifo_lvl_mask = 0x1ff,
122 .rx_lvl_offset = 15,
123 .tx_st_done = 25,
124};
125
126static u64 spi_dmamask = DMA_BIT_MASK(32);
127
128struct platform_device s5p64x0_device_spi0 = {
129 .name = "s3c64xx-spi",
130 .id = 0,
131 .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
132 .resource = s5p64x0_spi0_resource,
133 .dev = {
134 .dma_mask = &spi_dmamask,
135 .coherent_dma_mask = DMA_BIT_MASK(32),
136 },
137};
138
139static struct resource s5p64x0_spi1_resource[] = {
140 [0] = {
141 .start = S5P64X0_PA_SPI1,
142 .end = S5P64X0_PA_SPI1 + 0x100 - 1,
143 .flags = IORESOURCE_MEM,
144 },
145 [1] = {
146 .start = DMACH_SPI1_TX,
147 .end = DMACH_SPI1_TX,
148 .flags = IORESOURCE_DMA,
149 },
150 [2] = {
151 .start = DMACH_SPI1_RX,
152 .end = DMACH_SPI1_RX,
153 .flags = IORESOURCE_DMA,
154 },
155 [3] = {
156 .start = IRQ_SPI1,
157 .end = IRQ_SPI1,
158 .flags = IORESOURCE_IRQ,
159 },
160};
161
162static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
163 .cfg_gpio = s5p6440_spi_cfg_gpio,
164 .fifo_lvl_mask = 0x7f,
165 .rx_lvl_offset = 15,
166 .tx_st_done = 25,
167};
168
169static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
170 .cfg_gpio = s5p6450_spi_cfg_gpio,
171 .fifo_lvl_mask = 0x7f,
172 .rx_lvl_offset = 15,
173 .tx_st_done = 25,
174};
175
176struct platform_device s5p64x0_device_spi1 = {
177 .name = "s3c64xx-spi",
178 .id = 1,
179 .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
180 .resource = s5p64x0_spi1_resource,
181 .dev = {
182 .dma_mask = &spi_dmamask,
183 .coherent_dma_mask = DMA_BIT_MASK(32),
184 },
185};
186
187void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
188{
189 struct s3c64xx_spi_info *pd;
190
191 /* Reject invalid configuration */
192 if (!num_cs || src_clk_nr < 0
193 || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
194 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
195 return;
196 }
197
198 switch (cntrlr) {
199 case 0:
200 if (soc_is_s5p6450())
201 pd = &s5p6450_spi0_pdata;
202 else
203 pd = &s5p6440_spi0_pdata;
204
205 s5p64x0_device_spi0.dev.platform_data = pd;
206 break;
207 case 1:
208 if (soc_is_s5p6450())
209 pd = &s5p6450_spi1_pdata;
210 else
211 pd = &s5p6440_spi1_pdata;
212
213 s5p64x0_device_spi1.dev.platform_data = pd;
214 break;
215 default:
216 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
217 __func__, cntrlr);
218 return;
219 }
220
221 pd->num_cs = num_cs;
222 pd->src_clk_nr = src_clk_nr;
223 pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
224}
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 442dd4ad12d..f820c074440 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -38,176 +38,74 @@
38 38
39static u64 dma_dmamask = DMA_BIT_MASK(32); 39static u64 dma_dmamask = DMA_BIT_MASK(32);
40 40
41struct dma_pl330_peri s5p6440_pdma_peri[22] = { 41u8 s5p6440_pdma_peri[] = {
42 { 42 DMACH_UART0_RX,
43 .peri_id = (u8)DMACH_UART0_RX, 43 DMACH_UART0_TX,
44 .rqtype = DEVTOMEM, 44 DMACH_UART1_RX,
45 }, { 45 DMACH_UART1_TX,
46 .peri_id = (u8)DMACH_UART0_TX, 46 DMACH_UART2_RX,
47 .rqtype = MEMTODEV, 47 DMACH_UART2_TX,
48 }, { 48 DMACH_UART3_RX,
49 .peri_id = (u8)DMACH_UART1_RX, 49 DMACH_UART3_TX,
50 .rqtype = DEVTOMEM, 50 DMACH_MAX,
51 }, { 51 DMACH_MAX,
52 .peri_id = (u8)DMACH_UART1_TX, 52 DMACH_PCM0_TX,
53 .rqtype = MEMTODEV, 53 DMACH_PCM0_RX,
54 }, { 54 DMACH_I2S0_TX,
55 .peri_id = (u8)DMACH_UART2_RX, 55 DMACH_I2S0_RX,
56 .rqtype = DEVTOMEM, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI0_RX,
58 .peri_id = (u8)DMACH_UART2_TX, 58 DMACH_MAX,
59 .rqtype = MEMTODEV, 59 DMACH_MAX,
60 }, { 60 DMACH_MAX,
61 .peri_id = (u8)DMACH_UART3_RX, 61 DMACH_MAX,
62 .rqtype = DEVTOMEM, 62 DMACH_SPI1_TX,
63 }, { 63 DMACH_SPI1_RX,
64 .peri_id = (u8)DMACH_UART3_TX,
65 .rqtype = MEMTODEV,
66 }, {
67 .peri_id = DMACH_MAX,
68 }, {
69 .peri_id = DMACH_MAX,
70 }, {
71 .peri_id = (u8)DMACH_PCM0_TX,
72 .rqtype = MEMTODEV,
73 }, {
74 .peri_id = (u8)DMACH_PCM0_RX,
75 .rqtype = DEVTOMEM,
76 }, {
77 .peri_id = (u8)DMACH_I2S0_TX,
78 .rqtype = MEMTODEV,
79 }, {
80 .peri_id = (u8)DMACH_I2S0_RX,
81 .rqtype = DEVTOMEM,
82 }, {
83 .peri_id = (u8)DMACH_SPI0_TX,
84 .rqtype = MEMTODEV,
85 }, {
86 .peri_id = (u8)DMACH_SPI0_RX,
87 .rqtype = DEVTOMEM,
88 }, {
89 .peri_id = (u8)DMACH_MAX,
90 }, {
91 .peri_id = (u8)DMACH_MAX,
92 }, {
93 .peri_id = (u8)DMACH_MAX,
94 }, {
95 .peri_id = (u8)DMACH_MAX,
96 }, {
97 .peri_id = (u8)DMACH_SPI1_TX,
98 .rqtype = MEMTODEV,
99 }, {
100 .peri_id = (u8)DMACH_SPI1_RX,
101 .rqtype = DEVTOMEM,
102 },
103}; 64};
104 65
105struct dma_pl330_platdata s5p6440_pdma_pdata = { 66struct dma_pl330_platdata s5p6440_pdma_pdata = {
106 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), 67 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
107 .peri = s5p6440_pdma_peri, 68 .peri_id = s5p6440_pdma_peri,
108}; 69};
109 70
110struct dma_pl330_peri s5p6450_pdma_peri[32] = { 71u8 s5p6450_pdma_peri[] = {
111 { 72 DMACH_UART0_RX,
112 .peri_id = (u8)DMACH_UART0_RX, 73 DMACH_UART0_TX,
113 .rqtype = DEVTOMEM, 74 DMACH_UART1_RX,
114 }, { 75 DMACH_UART1_TX,
115 .peri_id = (u8)DMACH_UART0_TX, 76 DMACH_UART2_RX,
116 .rqtype = MEMTODEV, 77 DMACH_UART2_TX,
117 }, { 78 DMACH_UART3_RX,
118 .peri_id = (u8)DMACH_UART1_RX, 79 DMACH_UART3_TX,
119 .rqtype = DEVTOMEM, 80 DMACH_UART4_RX,
120 }, { 81 DMACH_UART4_TX,
121 .peri_id = (u8)DMACH_UART1_TX, 82 DMACH_PCM0_TX,
122 .rqtype = MEMTODEV, 83 DMACH_PCM0_RX,
123 }, { 84 DMACH_I2S0_TX,
124 .peri_id = (u8)DMACH_UART2_RX, 85 DMACH_I2S0_RX,
125 .rqtype = DEVTOMEM, 86 DMACH_SPI0_TX,
126 }, { 87 DMACH_SPI0_RX,
127 .peri_id = (u8)DMACH_UART2_TX, 88 DMACH_PCM1_TX,
128 .rqtype = MEMTODEV, 89 DMACH_PCM1_RX,
129 }, { 90 DMACH_PCM2_TX,
130 .peri_id = (u8)DMACH_UART3_RX, 91 DMACH_PCM2_RX,
131 .rqtype = DEVTOMEM, 92 DMACH_SPI1_TX,
132 }, { 93 DMACH_SPI1_RX,
133 .peri_id = (u8)DMACH_UART3_TX, 94 DMACH_USI_TX,
134 .rqtype = MEMTODEV, 95 DMACH_USI_RX,
135 }, { 96 DMACH_MAX,
136 .peri_id = (u8)DMACH_UART4_RX, 97 DMACH_I2S1_TX,
137 .rqtype = DEVTOMEM, 98 DMACH_I2S1_RX,
138 }, { 99 DMACH_I2S2_TX,
139 .peri_id = (u8)DMACH_UART4_TX, 100 DMACH_I2S2_RX,
140 .rqtype = MEMTODEV, 101 DMACH_PWM,
141 }, { 102 DMACH_UART5_RX,
142 .peri_id = (u8)DMACH_PCM0_TX, 103 DMACH_UART5_TX,
143 .rqtype = MEMTODEV,
144 }, {
145 .peri_id = (u8)DMACH_PCM0_RX,
146 .rqtype = DEVTOMEM,
147 }, {
148 .peri_id = (u8)DMACH_I2S0_TX,
149 .rqtype = MEMTODEV,
150 }, {
151 .peri_id = (u8)DMACH_I2S0_RX,
152 .rqtype = DEVTOMEM,
153 }, {
154 .peri_id = (u8)DMACH_SPI0_TX,
155 .rqtype = MEMTODEV,
156 }, {
157 .peri_id = (u8)DMACH_SPI0_RX,
158 .rqtype = DEVTOMEM,
159 }, {
160 .peri_id = (u8)DMACH_PCM1_TX,
161 .rqtype = MEMTODEV,
162 }, {
163 .peri_id = (u8)DMACH_PCM1_RX,
164 .rqtype = DEVTOMEM,
165 }, {
166 .peri_id = (u8)DMACH_PCM2_TX,
167 .rqtype = MEMTODEV,
168 }, {
169 .peri_id = (u8)DMACH_PCM2_RX,
170 .rqtype = DEVTOMEM,
171 }, {
172 .peri_id = (u8)DMACH_SPI1_TX,
173 .rqtype = MEMTODEV,
174 }, {
175 .peri_id = (u8)DMACH_SPI1_RX,
176 .rqtype = DEVTOMEM,
177 }, {
178 .peri_id = (u8)DMACH_USI_TX,
179 .rqtype = MEMTODEV,
180 }, {
181 .peri_id = (u8)DMACH_USI_RX,
182 .rqtype = DEVTOMEM,
183 }, {
184 .peri_id = (u8)DMACH_MAX,
185 }, {
186 .peri_id = (u8)DMACH_I2S1_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_I2S1_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_I2S2_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_I2S2_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_PWM,
199 }, {
200 .peri_id = (u8)DMACH_UART5_RX,
201 .rqtype = DEVTOMEM,
202 }, {
203 .peri_id = (u8)DMACH_UART5_TX,
204 .rqtype = MEMTODEV,
205 },
206}; 104};
207 105
208struct dma_pl330_platdata s5p6450_pdma_pdata = { 106struct dma_pl330_platdata s5p6450_pdma_pdata = {
209 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), 107 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
210 .peri = s5p6450_pdma_peri, 108 .peri_id = s5p6450_pdma_peri,
211}; 109};
212 110
213struct amba_device s5p64x0_device_pdma = { 111struct amba_device s5p64x0_device_pdma = {
@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = {
227 125
228static int __init s5p64x0_dma_init(void) 126static int __init s5p64x0_dma_init(void)
229{ 127{
230 if (soc_is_s5p6450()) 128 if (soc_is_s5p6450()) {
129 dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
130 dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
231 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; 131 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
232 else 132 } else {
133 dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
134 dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
233 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; 135 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
136 }
234 137
235 amba_device_register(&s5p64x0_device_pdma, &iomem_resource); 138 amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
236 139
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 53982db9d25..5b845e849b3 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -141,6 +141,8 @@
141 141
142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) 142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
143 143
144#define IRQ_TIMER_BASE (11)
145
144/* Set the default NR_IRQS */ 146/* Set the default NR_IRQS */
145 147
146#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) 148#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 4d3ac8a3709..0c0175dbfa3 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -67,6 +67,8 @@
67#define S3C_PA_RTC S5P64X0_PA_RTC 67#define S3C_PA_RTC S5P64X0_PA_RTC
68#define S3C_PA_WDT S5P64X0_PA_WDT 68#define S3C_PA_WDT S5P64X0_PA_WDT
69#define S3C_PA_FB S5P64X0_PA_FB 69#define S3C_PA_FB S5P64X0_PA_FB
70#define S3C_PA_SPI0 S5P64X0_PA_SPI0
71#define S3C_PA_SPI1 S5P64X0_PA_SPI1
70 72
71#define S5P_PA_CHIPID S5P64X0_PA_CHIPID 73#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
72#define S5P_PA_SROMC S5P64X0_PA_SROMC 74#define S5P_PA_SROMC S5P64X0_PA_SROMC
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 34d98a1dae5..a40e325d62c 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -24,6 +24,7 @@
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/pwm_backlight.h> 25#include <linux/pwm_backlight.h>
26#include <linux/fb.h> 26#include <linux/fb.h>
27#include <linux/mmc/host.h>
27 28
28#include <video/platform_lcd.h> 29#include <video/platform_lcd.h>
29 30
@@ -52,6 +53,7 @@
52#include <plat/backlight.h> 53#include <plat/backlight.h>
53#include <plat/fb.h> 54#include <plat/fb.h>
54#include <plat/regs-fb.h> 55#include <plat/regs-fb.h>
56#include <plat/sdhci.h>
55 57
56#include "common.h" 58#include "common.h"
57 59
@@ -163,6 +165,25 @@ static struct platform_device *smdk6440_devices[] __initdata = {
163 &s5p6440_device_iis, 165 &s5p6440_device_iis,
164 &s3c_device_fb, 166 &s3c_device_fb,
165 &smdk6440_lcd_lte480wv, 167 &smdk6440_lcd_lte480wv,
168 &s3c_device_hsmmc0,
169 &s3c_device_hsmmc1,
170 &s3c_device_hsmmc2,
171};
172
173static struct s3c_sdhci_platdata smdk6440_hsmmc0_pdata __initdata = {
174 .cd_type = S3C_SDHCI_CD_NONE,
175};
176
177static struct s3c_sdhci_platdata smdk6440_hsmmc1_pdata __initdata = {
178 .cd_type = S3C_SDHCI_CD_INTERNAL,
179#if defined(CONFIG_S5P64X0_SD_CH1_8BIT)
180 .max_width = 8,
181 .host_caps = MMC_CAP_8_BIT_DATA,
182#endif
183};
184
185static struct s3c_sdhci_platdata smdk6440_hsmmc2_pdata __initdata = {
186 .cd_type = S3C_SDHCI_CD_NONE,
166}; 187};
167 188
168static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = { 189static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -236,6 +257,10 @@ static void __init smdk6440_machine_init(void)
236 s5p6440_set_lcd_interface(); 257 s5p6440_set_lcd_interface();
237 s3c_fb_set_platdata(&smdk6440_lcd_pdata); 258 s3c_fb_set_platdata(&smdk6440_lcd_pdata);
238 259
260 s3c_sdhci0_set_platdata(&smdk6440_hsmmc0_pdata);
261 s3c_sdhci1_set_platdata(&smdk6440_hsmmc1_pdata);
262 s3c_sdhci2_set_platdata(&smdk6440_hsmmc2_pdata);
263
239 platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices)); 264 platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
240} 265}
241 266
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 135cf5d8473..efb69e2f2af 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -24,6 +24,7 @@
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/pwm_backlight.h> 25#include <linux/pwm_backlight.h>
26#include <linux/fb.h> 26#include <linux/fb.h>
27#include <linux/mmc/host.h>
27 28
28#include <video/platform_lcd.h> 29#include <video/platform_lcd.h>
29 30
@@ -52,6 +53,7 @@
52#include <plat/backlight.h> 53#include <plat/backlight.h>
53#include <plat/fb.h> 54#include <plat/fb.h>
54#include <plat/regs-fb.h> 55#include <plat/regs-fb.h>
56#include <plat/sdhci.h>
55 57
56#include "common.h" 58#include "common.h"
57 59
@@ -181,10 +183,28 @@ static struct platform_device *smdk6450_devices[] __initdata = {
181 &s5p6450_device_iis0, 183 &s5p6450_device_iis0,
182 &s3c_device_fb, 184 &s3c_device_fb,
183 &smdk6450_lcd_lte480wv, 185 &smdk6450_lcd_lte480wv,
184 186 &s3c_device_hsmmc0,
187 &s3c_device_hsmmc1,
188 &s3c_device_hsmmc2,
185 /* s5p6450_device_spi0 will be added */ 189 /* s5p6450_device_spi0 will be added */
186}; 190};
187 191
192static struct s3c_sdhci_platdata smdk6450_hsmmc0_pdata __initdata = {
193 .cd_type = S3C_SDHCI_CD_NONE,
194};
195
196static struct s3c_sdhci_platdata smdk6450_hsmmc1_pdata __initdata = {
197 .cd_type = S3C_SDHCI_CD_NONE,
198#if defined(CONFIG_S5P64X0_SD_CH1_8BIT)
199 .max_width = 8,
200 .host_caps = MMC_CAP_8_BIT_DATA,
201#endif
202};
203
204static struct s3c_sdhci_platdata smdk6450_hsmmc2_pdata __initdata = {
205 .cd_type = S3C_SDHCI_CD_NONE,
206};
207
188static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = { 208static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = {
189 .flags = 0, 209 .flags = 0,
190 .slave_addr = 0x10, 210 .slave_addr = 0x10,
@@ -256,6 +276,10 @@ static void __init smdk6450_machine_init(void)
256 s5p6450_set_lcd_interface(); 276 s5p6450_set_lcd_interface();
257 s3c_fb_set_platdata(&smdk6450_lcd_pdata); 277 s3c_fb_set_platdata(&smdk6450_lcd_pdata);
258 278
279 s3c_sdhci0_set_platdata(&smdk6450_hsmmc0_pdata);
280 s3c_sdhci1_set_platdata(&smdk6450_hsmmc1_pdata);
281 s3c_sdhci2_set_platdata(&smdk6450_hsmmc2_pdata);
282
259 platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices)); 283 platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
260} 284}
261 285
diff --git a/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c b/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
new file mode 100644
index 00000000000..8410af0d12b
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
@@ -0,0 +1,104 @@
1/* linux/arch/arm/mach-s5p64x0/setup-sdhci-gpio.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P64X0 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/platform_device.h>
14#include <linux/io.h>
15#include <linux/gpio.h>
16
17#include <mach/regs-gpio.h>
18#include <mach/regs-clock.h>
19
20#include <plat/gpio-cfg.h>
21#include <plat/sdhci.h>
22#include <plat/cpu.h>
23
24void s5p64x0_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
25{
26 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
27
28 /* Set all the necessary GPG pins to special-function 2 */
29 if (soc_is_s5p6450())
30 s3c_gpio_cfgrange_nopull(S5P6450_GPG(0), 2 + width,
31 S3C_GPIO_SFN(2));
32 else
33 s3c_gpio_cfgrange_nopull(S5P6440_GPG(0), 2 + width,
34 S3C_GPIO_SFN(2));
35
36 /* Set GPG[6] pin to special-function 2 - MMC0 CDn */
37 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
38 if (soc_is_s5p6450()) {
39 s3c_gpio_setpull(S5P6450_GPG(6), S3C_GPIO_PULL_UP);
40 s3c_gpio_cfgpin(S5P6450_GPG(6), S3C_GPIO_SFN(2));
41 } else {
42 s3c_gpio_setpull(S5P6440_GPG(6), S3C_GPIO_PULL_UP);
43 s3c_gpio_cfgpin(S5P6440_GPG(6), S3C_GPIO_SFN(2));
44 }
45 }
46}
47
48void s5p64x0_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
49{
50 struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
51
52 /* Set GPH[0:1] pins to special-function 2 - CLK and CMD */
53 if (soc_is_s5p6450())
54 s3c_gpio_cfgrange_nopull(S5P6450_GPH(0), 2, S3C_GPIO_SFN(2));
55 else
56 s3c_gpio_cfgrange_nopull(S5P6440_GPH(0), 2 , S3C_GPIO_SFN(2));
57
58 switch (width) {
59 case 8:
60 /* Set data pins GPH[6:9] special-function 2 */
61 if (soc_is_s5p6450())
62 s3c_gpio_cfgrange_nopull(S5P6450_GPH(6), 4,
63 S3C_GPIO_SFN(2));
64 else
65 s3c_gpio_cfgrange_nopull(S5P6440_GPH(6), 4,
66 S3C_GPIO_SFN(2));
67 case 4:
68 /* set data pins GPH[2:5] special-function 2 */
69 if (soc_is_s5p6450())
70 s3c_gpio_cfgrange_nopull(S5P6450_GPH(2), 4,
71 S3C_GPIO_SFN(2));
72 else
73 s3c_gpio_cfgrange_nopull(S5P6440_GPH(2), 4,
74 S3C_GPIO_SFN(2));
75 default:
76 break;
77 }
78
79 /* Set GPG[6] pin to special-funtion 3 : MMC1 CDn */
80 if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
81 if (soc_is_s5p6450()) {
82 s3c_gpio_setpull(S5P6450_GPG(6), S3C_GPIO_PULL_UP);
83 s3c_gpio_cfgpin(S5P6450_GPG(6), S3C_GPIO_SFN(3));
84 } else {
85 s3c_gpio_setpull(S5P6440_GPG(6), S3C_GPIO_PULL_UP);
86 s3c_gpio_cfgpin(S5P6440_GPG(6), S3C_GPIO_SFN(3));
87 }
88 }
89}
90
91void s5p6440_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
92{
93 /* Set GPC[4:5] pins to special-function 3 - CLK and CMD */
94 s3c_gpio_cfgrange_nopull(S5P6440_GPC(4), 2, S3C_GPIO_SFN(3));
95
96 /* Set data pins GPH[6:9] pins to special-function 3 */
97 s3c_gpio_cfgrange_nopull(S5P6440_GPH(6), 4, S3C_GPIO_SFN(3));
98}
99
100void s5p6450_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
101{
102 /* Set all the necessary GPG pins to special-function 3 */
103 s3c_gpio_cfgrange_nopull(S5P6450_GPG(7), 2 + width, S3C_GPIO_SFN(3));
104}
diff --git a/arch/arm/mach-s5p64x0/setup-spi.c b/arch/arm/mach-s5p64x0/setup-spi.c
new file mode 100644
index 00000000000..e9b84124035
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-spi.c
@@ -0,0 +1,55 @@
1/* linux/arch/arm/mach-s5p64x0/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13#include <linux/io.h>
14
15#include <plat/gpio-cfg.h>
16#include <plat/cpu.h>
17#include <plat/s3c64xx-spi.h>
18
19#ifdef CONFIG_S3C64XX_DEV_SPI0
20struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
21 .fifo_lvl_mask = 0x1ff,
22 .rx_lvl_offset = 15,
23 .tx_st_done = 25,
24};
25
26int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
27{
28 if (soc_is_s5p6450())
29 s3c_gpio_cfgall_range(S5P6450_GPC(0), 3,
30 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
31 else
32 s3c_gpio_cfgall_range(S5P6440_GPC(0), 3,
33 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
34 return 0;
35}
36#endif
37
38#ifdef CONFIG_S3C64XX_DEV_SPI1
39struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
40 .fifo_lvl_mask = 0x7f,
41 .rx_lvl_offset = 15,
42 .tx_st_done = 25,
43};
44
45int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
46{
47 if (soc_is_s5p6450())
48 s3c_gpio_cfgall_range(S5P6450_GPC(4), 3,
49 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
50 else
51 s3c_gpio_cfgall_range(S5P6440_GPC(4), 3,
52 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
53 return 0;
54}
55#endif
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index e538a4c67e9..75a26eaf263 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -45,6 +45,11 @@ config S5PC100_SETUP_SDHCI_GPIO
45 help 45 help
46 Common setup code for SDHCI gpio. 46 Common setup code for SDHCI gpio.
47 47
48config S5PC100_SETUP_SPI
49 bool
50 help
51 Common setup code for SPI GPIO configurations.
52
48config MACH_SMDKC100 53config MACH_SMDKC100
49 bool "SMDKC100" 54 bool "SMDKC100"
50 select CPU_S5PC100 55 select CPU_S5PC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index c3166c4d2ac..118c711f74e 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -22,12 +22,11 @@ obj-$(CONFIG_MACH_SMDKC100) += mach-smdkc100.o
22# device support 22# device support
23 23
24obj-y += dev-audio.o 24obj-y += dev-audio.o
25obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
26 25
27obj-y += setup-i2c0.o 26obj-y += setup-i2c0.o
28obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o 27obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o
29obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o 28obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
30obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o 29obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o
31obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o 30obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o
32obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o
33obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 31obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
32obj-$(CONFIG_S5PC100_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index c4c74893f53..247194dd366 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -427,24 +427,6 @@ static struct clk init_clocks_off[] = {
427 .enable = s5pc100_d0_2_ctrl, 427 .enable = s5pc100_d0_2_ctrl,
428 .ctrlbit = (1 << 1), 428 .ctrlbit = (1 << 1),
429 }, { 429 }, {
430 .name = "hsmmc",
431 .devname = "s3c-sdhci.2",
432 .parent = &clk_div_d1_bus.clk,
433 .enable = s5pc100_d1_0_ctrl,
434 .ctrlbit = (1 << 7),
435 }, {
436 .name = "hsmmc",
437 .devname = "s3c-sdhci.1",
438 .parent = &clk_div_d1_bus.clk,
439 .enable = s5pc100_d1_0_ctrl,
440 .ctrlbit = (1 << 6),
441 }, {
442 .name = "hsmmc",
443 .devname = "s3c-sdhci.0",
444 .parent = &clk_div_d1_bus.clk,
445 .enable = s5pc100_d1_0_ctrl,
446 .ctrlbit = (1 << 5),
447 }, {
448 .name = "modemif", 430 .name = "modemif",
449 .parent = &clk_div_d1_bus.clk, 431 .parent = &clk_div_d1_bus.clk,
450 .enable = s5pc100_d1_0_ctrl, 432 .enable = s5pc100_d1_0_ctrl,
@@ -674,24 +656,6 @@ static struct clk init_clocks_off[] = {
674 .enable = s5pc100_d1_5_ctrl, 656 .enable = s5pc100_d1_5_ctrl,
675 .ctrlbit = (1 << 8), 657 .ctrlbit = (1 << 8),
676 }, { 658 }, {
677 .name = "spi_48m",
678 .devname = "s3c64xx-spi.0",
679 .parent = &clk_mout_48m.clk,
680 .enable = s5pc100_sclk0_ctrl,
681 .ctrlbit = (1 << 7),
682 }, {
683 .name = "spi_48m",
684 .devname = "s3c64xx-spi.1",
685 .parent = &clk_mout_48m.clk,
686 .enable = s5pc100_sclk0_ctrl,
687 .ctrlbit = (1 << 8),
688 }, {
689 .name = "spi_48m",
690 .devname = "s3c64xx-spi.2",
691 .parent = &clk_mout_48m.clk,
692 .enable = s5pc100_sclk0_ctrl,
693 .ctrlbit = (1 << 9),
694 }, {
695 .name = "mmc_48m", 659 .name = "mmc_48m",
696 .devname = "s3c-sdhci.0", 660 .devname = "s3c-sdhci.0",
697 .parent = &clk_mout_48m.clk, 661 .parent = &clk_mout_48m.clk,
@@ -712,6 +676,54 @@ static struct clk init_clocks_off[] = {
712 }, 676 },
713}; 677};
714 678
679static struct clk clk_hsmmc2 = {
680 .name = "hsmmc",
681 .devname = "s3c-sdhci.2",
682 .parent = &clk_div_d1_bus.clk,
683 .enable = s5pc100_d1_0_ctrl,
684 .ctrlbit = (1 << 7),
685};
686
687static struct clk clk_hsmmc1 = {
688 .name = "hsmmc",
689 .devname = "s3c-sdhci.1",
690 .parent = &clk_div_d1_bus.clk,
691 .enable = s5pc100_d1_0_ctrl,
692 .ctrlbit = (1 << 6),
693};
694
695static struct clk clk_hsmmc0 = {
696 .name = "hsmmc",
697 .devname = "s3c-sdhci.0",
698 .parent = &clk_div_d1_bus.clk,
699 .enable = s5pc100_d1_0_ctrl,
700 .ctrlbit = (1 << 5),
701};
702
703static struct clk clk_48m_spi0 = {
704 .name = "spi_48m",
705 .devname = "s3c64xx-spi.0",
706 .parent = &clk_mout_48m.clk,
707 .enable = s5pc100_sclk0_ctrl,
708 .ctrlbit = (1 << 7),
709};
710
711static struct clk clk_48m_spi1 = {
712 .name = "spi_48m",
713 .devname = "s3c64xx-spi.1",
714 .parent = &clk_mout_48m.clk,
715 .enable = s5pc100_sclk0_ctrl,
716 .ctrlbit = (1 << 8),
717};
718
719static struct clk clk_48m_spi2 = {
720 .name = "spi_48m",
721 .devname = "s3c64xx-spi.2",
722 .parent = &clk_mout_48m.clk,
723 .enable = s5pc100_sclk0_ctrl,
724 .ctrlbit = (1 << 9),
725};
726
715static struct clk clk_vclk54m = { 727static struct clk clk_vclk54m = {
716 .name = "vclk_54m", 728 .name = "vclk_54m",
717 .rate = 54000000, 729 .rate = 54000000,
@@ -930,49 +942,6 @@ static struct clksrc_clk clk_sclk_spdif = {
930static struct clksrc_clk clksrcs[] = { 942static struct clksrc_clk clksrcs[] = {
931 { 943 {
932 .clk = { 944 .clk = {
933 .name = "sclk_spi",
934 .devname = "s3c64xx-spi.0",
935 .ctrlbit = (1 << 4),
936 .enable = s5pc100_sclk0_ctrl,
937
938 },
939 .sources = &clk_src_group1,
940 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
941 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
942 }, {
943 .clk = {
944 .name = "sclk_spi",
945 .devname = "s3c64xx-spi.1",
946 .ctrlbit = (1 << 5),
947 .enable = s5pc100_sclk0_ctrl,
948
949 },
950 .sources = &clk_src_group1,
951 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
952 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
953 }, {
954 .clk = {
955 .name = "sclk_spi",
956 .devname = "s3c64xx-spi.2",
957 .ctrlbit = (1 << 6),
958 .enable = s5pc100_sclk0_ctrl,
959
960 },
961 .sources = &clk_src_group1,
962 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
963 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
964 }, {
965 .clk = {
966 .name = "uclk1",
967 .ctrlbit = (1 << 3),
968 .enable = s5pc100_sclk0_ctrl,
969
970 },
971 .sources = &clk_src_group2,
972 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
973 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
974 }, {
975 .clk = {
976 .name = "sclk_mixer", 945 .name = "sclk_mixer",
977 .ctrlbit = (1 << 6), 946 .ctrlbit = (1 << 6),
978 .enable = s5pc100_sclk0_ctrl, 947 .enable = s5pc100_sclk0_ctrl,
@@ -1025,39 +994,6 @@ static struct clksrc_clk clksrcs[] = {
1025 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 }, 994 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 },
1026 }, { 995 }, {
1027 .clk = { 996 .clk = {
1028 .name = "sclk_mmc",
1029 .devname = "s3c-sdhci.0",
1030 .ctrlbit = (1 << 12),
1031 .enable = s5pc100_sclk1_ctrl,
1032
1033 },
1034 .sources = &clk_src_mmc0,
1035 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
1036 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
1037 }, {
1038 .clk = {
1039 .name = "sclk_mmc",
1040 .devname = "s3c-sdhci.1",
1041 .ctrlbit = (1 << 13),
1042 .enable = s5pc100_sclk1_ctrl,
1043
1044 },
1045 .sources = &clk_src_mmc12,
1046 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
1047 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
1048 }, {
1049 .clk = {
1050 .name = "sclk_mmc",
1051 .devname = "s3c-sdhci.2",
1052 .ctrlbit = (1 << 14),
1053 .enable = s5pc100_sclk1_ctrl,
1054
1055 },
1056 .sources = &clk_src_mmc12,
1057 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
1058 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
1059 }, {
1060 .clk = {
1061 .name = "sclk_irda", 997 .name = "sclk_irda",
1062 .ctrlbit = (1 << 10), 998 .ctrlbit = (1 << 10),
1063 .enable = s5pc100_sclk0_ctrl, 999 .enable = s5pc100_sclk0_ctrl,
@@ -1099,6 +1035,89 @@ static struct clksrc_clk clksrcs[] = {
1099 }, 1035 },
1100}; 1036};
1101 1037
1038static struct clksrc_clk clk_sclk_uart = {
1039 .clk = {
1040 .name = "uclk1",
1041 .ctrlbit = (1 << 3),
1042 .enable = s5pc100_sclk0_ctrl,
1043 },
1044 .sources = &clk_src_group2,
1045 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
1046 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
1047};
1048
1049static struct clksrc_clk clk_sclk_mmc0 = {
1050 .clk = {
1051 .name = "sclk_mmc",
1052 .devname = "s3c-sdhci.0",
1053 .ctrlbit = (1 << 12),
1054 .enable = s5pc100_sclk1_ctrl,
1055 },
1056 .sources = &clk_src_mmc0,
1057 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
1058 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
1059};
1060
1061static struct clksrc_clk clk_sclk_mmc1 = {
1062 .clk = {
1063 .name = "sclk_mmc",
1064 .devname = "s3c-sdhci.1",
1065 .ctrlbit = (1 << 13),
1066 .enable = s5pc100_sclk1_ctrl,
1067 },
1068 .sources = &clk_src_mmc12,
1069 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
1070 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
1071};
1072
1073static struct clksrc_clk clk_sclk_mmc2 = {
1074 .clk = {
1075 .name = "sclk_mmc",
1076 .devname = "s3c-sdhci.2",
1077 .ctrlbit = (1 << 14),
1078 .enable = s5pc100_sclk1_ctrl,
1079 },
1080 .sources = &clk_src_mmc12,
1081 .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
1082 .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
1083};
1084
1085static struct clksrc_clk clk_sclk_spi0 = {
1086 .clk = {
1087 .name = "sclk_spi",
1088 .devname = "s3c64xx-spi.0",
1089 .ctrlbit = (1 << 4),
1090 .enable = s5pc100_sclk0_ctrl,
1091 },
1092 .sources = &clk_src_group1,
1093 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
1094 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
1095};
1096
1097static struct clksrc_clk clk_sclk_spi1 = {
1098 .clk = {
1099 .name = "sclk_spi",
1100 .devname = "s3c64xx-spi.1",
1101 .ctrlbit = (1 << 5),
1102 .enable = s5pc100_sclk0_ctrl,
1103 },
1104 .sources = &clk_src_group1,
1105 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
1106 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
1107};
1108
1109static struct clksrc_clk clk_sclk_spi2 = {
1110 .clk = {
1111 .name = "sclk_spi",
1112 .devname = "s3c64xx-spi.2",
1113 .ctrlbit = (1 << 6),
1114 .enable = s5pc100_sclk0_ctrl,
1115 },
1116 .sources = &clk_src_group1,
1117 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
1118 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
1119};
1120
1102/* Clock initialisation code */ 1121/* Clock initialisation code */
1103static struct clksrc_clk *sysclks[] = { 1122static struct clksrc_clk *sysclks[] = {
1104 &clk_mout_apll, 1123 &clk_mout_apll,
@@ -1128,6 +1147,25 @@ static struct clksrc_clk *sysclks[] = {
1128 &clk_sclk_spdif, 1147 &clk_sclk_spdif,
1129}; 1148};
1130 1149
1150static struct clk *clk_cdev[] = {
1151 &clk_hsmmc0,
1152 &clk_hsmmc1,
1153 &clk_hsmmc2,
1154 &clk_48m_spi0,
1155 &clk_48m_spi1,
1156 &clk_48m_spi2,
1157};
1158
1159static struct clksrc_clk *clksrc_cdev[] = {
1160 &clk_sclk_uart,
1161 &clk_sclk_mmc0,
1162 &clk_sclk_mmc1,
1163 &clk_sclk_mmc2,
1164 &clk_sclk_spi0,
1165 &clk_sclk_spi1,
1166 &clk_sclk_spi2,
1167};
1168
1131void __init_or_cpufreq s5pc100_setup_clocks(void) 1169void __init_or_cpufreq s5pc100_setup_clocks(void)
1132{ 1170{
1133 unsigned long xtal; 1171 unsigned long xtal;
@@ -1267,6 +1305,24 @@ static struct clk *clks[] __initdata = {
1267 &clk_pcmcdclk1, 1305 &clk_pcmcdclk1,
1268}; 1306};
1269 1307
1308static struct clk_lookup s5pc100_clk_lookup[] = {
1309 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
1310 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk),
1311 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
1312 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
1313 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
1314 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1315 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1316 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1317 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1318 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_48m_spi0),
1319 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_sclk_spi0.clk),
1320 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_48m_spi1),
1321 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_sclk_spi1.clk),
1322 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk1", &clk_48m_spi2),
1323 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk2", &clk_sclk_spi2.clk),
1324};
1325
1270void __init s5pc100_register_clocks(void) 1326void __init s5pc100_register_clocks(void)
1271{ 1327{
1272 int ptr; 1328 int ptr;
@@ -1278,9 +1334,16 @@ void __init s5pc100_register_clocks(void)
1278 1334
1279 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1335 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1280 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1336 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1337 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1338 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1281 1339
1282 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1340 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1283 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1341 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1342 clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup));
1343
1344 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1345 for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1346 s3c_disable_clocks(clk_cdev[ptr], 1);
1284 1347
1285 s3c24xx_register_clock(&dummy_apb_pclk); 1348 s3c24xx_register_clock(&dummy_apb_pclk);
1286 1349
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c
deleted file mode 100644
index e5d6c4dceb5..00000000000
--- a/arch/arm/mach-s5pc100/dev-spi.c
+++ /dev/null
@@ -1,227 +0,0 @@
1/* linux/arch/arm/mach-s5pc100/dev-spi.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
14
15#include <mach/dma.h>
16#include <mach/map.h>
17#include <mach/spi-clocks.h>
18#include <mach/irqs.h>
19
20#include <plat/s3c64xx-spi.h>
21#include <plat/gpio-cfg.h>
22#include <plat/irqs.h>
23
24static char *spi_src_clks[] = {
25 [S5PC100_SPI_SRCCLK_PCLK] = "pclk",
26 [S5PC100_SPI_SRCCLK_48M] = "spi_48m",
27 [S5PC100_SPI_SRCCLK_SPIBUS] = "spi_bus",
28};
29
30/* SPI Controller platform_devices */
31
32/* Since we emulate multi-cs capability, we do not touch the CS.
33 * The emulated CS is toggled by board specific mechanism, as it can
34 * be either some immediate GPIO or some signal out of some other
35 * chip in between ... or some yet another way.
36 * We simply do not assume anything about CS.
37 */
38static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
39{
40 switch (pdev->id) {
41 case 0:
42 s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
43 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
44 break;
45
46 case 1:
47 s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
48 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
49 break;
50
51 case 2:
52 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
53 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
54 s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
55 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
56 break;
57
58 default:
59 dev_err(&pdev->dev, "Invalid SPI Controller number!");
60 return -EINVAL;
61 }
62
63 return 0;
64}
65
66static struct resource s5pc100_spi0_resource[] = {
67 [0] = {
68 .start = S5PC100_PA_SPI0,
69 .end = S5PC100_PA_SPI0 + 0x100 - 1,
70 .flags = IORESOURCE_MEM,
71 },
72 [1] = {
73 .start = DMACH_SPI0_TX,
74 .end = DMACH_SPI0_TX,
75 .flags = IORESOURCE_DMA,
76 },
77 [2] = {
78 .start = DMACH_SPI0_RX,
79 .end = DMACH_SPI0_RX,
80 .flags = IORESOURCE_DMA,
81 },
82 [3] = {
83 .start = IRQ_SPI0,
84 .end = IRQ_SPI0,
85 .flags = IORESOURCE_IRQ,
86 },
87};
88
89static struct s3c64xx_spi_info s5pc100_spi0_pdata = {
90 .cfg_gpio = s5pc100_spi_cfg_gpio,
91 .fifo_lvl_mask = 0x7f,
92 .rx_lvl_offset = 13,
93 .high_speed = 1,
94 .tx_st_done = 21,
95};
96
97static u64 spi_dmamask = DMA_BIT_MASK(32);
98
99struct platform_device s5pc100_device_spi0 = {
100 .name = "s3c64xx-spi",
101 .id = 0,
102 .num_resources = ARRAY_SIZE(s5pc100_spi0_resource),
103 .resource = s5pc100_spi0_resource,
104 .dev = {
105 .dma_mask = &spi_dmamask,
106 .coherent_dma_mask = DMA_BIT_MASK(32),
107 .platform_data = &s5pc100_spi0_pdata,
108 },
109};
110
111static struct resource s5pc100_spi1_resource[] = {
112 [0] = {
113 .start = S5PC100_PA_SPI1,
114 .end = S5PC100_PA_SPI1 + 0x100 - 1,
115 .flags = IORESOURCE_MEM,
116 },
117 [1] = {
118 .start = DMACH_SPI1_TX,
119 .end = DMACH_SPI1_TX,
120 .flags = IORESOURCE_DMA,
121 },
122 [2] = {
123 .start = DMACH_SPI1_RX,
124 .end = DMACH_SPI1_RX,
125 .flags = IORESOURCE_DMA,
126 },
127 [3] = {
128 .start = IRQ_SPI1,
129 .end = IRQ_SPI1,
130 .flags = IORESOURCE_IRQ,
131 },
132};
133
134static struct s3c64xx_spi_info s5pc100_spi1_pdata = {
135 .cfg_gpio = s5pc100_spi_cfg_gpio,
136 .fifo_lvl_mask = 0x7f,
137 .rx_lvl_offset = 13,
138 .high_speed = 1,
139 .tx_st_done = 21,
140};
141
142struct platform_device s5pc100_device_spi1 = {
143 .name = "s3c64xx-spi",
144 .id = 1,
145 .num_resources = ARRAY_SIZE(s5pc100_spi1_resource),
146 .resource = s5pc100_spi1_resource,
147 .dev = {
148 .dma_mask = &spi_dmamask,
149 .coherent_dma_mask = DMA_BIT_MASK(32),
150 .platform_data = &s5pc100_spi1_pdata,
151 },
152};
153
154static struct resource s5pc100_spi2_resource[] = {
155 [0] = {
156 .start = S5PC100_PA_SPI2,
157 .end = S5PC100_PA_SPI2 + 0x100 - 1,
158 .flags = IORESOURCE_MEM,
159 },
160 [1] = {
161 .start = DMACH_SPI2_TX,
162 .end = DMACH_SPI2_TX,
163 .flags = IORESOURCE_DMA,
164 },
165 [2] = {
166 .start = DMACH_SPI2_RX,
167 .end = DMACH_SPI2_RX,
168 .flags = IORESOURCE_DMA,
169 },
170 [3] = {
171 .start = IRQ_SPI2,
172 .end = IRQ_SPI2,
173 .flags = IORESOURCE_IRQ,
174 },
175};
176
177static struct s3c64xx_spi_info s5pc100_spi2_pdata = {
178 .cfg_gpio = s5pc100_spi_cfg_gpio,
179 .fifo_lvl_mask = 0x7f,
180 .rx_lvl_offset = 13,
181 .high_speed = 1,
182 .tx_st_done = 21,
183};
184
185struct platform_device s5pc100_device_spi2 = {
186 .name = "s3c64xx-spi",
187 .id = 2,
188 .num_resources = ARRAY_SIZE(s5pc100_spi2_resource),
189 .resource = s5pc100_spi2_resource,
190 .dev = {
191 .dma_mask = &spi_dmamask,
192 .coherent_dma_mask = DMA_BIT_MASK(32),
193 .platform_data = &s5pc100_spi2_pdata,
194 },
195};
196
197void __init s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
198{
199 struct s3c64xx_spi_info *pd;
200
201 /* Reject invalid configuration */
202 if (!num_cs || src_clk_nr < 0
203 || src_clk_nr > S5PC100_SPI_SRCCLK_SPIBUS) {
204 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
205 return;
206 }
207
208 switch (cntrlr) {
209 case 0:
210 pd = &s5pc100_spi0_pdata;
211 break;
212 case 1:
213 pd = &s5pc100_spi1_pdata;
214 break;
215 case 2:
216 pd = &s5pc100_spi2_pdata;
217 break;
218 default:
219 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
220 __func__, cntrlr);
221 return;
222 }
223
224 pd->num_cs = num_cs;
225 pd->src_clk_nr = src_clk_nr;
226 pd->src_clk_name = spi_src_clks[src_clk_nr];
227}
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index 065a087f5a8..c841f4d313f 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -35,100 +35,42 @@
35 35
36static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
37 37
38struct dma_pl330_peri pdma0_peri[30] = { 38u8 pdma0_peri[] = {
39 { 39 DMACH_UART0_RX,
40 .peri_id = (u8)DMACH_UART0_RX, 40 DMACH_UART0_TX,
41 .rqtype = DEVTOMEM, 41 DMACH_UART1_RX,
42 }, { 42 DMACH_UART1_TX,
43 .peri_id = (u8)DMACH_UART0_TX, 43 DMACH_UART2_RX,
44 .rqtype = MEMTODEV, 44 DMACH_UART2_TX,
45 }, { 45 DMACH_UART3_RX,
46 .peri_id = (u8)DMACH_UART1_RX, 46 DMACH_UART3_TX,
47 .rqtype = DEVTOMEM, 47 DMACH_IRDA,
48 }, { 48 DMACH_I2S0_RX,
49 .peri_id = (u8)DMACH_UART1_TX, 49 DMACH_I2S0_TX,
50 .rqtype = MEMTODEV, 50 DMACH_I2S0S_TX,
51 }, { 51 DMACH_I2S1_RX,
52 .peri_id = (u8)DMACH_UART2_RX, 52 DMACH_I2S1_TX,
53 .rqtype = DEVTOMEM, 53 DMACH_I2S2_RX,
54 }, { 54 DMACH_I2S2_TX,
55 .peri_id = (u8)DMACH_UART2_TX, 55 DMACH_SPI0_RX,
56 .rqtype = MEMTODEV, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI1_RX,
58 .peri_id = (u8)DMACH_UART3_RX, 58 DMACH_SPI1_TX,
59 .rqtype = DEVTOMEM, 59 DMACH_SPI2_RX,
60 }, { 60 DMACH_SPI2_TX,
61 .peri_id = (u8)DMACH_UART3_TX, 61 DMACH_AC97_MICIN,
62 .rqtype = MEMTODEV, 62 DMACH_AC97_PCMIN,
63 }, { 63 DMACH_AC97_PCMOUT,
64 .peri_id = DMACH_IRDA, 64 DMACH_EXTERNAL,
65 }, { 65 DMACH_PWM,
66 .peri_id = (u8)DMACH_I2S0_RX, 66 DMACH_SPDIF,
67 .rqtype = DEVTOMEM, 67 DMACH_HSI_RX,
68 }, { 68 DMACH_HSI_TX,
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_I2S2_RX,
82 .rqtype = DEVTOMEM,
83 }, {
84 .peri_id = (u8)DMACH_I2S2_TX,
85 .rqtype = MEMTODEV,
86 }, {
87 .peri_id = (u8)DMACH_SPI0_RX,
88 .rqtype = DEVTOMEM,
89 }, {
90 .peri_id = (u8)DMACH_SPI0_TX,
91 .rqtype = MEMTODEV,
92 }, {
93 .peri_id = (u8)DMACH_SPI1_RX,
94 .rqtype = DEVTOMEM,
95 }, {
96 .peri_id = (u8)DMACH_SPI1_TX,
97 .rqtype = MEMTODEV,
98 }, {
99 .peri_id = (u8)DMACH_SPI2_RX,
100 .rqtype = DEVTOMEM,
101 }, {
102 .peri_id = (u8)DMACH_SPI2_TX,
103 .rqtype = MEMTODEV,
104 }, {
105 .peri_id = (u8)DMACH_AC97_MICIN,
106 .rqtype = DEVTOMEM,
107 }, {
108 .peri_id = (u8)DMACH_AC97_PCMIN,
109 .rqtype = DEVTOMEM,
110 }, {
111 .peri_id = (u8)DMACH_AC97_PCMOUT,
112 .rqtype = MEMTODEV,
113 }, {
114 .peri_id = (u8)DMACH_EXTERNAL,
115 }, {
116 .peri_id = (u8)DMACH_PWM,
117 }, {
118 .peri_id = (u8)DMACH_SPDIF,
119 .rqtype = MEMTODEV,
120 }, {
121 .peri_id = (u8)DMACH_HSI_RX,
122 .rqtype = DEVTOMEM,
123 }, {
124 .peri_id = (u8)DMACH_HSI_TX,
125 .rqtype = MEMTODEV,
126 },
127}; 69};
128 70
129struct dma_pl330_platdata s5pc100_pdma0_pdata = { 71struct dma_pl330_platdata s5pc100_pdma0_pdata = {
130 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 72 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
131 .peri = pdma0_peri, 73 .peri_id = pdma0_peri,
132}; 74};
133 75
134struct amba_device s5pc100_device_pdma0 = { 76struct amba_device s5pc100_device_pdma0 = {
@@ -147,98 +89,42 @@ struct amba_device s5pc100_device_pdma0 = {
147 .periphid = 0x00041330, 89 .periphid = 0x00041330,
148}; 90};
149 91
150struct dma_pl330_peri pdma1_peri[30] = { 92u8 pdma1_peri[] = {
151 { 93 DMACH_UART0_RX,
152 .peri_id = (u8)DMACH_UART0_RX, 94 DMACH_UART0_TX,
153 .rqtype = DEVTOMEM, 95 DMACH_UART1_RX,
154 }, { 96 DMACH_UART1_TX,
155 .peri_id = (u8)DMACH_UART0_TX, 97 DMACH_UART2_RX,
156 .rqtype = MEMTODEV, 98 DMACH_UART2_TX,
157 }, { 99 DMACH_UART3_RX,
158 .peri_id = (u8)DMACH_UART1_RX, 100 DMACH_UART3_TX,
159 .rqtype = DEVTOMEM, 101 DMACH_IRDA,
160 }, { 102 DMACH_I2S0_RX,
161 .peri_id = (u8)DMACH_UART1_TX, 103 DMACH_I2S0_TX,
162 .rqtype = MEMTODEV, 104 DMACH_I2S0S_TX,
163 }, { 105 DMACH_I2S1_RX,
164 .peri_id = (u8)DMACH_UART2_RX, 106 DMACH_I2S1_TX,
165 .rqtype = DEVTOMEM, 107 DMACH_I2S2_RX,
166 }, { 108 DMACH_I2S2_TX,
167 .peri_id = (u8)DMACH_UART2_TX, 109 DMACH_SPI0_RX,
168 .rqtype = MEMTODEV, 110 DMACH_SPI0_TX,
169 }, { 111 DMACH_SPI1_RX,
170 .peri_id = (u8)DMACH_UART3_RX, 112 DMACH_SPI1_TX,
171 .rqtype = DEVTOMEM, 113 DMACH_SPI2_RX,
172 }, { 114 DMACH_SPI2_TX,
173 .peri_id = (u8)DMACH_UART3_TX, 115 DMACH_PCM0_RX,
174 .rqtype = MEMTODEV, 116 DMACH_PCM0_TX,
175 }, { 117 DMACH_PCM1_RX,
176 .peri_id = DMACH_IRDA, 118 DMACH_PCM1_TX,
177 }, { 119 DMACH_MSM_REQ0,
178 .peri_id = (u8)DMACH_I2S0_RX, 120 DMACH_MSM_REQ1,
179 .rqtype = DEVTOMEM, 121 DMACH_MSM_REQ2,
180 }, { 122 DMACH_MSM_REQ3,
181 .peri_id = (u8)DMACH_I2S0_TX,
182 .rqtype = MEMTODEV,
183 }, {
184 .peri_id = (u8)DMACH_I2S0S_TX,
185 .rqtype = MEMTODEV,
186 }, {
187 .peri_id = (u8)DMACH_I2S1_RX,
188 .rqtype = DEVTOMEM,
189 }, {
190 .peri_id = (u8)DMACH_I2S1_TX,
191 .rqtype = MEMTODEV,
192 }, {
193 .peri_id = (u8)DMACH_I2S2_RX,
194 .rqtype = DEVTOMEM,
195 }, {
196 .peri_id = (u8)DMACH_I2S2_TX,
197 .rqtype = MEMTODEV,
198 }, {
199 .peri_id = (u8)DMACH_SPI0_RX,
200 .rqtype = DEVTOMEM,
201 }, {
202 .peri_id = (u8)DMACH_SPI0_TX,
203 .rqtype = MEMTODEV,
204 }, {
205 .peri_id = (u8)DMACH_SPI1_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_SPI1_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_SPI2_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_SPI2_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_PCM0_RX,
218 .rqtype = DEVTOMEM,
219 }, {
220 .peri_id = (u8)DMACH_PCM1_TX,
221 .rqtype = MEMTODEV,
222 }, {
223 .peri_id = (u8)DMACH_PCM1_RX,
224 .rqtype = DEVTOMEM,
225 }, {
226 .peri_id = (u8)DMACH_PCM1_TX,
227 .rqtype = MEMTODEV,
228 }, {
229 .peri_id = (u8)DMACH_MSM_REQ0,
230 }, {
231 .peri_id = (u8)DMACH_MSM_REQ1,
232 }, {
233 .peri_id = (u8)DMACH_MSM_REQ2,
234 }, {
235 .peri_id = (u8)DMACH_MSM_REQ3,
236 },
237}; 123};
238 124
239struct dma_pl330_platdata s5pc100_pdma1_pdata = { 125struct dma_pl330_platdata s5pc100_pdma1_pdata = {
240 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 126 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
241 .peri = pdma1_peri, 127 .peri_id = pdma1_peri,
242}; 128};
243 129
244struct amba_device s5pc100_device_pdma1 = { 130struct amba_device s5pc100_device_pdma1 = {
@@ -259,7 +145,12 @@ struct amba_device s5pc100_device_pdma1 = {
259 145
260static int __init s5pc100_dma_init(void) 146static int __init s5pc100_dma_init(void)
261{ 147{
148 dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask);
149 dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask);
262 amba_device_register(&s5pc100_device_pdma0, &iomem_resource); 150 amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
151
152 dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask);
153 dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask);
263 amba_device_register(&s5pc100_device_pdma1, &iomem_resource); 154 amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
264 155
265 return 0; 156 return 0;
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index d2eb4757381..2870f12c792 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -97,6 +97,8 @@
97#define IRQ_SDMFIQ S5P_IRQ_VIC2(31) 97#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
98#define IRQ_VIC_END S5P_IRQ_VIC2(31) 98#define IRQ_VIC_END S5P_IRQ_VIC2(31)
99 99
100#define IRQ_TIMER_BASE (11)
101
100#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 102#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
101#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 103#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
102 104
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index ccbe6b767f7..54bc4f82e17 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -100,6 +100,9 @@
100#define S3C_PA_USB_HSOTG S5PC100_PA_USB_HSOTG 100#define S3C_PA_USB_HSOTG S5PC100_PA_USB_HSOTG
101#define S3C_PA_USB_HSPHY S5PC100_PA_USB_HSPHY 101#define S3C_PA_USB_HSPHY S5PC100_PA_USB_HSPHY
102#define S3C_PA_WDT S5PC100_PA_WATCHDOG 102#define S3C_PA_WDT S5PC100_PA_WATCHDOG
103#define S3C_PA_SPI0 S5PC100_PA_SPI0
104#define S3C_PA_SPI1 S5PC100_PA_SPI1
105#define S3C_PA_SPI2 S5PC100_PA_SPI2
103 106
104#define S5P_PA_CHIPID S5PC100_PA_CHIPID 107#define S5P_PA_CHIPID S5PC100_PA_CHIPID
105#define S5P_PA_FIMC0 S5PC100_PA_FIMC0 108#define S5P_PA_FIMC0 S5PC100_PA_FIMC0
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
deleted file mode 100644
index 6418c6e8a7b..00000000000
--- a/arch/arm/mach-s5pc100/setup-sdhci.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
2 *
3 * Copyright 2008 Samsung Electronics
4 *
5 * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
6 *
7 * Based on mach-s3c6410/setup-sdhci.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/types.h>
15
16/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
17
18char *s5pc100_hsmmc_clksrcs[4] = {
19 [0] = "hsmmc", /* HCLK */
20 /* [1] = "hsmmc", - duplicate HCLK entry */
21 [2] = "sclk_mmc", /* mmc_bus */
22 /* [3] = "48m", - note not successfully used yet */
23};
diff --git a/arch/arm/mach-s5pc100/setup-spi.c b/arch/arm/mach-s5pc100/setup-spi.c
new file mode 100644
index 00000000000..431a6f747ca
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-spi.c
@@ -0,0 +1,65 @@
1/* linux/arch/arm/mach-s5pc100/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16
17#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = {
19 .fifo_lvl_mask = 0x7f,
20 .rx_lvl_offset = 13,
21 .high_speed = 1,
22 .tx_st_done = 21,
23};
24
25int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
26{
27 s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
28 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
29 return 0;
30}
31#endif
32
33#ifdef CONFIG_S3C64XX_DEV_SPI1
34struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = {
35 .fifo_lvl_mask = 0x7f,
36 .rx_lvl_offset = 13,
37 .high_speed = 1,
38 .tx_st_done = 21,
39};
40
41int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
42{
43 s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
44 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
45 return 0;
46}
47#endif
48
49#ifdef CONFIG_S3C64XX_DEV_SPI2
50struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = {
51 .fifo_lvl_mask = 0x7f,
52 .rx_lvl_offset = 13,
53 .high_speed = 1,
54 .tx_st_done = 21,
55};
56
57int s3c64xx_spi2_cfg_gpio(struct platform_device *dev)
58{
59 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
60 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
61 s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
62 S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
63 return 0;
64}
65#endif
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 646057ab2e4..2cdc42e838b 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -60,6 +60,11 @@ config S5PV210_SETUP_FIMC
60 help 60 help
61 Common setup code for the camera interfaces. 61 Common setup code for the camera interfaces.
62 62
63config S5PV210_SETUP_SPI
64 bool
65 help
66 Common setup code for SPI GPIO configurations.
67
63menu "S5PC110 Machines" 68menu "S5PC110 Machines"
64 69
65config MACH_AQUILA 70config MACH_AQUILA
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 4c59186de95..76a121dd52b 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
29# device support 29# device support
30 30
31obj-y += dev-audio.o 31obj-y += dev-audio.o
32obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
33 32
34obj-y += setup-i2c0.o 33obj-y += setup-i2c0.o
35obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o 34obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
@@ -38,5 +37,5 @@ obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
38obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o 37obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o
39obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o 38obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
40obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o 39obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o
41obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o
42obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 40obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
41obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 04c9b578e62..c78dfddd77f 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -400,30 +400,6 @@ static struct clk init_clocks_off[] = {
400 .enable = s5pv210_clk_ip1_ctrl, 400 .enable = s5pv210_clk_ip1_ctrl,
401 .ctrlbit = (1<<25), 401 .ctrlbit = (1<<25),
402 }, { 402 }, {
403 .name = "hsmmc",
404 .devname = "s3c-sdhci.0",
405 .parent = &clk_hclk_psys.clk,
406 .enable = s5pv210_clk_ip2_ctrl,
407 .ctrlbit = (1<<16),
408 }, {
409 .name = "hsmmc",
410 .devname = "s3c-sdhci.1",
411 .parent = &clk_hclk_psys.clk,
412 .enable = s5pv210_clk_ip2_ctrl,
413 .ctrlbit = (1<<17),
414 }, {
415 .name = "hsmmc",
416 .devname = "s3c-sdhci.2",
417 .parent = &clk_hclk_psys.clk,
418 .enable = s5pv210_clk_ip2_ctrl,
419 .ctrlbit = (1<<18),
420 }, {
421 .name = "hsmmc",
422 .devname = "s3c-sdhci.3",
423 .parent = &clk_hclk_psys.clk,
424 .enable = s5pv210_clk_ip2_ctrl,
425 .ctrlbit = (1<<19),
426 }, {
427 .name = "systimer", 403 .name = "systimer",
428 .parent = &clk_pclk_psys.clk, 404 .parent = &clk_pclk_psys.clk,
429 .enable = s5pv210_clk_ip3_ctrl, 405 .enable = s5pv210_clk_ip3_ctrl,
@@ -560,6 +536,38 @@ static struct clk init_clocks[] = {
560 }, 536 },
561}; 537};
562 538
539static struct clk clk_hsmmc0 = {
540 .name = "hsmmc",
541 .devname = "s3c-sdhci.0",
542 .parent = &clk_hclk_psys.clk,
543 .enable = s5pv210_clk_ip2_ctrl,
544 .ctrlbit = (1<<16),
545};
546
547static struct clk clk_hsmmc1 = {
548 .name = "hsmmc",
549 .devname = "s3c-sdhci.1",
550 .parent = &clk_hclk_psys.clk,
551 .enable = s5pv210_clk_ip2_ctrl,
552 .ctrlbit = (1<<17),
553};
554
555static struct clk clk_hsmmc2 = {
556 .name = "hsmmc",
557 .devname = "s3c-sdhci.2",
558 .parent = &clk_hclk_psys.clk,
559 .enable = s5pv210_clk_ip2_ctrl,
560 .ctrlbit = (1<<18),
561};
562
563static struct clk clk_hsmmc3 = {
564 .name = "hsmmc",
565 .devname = "s3c-sdhci.3",
566 .parent = &clk_hclk_psys.clk,
567 .enable = s5pv210_clk_ip2_ctrl,
568 .ctrlbit = (1<<19),
569};
570
563static struct clk *clkset_uart_list[] = { 571static struct clk *clkset_uart_list[] = {
564 [6] = &clk_mout_mpll.clk, 572 [6] = &clk_mout_mpll.clk,
565 [7] = &clk_mout_epll.clk, 573 [7] = &clk_mout_epll.clk,
@@ -810,46 +818,6 @@ static struct clksrc_clk clksrcs[] = {
810 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, 818 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
811 }, { 819 }, {
812 .clk = { 820 .clk = {
813 .name = "uclk1",
814 .devname = "s5pv210-uart.0",
815 .enable = s5pv210_clk_mask0_ctrl,
816 .ctrlbit = (1 << 12),
817 },
818 .sources = &clkset_uart,
819 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
820 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
821 }, {
822 .clk = {
823 .name = "uclk1",
824 .devname = "s5pv210-uart.1",
825 .enable = s5pv210_clk_mask0_ctrl,
826 .ctrlbit = (1 << 13),
827 },
828 .sources = &clkset_uart,
829 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
830 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
831 }, {
832 .clk = {
833 .name = "uclk1",
834 .devname = "s5pv210-uart.2",
835 .enable = s5pv210_clk_mask0_ctrl,
836 .ctrlbit = (1 << 14),
837 },
838 .sources = &clkset_uart,
839 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
840 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
841 }, {
842 .clk = {
843 .name = "uclk1",
844 .devname = "s5pv210-uart.3",
845 .enable = s5pv210_clk_mask0_ctrl,
846 .ctrlbit = (1 << 15),
847 },
848 .sources = &clkset_uart,
849 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
850 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
851 }, {
852 .clk = {
853 .name = "sclk_fimc", 821 .name = "sclk_fimc",
854 .devname = "s5pv210-fimc.0", 822 .devname = "s5pv210-fimc.0",
855 .enable = s5pv210_clk_mask1_ctrl, 823 .enable = s5pv210_clk_mask1_ctrl,
@@ -907,46 +875,6 @@ static struct clksrc_clk clksrcs[] = {
907 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 }, 875 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
908 }, { 876 }, {
909 .clk = { 877 .clk = {
910 .name = "sclk_mmc",
911 .devname = "s3c-sdhci.0",
912 .enable = s5pv210_clk_mask0_ctrl,
913 .ctrlbit = (1 << 8),
914 },
915 .sources = &clkset_group2,
916 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
917 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
918 }, {
919 .clk = {
920 .name = "sclk_mmc",
921 .devname = "s3c-sdhci.1",
922 .enable = s5pv210_clk_mask0_ctrl,
923 .ctrlbit = (1 << 9),
924 },
925 .sources = &clkset_group2,
926 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
927 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
928 }, {
929 .clk = {
930 .name = "sclk_mmc",
931 .devname = "s3c-sdhci.2",
932 .enable = s5pv210_clk_mask0_ctrl,
933 .ctrlbit = (1 << 10),
934 },
935 .sources = &clkset_group2,
936 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
937 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
938 }, {
939 .clk = {
940 .name = "sclk_mmc",
941 .devname = "s3c-sdhci.3",
942 .enable = s5pv210_clk_mask0_ctrl,
943 .ctrlbit = (1 << 11),
944 },
945 .sources = &clkset_group2,
946 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
947 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
948 }, {
949 .clk = {
950 .name = "sclk_mfc", 878 .name = "sclk_mfc",
951 .devname = "s5p-mfc", 879 .devname = "s5p-mfc",
952 .enable = s5pv210_clk_ip0_ctrl, 880 .enable = s5pv210_clk_ip0_ctrl,
@@ -984,26 +912,6 @@ static struct clksrc_clk clksrcs[] = {
984 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 }, 912 .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
985 }, { 913 }, {
986 .clk = { 914 .clk = {
987 .name = "sclk_spi",
988 .devname = "s3c64xx-spi.0",
989 .enable = s5pv210_clk_mask0_ctrl,
990 .ctrlbit = (1 << 16),
991 },
992 .sources = &clkset_group2,
993 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
994 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
995 }, {
996 .clk = {
997 .name = "sclk_spi",
998 .devname = "s3c64xx-spi.1",
999 .enable = s5pv210_clk_mask0_ctrl,
1000 .ctrlbit = (1 << 17),
1001 },
1002 .sources = &clkset_group2,
1003 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1004 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1005 }, {
1006 .clk = {
1007 .name = "sclk_pwi", 915 .name = "sclk_pwi",
1008 .enable = s5pv210_clk_mask0_ctrl, 916 .enable = s5pv210_clk_mask0_ctrl,
1009 .ctrlbit = (1 << 29), 917 .ctrlbit = (1 << 29),
@@ -1023,6 +931,147 @@ static struct clksrc_clk clksrcs[] = {
1023 }, 931 },
1024}; 932};
1025 933
934static struct clksrc_clk clk_sclk_uart0 = {
935 .clk = {
936 .name = "uclk1",
937 .devname = "s5pv210-uart.0",
938 .enable = s5pv210_clk_mask0_ctrl,
939 .ctrlbit = (1 << 12),
940 },
941 .sources = &clkset_uart,
942 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
943 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
944};
945
946static struct clksrc_clk clk_sclk_uart1 = {
947 .clk = {
948 .name = "uclk1",
949 .devname = "s5pv210-uart.1",
950 .enable = s5pv210_clk_mask0_ctrl,
951 .ctrlbit = (1 << 13),
952 },
953 .sources = &clkset_uart,
954 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
955 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
956};
957
958static struct clksrc_clk clk_sclk_uart2 = {
959 .clk = {
960 .name = "uclk1",
961 .devname = "s5pv210-uart.2",
962 .enable = s5pv210_clk_mask0_ctrl,
963 .ctrlbit = (1 << 14),
964 },
965 .sources = &clkset_uart,
966 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
967 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
968};
969
970static struct clksrc_clk clk_sclk_uart3 = {
971 .clk = {
972 .name = "uclk1",
973 .devname = "s5pv210-uart.3",
974 .enable = s5pv210_clk_mask0_ctrl,
975 .ctrlbit = (1 << 15),
976 },
977 .sources = &clkset_uart,
978 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
979 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
980};
981
982static struct clksrc_clk clk_sclk_mmc0 = {
983 .clk = {
984 .name = "sclk_mmc",
985 .devname = "s3c-sdhci.0",
986 .enable = s5pv210_clk_mask0_ctrl,
987 .ctrlbit = (1 << 8),
988 },
989 .sources = &clkset_group2,
990 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
991 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
992};
993
994static struct clksrc_clk clk_sclk_mmc1 = {
995 .clk = {
996 .name = "sclk_mmc",
997 .devname = "s3c-sdhci.1",
998 .enable = s5pv210_clk_mask0_ctrl,
999 .ctrlbit = (1 << 9),
1000 },
1001 .sources = &clkset_group2,
1002 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
1003 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
1004};
1005
1006static struct clksrc_clk clk_sclk_mmc2 = {
1007 .clk = {
1008 .name = "sclk_mmc",
1009 .devname = "s3c-sdhci.2",
1010 .enable = s5pv210_clk_mask0_ctrl,
1011 .ctrlbit = (1 << 10),
1012 },
1013 .sources = &clkset_group2,
1014 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
1015 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
1016};
1017
1018static struct clksrc_clk clk_sclk_mmc3 = {
1019 .clk = {
1020 .name = "sclk_mmc",
1021 .devname = "s3c-sdhci.3",
1022 .enable = s5pv210_clk_mask0_ctrl,
1023 .ctrlbit = (1 << 11),
1024 },
1025 .sources = &clkset_group2,
1026 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
1027 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
1028};
1029
1030static struct clksrc_clk clk_sclk_spi0 = {
1031 .clk = {
1032 .name = "sclk_spi",
1033 .devname = "s3c64xx-spi.0",
1034 .enable = s5pv210_clk_mask0_ctrl,
1035 .ctrlbit = (1 << 16),
1036 },
1037 .sources = &clkset_group2,
1038 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
1039 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
1040 };
1041
1042static struct clksrc_clk clk_sclk_spi1 = {
1043 .clk = {
1044 .name = "sclk_spi",
1045 .devname = "s3c64xx-spi.1",
1046 .enable = s5pv210_clk_mask0_ctrl,
1047 .ctrlbit = (1 << 17),
1048 },
1049 .sources = &clkset_group2,
1050 .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1051 .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1052 };
1053
1054
1055static struct clksrc_clk *clksrc_cdev[] = {
1056 &clk_sclk_uart0,
1057 &clk_sclk_uart1,
1058 &clk_sclk_uart2,
1059 &clk_sclk_uart3,
1060 &clk_sclk_mmc0,
1061 &clk_sclk_mmc1,
1062 &clk_sclk_mmc2,
1063 &clk_sclk_mmc3,
1064 &clk_sclk_spi0,
1065 &clk_sclk_spi1,
1066};
1067
1068static struct clk *clk_cdev[] = {
1069 &clk_hsmmc0,
1070 &clk_hsmmc1,
1071 &clk_hsmmc2,
1072 &clk_hsmmc3,
1073};
1074
1026/* Clock initialisation code */ 1075/* Clock initialisation code */
1027static struct clksrc_clk *sysclks[] = { 1076static struct clksrc_clk *sysclks[] = {
1028 &clk_mout_apll, 1077 &clk_mout_apll,
@@ -1262,6 +1311,25 @@ static struct clk *clks[] __initdata = {
1262 &clk_pcmcdclk2, 1311 &clk_pcmcdclk2,
1263}; 1312};
1264 1313
1314static struct clk_lookup s5pv210_clk_lookup[] = {
1315 CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
1316 CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
1317 CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
1318 CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
1319 CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
1320 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
1321 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
1322 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
1323 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3),
1324 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1325 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1326 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1327 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1328 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1329 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
1330 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
1331};
1332
1265void __init s5pv210_register_clocks(void) 1333void __init s5pv210_register_clocks(void)
1266{ 1334{
1267 int ptr; 1335 int ptr;
@@ -1274,11 +1342,19 @@ void __init s5pv210_register_clocks(void)
1274 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) 1342 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1275 s3c_register_clksrc(sclk_tv[ptr], 1); 1343 s3c_register_clksrc(sclk_tv[ptr], 1);
1276 1344
1345 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1346 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1347
1277 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1348 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1278 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1349 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1279 1350
1280 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1351 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1281 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1352 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1353 clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
1354
1355 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1356 for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1357 s3c_disable_clocks(clk_cdev[ptr], 1);
1282 1358
1283 s3c24xx_register_clock(&dummy_apb_pclk); 1359 s3c24xx_register_clock(&dummy_apb_pclk);
1284 s3c_pwmclk_init(); 1360 s3c_pwmclk_init();
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 0ec393305d7..9c1bcdcc12c 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -254,28 +254,9 @@ int __init s5pv210_init(void)
254 return device_register(&s5pv210_dev); 254 return device_register(&s5pv210_dev);
255} 255}
256 256
257static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
258 [0] = {
259 .name = "pclk",
260 .divisor = 1,
261 .min_baud = 0,
262 .max_baud = 0,
263 },
264};
265
266/* uart registration process */ 257/* uart registration process */
267 258
268void __init s5pv210_init_uarts(struct s3c2410_uartcfg *cfg, int no) 259void __init s5pv210_init_uarts(struct s3c2410_uartcfg *cfg, int no)
269{ 260{
270 struct s3c2410_uartcfg *tcfg = cfg;
271 u32 ucnt;
272
273 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
274 if (!tcfg->clocks) {
275 tcfg->clocks = s5pv210_serial_clocks;
276 tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
277 }
278 }
279
280 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); 261 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
281} 262}
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c
deleted file mode 100644
index eaf9a7bff7a..00000000000
--- a/arch/arm/mach-s5pv210/dev-spi.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/* linux/arch/arm/mach-s5pv210/dev-spi.c
2 *
3 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4 * Jaswinder Singh <jassi.brar@samsung.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
13#include <linux/gpio.h>
14
15#include <mach/dma.h>
16#include <mach/map.h>
17#include <mach/irqs.h>
18#include <mach/spi-clocks.h>
19
20#include <plat/s3c64xx-spi.h>
21#include <plat/gpio-cfg.h>
22
23static char *spi_src_clks[] = {
24 [S5PV210_SPI_SRCCLK_PCLK] = "pclk",
25 [S5PV210_SPI_SRCCLK_SCLK] = "sclk_spi",
26};
27
28/* SPI Controller platform_devices */
29
30/* Since we emulate multi-cs capability, we do not touch the CS.
31 * The emulated CS is toggled by board specific mechanism, as it can
32 * be either some immediate GPIO or some signal out of some other
33 * chip in between ... or some yet another way.
34 * We simply do not assume anything about CS.
35 */
36static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
37{
38 unsigned int base;
39
40 switch (pdev->id) {
41 case 0:
42 base = S5PV210_GPB(0);
43 break;
44
45 case 1:
46 base = S5PV210_GPB(4);
47 break;
48
49 default:
50 dev_err(&pdev->dev, "Invalid SPI Controller number!");
51 return -EINVAL;
52 }
53
54 s3c_gpio_cfgall_range(base, 3,
55 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
56
57 return 0;
58}
59
60static struct resource s5pv210_spi0_resource[] = {
61 [0] = {
62 .start = S5PV210_PA_SPI0,
63 .end = S5PV210_PA_SPI0 + 0x100 - 1,
64 .flags = IORESOURCE_MEM,
65 },
66 [1] = {
67 .start = DMACH_SPI0_TX,
68 .end = DMACH_SPI0_TX,
69 .flags = IORESOURCE_DMA,
70 },
71 [2] = {
72 .start = DMACH_SPI0_RX,
73 .end = DMACH_SPI0_RX,
74 .flags = IORESOURCE_DMA,
75 },
76 [3] = {
77 .start = IRQ_SPI0,
78 .end = IRQ_SPI0,
79 .flags = IORESOURCE_IRQ,
80 },
81};
82
83static struct s3c64xx_spi_info s5pv210_spi0_pdata = {
84 .cfg_gpio = s5pv210_spi_cfg_gpio,
85 .fifo_lvl_mask = 0x1ff,
86 .rx_lvl_offset = 15,
87 .high_speed = 1,
88 .tx_st_done = 25,
89};
90
91static u64 spi_dmamask = DMA_BIT_MASK(32);
92
93struct platform_device s5pv210_device_spi0 = {
94 .name = "s3c64xx-spi",
95 .id = 0,
96 .num_resources = ARRAY_SIZE(s5pv210_spi0_resource),
97 .resource = s5pv210_spi0_resource,
98 .dev = {
99 .dma_mask = &spi_dmamask,
100 .coherent_dma_mask = DMA_BIT_MASK(32),
101 .platform_data = &s5pv210_spi0_pdata,
102 },
103};
104
105static struct resource s5pv210_spi1_resource[] = {
106 [0] = {
107 .start = S5PV210_PA_SPI1,
108 .end = S5PV210_PA_SPI1 + 0x100 - 1,
109 .flags = IORESOURCE_MEM,
110 },
111 [1] = {
112 .start = DMACH_SPI1_TX,
113 .end = DMACH_SPI1_TX,
114 .flags = IORESOURCE_DMA,
115 },
116 [2] = {
117 .start = DMACH_SPI1_RX,
118 .end = DMACH_SPI1_RX,
119 .flags = IORESOURCE_DMA,
120 },
121 [3] = {
122 .start = IRQ_SPI1,
123 .end = IRQ_SPI1,
124 .flags = IORESOURCE_IRQ,
125 },
126};
127
128static struct s3c64xx_spi_info s5pv210_spi1_pdata = {
129 .cfg_gpio = s5pv210_spi_cfg_gpio,
130 .fifo_lvl_mask = 0x7f,
131 .rx_lvl_offset = 15,
132 .high_speed = 1,
133 .tx_st_done = 25,
134};
135
136struct platform_device s5pv210_device_spi1 = {
137 .name = "s3c64xx-spi",
138 .id = 1,
139 .num_resources = ARRAY_SIZE(s5pv210_spi1_resource),
140 .resource = s5pv210_spi1_resource,
141 .dev = {
142 .dma_mask = &spi_dmamask,
143 .coherent_dma_mask = DMA_BIT_MASK(32),
144 .platform_data = &s5pv210_spi1_pdata,
145 },
146};
147
148void __init s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
149{
150 struct s3c64xx_spi_info *pd;
151
152 /* Reject invalid configuration */
153 if (!num_cs || src_clk_nr < 0
154 || src_clk_nr > S5PV210_SPI_SRCCLK_SCLK) {
155 printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
156 return;
157 }
158
159 switch (cntrlr) {
160 case 0:
161 pd = &s5pv210_spi0_pdata;
162 break;
163 case 1:
164 pd = &s5pv210_spi1_pdata;
165 break;
166 default:
167 printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
168 __func__, cntrlr);
169 return;
170 }
171
172 pd->num_cs = num_cs;
173 pd->src_clk_nr = src_clk_nr;
174 pd->src_clk_name = spi_src_clks[src_clk_nr];
175}
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 86b749c18b7..a6113e0267f 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -35,90 +35,40 @@
35 35
36static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
37 37
38struct dma_pl330_peri pdma0_peri[28] = { 38u8 pdma0_peri[] = {
39 { 39 DMACH_UART0_RX,
40 .peri_id = (u8)DMACH_UART0_RX, 40 DMACH_UART0_TX,
41 .rqtype = DEVTOMEM, 41 DMACH_UART1_RX,
42 }, { 42 DMACH_UART1_TX,
43 .peri_id = (u8)DMACH_UART0_TX, 43 DMACH_UART2_RX,
44 .rqtype = MEMTODEV, 44 DMACH_UART2_TX,
45 }, { 45 DMACH_UART3_RX,
46 .peri_id = (u8)DMACH_UART1_RX, 46 DMACH_UART3_TX,
47 .rqtype = DEVTOMEM, 47 DMACH_MAX,
48 }, { 48 DMACH_I2S0_RX,
49 .peri_id = (u8)DMACH_UART1_TX, 49 DMACH_I2S0_TX,
50 .rqtype = MEMTODEV, 50 DMACH_I2S0S_TX,
51 }, { 51 DMACH_I2S1_RX,
52 .peri_id = (u8)DMACH_UART2_RX, 52 DMACH_I2S1_TX,
53 .rqtype = DEVTOMEM, 53 DMACH_MAX,
54 }, { 54 DMACH_MAX,
55 .peri_id = (u8)DMACH_UART2_TX, 55 DMACH_SPI0_RX,
56 .rqtype = MEMTODEV, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI1_RX,
58 .peri_id = (u8)DMACH_UART3_RX, 58 DMACH_SPI1_TX,
59 .rqtype = DEVTOMEM, 59 DMACH_MAX,
60 }, { 60 DMACH_MAX,
61 .peri_id = (u8)DMACH_UART3_TX, 61 DMACH_AC97_MICIN,
62 .rqtype = MEMTODEV, 62 DMACH_AC97_PCMIN,
63 }, { 63 DMACH_AC97_PCMOUT,
64 .peri_id = DMACH_MAX, 64 DMACH_MAX,
65 }, { 65 DMACH_PWM,
66 .peri_id = (u8)DMACH_I2S0_RX, 66 DMACH_SPDIF,
67 .rqtype = DEVTOMEM,
68 }, {
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_MAX,
82 }, {
83 .peri_id = (u8)DMACH_MAX,
84 }, {
85 .peri_id = (u8)DMACH_SPI0_RX,
86 .rqtype = DEVTOMEM,
87 }, {
88 .peri_id = (u8)DMACH_SPI0_TX,
89 .rqtype = MEMTODEV,
90 }, {
91 .peri_id = (u8)DMACH_SPI1_RX,
92 .rqtype = DEVTOMEM,
93 }, {
94 .peri_id = (u8)DMACH_SPI1_TX,
95 .rqtype = MEMTODEV,
96 }, {
97 .peri_id = (u8)DMACH_MAX,
98 }, {
99 .peri_id = (u8)DMACH_MAX,
100 }, {
101 .peri_id = (u8)DMACH_AC97_MICIN,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_AC97_PCMIN,
105 .rqtype = DEVTOMEM,
106 }, {
107 .peri_id = (u8)DMACH_AC97_PCMOUT,
108 .rqtype = MEMTODEV,
109 }, {
110 .peri_id = (u8)DMACH_MAX,
111 }, {
112 .peri_id = (u8)DMACH_PWM,
113 }, {
114 .peri_id = (u8)DMACH_SPDIF,
115 .rqtype = MEMTODEV,
116 },
117}; 67};
118 68
119struct dma_pl330_platdata s5pv210_pdma0_pdata = { 69struct dma_pl330_platdata s5pv210_pdma0_pdata = {
120 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 70 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
121 .peri = pdma0_peri, 71 .peri_id = pdma0_peri,
122}; 72};
123 73
124struct amba_device s5pv210_device_pdma0 = { 74struct amba_device s5pv210_device_pdma0 = {
@@ -137,102 +87,44 @@ struct amba_device s5pv210_device_pdma0 = {
137 .periphid = 0x00041330, 87 .periphid = 0x00041330,
138}; 88};
139 89
140struct dma_pl330_peri pdma1_peri[32] = { 90u8 pdma1_peri[] = {
141 { 91 DMACH_UART0_RX,
142 .peri_id = (u8)DMACH_UART0_RX, 92 DMACH_UART0_TX,
143 .rqtype = DEVTOMEM, 93 DMACH_UART1_RX,
144 }, { 94 DMACH_UART1_TX,
145 .peri_id = (u8)DMACH_UART0_TX, 95 DMACH_UART2_RX,
146 .rqtype = MEMTODEV, 96 DMACH_UART2_TX,
147 }, { 97 DMACH_UART3_RX,
148 .peri_id = (u8)DMACH_UART1_RX, 98 DMACH_UART3_TX,
149 .rqtype = DEVTOMEM, 99 DMACH_MAX,
150 }, { 100 DMACH_I2S0_RX,
151 .peri_id = (u8)DMACH_UART1_TX, 101 DMACH_I2S0_TX,
152 .rqtype = MEMTODEV, 102 DMACH_I2S0S_TX,
153 }, { 103 DMACH_I2S1_RX,
154 .peri_id = (u8)DMACH_UART2_RX, 104 DMACH_I2S1_TX,
155 .rqtype = DEVTOMEM, 105 DMACH_I2S2_RX,
156 }, { 106 DMACH_I2S2_TX,
157 .peri_id = (u8)DMACH_UART2_TX, 107 DMACH_SPI0_RX,
158 .rqtype = MEMTODEV, 108 DMACH_SPI0_TX,
159 }, { 109 DMACH_SPI1_RX,
160 .peri_id = (u8)DMACH_UART3_RX, 110 DMACH_SPI1_TX,
161 .rqtype = DEVTOMEM, 111 DMACH_MAX,
162 }, { 112 DMACH_MAX,
163 .peri_id = (u8)DMACH_UART3_TX, 113 DMACH_PCM0_RX,
164 .rqtype = MEMTODEV, 114 DMACH_PCM0_TX,
165 }, { 115 DMACH_PCM1_RX,
166 .peri_id = DMACH_MAX, 116 DMACH_PCM1_TX,
167 }, { 117 DMACH_MSM_REQ0,
168 .peri_id = (u8)DMACH_I2S0_RX, 118 DMACH_MSM_REQ1,
169 .rqtype = DEVTOMEM, 119 DMACH_MSM_REQ2,
170 }, { 120 DMACH_MSM_REQ3,
171 .peri_id = (u8)DMACH_I2S0_TX, 121 DMACH_PCM2_RX,
172 .rqtype = MEMTODEV, 122 DMACH_PCM2_TX,
173 }, {
174 .peri_id = (u8)DMACH_I2S0S_TX,
175 .rqtype = MEMTODEV,
176 }, {
177 .peri_id = (u8)DMACH_I2S1_RX,
178 .rqtype = DEVTOMEM,
179 }, {
180 .peri_id = (u8)DMACH_I2S1_TX,
181 .rqtype = MEMTODEV,
182 }, {
183 .peri_id = (u8)DMACH_I2S2_RX,
184 .rqtype = DEVTOMEM,
185 }, {
186 .peri_id = (u8)DMACH_I2S2_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_SPI0_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_SPI0_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_SPI1_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_SPI1_TX,
199 .rqtype = MEMTODEV,
200 }, {
201 .peri_id = (u8)DMACH_MAX,
202 }, {
203 .peri_id = (u8)DMACH_MAX,
204 }, {
205 .peri_id = (u8)DMACH_PCM0_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_PCM0_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_PCM1_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_PCM1_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_MSM_REQ0,
218 }, {
219 .peri_id = (u8)DMACH_MSM_REQ1,
220 }, {
221 .peri_id = (u8)DMACH_MSM_REQ2,
222 }, {
223 .peri_id = (u8)DMACH_MSM_REQ3,
224 }, {
225 .peri_id = (u8)DMACH_PCM2_RX,
226 .rqtype = DEVTOMEM,
227 }, {
228 .peri_id = (u8)DMACH_PCM2_TX,
229 .rqtype = MEMTODEV,
230 },
231}; 123};
232 124
233struct dma_pl330_platdata s5pv210_pdma1_pdata = { 125struct dma_pl330_platdata s5pv210_pdma1_pdata = {
234 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 126 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
235 .peri = pdma1_peri, 127 .peri_id = pdma1_peri,
236}; 128};
237 129
238struct amba_device s5pv210_device_pdma1 = { 130struct amba_device s5pv210_device_pdma1 = {
@@ -253,7 +145,12 @@ struct amba_device s5pv210_device_pdma1 = {
253 145
254static int __init s5pv210_dma_init(void) 146static int __init s5pv210_dma_init(void)
255{ 147{
148 dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask);
149 dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask);
256 amba_device_register(&s5pv210_device_pdma0, &iomem_resource); 150 amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
151
152 dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask);
153 dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask);
257 amba_device_register(&s5pv210_device_pdma1, &iomem_resource); 154 amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
258 155
259 return 0; 156 return 0;
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 5e0de3a31f3..e777e010ed2 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -118,6 +118,8 @@
118#define IRQ_MDNIE3 S5P_IRQ_VIC3(8) 118#define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
119#define IRQ_VIC_END S5P_IRQ_VIC3(31) 119#define IRQ_VIC_END S5P_IRQ_VIC3(31)
120 120
121#define IRQ_TIMER_BASE (11)
122
121#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 123#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
122#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 124#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
123 125
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 7ff609f1568..89c34b8f73b 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -109,6 +109,8 @@
109#define S3C_PA_RTC S5PV210_PA_RTC 109#define S3C_PA_RTC S5PV210_PA_RTC
110#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG 110#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
111#define S3C_PA_WDT S5PV210_PA_WATCHDOG 111#define S3C_PA_WDT S5PV210_PA_WATCHDOG
112#define S3C_PA_SPI0 S5PV210_PA_SPI0
113#define S3C_PA_SPI1 S5PV210_PA_SPI1
112 114
113#define S5P_PA_CHIPID S5PV210_PA_CHIPID 115#define S5P_PA_CHIPID S5PV210_PA_CHIPID
114#define S5P_PA_FIMC0 S5PV210_PA_FIMC0 116#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 6f7dfe993c1..5e734d025a6 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -597,8 +597,7 @@ static struct s3c_sdhci_platdata aquila_hsmmc2_data __initdata = {
597 597
598static void aquila_setup_sdhci(void) 598static void aquila_setup_sdhci(void)
599{ 599{
600 gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN"); 600 gpio_request_one(AQUILA_EXT_FLASH_EN, GPIOF_OUT_INIT_HIGH, "FLASH_EN");
601 gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
602 601
603 s3c_sdhci0_set_platdata(&aquila_hsmmc0_data); 602 s3c_sdhci0_set_platdata(&aquila_hsmmc0_data);
604 s3c_sdhci1_set_platdata(&aquila_hsmmc1_data); 603 s3c_sdhci1_set_platdata(&aquila_hsmmc1_data);
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 12c69371739..ff915261043 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -229,8 +229,7 @@ static void __init goni_radio_init(void)
229 i2c1_devs[0].irq = gpio_to_irq(gpio); 229 i2c1_devs[0].irq = gpio_to_irq(gpio);
230 230
231 gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */ 231 gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */
232 gpio_request(gpio, "FM_RST"); 232 gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "FM_RST");
233 gpio_direction_output(gpio, 1);
234} 233}
235 234
236/* TSP */ 235/* TSP */
@@ -266,8 +265,7 @@ static void __init goni_tsp_init(void)
266 int gpio; 265 int gpio;
267 266
268 gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */ 267 gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */
269 gpio_request(gpio, "TSP_LDO_ON"); 268 gpio_request_one(gpio, GPIOF_OUT_INIT_HIGH, "TSP_LDO_ON");
270 gpio_direction_output(gpio, 1);
271 gpio_export(gpio, 0); 269 gpio_export(gpio, 0);
272 270
273 gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */ 271 gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index b4021dd802a..dff9ea7b5bb 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -155,15 +155,12 @@ static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
155{ 155{
156 if (power) { 156 if (power) {
157#if !defined(CONFIG_BACKLIGHT_PWM) 157#if !defined(CONFIG_BACKLIGHT_PWM)
158 gpio_request(S5PV210_GPD0(3), "GPD0"); 158 gpio_request_one(S5PV210_GPD0(3), GPIOF_OUT_INIT_HIGH, "GPD0");
159 gpio_direction_output(S5PV210_GPD0(3), 1);
160 gpio_free(S5PV210_GPD0(3)); 159 gpio_free(S5PV210_GPD0(3));
161#endif 160#endif
162 161
163 /* fire nRESET on power up */ 162 /* fire nRESET on power up */
164 gpio_request(S5PV210_GPH0(6), "GPH0"); 163 gpio_request_one(S5PV210_GPH0(6), GPIOF_OUT_INIT_HIGH, "GPH0");
165
166 gpio_direction_output(S5PV210_GPH0(6), 1);
167 164
168 gpio_set_value(S5PV210_GPH0(6), 0); 165 gpio_set_value(S5PV210_GPH0(6), 0);
169 mdelay(10); 166 mdelay(10);
@@ -174,8 +171,7 @@ static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
174 gpio_free(S5PV210_GPH0(6)); 171 gpio_free(S5PV210_GPH0(6));
175 } else { 172 } else {
176#if !defined(CONFIG_BACKLIGHT_PWM) 173#if !defined(CONFIG_BACKLIGHT_PWM)
177 gpio_request(S5PV210_GPD0(3), "GPD0"); 174 gpio_request_one(S5PV210_GPD0(3), GPIOF_OUT_INIT_LOW, "GPD0");
178 gpio_direction_output(S5PV210_GPD0(3), 0);
179 gpio_free(S5PV210_GPD0(3)); 175 gpio_free(S5PV210_GPD0(3));
180#endif 176#endif
181 } 177 }
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
deleted file mode 100644
index 6b8ccc4d35f..00000000000
--- a/arch/arm/mach-s5pv210/setup-sdhci.c
+++ /dev/null
@@ -1,22 +0,0 @@
1/* linux/arch/arm/mach-s5pv210/setup-sdhci.c
2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - Helper functions for settign up SDHCI device(s) (HSMMC)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/types.h>
14
15/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
16
17char *s5pv210_hsmmc_clksrcs[4] = {
18 [0] = "hsmmc", /* HCLK */
19 /* [1] = "hsmmc", - duplicate HCLK entry */
20 [2] = "sclk_mmc", /* mmc_bus */
21 /* [3] = NULL, - reserved */
22};
diff --git a/arch/arm/mach-s5pv210/setup-spi.c b/arch/arm/mach-s5pv210/setup-spi.c
new file mode 100644
index 00000000000..f43c5048a37
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-spi.c
@@ -0,0 +1,51 @@
1/* linux/arch/arm/mach-s5pv210/setup-spi.c
2 *
3 * Copyright (C) 2011 Samsung Electronics Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16
17#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata = {
19 .fifo_lvl_mask = 0x1ff,
20 .rx_lvl_offset = 15,
21 .high_speed = 1,
22 .tx_st_done = 25,
23};
24
25int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
26{
27 s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
28 s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
29 s3c_gpio_cfgall_range(S5PV210_GPB(2), 2,
30 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
31 return 0;
32}
33#endif
34
35#ifdef CONFIG_S3C64XX_DEV_SPI1
36struct s3c64xx_spi_info s3c64xx_spi1_pdata = {
37 .fifo_lvl_mask = 0x7f,
38 .rx_lvl_offset = 15,
39 .high_speed = 1,
40 .tx_st_done = 25,
41};
42
43int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
44{
45 s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
46 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
47 s3c_gpio_cfgall_range(S5PV210_GPB(6), 2,
48 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
49 return 0;
50}
51#endif
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index dab3c6347a8..d6df9f6c9f7 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -11,17 +11,39 @@
11#include <linux/clk.h> 11#include <linux/clk.h>
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/mutex.h> 13#include <linux/mutex.h>
14#include <linux/io.h>
15#include <linux/clkdev.h>
14 16
15#include <mach/hardware.h> 17#include <mach/hardware.h>
16 18
17/* 19struct clkops {
18 * Very simple clock implementation - we only have one clock to deal with. 20 void (*enable)(struct clk *);
19 */ 21 void (*disable)(struct clk *);
22 unsigned long (*getrate)(struct clk *);
23};
24
20struct clk { 25struct clk {
26 const struct clkops *ops;
27 unsigned long rate;
21 unsigned int enabled; 28 unsigned int enabled;
22}; 29};
23 30
24static void clk_gpio27_enable(void) 31#define INIT_CLKREG(_clk, _devname, _conname) \
32 { \
33 .clk = _clk, \
34 .dev_id = _devname, \
35 .con_id = _conname, \
36 }
37
38#define DEFINE_CLK(_name, _ops, _rate) \
39struct clk clk_##_name = { \
40 .ops = _ops, \
41 .rate = _rate, \
42 }
43
44static DEFINE_SPINLOCK(clocks_lock);
45
46static void clk_gpio27_enable(struct clk *clk)
25{ 47{
26 /* 48 /*
27 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: 49 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -32,38 +54,22 @@ static void clk_gpio27_enable(void)
32 TUCR = TUCR_3_6864MHz; 54 TUCR = TUCR_3_6864MHz;
33} 55}
34 56
35static void clk_gpio27_disable(void) 57static void clk_gpio27_disable(struct clk *clk)
36{ 58{
37 TUCR = 0; 59 TUCR = 0;
38 GPDR &= ~GPIO_32_768kHz; 60 GPDR &= ~GPIO_32_768kHz;
39 GAFR &= ~GPIO_32_768kHz; 61 GAFR &= ~GPIO_32_768kHz;
40} 62}
41 63
42static struct clk clk_gpio27;
43
44static DEFINE_SPINLOCK(clocks_lock);
45
46struct clk *clk_get(struct device *dev, const char *id)
47{
48 const char *devname = dev_name(dev);
49
50 return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
51}
52EXPORT_SYMBOL(clk_get);
53
54void clk_put(struct clk *clk)
55{
56}
57EXPORT_SYMBOL(clk_put);
58
59int clk_enable(struct clk *clk) 64int clk_enable(struct clk *clk)
60{ 65{
61 unsigned long flags; 66 unsigned long flags;
62 67
63 spin_lock_irqsave(&clocks_lock, flags); 68 spin_lock_irqsave(&clocks_lock, flags);
64 if (clk->enabled++ == 0) 69 if (clk->enabled++ == 0)
65 clk_gpio27_enable(); 70 clk->ops->enable(clk);
66 spin_unlock_irqrestore(&clocks_lock, flags); 71 spin_unlock_irqrestore(&clocks_lock, flags);
72
67 return 0; 73 return 0;
68} 74}
69EXPORT_SYMBOL(clk_enable); 75EXPORT_SYMBOL(clk_enable);
@@ -76,13 +82,48 @@ void clk_disable(struct clk *clk)
76 82
77 spin_lock_irqsave(&clocks_lock, flags); 83 spin_lock_irqsave(&clocks_lock, flags);
78 if (--clk->enabled == 0) 84 if (--clk->enabled == 0)
79 clk_gpio27_disable(); 85 clk->ops->disable(clk);
80 spin_unlock_irqrestore(&clocks_lock, flags); 86 spin_unlock_irqrestore(&clocks_lock, flags);
81} 87}
82EXPORT_SYMBOL(clk_disable); 88EXPORT_SYMBOL(clk_disable);
83 89
84unsigned long clk_get_rate(struct clk *clk) 90unsigned long clk_get_rate(struct clk *clk)
85{ 91{
86 return 3686400; 92 unsigned long rate;
93
94 rate = clk->rate;
95 if (clk->ops->getrate)
96 rate = clk->ops->getrate(clk);
97
98 return rate;
87} 99}
88EXPORT_SYMBOL(clk_get_rate); 100EXPORT_SYMBOL(clk_get_rate);
101
102const struct clkops clk_gpio27_ops = {
103 .enable = clk_gpio27_enable,
104 .disable = clk_gpio27_disable,
105};
106
107static void clk_dummy_enable(struct clk *clk) { }
108static void clk_dummy_disable(struct clk *clk) { }
109
110const struct clkops clk_dummy_ops = {
111 .enable = clk_dummy_enable,
112 .disable = clk_dummy_disable,
113};
114
115static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400);
116static DEFINE_CLK(dummy, &clk_dummy_ops, 0);
117
118static struct clk_lookup sa11xx_clkregs[] = {
119 INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL),
120 INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
121};
122
123static int __init sa11xx_clk_init(void)
124{
125 clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
126 return 0;
127}
128
129postcore_initcall(sa11xx_clk_init);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index bb10ee2cb89..480d2ea46b0 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -345,9 +345,29 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
345 sa11x0_register_device(&sa11x0ir_device, irda); 345 sa11x0_register_device(&sa11x0ir_device, irda);
346} 346}
347 347
348static struct resource sa11x0rtc_resources[] = {
349 [0] = {
350 .start = 0x90010000,
351 .end = 0x900100ff,
352 .flags = IORESOURCE_MEM,
353 },
354 [1] = {
355 .start = IRQ_RTC1Hz,
356 .end = IRQ_RTC1Hz,
357 .flags = IORESOURCE_IRQ,
358 },
359 [2] = {
360 .start = IRQ_RTCAlrm,
361 .end = IRQ_RTCAlrm,
362 .flags = IORESOURCE_IRQ,
363 },
364};
365
348static struct platform_device sa11x0rtc_device = { 366static struct platform_device sa11x0rtc_device = {
349 .name = "sa1100-rtc", 367 .name = "sa1100-rtc",
350 .id = -1, 368 .id = -1,
369 .resource = sa11x0rtc_resources,
370 .num_resources = ARRAY_SIZE(sa11x0rtc_resources),
351}; 371};
352 372
353static struct platform_device *sa11x0_devices[] __initdata = { 373static struct platform_device *sa11x0_devices[] __initdata = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 91aff7cb828..373652d76b9 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -2,11 +2,8 @@ if ARCH_TEGRA
2 2
3comment "NVIDIA Tegra options" 3comment "NVIDIA Tegra options"
4 4
5choice
6 prompt "Select Tegra processor family for target system"
7
8config ARCH_TEGRA_2x_SOC 5config ARCH_TEGRA_2x_SOC
9 bool "Tegra 2 family" 6 bool "Enable support for Tegra20 family"
10 select CPU_V7 7 select CPU_V7
11 select ARM_GIC 8 select ARM_GIC
12 select ARCH_REQUIRE_GPIOLIB 9 select ARCH_REQUIRE_GPIOLIB
@@ -17,22 +14,36 @@ config ARCH_TEGRA_2x_SOC
17 Support for NVIDIA Tegra AP20 and T20 processors, based on the 14 Support for NVIDIA Tegra AP20 and T20 processors, based on the
18 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller 15 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
19 16
20endchoice 17config ARCH_TEGRA_3x_SOC
18 bool "Enable support for Tegra30 family"
19 select CPU_V7
20 select ARM_GIC
21 select ARCH_REQUIRE_GPIOLIB
22 select USB_ARCH_HAS_EHCI if USB_SUPPORT
23 select USB_ULPI if USB_SUPPORT
24 select USB_ULPI_VIEWPORT if USB_SUPPORT
25 select USE_OF
26 help
27 Support for NVIDIA Tegra T30 processor family, based on the
28 ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
21 29
22config TEGRA_PCI 30config TEGRA_PCI
23 bool "PCI Express support" 31 bool "PCI Express support"
32 depends on ARCH_TEGRA_2x_SOC
24 select PCI 33 select PCI
25 34
26comment "Tegra board type" 35comment "Tegra board type"
27 36
28config MACH_HARMONY 37config MACH_HARMONY
29 bool "Harmony board" 38 bool "Harmony board"
39 depends on ARCH_TEGRA_2x_SOC
30 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC 40 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC
31 help 41 help
32 Support for nVidia Harmony development platform 42 Support for nVidia Harmony development platform
33 43
34config MACH_KAEN 44config MACH_KAEN
35 bool "Kaen board" 45 bool "Kaen board"
46 depends on ARCH_TEGRA_2x_SOC
36 select MACH_SEABOARD 47 select MACH_SEABOARD
37 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC 48 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC
38 help 49 help
@@ -40,11 +51,13 @@ config MACH_KAEN
40 51
41config MACH_PAZ00 52config MACH_PAZ00
42 bool "Paz00 board" 53 bool "Paz00 board"
54 depends on ARCH_TEGRA_2x_SOC
43 help 55 help
44 Support for the Toshiba AC100/Dynabook AZ netbook 56 Support for the Toshiba AC100/Dynabook AZ netbook
45 57
46config MACH_SEABOARD 58config MACH_SEABOARD
47 bool "Seaboard board" 59 bool "Seaboard board"
60 depends on ARCH_TEGRA_2x_SOC
48 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC 61 select MACH_HAS_SND_SOC_TEGRA_WM8903 if SND_SOC
49 help 62 help
50 Support for nVidia Seaboard development platform. It will 63 Support for nVidia Seaboard development platform. It will
@@ -52,25 +65,29 @@ config MACH_SEABOARD
52 have large similarities with the seaboard design. 65 have large similarities with the seaboard design.
53 66
54config MACH_TEGRA_DT 67config MACH_TEGRA_DT
55 bool "Generic Tegra board (FDT support)" 68 bool "Generic Tegra20 board (FDT support)"
69 depends on ARCH_TEGRA_2x_SOC
56 select USE_OF 70 select USE_OF
57 help 71 help
58 Support for generic nVidia Tegra boards using Flattened Device Tree 72 Support for generic NVIDIA Tegra20 boards using Flattened Device Tree
59 73
60config MACH_TRIMSLICE 74config MACH_TRIMSLICE
61 bool "TrimSlice board" 75 bool "TrimSlice board"
76 depends on ARCH_TEGRA_2x_SOC
62 select TEGRA_PCI 77 select TEGRA_PCI
63 help 78 help
64 Support for CompuLab TrimSlice platform 79 Support for CompuLab TrimSlice platform
65 80
66config MACH_WARIO 81config MACH_WARIO
67 bool "Wario board" 82 bool "Wario board"
83 depends on ARCH_TEGRA_2x_SOC
68 select MACH_SEABOARD 84 select MACH_SEABOARD
69 help 85 help
70 Support for the Wario version of Seaboard 86 Support for the Wario version of Seaboard
71 87
72config MACH_VENTANA 88config MACH_VENTANA
73 bool "Ventana board" 89 bool "Ventana board"
90 depends on ARCH_TEGRA_2x_SOC
74 select MACH_TEGRA_DT 91 select MACH_TEGRA_DT
75 help 92 help
76 Support for the nVidia Ventana development platform 93 Support for the nVidia Ventana development platform
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 91a07e18720..e120ff54f66 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -1,3 +1,4 @@
1obj-y += board-pinmux.o
1obj-y += common.o 2obj-y += common.o
2obj-y += devices.o 3obj-y += devices.o
3obj-y += io.o 4obj-y += io.o
@@ -5,12 +6,13 @@ obj-y += irq.o
5obj-y += clock.o 6obj-y += clock.o
6obj-y += timer.o 7obj-y += timer.o
7obj-y += pinmux.o 8obj-y += pinmux.o
8obj-y += powergate.o
9obj-y += fuse.o 9obj-y += fuse.o
10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o 10obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o
11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o 11obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 12obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o 13obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o
14obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
14obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o 16obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
15obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 17obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
16obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 18obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
@@ -18,20 +20,22 @@ obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
18obj-$(CONFIG_TEGRA_PCI) += pcie.o 20obj-$(CONFIG_TEGRA_PCI) += pcie.o
19obj-$(CONFIG_USB_SUPPORT) += usb_phy.o 21obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
20 22
21obj-${CONFIG_MACH_HARMONY} += board-harmony.o 23obj-$(CONFIG_MACH_HARMONY) += board-harmony.o
22obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o 24obj-$(CONFIG_MACH_HARMONY) += board-harmony-pinmux.o
23obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o 25obj-$(CONFIG_MACH_HARMONY) += board-harmony-pcie.o
24obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o 26obj-$(CONFIG_MACH_HARMONY) += board-harmony-power.o
25 27
26obj-${CONFIG_MACH_PAZ00} += board-paz00.o 28obj-$(CONFIG_MACH_PAZ00) += board-paz00.o
27obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o 29obj-$(CONFIG_MACH_PAZ00) += board-paz00-pinmux.o
28 30
29obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o 31obj-$(CONFIG_MACH_SEABOARD) += board-seaboard.o
30obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o 32obj-$(CONFIG_MACH_SEABOARD) += board-seaboard-pinmux.o
31 33
32obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o 34obj-$(CONFIG_MACH_TEGRA_DT) += board-dt-tegra20.o
33obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o 35obj-$(CONFIG_MACH_TEGRA_DT) += board-harmony-pinmux.o
34obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o 36obj-$(CONFIG_MACH_TEGRA_DT) += board-seaboard-pinmux.o
37obj-$(CONFIG_MACH_TEGRA_DT) += board-paz00-pinmux.o
38obj-$(CONFIG_MACH_TEGRA_DT) += board-trimslice-pinmux.o
35 39
36obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o 40obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice.o
37obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o 41obj-$(CONFIG_MACH_TRIMSLICE) += board-trimslice-pinmux.o
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
index bd12c9fb81e..9a82094092d 100644
--- a/arch/arm/mach-tegra/Makefile.boot
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -3,5 +3,8 @@ params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
3initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000 3initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
4 4
5dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb 5dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
6dtb-$(CONFIG_MACH_PAZ00) += tegra-paz00.dtb
6dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb 7dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
8dtb-$(CONFIG_MACH_TRIMSLICE) += tegra-trimslice.dtb
7dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb 9dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb
10dtb-$(CONFIG_ARCH_TEGRA_3x_SOC) += tegra-cardhu.dtb
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index e417a8383db..7a95e0bc4ab 100644
--- a/arch/arm/mach-tegra/board-dt.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -37,6 +37,7 @@
37#include <asm/mach/arch.h> 37#include <asm/mach/arch.h>
38#include <asm/mach/time.h> 38#include <asm/mach/time.h>
39#include <asm/setup.h> 39#include <asm/setup.h>
40#include <asm/hardware/gic.h>
40 41
41#include <mach/iomap.h> 42#include <mach/iomap.h>
42#include <mach/irqs.h> 43#include <mach/irqs.h>
@@ -47,10 +48,14 @@
47#include "devices.h" 48#include "devices.h"
48 49
49void harmony_pinmux_init(void); 50void harmony_pinmux_init(void);
51void paz00_pinmux_init(void);
50void seaboard_pinmux_init(void); 52void seaboard_pinmux_init(void);
53void trimslice_pinmux_init(void);
51void ventana_pinmux_init(void); 54void ventana_pinmux_init(void);
52 55
53struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = { 56struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
57 OF_DEV_AUXDATA("nvidia,tegra20-pinmux", TEGRA_APB_MISC_BASE + 0x14, "tegra-pinmux", NULL),
58 OF_DEV_AUXDATA("nvidia,tegra20-gpio", TEGRA_GPIO_BASE, "tegra-gpio", NULL),
54 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL), 59 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
55 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL), 60 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
56 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL), 61 OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
@@ -58,16 +63,30 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
58 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL), 63 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
59 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL), 64 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
60 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL), 65 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
61 OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL), 66 OF_DEV_AUXDATA("nvidia,tegra20-i2c-dvc", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
62 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL), 67 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL),
63 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL), 68 OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S2_BASE, "tegra-i2s.1", NULL),
64 OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL), 69 OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL),
70 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB_BASE, "tegra-ehci.0",
71 &tegra_ehci1_device.dev.platform_data),
72 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB2_BASE, "tegra-ehci.1",
73 &tegra_ehci2_device.dev.platform_data),
74 OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
75 &tegra_ehci3_device.dev.platform_data),
65 {} 76 {}
66}; 77};
67 78
68static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = { 79static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
69 /* name parent rate enabled */ 80 /* name parent rate enabled */
70 { "uartd", "pll_p", 216000000, true }, 81 { "uartd", "pll_p", 216000000, true },
82 { "usbd", "clk_m", 12000000, false },
83 { "usb2", "clk_m", 12000000, false },
84 { "usb3", "clk_m", 12000000, false },
85 { "pll_a", "pll_p_out1", 56448000, true },
86 { "pll_a_out0", "pll_a", 11289600, true },
87 { "cdev1", NULL, 0, true },
88 { "i2s1", "pll_a_out0", 11289600, false},
89 { "i2s2", "pll_a_out0", 11289600, false},
71 { NULL, NULL, 0, 0}, 90 { NULL, NULL, 0, 0},
72}; 91};
73 92
@@ -76,39 +95,23 @@ static struct of_device_id tegra_dt_match_table[] __initdata = {
76 {} 95 {}
77}; 96};
78 97
79static struct of_device_id tegra_dt_gic_match[] __initdata = {
80 { .compatible = "nvidia,tegra20-gic", },
81 {}
82};
83
84static struct { 98static struct {
85 char *machine; 99 char *machine;
86 void (*init)(void); 100 void (*init)(void);
87} pinmux_configs[] = { 101} pinmux_configs[] = {
102 { "compulab,trimslice", trimslice_pinmux_init },
88 { "nvidia,harmony", harmony_pinmux_init }, 103 { "nvidia,harmony", harmony_pinmux_init },
104 { "compal,paz00", paz00_pinmux_init },
89 { "nvidia,seaboard", seaboard_pinmux_init }, 105 { "nvidia,seaboard", seaboard_pinmux_init },
90 { "nvidia,ventana", ventana_pinmux_init }, 106 { "nvidia,ventana", ventana_pinmux_init },
91}; 107};
92 108
93static void __init tegra_dt_init(void) 109static void __init tegra_dt_init(void)
94{ 110{
95 struct device_node *node;
96 int i; 111 int i;
97 112
98 node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match,
99 TEGRA_ARM_INT_DIST_BASE);
100 if (node)
101 irq_domain_add_simple(node, INT_GIC_BASE);
102
103 tegra_clk_init_from_table(tegra_dt_clk_init_table); 113 tegra_clk_init_from_table(tegra_dt_clk_init_table);
104 114
105 /*
106 * Finished with the static registrations now; fill in the missing
107 * devices
108 */
109 of_platform_populate(NULL, tegra_dt_match_table,
110 tegra20_auxdata_lookup, NULL);
111
112 for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) { 115 for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) {
113 if (of_machine_is_compatible(pinmux_configs[i].machine)) { 116 if (of_machine_is_compatible(pinmux_configs[i].machine)) {
114 pinmux_configs[i].init(); 117 pinmux_configs[i].init();
@@ -118,22 +121,31 @@ static void __init tegra_dt_init(void)
118 121
119 WARN(i == ARRAY_SIZE(pinmux_configs), 122 WARN(i == ARRAY_SIZE(pinmux_configs),
120 "Unknown platform! Pinmuxing not initialized\n"); 123 "Unknown platform! Pinmuxing not initialized\n");
124
125 /*
126 * Finished with the static registrations now; fill in the missing
127 * devices
128 */
129 of_platform_populate(NULL, tegra_dt_match_table,
130 tegra20_auxdata_lookup, NULL);
121} 131}
122 132
123static const char * tegra_dt_board_compat[] = { 133static const char *tegra20_dt_board_compat[] = {
134 "compulab,trimslice",
124 "nvidia,harmony", 135 "nvidia,harmony",
136 "compal,paz00",
125 "nvidia,seaboard", 137 "nvidia,seaboard",
126 "nvidia,ventana", 138 "nvidia,ventana",
127 NULL 139 NULL
128}; 140};
129 141
130DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)") 142DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
131 .map_io = tegra_map_common_io, 143 .map_io = tegra_map_common_io,
132 .init_early = tegra_init_early, 144 .init_early = tegra20_init_early,
133 .init_irq = tegra_init_irq, 145 .init_irq = tegra_dt_init_irq,
134 .handle_irq = gic_handle_irq, 146 .handle_irq = gic_handle_irq,
135 .timer = &tegra_timer, 147 .timer = &tegra_timer,
136 .init_machine = tegra_dt_init, 148 .init_machine = tegra_dt_init,
137 .restart = tegra_assert_system_reset, 149 .restart = tegra_assert_system_reset,
138 .dt_compat = tegra_dt_board_compat, 150 .dt_compat = tegra20_dt_board_compat,
139MACHINE_END 151MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
new file mode 100644
index 00000000000..3c197e2440b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -0,0 +1,63 @@
1/*
2 * arch/arm/mach-tegra/board-dt-tegra30.c
3 *
4 * NVIDIA Tegra30 device tree board support
5 *
6 * Copyright (C) 2011 NVIDIA Corporation
7 *
8 * Derived from:
9 *
10 * arch/arm/mach-tegra/board-dt-tegra20.c
11 *
12 * Copyright (C) 2010 Secret Lab Technologies, Ltd.
13 * Copyright (C) 2010 Google, Inc.
14 *
15 * This software is licensed under the terms of the GNU General Public
16 * License version 2, as published by the Free Software Foundation, and
17 * may be copied, distributed, and modified under those terms.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 */
25
26#include <linux/kernel.h>
27#include <linux/of.h>
28#include <linux/of_address.h>
29#include <linux/of_fdt.h>
30#include <linux/of_irq.h>
31#include <linux/of_platform.h>
32
33#include <asm/mach/arch.h>
34#include <asm/hardware/gic.h>
35
36#include "board.h"
37
38static struct of_device_id tegra_dt_match_table[] __initdata = {
39 { .compatible = "simple-bus", },
40 {}
41};
42
43static void __init tegra30_dt_init(void)
44{
45 of_platform_populate(NULL, tegra_dt_match_table,
46 NULL, NULL);
47}
48
49static const char *tegra30_dt_board_compat[] = {
50 "nvidia,cardhu",
51 NULL
52};
53
54DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
55 .map_io = tegra_map_common_io,
56 .init_early = tegra30_init_early,
57 .init_irq = tegra_dt_init_irq,
58 .handle_irq = gic_handle_irq,
59 .timer = &tegra_timer,
60 .init_machine = tegra30_dt_init,
61 .restart = tegra_assert_system_reset,
62 .dt_compat = tegra30_dt_board_compat,
63MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
index 6db7d699ef1..33c4fedab84 100644
--- a/arch/arm/mach-tegra/board-harmony-pcie.c
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -22,7 +22,6 @@
22 22
23#include <asm/mach-types.h> 23#include <asm/mach-types.h>
24 24
25#include <mach/pinmux.h>
26#include "board.h" 25#include "board.h"
27#include "board-harmony.h" 26#include "board-harmony.h"
28 27
@@ -48,10 +47,6 @@ static int __init harmony_pcie_init(void)
48 47
49 regulator_enable(regulator); 48 regulator_enable(regulator);
50 49
51 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL);
52 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL);
53 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL);
54
55 err = tegra_pcie_init(true, true); 50 err = tegra_pcie_init(true, true);
56 if (err) 51 if (err)
57 goto err_pcie; 52 goto err_pcie;
@@ -59,10 +54,6 @@ static int __init harmony_pcie_init(void)
59 return 0; 54 return 0;
60 55
61err_pcie: 56err_pcie:
62 tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_TRISTATE);
63 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE);
64 tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE);
65
66 regulator_disable(regulator); 57 regulator_disable(regulator);
67 regulator_put(regulator); 58 regulator_put(regulator);
68err_reg: 59err_reg:
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
index 7a4a26d5174..465808c8ac0 100644
--- a/arch/arm/mach-tegra/board-harmony-pinmux.c
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -19,10 +19,11 @@
19#include <linux/of.h> 19#include <linux/of.h>
20 20
21#include <mach/pinmux.h> 21#include <mach/pinmux.h>
22#include <mach/pinmux-tegra20.h>
22 23
23#include "gpio-names.h" 24#include "gpio-names.h"
24#include "board-harmony.h" 25#include "board-harmony.h"
25#include "devices.h" 26#include "board-pinmux.h"
26 27
27static struct tegra_pingroup_config harmony_pinmux[] = { 28static struct tegra_pingroup_config harmony_pinmux[] = {
28 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 29 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -143,11 +144,6 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
143 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 144 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144}; 145};
145 146
146static struct platform_device *pinmux_devices[] = {
147 &tegra_gpio_device,
148 &tegra_pinmux_device,
149};
150
151static struct tegra_gpio_table gpio_table[] = { 147static struct tegra_gpio_table gpio_table[] = {
152 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, 148 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
153 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, 149 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
@@ -161,13 +157,14 @@ static struct tegra_gpio_table gpio_table[] = {
161 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true }, 157 { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
162}; 158};
163 159
160static struct tegra_board_pinmux_conf conf = {
161 .pgs = harmony_pinmux,
162 .pg_count = ARRAY_SIZE(harmony_pinmux),
163 .gpios = gpio_table,
164 .gpio_count = ARRAY_SIZE(gpio_table),
165};
166
164void harmony_pinmux_init(void) 167void harmony_pinmux_init(void)
165{ 168{
166 if (!of_machine_is_compatible("nvidia,tegra20")) 169 tegra_board_pinmux_init(&conf, NULL);
167 platform_add_devices(pinmux_devices,
168 ARRAY_SIZE(pinmux_devices));
169
170 tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
171
172 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
173} 170}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 70ee674131f..a0f9634f672 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -186,7 +186,7 @@ MACHINE_START(HARMONY, "harmony")
186 .atag_offset = 0x100, 186 .atag_offset = 0x100,
187 .fixup = tegra_harmony_fixup, 187 .fixup = tegra_harmony_fixup,
188 .map_io = tegra_map_common_io, 188 .map_io = tegra_map_common_io,
189 .init_early = tegra_init_early, 189 .init_early = tegra20_init_early,
190 .init_irq = tegra_init_irq, 190 .init_irq = tegra_init_irq,
191 .handle_irq = gic_handle_irq, 191 .handle_irq = gic_handle_irq,
192 .timer = &tegra_timer, 192 .timer = &tegra_timer,
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
index be30e215f4b..c775572dcea 100644
--- a/arch/arm/mach-tegra/board-paz00-pinmux.c
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
@@ -19,10 +19,11 @@
19#include <linux/of.h> 19#include <linux/of.h>
20 20
21#include <mach/pinmux.h> 21#include <mach/pinmux.h>
22#include <mach/pinmux-tegra20.h>
22 23
23#include "gpio-names.h" 24#include "gpio-names.h"
24#include "board-paz00.h" 25#include "board-paz00.h"
25#include "devices.h" 26#include "board-pinmux.h"
26 27
27static struct tegra_pingroup_config paz00_pinmux[] = { 28static struct tegra_pingroup_config paz00_pinmux[] = {
28 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 29 {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -30,7 +31,7 @@ static struct tegra_pingroup_config paz00_pinmux[] = {
30 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 31 {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
31 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 32 {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
32 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 33 {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
33 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 34 {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
34 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, 35 {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
35 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 36 {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
36 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 37 {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
@@ -143,11 +144,6 @@ static struct tegra_pingroup_config paz00_pinmux[] = {
143 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 144 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144}; 145};
145 146
146static struct platform_device *pinmux_devices[] = {
147 &tegra_gpio_device,
148 &tegra_pinmux_device,
149};
150
151static struct tegra_gpio_table gpio_table[] = { 147static struct tegra_gpio_table gpio_table[] = {
152 { .gpio = TEGRA_GPIO_SD1_CD, .enable = true }, 148 { .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
153 { .gpio = TEGRA_GPIO_SD1_WP, .enable = true }, 149 { .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
@@ -158,13 +154,14 @@ static struct tegra_gpio_table gpio_table[] = {
158 { .gpio = TEGRA_WIFI_LED, .enable = true }, 154 { .gpio = TEGRA_WIFI_LED, .enable = true },
159}; 155};
160 156
157static struct tegra_board_pinmux_conf conf = {
158 .pgs = paz00_pinmux,
159 .pg_count = ARRAY_SIZE(paz00_pinmux),
160 .gpios = gpio_table,
161 .gpio_count = ARRAY_SIZE(gpio_table),
162};
163
161void paz00_pinmux_init(void) 164void paz00_pinmux_init(void)
162{ 165{
163 if (!of_machine_is_compatible("nvidia,tegra20")) 166 tegra_board_pinmux_init(&conf, NULL);
164 platform_add_devices(pinmux_devices,
165 ARRAY_SIZE(pinmux_devices));
166
167 tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
168
169 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
170} 167}
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
index 33d6205ad30..fcf4f377b1d 100644
--- a/arch/arm/mach-tegra/board-paz00.c
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -23,8 +23,10 @@
23#include <linux/serial_8250.h> 23#include <linux/serial_8250.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/gpio_keys.h>
26#include <linux/pda_power.h> 27#include <linux/pda_power.h>
27#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/input.h>
28#include <linux/i2c.h> 30#include <linux/i2c.h>
29#include <linux/gpio.h> 31#include <linux/gpio.h>
30#include <linux/rfkill-gpio.h> 32#include <linux/rfkill-gpio.h>
@@ -115,12 +117,37 @@ static struct platform_device leds_gpio = {
115 }, 117 },
116}; 118};
117 119
120static struct gpio_keys_button paz00_gpio_keys_buttons[] = {
121 {
122 .code = KEY_POWER,
123 .gpio = TEGRA_GPIO_POWERKEY,
124 .active_low = 1,
125 .desc = "Power",
126 .type = EV_KEY,
127 .wakeup = 1,
128 },
129};
130
131static struct gpio_keys_platform_data paz00_gpio_keys = {
132 .buttons = paz00_gpio_keys_buttons,
133 .nbuttons = ARRAY_SIZE(paz00_gpio_keys_buttons),
134};
135
136static struct platform_device gpio_keys_device = {
137 .name = "gpio-keys",
138 .id = -1,
139 .dev = {
140 .platform_data = &paz00_gpio_keys,
141 },
142};
143
118static struct platform_device *paz00_devices[] __initdata = { 144static struct platform_device *paz00_devices[] __initdata = {
119 &debug_uart, 145 &debug_uart,
120 &tegra_sdhci_device4, 146 &tegra_sdhci_device4,
121 &tegra_sdhci_device1, 147 &tegra_sdhci_device1,
122 &wifi_rfkill_device, 148 &wifi_rfkill_device,
123 &leds_gpio, 149 &leds_gpio,
150 &gpio_keys_device,
124}; 151};
125 152
126static void paz00_i2c_init(void) 153static void paz00_i2c_init(void)
@@ -189,7 +216,7 @@ MACHINE_START(PAZ00, "Toshiba AC100 / Dynabook AZ")
189 .atag_offset = 0x100, 216 .atag_offset = 0x100,
190 .fixup = tegra_paz00_fixup, 217 .fixup = tegra_paz00_fixup,
191 .map_io = tegra_map_common_io, 218 .map_io = tegra_map_common_io,
192 .init_early = tegra_init_early, 219 .init_early = tegra20_init_early,
193 .init_irq = tegra_init_irq, 220 .init_irq = tegra_init_irq,
194 .handle_irq = gic_handle_irq, 221 .handle_irq = gic_handle_irq,
195 .timer = &tegra_timer, 222 .timer = &tegra_timer,
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
index 8aff06eb58c..ffa83f580db 100644
--- a/arch/arm/mach-tegra/board-paz00.h
+++ b/arch/arm/mach-tegra/board-paz00.h
@@ -32,6 +32,9 @@
32#define TEGRA_WIFI_RST TEGRA_GPIO_PD1 32#define TEGRA_WIFI_RST TEGRA_GPIO_PD1
33#define TEGRA_WIFI_LED TEGRA_GPIO_PD0 33#define TEGRA_WIFI_LED TEGRA_GPIO_PD0
34 34
35/* WakeUp */
36#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PJ7
37
35void paz00_pinmux_init(void); 38void paz00_pinmux_init(void);
36 39
37#endif 40#endif
diff --git a/arch/arm/mach-tegra/board-pinmux.c b/arch/arm/mach-tegra/board-pinmux.c
new file mode 100644
index 00000000000..adc3efe979b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-pinmux.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/device.h>
16#include <linux/kernel.h>
17#include <linux/notifier.h>
18#include <linux/of.h>
19#include <linux/string.h>
20
21#include <mach/gpio-tegra.h>
22#include <mach/pinmux.h>
23
24#include "board-pinmux.h"
25#include "devices.h"
26
27struct tegra_board_pinmux_conf *confs[2];
28
29static void tegra_board_pinmux_setup_gpios(void)
30{
31 int i;
32
33 for (i = 0; i < ARRAY_SIZE(confs); i++) {
34 if (!confs[i])
35 continue;
36
37 tegra_gpio_config(confs[i]->gpios, confs[i]->gpio_count);
38 }
39}
40
41static void tegra_board_pinmux_setup_pinmux(void)
42{
43 int i;
44
45 for (i = 0; i < ARRAY_SIZE(confs); i++) {
46 if (!confs[i])
47 continue;
48
49 tegra_pinmux_config_table(confs[i]->pgs, confs[i]->pg_count);
50
51 if (confs[i]->drives)
52 tegra_drive_pinmux_config_table(confs[i]->drives,
53 confs[i]->drive_count);
54 }
55}
56
57static int tegra_board_pinmux_bus_notify(struct notifier_block *nb,
58 unsigned long event, void *vdev)
59{
60 static bool had_gpio;
61 static bool had_pinmux;
62
63 struct device *dev = vdev;
64 const char *devname;
65
66 if (event != BUS_NOTIFY_BOUND_DRIVER)
67 return NOTIFY_DONE;
68
69 devname = dev_name(dev);
70
71 if (!had_gpio && !strcmp(devname, GPIO_DEV)) {
72 tegra_board_pinmux_setup_gpios();
73 had_gpio = true;
74 } else if (!had_pinmux && !strcmp(devname, PINMUX_DEV)) {
75 tegra_board_pinmux_setup_pinmux();
76 had_pinmux = true;
77 }
78
79 if (had_gpio && had_pinmux)
80 return NOTIFY_STOP_MASK;
81 else
82 return NOTIFY_DONE;
83}
84
85static struct notifier_block nb = {
86 .notifier_call = tegra_board_pinmux_bus_notify,
87};
88
89static struct platform_device *devices[] = {
90 &tegra_gpio_device,
91 &tegra_pinmux_device,
92};
93
94void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a,
95 struct tegra_board_pinmux_conf *conf_b)
96{
97 confs[0] = conf_a;
98 confs[1] = conf_b;
99
100 bus_register_notifier(&platform_bus_type, &nb);
101
102 if (!of_machine_is_compatible("nvidia,tegra20"))
103 platform_add_devices(devices, ARRAY_SIZE(devices));
104}
diff --git a/arch/arm/mach-tegra/board-pinmux.h b/arch/arm/mach-tegra/board-pinmux.h
new file mode 100644
index 00000000000..4aac73546f5
--- /dev/null
+++ b/arch/arm/mach-tegra/board-pinmux.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef __MACH_TEGRA_BOARD_PINMUX_H
16#define __MACH_TEGRA_BOARD_PINMUX_H
17
18#define GPIO_DEV "tegra-gpio"
19#define PINMUX_DEV "tegra-pinmux"
20
21struct tegra_pingroup_config;
22struct tegra_gpio_table;
23
24struct tegra_board_pinmux_conf {
25 struct tegra_pingroup_config *pgs;
26 int pg_count;
27
28 struct tegra_drive_pingroup_config *drives;
29 int drive_count;
30
31 struct tegra_gpio_table *gpios;
32 int gpio_count;
33};
34
35void tegra_board_pinmux_init(struct tegra_board_pinmux_conf *conf_a,
36 struct tegra_board_pinmux_conf *conf_b);
37
38#endif
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
index b1c2972f62f..55e7e43a14a 100644
--- a/arch/arm/mach-tegra/board-seaboard-pinmux.c
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -19,11 +19,11 @@
19#include <linux/of.h> 19#include <linux/of.h>
20 20
21#include <mach/pinmux.h> 21#include <mach/pinmux.h>
22#include <mach/pinmux-t2.h> 22#include <mach/pinmux-tegra20.h>
23 23
24#include "gpio-names.h" 24#include "gpio-names.h"
25#include "board-pinmux.h"
25#include "board-seaboard.h" 26#include "board-seaboard.h"
26#include "devices.h"
27 27
28#define DEFAULT_DRIVE(_name) \ 28#define DEFAULT_DRIVE(_name) \
29 { \ 29 { \
@@ -37,11 +37,11 @@
37 .slew_falling = TEGRA_SLEW_SLOWEST, \ 37 .slew_falling = TEGRA_SLEW_SLOWEST, \
38 } 38 }
39 39
40static __initdata struct tegra_drive_pingroup_config seaboard_drive_pinmux[] = { 40static struct tegra_drive_pingroup_config seaboard_drive_pinmux[] = {
41 DEFAULT_DRIVE(SDIO1), 41 DEFAULT_DRIVE(SDIO1),
42}; 42};
43 43
44static __initdata struct tegra_pingroup_config seaboard_pinmux[] = { 44static struct tegra_pingroup_config common_pinmux[] = {
45 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 45 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
46 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 46 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
47 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 47 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -55,7 +55,6 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
55 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 55 {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 56 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
57 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 57 {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
58 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
59 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, 58 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
60 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, 59 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
61 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL}, 60 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
@@ -65,7 +64,6 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
65 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 64 {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
66 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 65 {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
67 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 66 {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
68 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
69 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 67 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
70 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 68 {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
71 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 69 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -108,13 +106,8 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
108 {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 106 {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
109 {TEGRA_PINGROUP_LM1, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 107 {TEGRA_PINGROUP_LM1, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
110 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 108 {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
112 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 109 {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
113 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
114 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 110 {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
115 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
116 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
117 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 111 {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
119 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 112 {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
120 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 113 {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
@@ -122,25 +115,19 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
122 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 115 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
123 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 116 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
124 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 117 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
125 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
126 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 118 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
127 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 119 {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
128 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 120 {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
129 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 121 {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
130 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 122 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
131 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 123 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
132 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
133 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 124 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
134 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
135 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 125 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
136 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 126 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
137 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
138 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 127 {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
139 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
140 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 128 {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
141 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 129 {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
142 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE}, 130 {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
143 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
144 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 131 {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
145 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 132 {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
146 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 133 {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
@@ -160,13 +147,24 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
160 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 147 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
161}; 148};
162 149
163static __initdata struct tegra_pingroup_config ventana_pinmux[] = { 150static struct tegra_pingroup_config seaboard_pinmux[] = {
164 {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 151 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
152 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
153 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
154 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
155 {TEGRA_PINGROUP_LSC1, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
156 {TEGRA_PINGROUP_LSCK, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
157 {TEGRA_PINGROUP_LSDA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
158 {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
159 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
160 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
161 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
162 {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
163 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
164};
165
166static struct tegra_pingroup_config ventana_pinmux[] = {
165 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 167 {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
166 {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
167 {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
168 {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
169 {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
170 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 168 {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
171 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 169 {TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
172 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 170 {TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
@@ -181,65 +179,59 @@ static __initdata struct tegra_pingroup_config ventana_pinmux[] = {
181 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 179 {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
182}; 180};
183 181
184static struct platform_device *pinmux_devices[] = {
185 &tegra_gpio_device,
186 &tegra_pinmux_device,
187};
188
189static struct tegra_gpio_table common_gpio_table[] = { 182static struct tegra_gpio_table common_gpio_table[] = {
190 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true }, 183 { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
191 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true }, 184 { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
192 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true }, 185 { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
186 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
187};
188
189static struct tegra_gpio_table seaboard_gpio_table[] = {
193 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true }, 190 { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
194 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true }, 191 { .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
195 { .gpio = TEGRA_GPIO_HP_DET, .enable = true }, 192 { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
196 { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true }, 193 { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
197 { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
198 { .gpio = TEGRA_GPIO_USB1, .enable = true }, 194 { .gpio = TEGRA_GPIO_USB1, .enable = true },
199}; 195};
200 196
201static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size) 197static struct tegra_gpio_table ventana_gpio_table[] = {
202{ 198 /* hp_det */
203 int i, j; 199 { .gpio = TEGRA_GPIO_PW2, .enable = true },
204 struct tegra_pingroup_config *new_pingroup, *base_pingroup; 200 /* int_mic_en */
205 201 { .gpio = TEGRA_GPIO_PX0, .enable = true },
206 /* Update base seaboard pinmux table with secondary board 202 /* ext_mic_en */
207 * specific pinmux table table. 203 { .gpio = TEGRA_GPIO_PX1, .enable = true },
208 */ 204};
209 for (i = 0; i < size; i++) {
210 new_pingroup = &newtbl[i];
211 for (j = 0; j < ARRAY_SIZE(seaboard_pinmux); j++) {
212 base_pingroup = &seaboard_pinmux[j];
213 if (new_pingroup->pingroup == base_pingroup->pingroup) {
214 *base_pingroup = *new_pingroup;
215 break;
216 }
217 }
218 }
219}
220
221void __init seaboard_common_pinmux_init(void)
222{
223 if (!of_machine_is_compatible("nvidia,tegra20"))
224 platform_add_devices(pinmux_devices,
225 ARRAY_SIZE(pinmux_devices));
226 205
227 tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux)); 206static struct tegra_board_pinmux_conf common_conf = {
207 .pgs = common_pinmux,
208 .pg_count = ARRAY_SIZE(common_pinmux),
209 .gpios = common_gpio_table,
210 .gpio_count = ARRAY_SIZE(common_gpio_table),
211};
228 212
229 tegra_drive_pinmux_config_table(seaboard_drive_pinmux, 213static struct tegra_board_pinmux_conf seaboard_conf = {
230 ARRAY_SIZE(seaboard_drive_pinmux)); 214 .pgs = seaboard_pinmux,
215 .pg_count = ARRAY_SIZE(seaboard_pinmux),
216 .drives = seaboard_drive_pinmux,
217 .drive_count = ARRAY_SIZE(seaboard_drive_pinmux),
218 .gpios = seaboard_gpio_table,
219 .gpio_count = ARRAY_SIZE(seaboard_gpio_table),
220};
231 221
232 tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table)); 222static struct tegra_board_pinmux_conf ventana_conf = {
233} 223 .pgs = ventana_pinmux,
224 .pg_count = ARRAY_SIZE(ventana_pinmux),
225 .gpios = ventana_gpio_table,
226 .gpio_count = ARRAY_SIZE(ventana_gpio_table),
227};
234 228
235void __init seaboard_pinmux_init(void) 229void seaboard_pinmux_init(void)
236{ 230{
237 seaboard_common_pinmux_init(); 231 tegra_board_pinmux_init(&common_conf, &seaboard_conf);
238} 232}
239 233
240void __init ventana_pinmux_init(void) 234void ventana_pinmux_init(void)
241{ 235{
242 update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux)); 236 tegra_board_pinmux_init(&common_conf, &ventana_conf);
243 seaboard_common_pinmux_init();
244} 237}
245
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index c1599eb8e0c..cfc74d46a09 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -283,7 +283,7 @@ static void __init tegra_wario_init(void)
283MACHINE_START(SEABOARD, "seaboard") 283MACHINE_START(SEABOARD, "seaboard")
284 .atag_offset = 0x100, 284 .atag_offset = 0x100,
285 .map_io = tegra_map_common_io, 285 .map_io = tegra_map_common_io,
286 .init_early = tegra_init_early, 286 .init_early = tegra20_init_early,
287 .init_irq = tegra_init_irq, 287 .init_irq = tegra_init_irq,
288 .handle_irq = gic_handle_irq, 288 .handle_irq = gic_handle_irq,
289 .timer = &tegra_timer, 289 .timer = &tegra_timer,
@@ -294,7 +294,7 @@ MACHINE_END
294MACHINE_START(KAEN, "kaen") 294MACHINE_START(KAEN, "kaen")
295 .atag_offset = 0x100, 295 .atag_offset = 0x100,
296 .map_io = tegra_map_common_io, 296 .map_io = tegra_map_common_io,
297 .init_early = tegra_init_early, 297 .init_early = tegra20_init_early,
298 .init_irq = tegra_init_irq, 298 .init_irq = tegra_init_irq,
299 .handle_irq = gic_handle_irq, 299 .handle_irq = gic_handle_irq,
300 .timer = &tegra_timer, 300 .timer = &tegra_timer,
@@ -305,7 +305,7 @@ MACHINE_END
305MACHINE_START(WARIO, "wario") 305MACHINE_START(WARIO, "wario")
306 .atag_offset = 0x100, 306 .atag_offset = 0x100,
307 .map_io = tegra_map_common_io, 307 .map_io = tegra_map_common_io,
308 .init_early = tegra_init_early, 308 .init_early = tegra20_init_early,
309 .init_irq = tegra_init_irq, 309 .init_irq = tegra_init_irq,
310 .handle_irq = gic_handle_irq, 310 .handle_irq = gic_handle_irq,
311 .timer = &tegra_timer, 311 .timer = &tegra_timer,
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
index 7ab719d46da..a21a2be57cb 100644
--- a/arch/arm/mach-tegra/board-trimslice-pinmux.c
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
@@ -19,12 +19,13 @@
19#include <linux/of.h> 19#include <linux/of.h>
20 20
21#include <mach/pinmux.h> 21#include <mach/pinmux.h>
22#include <mach/pinmux-tegra20.h>
22 23
23#include "gpio-names.h" 24#include "gpio-names.h"
25#include "board-pinmux.h"
24#include "board-trimslice.h" 26#include "board-trimslice.h"
25#include "devices.h"
26 27
27static __initdata struct tegra_pingroup_config trimslice_pinmux[] = { 28static struct tegra_pingroup_config trimslice_pinmux[] = {
28 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 29 {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
29 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 30 {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
30 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 31 {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
@@ -105,7 +106,7 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
105 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 106 {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
106 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 107 {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
107 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 108 {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
108 {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 109 {TEGRA_PINGROUP_PTA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
109 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 110 {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
110 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 111 {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
111 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 112 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
@@ -143,11 +144,6 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
143 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 144 {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
144}; 145};
145 146
146static struct platform_device *pinmux_devices[] = {
147 &tegra_gpio_device,
148 &tegra_pinmux_device,
149};
150
151static struct tegra_gpio_table gpio_table[] = { 147static struct tegra_gpio_table gpio_table[] = {
152 { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */ 148 { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
153 { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */ 149 { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
@@ -156,11 +152,14 @@ static struct tegra_gpio_table gpio_table[] = {
156 { .gpio = TRIMSLICE_GPIO_USB2_RST, .enable = true }, /* USB2 PHY rst */ 152 { .gpio = TRIMSLICE_GPIO_USB2_RST, .enable = true }, /* USB2 PHY rst */
157}; 153};
158 154
159void __init trimslice_pinmux_init(void) 155static struct tegra_board_pinmux_conf conf = {
156 .pgs = trimslice_pinmux,
157 .pg_count = ARRAY_SIZE(trimslice_pinmux),
158 .gpios = gpio_table,
159 .gpio_count = ARRAY_SIZE(gpio_table),
160};
161
162void trimslice_pinmux_init(void)
160{ 163{
161 if (!of_machine_is_compatible("nvidia,tegra20")) 164 tegra_board_pinmux_init(&conf, NULL);
162 platform_add_devices(pinmux_devices,
163 ARRAY_SIZE(pinmux_devices));
164 tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
165 tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
166} 165}
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
index c242314a1db..cd52820a3e3 100644
--- a/arch/arm/mach-tegra/board-trimslice.c
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -175,7 +175,7 @@ MACHINE_START(TRIMSLICE, "trimslice")
175 .atag_offset = 0x100, 175 .atag_offset = 0x100,
176 .fixup = tegra_trimslice_fixup, 176 .fixup = tegra_trimslice_fixup,
177 .map_io = tegra_map_common_io, 177 .map_io = tegra_map_common_io,
178 .init_early = tegra_init_early, 178 .init_early = tegra20_init_early,
179 .init_irq = tegra_init_irq, 179 .init_irq = tegra_init_irq,
180 .handle_irq = gic_handle_irq, 180 .handle_irq = gic_handle_irq,
181 .timer = &tegra_timer, 181 .timer = &tegra_timer,
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 1d14df7eb7d..75d1543d77c 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -25,10 +25,11 @@
25 25
26void tegra_assert_system_reset(char mode, const char *cmd); 26void tegra_assert_system_reset(char mode, const char *cmd);
27 27
28void __init tegra_init_early(void); 28void __init tegra20_init_early(void);
29void __init tegra30_init_early(void);
29void __init tegra_map_common_io(void); 30void __init tegra_map_common_io(void);
30void __init tegra_init_irq(void); 31void __init tegra_init_irq(void);
31void __init tegra_init_clock(void); 32void __init tegra_dt_init_irq(void);
32int __init tegra_pcie_init(bool init_port0, bool init_port1); 33int __init tegra_pcie_init(bool init_port0, bool init_port1);
33 34
34extern struct sys_timer tegra_timer; 35extern struct sys_timer tegra_timer;
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index f8d41ffc0ca..8337068a4ab 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -387,35 +387,18 @@ EXPORT_SYMBOL(tegra_clk_init_from_table);
387 387
388void tegra_periph_reset_deassert(struct clk *c) 388void tegra_periph_reset_deassert(struct clk *c)
389{ 389{
390 tegra2_periph_reset_deassert(c); 390 BUG_ON(!c->ops->reset);
391 c->ops->reset(c, false);
391} 392}
392EXPORT_SYMBOL(tegra_periph_reset_deassert); 393EXPORT_SYMBOL(tegra_periph_reset_deassert);
393 394
394void tegra_periph_reset_assert(struct clk *c) 395void tegra_periph_reset_assert(struct clk *c)
395{ 396{
396 tegra2_periph_reset_assert(c); 397 BUG_ON(!c->ops->reset);
398 c->ops->reset(c, true);
397} 399}
398EXPORT_SYMBOL(tegra_periph_reset_assert); 400EXPORT_SYMBOL(tegra_periph_reset_assert);
399 401
400void __init tegra_init_clock(void)
401{
402 tegra2_init_clocks();
403}
404
405/*
406 * The SDMMC controllers have extra bits in the clock source register that
407 * adjust the delay between the clock and data to compenstate for delays
408 * on the PCB.
409 */
410void tegra_sdmmc_tap_delay(struct clk *c, int delay)
411{
412 unsigned long flags;
413
414 spin_lock_irqsave(&c->spinlock, flags);
415 tegra2_sdmmc_tap_delay(c, delay);
416 spin_unlock_irqrestore(&c->spinlock, flags);
417}
418
419#ifdef CONFIG_DEBUG_FS 402#ifdef CONFIG_DEBUG_FS
420 403
421static int __clk_lock_all_spinlocks(void) 404static int __clk_lock_all_spinlocks(void)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 688316abc64..5c44106616c 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -146,15 +146,11 @@ struct tegra_clk_init_table {
146}; 146};
147 147
148void tegra2_init_clocks(void); 148void tegra2_init_clocks(void);
149void tegra2_periph_reset_deassert(struct clk *c);
150void tegra2_periph_reset_assert(struct clk *c);
151void clk_init(struct clk *clk); 149void clk_init(struct clk *clk);
152struct clk *tegra_get_clock_by_name(const char *name); 150struct clk *tegra_get_clock_by_name(const char *name);
153unsigned long clk_measure_input_freq(void);
154int clk_reparent(struct clk *c, struct clk *parent); 151int clk_reparent(struct clk *c, struct clk *parent);
155void tegra_clk_init_from_table(struct tegra_clk_init_table *table); 152void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
156unsigned long clk_get_rate_locked(struct clk *c); 153unsigned long clk_get_rate_locked(struct clk *c);
157int clk_set_rate_locked(struct clk *c, unsigned long rate); 154int clk_set_rate_locked(struct clk *c, unsigned long rate);
158void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
159 155
160#endif 156#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 20f396d740f..a2eb90169ae 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-tegra/board-harmony.c 2 * arch/arm/mach-tegra/common.c
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * 5 *
@@ -21,8 +21,10 @@
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/of_irq.h>
24 25
25#include <asm/hardware/cache-l2x0.h> 26#include <asm/hardware/cache-l2x0.h>
27#include <asm/hardware/gic.h>
26 28
27#include <mach/iomap.h> 29#include <mach/iomap.h>
28#include <mach/system.h> 30#include <mach/system.h>
@@ -31,18 +33,31 @@
31#include "clock.h" 33#include "clock.h"
32#include "fuse.h" 34#include "fuse.h"
33 35
36#ifdef CONFIG_OF
37static const struct of_device_id tegra_dt_irq_match[] __initconst = {
38 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
39 { }
40};
41
42void __init tegra_dt_init_irq(void)
43{
44 tegra_init_irq();
45 of_irq_init(tegra_dt_irq_match);
46}
47#endif
48
34void tegra_assert_system_reset(char mode, const char *cmd) 49void tegra_assert_system_reset(char mode, const char *cmd)
35{ 50{
36 void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04); 51 void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0);
37 u32 reg; 52 u32 reg;
38 53
39 /* use *_related to avoid spinlock since caches are off */
40 reg = readl_relaxed(reset); 54 reg = readl_relaxed(reset);
41 reg |= 0x04; 55 reg |= 0x10;
42 writel_relaxed(reg, reset); 56 writel_relaxed(reg, reset);
43} 57}
44 58
45static __initdata struct tegra_clk_init_table common_clk_init_table[] = { 59#ifdef CONFIG_ARCH_TEGRA_2x_SOC
60static __initdata struct tegra_clk_init_table tegra20_clk_init_table[] = {
46 /* name parent rate enabled */ 61 /* name parent rate enabled */
47 { "clk_m", NULL, 0, true }, 62 { "clk_m", NULL, 0, true },
48 { "pll_p", "clk_m", 216000000, true }, 63 { "pll_p", "clk_m", 216000000, true },
@@ -58,24 +73,38 @@ static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
58 { "cpu", NULL, 0, true }, 73 { "cpu", NULL, 0, true },
59 { NULL, NULL, 0, 0}, 74 { NULL, NULL, 0, 0},
60}; 75};
76#endif
61 77
62static void __init tegra_init_cache(void) 78static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
63{ 79{
64#ifdef CONFIG_CACHE_L2X0 80#ifdef CONFIG_CACHE_L2X0
65 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; 81 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
82 u32 aux_ctrl, cache_type;
83
84 writel_relaxed(tag_latency, p + L2X0_TAG_LATENCY_CTRL);
85 writel_relaxed(data_latency, p + L2X0_DATA_LATENCY_CTRL);
66 86
67 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL); 87 cache_type = readl(p + L2X0_CACHE_TYPE);
68 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL); 88 aux_ctrl = (cache_type & 0x700) << (17-8);
89 aux_ctrl |= 0x6C000001;
69 90
70 l2x0_init(p, 0x6C080001, 0x8200c3fe); 91 l2x0_init(p, aux_ctrl, 0x8200c3fe);
71#endif 92#endif
72 93
73} 94}
74 95
75void __init tegra_init_early(void) 96#ifdef CONFIG_ARCH_TEGRA_2x_SOC
97void __init tegra20_init_early(void)
76{ 98{
77 tegra_init_fuse(); 99 tegra_init_fuse();
78 tegra_init_clock(); 100 tegra2_init_clocks();
79 tegra_clk_init_from_table(common_clk_init_table); 101 tegra_clk_init_from_table(tegra20_clk_init_table);
80 tegra_init_cache(); 102 tegra_init_cache(0x331, 0x441);
103}
104#endif
105#ifdef CONFIG_ARCH_TEGRA_3x_SOC
106void __init tegra30_init_early(void)
107{
108 tegra_init_cache(0x441, 0x551);
81} 109}
110#endif
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index c8baf8f80d2..fc3ecb66de0 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -26,6 +26,6 @@ void tegra_periph_reset_deassert(struct clk *c);
26void tegra_periph_reset_assert(struct clk *c); 26void tegra_periph_reset_assert(struct clk *c);
27 27
28unsigned long clk_get_rate_all_locked(struct clk *c); 28unsigned long clk_get_rate_all_locked(struct clk *c);
29void tegra_sdmmc_tap_delay(struct clk *c, int delay); 29void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
30 30
31#endif 31#endif
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
index ac11262149c..e577cfe27e7 100644
--- a/arch/arm/mach-tegra/include/mach/entry-macro.S
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -18,21 +18,3 @@
18 18
19 .macro arch_ret_to_user, tmp1, tmp2 19 .macro arch_ret_to_user, tmp1, tmp2
20 .endm 20 .endm
21
22#if !defined(CONFIG_ARM_GIC)
23 /* legacy interrupt controller for AP16 */
24
25 .macro get_irqnr_preamble, base, tmp
26 @ enable imprecise aborts
27 cpsie a
28 @ EVP base at 0xf010f000
29 mov \base, #0xf0000000
30 orr \base, #0x00100000
31 orr \base, #0x0000f000
32 .endm
33
34 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
35 ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS
36 cmp \irqnr, #0x80
37 .endm
38#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index 73265af4dda..a2146cd6867 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -25,7 +25,6 @@
25 25
26#define IRQ_LOCALTIMER 29 26#define IRQ_LOCALTIMER 29
27 27
28#ifdef CONFIG_ARCH_TEGRA_2x_SOC
29/* Primary Interrupt Controller */ 28/* Primary Interrupt Controller */
30#define INT_PRI_BASE (INT_GIC_BASE + 32) 29#define INT_PRI_BASE (INT_GIC_BASE + 32)
31#define INT_TMR1 (INT_PRI_BASE + 0) 30#define INT_TMR1 (INT_PRI_BASE + 0)
@@ -178,6 +177,5 @@
178#define NR_BOARD_IRQS 32 177#define NR_BOARD_IRQS 32
179 178
180#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS) 179#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS)
181#endif
182 180
183#endif 181#endif
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
index 4f3572a1c68..20bb0545f99 100644
--- a/arch/arm/mach-tegra/include/mach/kbc.h
+++ b/arch/arm/mach-tegra/include/mach/kbc.h
@@ -53,6 +53,7 @@ struct tegra_kbc_platform_data {
53 struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO]; 53 struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
54 const struct matrix_keymap_data *keymap_data; 54 const struct matrix_keymap_data *keymap_data;
55 55
56 u32 wakeup_key;
56 bool wakeup; 57 bool wakeup;
57 bool use_fn_map; 58 bool use_fn_map;
58 bool use_ghost_filter; 59 bool use_ghost_filter;
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h
index 4c262634726..6a40c1dbab1 100644
--- a/arch/arm/mach-tegra/include/mach/pinmux-t2.h
+++ b/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux-t2.h 2 * linux/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * 5 *
@@ -14,8 +14,8 @@
14 * 14 *
15 */ 15 */
16 16
17#ifndef __MACH_TEGRA_PINMUX_T2_H 17#ifndef __MACH_TEGRA_PINMUX_TEGRA20_H
18#define __MACH_TEGRA_PINMUX_T2_H 18#define __MACH_TEGRA_PINMUX_TEGRA20_H
19 19
20enum tegra_pingroup { 20enum tegra_pingroup {
21 TEGRA_PINGROUP_ATA = 0, 21 TEGRA_PINGROUP_ATA = 0,
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h b/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h
new file mode 100644
index 00000000000..c1aee3eb2df
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h
@@ -0,0 +1,320 @@
1/*
2 * linux/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2010,2011 Nvidia, Inc.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#ifndef __MACH_TEGRA_PINMUX_TEGRA30_H
19#define __MACH_TEGRA_PINMUX_TEGRA30_H
20
21enum tegra_pingroup {
22 TEGRA_PINGROUP_ULPI_DATA0 = 0,
23 TEGRA_PINGROUP_ULPI_DATA1,
24 TEGRA_PINGROUP_ULPI_DATA2,
25 TEGRA_PINGROUP_ULPI_DATA3,
26 TEGRA_PINGROUP_ULPI_DATA4,
27 TEGRA_PINGROUP_ULPI_DATA5,
28 TEGRA_PINGROUP_ULPI_DATA6,
29 TEGRA_PINGROUP_ULPI_DATA7,
30 TEGRA_PINGROUP_ULPI_CLK,
31 TEGRA_PINGROUP_ULPI_DIR,
32 TEGRA_PINGROUP_ULPI_NXT,
33 TEGRA_PINGROUP_ULPI_STP,
34 TEGRA_PINGROUP_DAP3_FS,
35 TEGRA_PINGROUP_DAP3_DIN,
36 TEGRA_PINGROUP_DAP3_DOUT,
37 TEGRA_PINGROUP_DAP3_SCLK,
38 TEGRA_PINGROUP_GPIO_PV0,
39 TEGRA_PINGROUP_GPIO_PV1,
40 TEGRA_PINGROUP_SDMMC1_CLK,
41 TEGRA_PINGROUP_SDMMC1_CMD,
42 TEGRA_PINGROUP_SDMMC1_DAT3,
43 TEGRA_PINGROUP_SDMMC1_DAT2,
44 TEGRA_PINGROUP_SDMMC1_DAT1,
45 TEGRA_PINGROUP_SDMMC1_DAT0,
46 TEGRA_PINGROUP_GPIO_PV2,
47 TEGRA_PINGROUP_GPIO_PV3,
48 TEGRA_PINGROUP_CLK2_OUT,
49 TEGRA_PINGROUP_CLK2_REQ,
50 TEGRA_PINGROUP_LCD_PWR1,
51 TEGRA_PINGROUP_LCD_PWR2,
52 TEGRA_PINGROUP_LCD_SDIN,
53 TEGRA_PINGROUP_LCD_SDOUT,
54 TEGRA_PINGROUP_LCD_WR_N,
55 TEGRA_PINGROUP_LCD_CS0_N,
56 TEGRA_PINGROUP_LCD_DC0,
57 TEGRA_PINGROUP_LCD_SCK,
58 TEGRA_PINGROUP_LCD_PWR0,
59 TEGRA_PINGROUP_LCD_PCLK,
60 TEGRA_PINGROUP_LCD_DE,
61 TEGRA_PINGROUP_LCD_HSYNC,
62 TEGRA_PINGROUP_LCD_VSYNC,
63 TEGRA_PINGROUP_LCD_D0,
64 TEGRA_PINGROUP_LCD_D1,
65 TEGRA_PINGROUP_LCD_D2,
66 TEGRA_PINGROUP_LCD_D3,
67 TEGRA_PINGROUP_LCD_D4,
68 TEGRA_PINGROUP_LCD_D5,
69 TEGRA_PINGROUP_LCD_D6,
70 TEGRA_PINGROUP_LCD_D7,
71 TEGRA_PINGROUP_LCD_D8,
72 TEGRA_PINGROUP_LCD_D9,
73 TEGRA_PINGROUP_LCD_D10,
74 TEGRA_PINGROUP_LCD_D11,
75 TEGRA_PINGROUP_LCD_D12,
76 TEGRA_PINGROUP_LCD_D13,
77 TEGRA_PINGROUP_LCD_D14,
78 TEGRA_PINGROUP_LCD_D15,
79 TEGRA_PINGROUP_LCD_D16,
80 TEGRA_PINGROUP_LCD_D17,
81 TEGRA_PINGROUP_LCD_D18,
82 TEGRA_PINGROUP_LCD_D19,
83 TEGRA_PINGROUP_LCD_D20,
84 TEGRA_PINGROUP_LCD_D21,
85 TEGRA_PINGROUP_LCD_D22,
86 TEGRA_PINGROUP_LCD_D23,
87 TEGRA_PINGROUP_LCD_CS1_N,
88 TEGRA_PINGROUP_LCD_M1,
89 TEGRA_PINGROUP_LCD_DC1,
90 TEGRA_PINGROUP_HDMI_INT,
91 TEGRA_PINGROUP_DDC_SCL,
92 TEGRA_PINGROUP_DDC_SDA,
93 TEGRA_PINGROUP_CRT_HSYNC,
94 TEGRA_PINGROUP_CRT_VSYNC,
95 TEGRA_PINGROUP_VI_D0,
96 TEGRA_PINGROUP_VI_D1,
97 TEGRA_PINGROUP_VI_D2,
98 TEGRA_PINGROUP_VI_D3,
99 TEGRA_PINGROUP_VI_D4,
100 TEGRA_PINGROUP_VI_D5,
101 TEGRA_PINGROUP_VI_D6,
102 TEGRA_PINGROUP_VI_D7,
103 TEGRA_PINGROUP_VI_D8,
104 TEGRA_PINGROUP_VI_D9,
105 TEGRA_PINGROUP_VI_D10,
106 TEGRA_PINGROUP_VI_D11,
107 TEGRA_PINGROUP_VI_PCLK,
108 TEGRA_PINGROUP_VI_MCLK,
109 TEGRA_PINGROUP_VI_VSYNC,
110 TEGRA_PINGROUP_VI_HSYNC,
111 TEGRA_PINGROUP_UART2_RXD,
112 TEGRA_PINGROUP_UART2_TXD,
113 TEGRA_PINGROUP_UART2_RTS_N,
114 TEGRA_PINGROUP_UART2_CTS_N,
115 TEGRA_PINGROUP_UART3_TXD,
116 TEGRA_PINGROUP_UART3_RXD,
117 TEGRA_PINGROUP_UART3_CTS_N,
118 TEGRA_PINGROUP_UART3_RTS_N,
119 TEGRA_PINGROUP_GPIO_PU0,
120 TEGRA_PINGROUP_GPIO_PU1,
121 TEGRA_PINGROUP_GPIO_PU2,
122 TEGRA_PINGROUP_GPIO_PU3,
123 TEGRA_PINGROUP_GPIO_PU4,
124 TEGRA_PINGROUP_GPIO_PU5,
125 TEGRA_PINGROUP_GPIO_PU6,
126 TEGRA_PINGROUP_GEN1_I2C_SDA,
127 TEGRA_PINGROUP_GEN1_I2C_SCL,
128 TEGRA_PINGROUP_DAP4_FS,
129 TEGRA_PINGROUP_DAP4_DIN,
130 TEGRA_PINGROUP_DAP4_DOUT,
131 TEGRA_PINGROUP_DAP4_SCLK,
132 TEGRA_PINGROUP_CLK3_OUT,
133 TEGRA_PINGROUP_CLK3_REQ,
134 TEGRA_PINGROUP_GMI_WP_N,
135 TEGRA_PINGROUP_GMI_IORDY,
136 TEGRA_PINGROUP_GMI_WAIT,
137 TEGRA_PINGROUP_GMI_ADV_N,
138 TEGRA_PINGROUP_GMI_CLK,
139 TEGRA_PINGROUP_GMI_CS0_N,
140 TEGRA_PINGROUP_GMI_CS1_N,
141 TEGRA_PINGROUP_GMI_CS2_N,
142 TEGRA_PINGROUP_GMI_CS3_N,
143 TEGRA_PINGROUP_GMI_CS4_N,
144 TEGRA_PINGROUP_GMI_CS6_N,
145 TEGRA_PINGROUP_GMI_CS7_N,
146 TEGRA_PINGROUP_GMI_AD0,
147 TEGRA_PINGROUP_GMI_AD1,
148 TEGRA_PINGROUP_GMI_AD2,
149 TEGRA_PINGROUP_GMI_AD3,
150 TEGRA_PINGROUP_GMI_AD4,
151 TEGRA_PINGROUP_GMI_AD5,
152 TEGRA_PINGROUP_GMI_AD6,
153 TEGRA_PINGROUP_GMI_AD7,
154 TEGRA_PINGROUP_GMI_AD8,
155 TEGRA_PINGROUP_GMI_AD9,
156 TEGRA_PINGROUP_GMI_AD10,
157 TEGRA_PINGROUP_GMI_AD11,
158 TEGRA_PINGROUP_GMI_AD12,
159 TEGRA_PINGROUP_GMI_AD13,
160 TEGRA_PINGROUP_GMI_AD14,
161 TEGRA_PINGROUP_GMI_AD15,
162 TEGRA_PINGROUP_GMI_A16,
163 TEGRA_PINGROUP_GMI_A17,
164 TEGRA_PINGROUP_GMI_A18,
165 TEGRA_PINGROUP_GMI_A19,
166 TEGRA_PINGROUP_GMI_WR_N,
167 TEGRA_PINGROUP_GMI_OE_N,
168 TEGRA_PINGROUP_GMI_DQS,
169 TEGRA_PINGROUP_GMI_RST_N,
170 TEGRA_PINGROUP_GEN2_I2C_SCL,
171 TEGRA_PINGROUP_GEN2_I2C_SDA,
172 TEGRA_PINGROUP_SDMMC4_CLK,
173 TEGRA_PINGROUP_SDMMC4_CMD,
174 TEGRA_PINGROUP_SDMMC4_DAT0,
175 TEGRA_PINGROUP_SDMMC4_DAT1,
176 TEGRA_PINGROUP_SDMMC4_DAT2,
177 TEGRA_PINGROUP_SDMMC4_DAT3,
178 TEGRA_PINGROUP_SDMMC4_DAT4,
179 TEGRA_PINGROUP_SDMMC4_DAT5,
180 TEGRA_PINGROUP_SDMMC4_DAT6,
181 TEGRA_PINGROUP_SDMMC4_DAT7,
182 TEGRA_PINGROUP_SDMMC4_RST_N,
183 TEGRA_PINGROUP_CAM_MCLK,
184 TEGRA_PINGROUP_GPIO_PCC1,
185 TEGRA_PINGROUP_GPIO_PBB0,
186 TEGRA_PINGROUP_CAM_I2C_SCL,
187 TEGRA_PINGROUP_CAM_I2C_SDA,
188 TEGRA_PINGROUP_GPIO_PBB3,
189 TEGRA_PINGROUP_GPIO_PBB4,
190 TEGRA_PINGROUP_GPIO_PBB5,
191 TEGRA_PINGROUP_GPIO_PBB6,
192 TEGRA_PINGROUP_GPIO_PBB7,
193 TEGRA_PINGROUP_GPIO_PCC2,
194 TEGRA_PINGROUP_JTAG_RTCK,
195 TEGRA_PINGROUP_PWR_I2C_SCL,
196 TEGRA_PINGROUP_PWR_I2C_SDA,
197 TEGRA_PINGROUP_KB_ROW0,
198 TEGRA_PINGROUP_KB_ROW1,
199 TEGRA_PINGROUP_KB_ROW2,
200 TEGRA_PINGROUP_KB_ROW3,
201 TEGRA_PINGROUP_KB_ROW4,
202 TEGRA_PINGROUP_KB_ROW5,
203 TEGRA_PINGROUP_KB_ROW6,
204 TEGRA_PINGROUP_KB_ROW7,
205 TEGRA_PINGROUP_KB_ROW8,
206 TEGRA_PINGROUP_KB_ROW9,
207 TEGRA_PINGROUP_KB_ROW10,
208 TEGRA_PINGROUP_KB_ROW11,
209 TEGRA_PINGROUP_KB_ROW12,
210 TEGRA_PINGROUP_KB_ROW13,
211 TEGRA_PINGROUP_KB_ROW14,
212 TEGRA_PINGROUP_KB_ROW15,
213 TEGRA_PINGROUP_KB_COL0,
214 TEGRA_PINGROUP_KB_COL1,
215 TEGRA_PINGROUP_KB_COL2,
216 TEGRA_PINGROUP_KB_COL3,
217 TEGRA_PINGROUP_KB_COL4,
218 TEGRA_PINGROUP_KB_COL5,
219 TEGRA_PINGROUP_KB_COL6,
220 TEGRA_PINGROUP_KB_COL7,
221 TEGRA_PINGROUP_CLK_32K_OUT,
222 TEGRA_PINGROUP_SYS_CLK_REQ,
223 TEGRA_PINGROUP_CORE_PWR_REQ,
224 TEGRA_PINGROUP_CPU_PWR_REQ,
225 TEGRA_PINGROUP_PWR_INT_N,
226 TEGRA_PINGROUP_CLK_32K_IN,
227 TEGRA_PINGROUP_OWR,
228 TEGRA_PINGROUP_DAP1_FS,
229 TEGRA_PINGROUP_DAP1_DIN,
230 TEGRA_PINGROUP_DAP1_DOUT,
231 TEGRA_PINGROUP_DAP1_SCLK,
232 TEGRA_PINGROUP_CLK1_REQ,
233 TEGRA_PINGROUP_CLK1_OUT,
234 TEGRA_PINGROUP_SPDIF_IN,
235 TEGRA_PINGROUP_SPDIF_OUT,
236 TEGRA_PINGROUP_DAP2_FS,
237 TEGRA_PINGROUP_DAP2_DIN,
238 TEGRA_PINGROUP_DAP2_DOUT,
239 TEGRA_PINGROUP_DAP2_SCLK,
240 TEGRA_PINGROUP_SPI2_MOSI,
241 TEGRA_PINGROUP_SPI2_MISO,
242 TEGRA_PINGROUP_SPI2_CS0_N,
243 TEGRA_PINGROUP_SPI2_SCK,
244 TEGRA_PINGROUP_SPI1_MOSI,
245 TEGRA_PINGROUP_SPI1_SCK,
246 TEGRA_PINGROUP_SPI1_CS0_N,
247 TEGRA_PINGROUP_SPI1_MISO,
248 TEGRA_PINGROUP_SPI2_CS1_N,
249 TEGRA_PINGROUP_SPI2_CS2_N,
250 TEGRA_PINGROUP_SDMMC3_CLK,
251 TEGRA_PINGROUP_SDMMC3_CMD,
252 TEGRA_PINGROUP_SDMMC3_DAT0,
253 TEGRA_PINGROUP_SDMMC3_DAT1,
254 TEGRA_PINGROUP_SDMMC3_DAT2,
255 TEGRA_PINGROUP_SDMMC3_DAT3,
256 TEGRA_PINGROUP_SDMMC3_DAT4,
257 TEGRA_PINGROUP_SDMMC3_DAT5,
258 TEGRA_PINGROUP_SDMMC3_DAT6,
259 TEGRA_PINGROUP_SDMMC3_DAT7,
260 TEGRA_PINGROUP_PEX_L0_PRSNT_N,
261 TEGRA_PINGROUP_PEX_L0_RST_N,
262 TEGRA_PINGROUP_PEX_L0_CLKREQ_N,
263 TEGRA_PINGROUP_PEX_WAKE_N,
264 TEGRA_PINGROUP_PEX_L1_PRSNT_N,
265 TEGRA_PINGROUP_PEX_L1_RST_N,
266 TEGRA_PINGROUP_PEX_L1_CLKREQ_N,
267 TEGRA_PINGROUP_PEX_L2_PRSNT_N,
268 TEGRA_PINGROUP_PEX_L2_RST_N,
269 TEGRA_PINGROUP_PEX_L2_CLKREQ_N,
270 TEGRA_PINGROUP_HDMI_CEC,
271 TEGRA_MAX_PINGROUP,
272};
273
274enum tegra_drive_pingroup {
275 TEGRA_DRIVE_PINGROUP_AO1 = 0,
276 TEGRA_DRIVE_PINGROUP_AO2,
277 TEGRA_DRIVE_PINGROUP_AT1,
278 TEGRA_DRIVE_PINGROUP_AT2,
279 TEGRA_DRIVE_PINGROUP_AT3,
280 TEGRA_DRIVE_PINGROUP_AT4,
281 TEGRA_DRIVE_PINGROUP_AT5,
282 TEGRA_DRIVE_PINGROUP_CDEV1,
283 TEGRA_DRIVE_PINGROUP_CDEV2,
284 TEGRA_DRIVE_PINGROUP_CSUS,
285 TEGRA_DRIVE_PINGROUP_DAP1,
286 TEGRA_DRIVE_PINGROUP_DAP2,
287 TEGRA_DRIVE_PINGROUP_DAP3,
288 TEGRA_DRIVE_PINGROUP_DAP4,
289 TEGRA_DRIVE_PINGROUP_DBG,
290 TEGRA_DRIVE_PINGROUP_LCD1,
291 TEGRA_DRIVE_PINGROUP_LCD2,
292 TEGRA_DRIVE_PINGROUP_SDIO2,
293 TEGRA_DRIVE_PINGROUP_SDIO3,
294 TEGRA_DRIVE_PINGROUP_SPI,
295 TEGRA_DRIVE_PINGROUP_UAA,
296 TEGRA_DRIVE_PINGROUP_UAB,
297 TEGRA_DRIVE_PINGROUP_UART2,
298 TEGRA_DRIVE_PINGROUP_UART3,
299 TEGRA_DRIVE_PINGROUP_VI1,
300 TEGRA_DRIVE_PINGROUP_SDIO1,
301 TEGRA_DRIVE_PINGROUP_CRT,
302 TEGRA_DRIVE_PINGROUP_DDC,
303 TEGRA_DRIVE_PINGROUP_GMA,
304 TEGRA_DRIVE_PINGROUP_GMB,
305 TEGRA_DRIVE_PINGROUP_GMC,
306 TEGRA_DRIVE_PINGROUP_GMD,
307 TEGRA_DRIVE_PINGROUP_GME,
308 TEGRA_DRIVE_PINGROUP_GMF,
309 TEGRA_DRIVE_PINGROUP_GMG,
310 TEGRA_DRIVE_PINGROUP_GMH,
311 TEGRA_DRIVE_PINGROUP_OWR,
312 TEGRA_DRIVE_PINGROUP_UAD,
313 TEGRA_DRIVE_PINGROUP_GPV,
314 TEGRA_DRIVE_PINGROUP_DEV3,
315 TEGRA_DRIVE_PINGROUP_CEC,
316 TEGRA_MAX_DRIVE_PINGROUP,
317};
318
319#endif
320
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
index bb7dfdb6120..055f1792c8f 100644
--- a/arch/arm/mach-tegra/include/mach/pinmux.h
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -2,6 +2,7 @@
2 * linux/arch/arm/mach-tegra/include/mach/pinmux.h 2 * linux/arch/arm/mach-tegra/include/mach/pinmux.h
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2010,2011 Nvidia, Inc.
5 * 6 *
6 * This software is licensed under the terms of the GNU General Public 7 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and 8 * License version 2, as published by the Free Software Foundation, and
@@ -17,18 +18,13 @@
17#ifndef __MACH_TEGRA_PINMUX_H 18#ifndef __MACH_TEGRA_PINMUX_H
18#define __MACH_TEGRA_PINMUX_H 19#define __MACH_TEGRA_PINMUX_H
19 20
20#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
21#include "pinmux-t2.h"
22#else
23#error "Undefined Tegra architecture"
24#endif
25
26enum tegra_mux_func { 21enum tegra_mux_func {
27 TEGRA_MUX_RSVD = 0x8000, 22 TEGRA_MUX_RSVD = 0x8000,
28 TEGRA_MUX_RSVD1 = 0x8000, 23 TEGRA_MUX_RSVD1 = 0x8000,
29 TEGRA_MUX_RSVD2 = 0x8001, 24 TEGRA_MUX_RSVD2 = 0x8001,
30 TEGRA_MUX_RSVD3 = 0x8002, 25 TEGRA_MUX_RSVD3 = 0x8002,
31 TEGRA_MUX_RSVD4 = 0x8003, 26 TEGRA_MUX_RSVD4 = 0x8003,
27 TEGRA_MUX_INVALID = 0x4000,
32 TEGRA_MUX_NONE = -1, 28 TEGRA_MUX_NONE = -1,
33 TEGRA_MUX_AHB_CLK, 29 TEGRA_MUX_AHB_CLK,
34 TEGRA_MUX_APB_CLK, 30 TEGRA_MUX_APB_CLK,
@@ -90,6 +86,49 @@ enum tegra_mux_func {
90 TEGRA_MUX_VI, 86 TEGRA_MUX_VI,
91 TEGRA_MUX_VI_SENSOR_CLK, 87 TEGRA_MUX_VI_SENSOR_CLK,
92 TEGRA_MUX_XIO, 88 TEGRA_MUX_XIO,
89 TEGRA_MUX_BLINK,
90 TEGRA_MUX_CEC,
91 TEGRA_MUX_CLK12,
92 TEGRA_MUX_DAP,
93 TEGRA_MUX_DAPSDMMC2,
94 TEGRA_MUX_DDR,
95 TEGRA_MUX_DEV3,
96 TEGRA_MUX_DTV,
97 TEGRA_MUX_VI_ALT1,
98 TEGRA_MUX_VI_ALT2,
99 TEGRA_MUX_VI_ALT3,
100 TEGRA_MUX_EMC_DLL,
101 TEGRA_MUX_EXTPERIPH1,
102 TEGRA_MUX_EXTPERIPH2,
103 TEGRA_MUX_EXTPERIPH3,
104 TEGRA_MUX_GMI_ALT,
105 TEGRA_MUX_HDA,
106 TEGRA_MUX_HSI,
107 TEGRA_MUX_I2C4,
108 TEGRA_MUX_I2C5,
109 TEGRA_MUX_I2CPWR,
110 TEGRA_MUX_I2S0,
111 TEGRA_MUX_I2S1,
112 TEGRA_MUX_I2S2,
113 TEGRA_MUX_I2S3,
114 TEGRA_MUX_I2S4,
115 TEGRA_MUX_NAND_ALT,
116 TEGRA_MUX_POPSDIO4,
117 TEGRA_MUX_POPSDMMC4,
118 TEGRA_MUX_PWM0,
119 TEGRA_MUX_PWM1,
120 TEGRA_MUX_PWM2,
121 TEGRA_MUX_PWM3,
122 TEGRA_MUX_SATA,
123 TEGRA_MUX_SPI5,
124 TEGRA_MUX_SPI6,
125 TEGRA_MUX_SYSCLK,
126 TEGRA_MUX_VGP1,
127 TEGRA_MUX_VGP2,
128 TEGRA_MUX_VGP3,
129 TEGRA_MUX_VGP4,
130 TEGRA_MUX_VGP5,
131 TEGRA_MUX_VGP6,
93 TEGRA_MUX_SAFE, 132 TEGRA_MUX_SAFE,
94 TEGRA_MAX_MUX, 133 TEGRA_MAX_MUX,
95}; 134};
@@ -105,6 +144,11 @@ enum tegra_tristate {
105 TEGRA_TRI_TRISTATE = 1, 144 TEGRA_TRI_TRISTATE = 1,
106}; 145};
107 146
147enum tegra_pin_io {
148 TEGRA_PIN_OUTPUT = 0,
149 TEGRA_PIN_INPUT = 1,
150};
151
108enum tegra_vddio { 152enum tegra_vddio {
109 TEGRA_VDDIO_BB = 0, 153 TEGRA_VDDIO_BB = 0,
110 TEGRA_VDDIO_LCD, 154 TEGRA_VDDIO_LCD,
@@ -115,10 +159,16 @@ enum tegra_vddio {
115 TEGRA_VDDIO_SYS, 159 TEGRA_VDDIO_SYS,
116 TEGRA_VDDIO_AUDIO, 160 TEGRA_VDDIO_AUDIO,
117 TEGRA_VDDIO_SD, 161 TEGRA_VDDIO_SD,
162 TEGRA_VDDIO_CAM,
163 TEGRA_VDDIO_GMI,
164 TEGRA_VDDIO_PEXCTL,
165 TEGRA_VDDIO_SDMMC1,
166 TEGRA_VDDIO_SDMMC3,
167 TEGRA_VDDIO_SDMMC4,
118}; 168};
119 169
120struct tegra_pingroup_config { 170struct tegra_pingroup_config {
121 enum tegra_pingroup pingroup; 171 int pingroup;
122 enum tegra_mux_func func; 172 enum tegra_mux_func func;
123 enum tegra_pullupdown pupd; 173 enum tegra_pullupdown pupd;
124 enum tegra_tristate tristate; 174 enum tegra_tristate tristate;
@@ -187,7 +237,7 @@ enum tegra_schmitt {
187}; 237};
188 238
189struct tegra_drive_pingroup_config { 239struct tegra_drive_pingroup_config {
190 enum tegra_drive_pingroup pingroup; 240 int pingroup;
191 enum tegra_hsm hsm; 241 enum tegra_hsm hsm;
192 enum tegra_schmitt schmitt; 242 enum tegra_schmitt schmitt;
193 enum tegra_drive drive; 243 enum tegra_drive drive;
@@ -208,6 +258,7 @@ struct tegra_pingroup_desc {
208 int funcs[4]; 258 int funcs[4];
209 int func_safe; 259 int func_safe;
210 int vddio; 260 int vddio;
261 enum tegra_pin_io io_default;
211 s16 tri_bank; /* Register bank the tri_reg exists within */ 262 s16 tri_bank; /* Register bank the tri_reg exists within */
212 s16 mux_bank; /* Register bank the mux_reg exists within */ 263 s16 mux_bank; /* Register bank the mux_reg exists within */
213 s16 pupd_bank; /* Register bank the pupd_reg exists within */ 264 s16 pupd_bank; /* Register bank the pupd_reg exists within */
@@ -217,15 +268,23 @@ struct tegra_pingroup_desc {
217 s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */ 268 s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
218 s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */ 269 s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
219 s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */ 270 s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
271 s8 lock_bit; /* offset of the LOCK bit into mux register bit */
272 s8 od_bit; /* offset of the OD bit into mux register bit */
273 s8 ioreset_bit; /* offset of the IO_RESET bit into mux register bit */
220}; 274};
221 275
222extern const struct tegra_pingroup_desc tegra_soc_pingroups[]; 276typedef void (*pinmux_init) (const struct tegra_pingroup_desc **pg,
223extern const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[]; 277 int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
278 int *pgdrive_max);
224 279
225int tegra_pinmux_set_tristate(enum tegra_pingroup pg, 280void tegra20_pinmux_init(const struct tegra_pingroup_desc **pg, int *pg_max,
226 enum tegra_tristate tristate); 281 const struct tegra_drive_pingroup_desc **pgdrive, int *pgdrive_max);
227int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, 282
228 enum tegra_pullupdown pupd); 283void tegra30_pinmux_init(const struct tegra_pingroup_desc **pg, int *pg_max,
284 const struct tegra_drive_pingroup_desc **pgdrive, int *pgdrive_max);
285
286int tegra_pinmux_set_tristate(int pg, enum tegra_tristate tristate);
287int tegra_pinmux_set_pullupdown(int pg, enum tegra_pullupdown pupd);
229 288
230void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, 289void tegra_pinmux_config_table(const struct tegra_pingroup_config *config,
231 int len); 290 int len);
@@ -241,4 +300,3 @@ void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *conf
241void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config, 300void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
242 int len, enum tegra_pullupdown pupd); 301 int len, enum tegra_pullupdown pupd);
243#endif 302#endif
244
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4956c3cea73..4e1afcd54fa 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h>
24 25
25#include <asm/hardware/gic.h> 26#include <asm/hardware/gic.h>
26 27
@@ -28,10 +29,6 @@
28 29
29#include "board.h" 30#include "board.h"
30 31
31#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
32#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
33#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
34
35#define ICTLR_CPU_IEP_VFIQ 0x08 32#define ICTLR_CPU_IEP_VFIQ 0x08
36#define ICTLR_CPU_IEP_FIR 0x14 33#define ICTLR_CPU_IEP_FIR 0x14
37#define ICTLR_CPU_IEP_FIR_SET 0x18 34#define ICTLR_CPU_IEP_FIR_SET 0x18
@@ -129,6 +126,11 @@ void __init tegra_init_irq(void)
129 gic_arch_extn.irq_unmask = tegra_unmask; 126 gic_arch_extn.irq_unmask = tegra_unmask;
130 gic_arch_extn.irq_retrigger = tegra_retrigger; 127 gic_arch_extn.irq_retrigger = tegra_retrigger;
131 128
132 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 129 /*
133 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); 130 * Check if there is a devicetree present, since the GIC will be
131 * initialized elsewhere under DT.
132 */
133 if (!of_have_populated_dt())
134 gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
135 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
134} 136}
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 97ef3e55dfd..ec63c6b2b6b 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -37,7 +37,6 @@
37#include <asm/sizes.h> 37#include <asm/sizes.h>
38#include <asm/mach/pci.h> 38#include <asm/mach/pci.h>
39 39
40#include <mach/pinmux.h>
41#include <mach/iomap.h> 40#include <mach/iomap.h>
42#include <mach/clk.h> 41#include <mach/clk.h>
43#include <mach/powergate.h> 42#include <mach/powergate.h>
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-tegra20-tables.c
index a0dc2bc28ed..734add1280b 100644
--- a/arch/arm/mach-tegra/pinmux-t2-tables.c
+++ b/arch/arm/mach-tegra/pinmux-tegra20-tables.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/arch/arm/mach-tegra/pinmux-t2-tables.c 2 * linux/arch/arm/mach-tegra/pinmux-tegra20-tables.c
3 * 3 *
4 * Common pinmux configurations for Tegra 2 SoCs 4 * Common pinmux configurations for Tegra20 SoCs
5 * 5 *
6 * Copyright (C) 2010 NVIDIA Corporation 6 * Copyright (C) 2010 NVIDIA Corporation
7 * 7 *
@@ -29,6 +29,7 @@
29 29
30#include <mach/iomap.h> 30#include <mach/iomap.h>
31#include <mach/pinmux.h> 31#include <mach/pinmux.h>
32#include <mach/pinmux-tegra20.h>
32#include <mach/suspend.h> 33#include <mach/suspend.h>
33 34
34#define TRISTATE_REG_A 0x14 35#define TRISTATE_REG_A 0x14
@@ -43,7 +44,7 @@
43 .reg = ((r) - PINGROUP_REG_A) \ 44 .reg = ((r) - PINGROUP_REG_A) \
44 } 45 }
45 46
46const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = { 47static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
47 DRIVE_PINGROUP(AO1, 0x868), 48 DRIVE_PINGROUP(AO1, 0x868),
48 DRIVE_PINGROUP(AO2, 0x86c), 49 DRIVE_PINGROUP(AO2, 0x86c),
49 DRIVE_PINGROUP(AT1, 0x870), 50 DRIVE_PINGROUP(AT1, 0x870),
@@ -105,9 +106,13 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
105 .pupd_bank = 2, \ 106 .pupd_bank = 2, \
106 .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \ 107 .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \
107 .pupd_bit = pupd_b, \ 108 .pupd_bit = pupd_b, \
109 .lock_bit = -1, \
110 .od_bit = -1, \
111 .ioreset_bit = -1, \
112 .io_default = -1, \
108 } 113 }
109 114
110const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = { 115static const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
111 PINGROUP(ATA, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0), 116 PINGROUP(ATA, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0),
112 PINGROUP(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2), 117 PINGROUP(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2),
113 PINGROUP(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4), 118 PINGROUP(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4),
@@ -226,3 +231,14 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
226 PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30), 231 PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30),
227 PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28), 232 PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28),
228}; 233};
234
235void __devinit tegra20_pinmux_init(const struct tegra_pingroup_desc **pg,
236 int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
237 int *pgdrive_max)
238{
239 *pg = tegra_soc_pingroups;
240 *pg_max = TEGRA_MAX_PINGROUP;
241 *pgdrive = tegra_soc_drive_pingroups;
242 *pgdrive_max = TEGRA_MAX_DRIVE_PINGROUP;
243}
244
diff --git a/arch/arm/mach-tegra/pinmux-tegra30-tables.c b/arch/arm/mach-tegra/pinmux-tegra30-tables.c
new file mode 100644
index 00000000000..14fc0e4c1c4
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux-tegra30-tables.c
@@ -0,0 +1,376 @@
1/*
2 * linux/arch/arm/mach-tegra/pinmux-tegra30-tables.c
3 *
4 * Common pinmux configurations for Tegra30 SoCs
5 *
6 * Copyright (C) 2010,2011 NVIDIA Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/errno.h>
24#include <linux/spinlock.h>
25#include <linux/io.h>
26#include <linux/init.h>
27#include <linux/string.h>
28
29#include <mach/iomap.h>
30#include <mach/pinmux.h>
31#include <mach/pinmux-tegra30.h>
32#include <mach/suspend.h>
33
34#define PINGROUP_REG_A 0x868
35#define MUXCTL_REG_A 0x3000
36
37#define DRIVE_PINGROUP(pg_name, r) \
38 [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
39 .name = #pg_name, \
40 .reg_bank = 0, \
41 .reg = ((r) - PINGROUP_REG_A) \
42 }
43
44static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
45 DRIVE_PINGROUP(AO1, 0x868),
46 DRIVE_PINGROUP(AO2, 0x86c),
47 DRIVE_PINGROUP(AT1, 0x870),
48 DRIVE_PINGROUP(AT2, 0x874),
49 DRIVE_PINGROUP(AT3, 0x878),
50 DRIVE_PINGROUP(AT4, 0x87c),
51 DRIVE_PINGROUP(AT5, 0x880),
52 DRIVE_PINGROUP(CDEV1, 0x884),
53 DRIVE_PINGROUP(CDEV2, 0x888),
54 DRIVE_PINGROUP(CSUS, 0x88c),
55 DRIVE_PINGROUP(DAP1, 0x890),
56 DRIVE_PINGROUP(DAP2, 0x894),
57 DRIVE_PINGROUP(DAP3, 0x898),
58 DRIVE_PINGROUP(DAP4, 0x89c),
59 DRIVE_PINGROUP(DBG, 0x8a0),
60 DRIVE_PINGROUP(LCD1, 0x8a4),
61 DRIVE_PINGROUP(LCD2, 0x8a8),
62 DRIVE_PINGROUP(SDIO2, 0x8ac),
63 DRIVE_PINGROUP(SDIO3, 0x8b0),
64 DRIVE_PINGROUP(SPI, 0x8b4),
65 DRIVE_PINGROUP(UAA, 0x8b8),
66 DRIVE_PINGROUP(UAB, 0x8bc),
67 DRIVE_PINGROUP(UART2, 0x8c0),
68 DRIVE_PINGROUP(UART3, 0x8c4),
69 DRIVE_PINGROUP(VI1, 0x8c8),
70 DRIVE_PINGROUP(SDIO1, 0x8ec),
71 DRIVE_PINGROUP(CRT, 0x8f8),
72 DRIVE_PINGROUP(DDC, 0x8fc),
73 DRIVE_PINGROUP(GMA, 0x900),
74 DRIVE_PINGROUP(GMB, 0x904),
75 DRIVE_PINGROUP(GMC, 0x908),
76 DRIVE_PINGROUP(GMD, 0x90c),
77 DRIVE_PINGROUP(GME, 0x910),
78 DRIVE_PINGROUP(GMF, 0x914),
79 DRIVE_PINGROUP(GMG, 0x918),
80 DRIVE_PINGROUP(GMH, 0x91c),
81 DRIVE_PINGROUP(OWR, 0x920),
82 DRIVE_PINGROUP(UAD, 0x924),
83 DRIVE_PINGROUP(GPV, 0x928),
84 DRIVE_PINGROUP(DEV3, 0x92c),
85 DRIVE_PINGROUP(CEC, 0x938),
86};
87
88#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, fs, iod, reg) \
89 [TEGRA_PINGROUP_ ## pg_name] = { \
90 .name = #pg_name, \
91 .vddio = TEGRA_VDDIO_ ## vdd, \
92 .funcs = { \
93 TEGRA_MUX_ ## f0, \
94 TEGRA_MUX_ ## f1, \
95 TEGRA_MUX_ ## f2, \
96 TEGRA_MUX_ ## f3, \
97 }, \
98 .func_safe = TEGRA_MUX_ ## fs, \
99 .tri_bank = 1, \
100 .tri_reg = ((reg) - MUXCTL_REG_A), \
101 .tri_bit = 4, \
102 .mux_bank = 1, \
103 .mux_reg = ((reg) - MUXCTL_REG_A), \
104 .mux_bit = 0, \
105 .pupd_bank = 1, \
106 .pupd_reg = ((reg) - MUXCTL_REG_A), \
107 .pupd_bit = 2, \
108 .io_default = TEGRA_PIN_ ## iod, \
109 .od_bit = 6, \
110 .lock_bit = 7, \
111 .ioreset_bit = 8, \
112 }
113
114static const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
115 /* NAME VDD f0 f1 f2 f3 fSafe io reg */
116 PINGROUP(ULPI_DATA0, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3000),
117 PINGROUP(ULPI_DATA1, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3004),
118 PINGROUP(ULPI_DATA2, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x3008),
119 PINGROUP(ULPI_DATA3, BB, SPI3, HSI, UARTA, ULPI, RSVD, INPUT, 0x300c),
120 PINGROUP(ULPI_DATA4, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3010),
121 PINGROUP(ULPI_DATA5, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3014),
122 PINGROUP(ULPI_DATA6, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x3018),
123 PINGROUP(ULPI_DATA7, BB, SPI2, HSI, UARTA, ULPI, RSVD, INPUT, 0x301c),
124 PINGROUP(ULPI_CLK, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3020),
125 PINGROUP(ULPI_DIR, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3024),
126 PINGROUP(ULPI_NXT, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x3028),
127 PINGROUP(ULPI_STP, BB, SPI1, RSVD, UARTD, ULPI, RSVD, INPUT, 0x302c),
128 PINGROUP(DAP3_FS, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3030),
129 PINGROUP(DAP3_DIN, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3034),
130 PINGROUP(DAP3_DOUT, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x3038),
131 PINGROUP(DAP3_SCLK, BB, I2S2, RSVD1, DISPLAYA, DISPLAYB, RSVD, INPUT, 0x303c),
132 PINGROUP(GPIO_PV0, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3040),
133 PINGROUP(GPIO_PV1, BB, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3044),
134 PINGROUP(SDMMC1_CLK, SDMMC1, SDIO1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x3048),
135 PINGROUP(SDMMC1_CMD, SDMMC1, SDIO1, RSVD1, RSVD2, INVALID, RSVD, INPUT, 0x304c),
136 PINGROUP(SDMMC1_DAT3, SDMMC1, SDIO1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3050),
137 PINGROUP(SDMMC1_DAT2, SDMMC1, SDIO1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3054),
138 PINGROUP(SDMMC1_DAT1, SDMMC1, SDIO1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x3058),
139 PINGROUP(SDMMC1_DAT0, SDMMC1, SDIO1, RSVD1, UARTE, INVALID, RSVD, INPUT, 0x305c),
140 PINGROUP(GPIO_PV2, SDMMC1, OWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3060),
141 PINGROUP(GPIO_PV3, SDMMC1, INVALID, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3064),
142 PINGROUP(CLK2_OUT, SDMMC1, EXTPERIPH2, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3068),
143 PINGROUP(CLK2_REQ, SDMMC1, DAP, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x306c),
144 PINGROUP(LCD_PWR1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3070),
145 PINGROUP(LCD_PWR2, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3074),
146 PINGROUP(LCD_SDIN, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3078),
147 PINGROUP(LCD_SDOUT, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x307c),
148 PINGROUP(LCD_WR_N, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3080),
149 PINGROUP(LCD_CS0_N, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD, RSVD, OUTPUT, 0x3084),
150 PINGROUP(LCD_DC0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3088),
151 PINGROUP(LCD_SCK, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x308c),
152 PINGROUP(LCD_PWR0, LCD, DISPLAYA, DISPLAYB, SPI5, INVALID, RSVD, OUTPUT, 0x3090),
153 PINGROUP(LCD_PCLK, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3094),
154 PINGROUP(LCD_DE, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3098),
155 PINGROUP(LCD_HSYNC, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x309c),
156 PINGROUP(LCD_VSYNC, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a0),
157 PINGROUP(LCD_D0, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a4),
158 PINGROUP(LCD_D1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30a8),
159 PINGROUP(LCD_D2, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ac),
160 PINGROUP(LCD_D3, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b0),
161 PINGROUP(LCD_D4, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b4),
162 PINGROUP(LCD_D5, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30b8),
163 PINGROUP(LCD_D6, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30bc),
164 PINGROUP(LCD_D7, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c0),
165 PINGROUP(LCD_D8, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c4),
166 PINGROUP(LCD_D9, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30c8),
167 PINGROUP(LCD_D10, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30cc),
168 PINGROUP(LCD_D11, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d0),
169 PINGROUP(LCD_D12, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d4),
170 PINGROUP(LCD_D13, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30d8),
171 PINGROUP(LCD_D14, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30dc),
172 PINGROUP(LCD_D15, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e0),
173 PINGROUP(LCD_D16, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e4),
174 PINGROUP(LCD_D17, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30e8),
175 PINGROUP(LCD_D18, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30ec),
176 PINGROUP(LCD_D19, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f0),
177 PINGROUP(LCD_D20, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f4),
178 PINGROUP(LCD_D21, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30f8),
179 PINGROUP(LCD_D22, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x30fc),
180 PINGROUP(LCD_D23, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3100),
181 PINGROUP(LCD_CS1_N, LCD, DISPLAYA, DISPLAYB, SPI5, RSVD2, RSVD, OUTPUT, 0x3104),
182 PINGROUP(LCD_M1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x3108),
183 PINGROUP(LCD_DC1, LCD, DISPLAYA, DISPLAYB, RSVD1, RSVD2, RSVD, OUTPUT, 0x310c),
184 PINGROUP(HDMI_INT, LCD, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3110),
185 PINGROUP(DDC_SCL, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3114),
186 PINGROUP(DDC_SDA, LCD, I2C4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3118),
187 PINGROUP(CRT_HSYNC, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x311c),
188 PINGROUP(CRT_VSYNC, LCD, CRT, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3120),
189 PINGROUP(VI_D0, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3124),
190 PINGROUP(VI_D1, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3128),
191 PINGROUP(VI_D2, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x312c),
192 PINGROUP(VI_D3, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3130),
193 PINGROUP(VI_D4, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3134),
194 PINGROUP(VI_D5, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3138),
195 PINGROUP(VI_D6, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x313c),
196 PINGROUP(VI_D7, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3140),
197 PINGROUP(VI_D8, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3144),
198 PINGROUP(VI_D9, VI, INVALID, SDIO2, VI, RSVD1, RSVD, INPUT, 0x3148),
199 PINGROUP(VI_D10, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x314c),
200 PINGROUP(VI_D11, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3150),
201 PINGROUP(VI_PCLK, VI, RSVD1, SDIO2, VI, RSVD2, RSVD, INPUT, 0x3154),
202 PINGROUP(VI_MCLK, VI, VI, INVALID, INVALID, INVALID, RSVD, INPUT, 0x3158),
203 PINGROUP(VI_VSYNC, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x315c),
204 PINGROUP(VI_HSYNC, VI, INVALID, RSVD1, VI, RSVD2, RSVD, INPUT, 0x3160),
205 PINGROUP(UART2_RXD, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3164),
206 PINGROUP(UART2_TXD, UART, IRDA, SPDIF, UARTA, SPI4, RSVD, INPUT, 0x3168),
207 PINGROUP(UART2_RTS_N, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x316c),
208 PINGROUP(UART2_CTS_N, UART, UARTA, UARTB, GMI, SPI4, RSVD, INPUT, 0x3170),
209 PINGROUP(UART3_TXD, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3174),
210 PINGROUP(UART3_RXD, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x3178),
211 PINGROUP(UART3_CTS_N, UART, UARTC, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x317c),
212 PINGROUP(UART3_RTS_N, UART, UARTC, PWM0, GMI, RSVD2, RSVD, INPUT, 0x3180),
213 PINGROUP(GPIO_PU0, UART, OWR, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3184),
214 PINGROUP(GPIO_PU1, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x3188),
215 PINGROUP(GPIO_PU2, UART, RSVD1, UARTA, GMI, RSVD2, RSVD, INPUT, 0x318c),
216 PINGROUP(GPIO_PU3, UART, PWM0, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3190),
217 PINGROUP(GPIO_PU4, UART, PWM1, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3194),
218 PINGROUP(GPIO_PU5, UART, PWM2, UARTA, GMI, RSVD1, RSVD, INPUT, 0x3198),
219 PINGROUP(GPIO_PU6, UART, PWM3, UARTA, GMI, RSVD1, RSVD, INPUT, 0x319c),
220 PINGROUP(GEN1_I2C_SDA, UART, I2C, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a0),
221 PINGROUP(GEN1_I2C_SCL, UART, I2C, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31a4),
222 PINGROUP(DAP4_FS, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31a8),
223 PINGROUP(DAP4_DIN, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31ac),
224 PINGROUP(DAP4_DOUT, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b0),
225 PINGROUP(DAP4_SCLK, UART, I2S3, RSVD1, GMI, RSVD2, RSVD, INPUT, 0x31b4),
226 PINGROUP(CLK3_OUT, UART, EXTPERIPH3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31b8),
227 PINGROUP(CLK3_REQ, UART, DEV3, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x31bc),
228 PINGROUP(GMI_WP_N, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31c0),
229 PINGROUP(GMI_IORDY, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c4),
230 PINGROUP(GMI_WAIT, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31c8),
231 PINGROUP(GMI_ADV_N, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31cc),
232 PINGROUP(GMI_CLK, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31d0),
233 PINGROUP(GMI_CS0_N, GMI, RSVD1, NAND, GMI, INVALID, RSVD, INPUT, 0x31d4),
234 PINGROUP(GMI_CS1_N, GMI, RSVD1, NAND, GMI, DTV, RSVD, INPUT, 0x31d8),
235 PINGROUP(GMI_CS2_N, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31dc),
236 PINGROUP(GMI_CS3_N, GMI, RSVD1, NAND, GMI, GMI_ALT, RSVD, INPUT, 0x31e0),
237 PINGROUP(GMI_CS4_N, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31e4),
238 PINGROUP(GMI_CS6_N, GMI, NAND, NAND_ALT, GMI, SATA, RSVD, INPUT, 0x31e8),
239 PINGROUP(GMI_CS7_N, GMI, NAND, NAND_ALT, GMI, GMI_ALT, RSVD, INPUT, 0x31ec),
240 PINGROUP(GMI_AD0, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f0),
241 PINGROUP(GMI_AD1, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f4),
242 PINGROUP(GMI_AD2, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31f8),
243 PINGROUP(GMI_AD3, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x31fc),
244 PINGROUP(GMI_AD4, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3200),
245 PINGROUP(GMI_AD5, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3204),
246 PINGROUP(GMI_AD6, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3208),
247 PINGROUP(GMI_AD7, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x320c),
248 PINGROUP(GMI_AD8, GMI, PWM0, NAND, GMI, RSVD2, RSVD, INPUT, 0x3210),
249 PINGROUP(GMI_AD9, GMI, PWM1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3214),
250 PINGROUP(GMI_AD10, GMI, PWM2, NAND, GMI, RSVD2, RSVD, INPUT, 0x3218),
251 PINGROUP(GMI_AD11, GMI, PWM3, NAND, GMI, RSVD2, RSVD, INPUT, 0x321c),
252 PINGROUP(GMI_AD12, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3220),
253 PINGROUP(GMI_AD13, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3224),
254 PINGROUP(GMI_AD14, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x3228),
255 PINGROUP(GMI_AD15, GMI, RSVD1, NAND, GMI, RSVD2, RSVD, INPUT, 0x322c),
256 PINGROUP(GMI_A16, GMI, UARTD, SPI4, GMI, GMI_ALT, RSVD, INPUT, 0x3230),
257 PINGROUP(GMI_A17, GMI, UARTD, SPI4, GMI, INVALID, RSVD, INPUT, 0x3234),
258 PINGROUP(GMI_A18, GMI, UARTD, SPI4, GMI, INVALID, RSVD, INPUT, 0x3238),
259 PINGROUP(GMI_A19, GMI, UARTD, SPI4, GMI, RSVD3, RSVD, INPUT, 0x323c),
260 PINGROUP(GMI_WR_N, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3240),
261 PINGROUP(GMI_OE_N, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3244),
262 PINGROUP(GMI_DQS, GMI, RSVD1, NAND, GMI, RSVD3, RSVD, INPUT, 0x3248),
263 PINGROUP(GMI_RST_N, GMI, NAND, NAND_ALT, GMI, RSVD3, RSVD, INPUT, 0x324c),
264 PINGROUP(GEN2_I2C_SCL, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3250),
265 PINGROUP(GEN2_I2C_SDA, GMI, I2C2, INVALID, GMI, RSVD3, RSVD, INPUT, 0x3254),
266 PINGROUP(SDMMC4_CLK, SDMMC4, INVALID, NAND, GMI, SDIO4, RSVD, INPUT, 0x3258),
267 PINGROUP(SDMMC4_CMD, SDMMC4, I2C3, NAND, GMI, SDIO4, RSVD, INPUT, 0x325c),
268 PINGROUP(SDMMC4_DAT0, SDMMC4, UARTE, SPI3, GMI, SDIO4, RSVD, INPUT, 0x3260),
269 PINGROUP(SDMMC4_DAT1, SDMMC4, UARTE, SPI3, GMI, SDIO4, RSVD, INPUT, 0x3264),
270 PINGROUP(SDMMC4_DAT2, SDMMC4, UARTE, SPI3, GMI, SDIO4, RSVD, INPUT, 0x3268),
271 PINGROUP(SDMMC4_DAT3, SDMMC4, UARTE, SPI3, GMI, SDIO4, RSVD, INPUT, 0x326c),
272 PINGROUP(SDMMC4_DAT4, SDMMC4, I2C3, I2S4, GMI, SDIO4, RSVD, INPUT, 0x3270),
273 PINGROUP(SDMMC4_DAT5, SDMMC4, VGP3, I2S4, GMI, SDIO4, RSVD, INPUT, 0x3274),
274 PINGROUP(SDMMC4_DAT6, SDMMC4, VGP4, I2S4, GMI, SDIO4, RSVD, INPUT, 0x3278),
275 PINGROUP(SDMMC4_DAT7, SDMMC4, VGP5, I2S4, GMI, SDIO4, RSVD, INPUT, 0x327c),
276 PINGROUP(SDMMC4_RST_N, SDMMC4, VGP6, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3280),
277 PINGROUP(CAM_MCLK, CAM, VI, INVALID, VI_ALT2, POPSDMMC4, RSVD, INPUT, 0x3284),
278 PINGROUP(GPIO_PCC1, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3288),
279 PINGROUP(GPIO_PBB0, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x328c),
280 PINGROUP(CAM_I2C_SCL, CAM, INVALID, I2C3, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3290),
281 PINGROUP(CAM_I2C_SDA, CAM, INVALID, I2C3, RSVD2, POPSDMMC4, RSVD, INPUT, 0x3294),
282 PINGROUP(GPIO_PBB3, CAM, VGP3, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x3298),
283 PINGROUP(GPIO_PBB4, CAM, VGP4, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x329c),
284 PINGROUP(GPIO_PBB5, CAM, VGP5, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x32a0),
285 PINGROUP(GPIO_PBB6, CAM, VGP6, DISPLAYA, DISPLAYB, POPSDMMC4, RSVD, INPUT, 0x32a4),
286 PINGROUP(GPIO_PBB7, CAM, I2S4, RSVD1, RSVD2, POPSDMMC4, RSVD, INPUT, 0x32a8),
287 PINGROUP(GPIO_PCC2, CAM, I2S4, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32ac),
288 PINGROUP(JTAG_RTCK, SYS, RTCK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b0),
289 PINGROUP(PWR_I2C_SCL, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b4),
290 PINGROUP(PWR_I2C_SDA, SYS, I2CPWR, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x32b8),
291 PINGROUP(KB_ROW0, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32bc),
292 PINGROUP(KB_ROW1, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c0),
293 PINGROUP(KB_ROW2, SYS, KBC, INVALID, RSVD2, RSVD3, RSVD, INPUT, 0x32c4),
294 PINGROUP(KB_ROW3, SYS, KBC, INVALID, RSVD2, INVALID, RSVD, INPUT, 0x32c8),
295 PINGROUP(KB_ROW4, SYS, KBC, INVALID, TRACE, RSVD3, RSVD, INPUT, 0x32cc),
296 PINGROUP(KB_ROW5, SYS, KBC, INVALID, TRACE, OWR, RSVD, INPUT, 0x32d0),
297 PINGROUP(KB_ROW6, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32d4),
298 PINGROUP(KB_ROW7, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32d8),
299 PINGROUP(KB_ROW8, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32dc),
300 PINGROUP(KB_ROW9, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32e0),
301 PINGROUP(KB_ROW10, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32e4),
302 PINGROUP(KB_ROW11, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32e8),
303 PINGROUP(KB_ROW12, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32ec),
304 PINGROUP(KB_ROW13, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32f0),
305 PINGROUP(KB_ROW14, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32f4),
306 PINGROUP(KB_ROW15, SYS, KBC, INVALID, SDIO2, INVALID, RSVD, INPUT, 0x32f8),
307 PINGROUP(KB_COL0, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x32fc),
308 PINGROUP(KB_COL1, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3300),
309 PINGROUP(KB_COL2, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3304),
310 PINGROUP(KB_COL3, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3308),
311 PINGROUP(KB_COL4, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x330c),
312 PINGROUP(KB_COL5, SYS, KBC, INVALID, TRACE, RSVD, RSVD, INPUT, 0x3310),
313 PINGROUP(KB_COL6, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3314),
314 PINGROUP(KB_COL7, SYS, KBC, INVALID, TRACE, INVALID, RSVD, INPUT, 0x3318),
315 PINGROUP(CLK_32K_OUT, SYS, BLINK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x331c),
316 PINGROUP(SYS_CLK_REQ, SYS, SYSCLK, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x3320),
317 PINGROUP(CORE_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3324),
318 PINGROUP(CPU_PWR_REQ, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3328),
319 PINGROUP(PWR_INT_N, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x332c),
320 PINGROUP(CLK_32K_IN, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3330),
321 PINGROUP(OWR, SYS, OWR, RSVD, RSVD, RSVD, RSVD, INPUT, 0x3334),
322 PINGROUP(DAP1_FS, AUDIO, I2S0, HDA, GMI, SDIO2, RSVD, INPUT, 0x3338),
323 PINGROUP(DAP1_DIN, AUDIO, I2S0, HDA, GMI, SDIO2, RSVD, INPUT, 0x333c),
324 PINGROUP(DAP1_DOUT, AUDIO, I2S0, HDA, GMI, SDIO2, RSVD, INPUT, 0x3340),
325 PINGROUP(DAP1_SCLK, AUDIO, I2S0, HDA, GMI, SDIO2, RSVD, INPUT, 0x3344),
326 PINGROUP(CLK1_REQ, AUDIO, DAP, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x3348),
327 PINGROUP(CLK1_OUT, AUDIO, EXTPERIPH1, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x334c),
328 PINGROUP(SPDIF_IN, AUDIO, SPDIF, HDA, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3350),
329 PINGROUP(SPDIF_OUT, AUDIO, SPDIF, RSVD1, INVALID, DAPSDMMC2, RSVD, INPUT, 0x3354),
330 PINGROUP(DAP2_FS, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3358),
331 PINGROUP(DAP2_DIN, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x335c),
332 PINGROUP(DAP2_DOUT, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3360),
333 PINGROUP(DAP2_SCLK, AUDIO, I2S1, HDA, RSVD2, GMI, RSVD, INPUT, 0x3364),
334 PINGROUP(SPI2_MOSI, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3368),
335 PINGROUP(SPI2_MISO, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x336c),
336 PINGROUP(SPI2_CS0_N, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3370),
337 PINGROUP(SPI2_SCK, AUDIO, SPI6, SPI2, INVALID, GMI, RSVD, INPUT, 0x3374),
338 PINGROUP(SPI1_MOSI, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3378),
339 PINGROUP(SPI1_SCK, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x337c),
340 PINGROUP(SPI1_CS0_N, AUDIO, SPI2, SPI1, INVALID, GMI, RSVD, INPUT, 0x3380),
341 PINGROUP(SPI1_MISO, AUDIO, INVALID, SPI1, INVALID, RSVD3, RSVD, INPUT, 0x3384),
342 PINGROUP(SPI2_CS1_N, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x3388),
343 PINGROUP(SPI2_CS2_N, AUDIO, INVALID, SPI2, INVALID, INVALID, RSVD, INPUT, 0x338c),
344 PINGROUP(SDMMC3_CLK, SDMMC3, UARTA, PWM2, SDIO3, INVALID, RSVD, INPUT, 0x3390),
345 PINGROUP(SDMMC3_CMD, SDMMC3, UARTA, PWM3, SDIO3, INVALID, RSVD, INPUT, 0x3394),
346 PINGROUP(SDMMC3_DAT0, SDMMC3, RSVD, RSVD1, SDIO3, INVALID, RSVD, INPUT, 0x3398),
347 PINGROUP(SDMMC3_DAT1, SDMMC3, RSVD, RSVD1, SDIO3, INVALID, RSVD, INPUT, 0x339c),
348 PINGROUP(SDMMC3_DAT2, SDMMC3, RSVD, PWM1, SDIO3, INVALID, RSVD, INPUT, 0x33a0),
349 PINGROUP(SDMMC3_DAT3, SDMMC3, RSVD, PWM0, SDIO3, INVALID, RSVD, INPUT, 0x33a4),
350 PINGROUP(SDMMC3_DAT4, SDMMC3, PWM1, INVALID, SDIO3, INVALID, RSVD, INPUT, 0x33a8),
351 PINGROUP(SDMMC3_DAT5, SDMMC3, PWM0, INVALID, SDIO3, INVALID, RSVD, INPUT, 0x33ac),
352 PINGROUP(SDMMC3_DAT6, SDMMC3, SPDIF, INVALID, SDIO3, INVALID, RSVD, INPUT, 0x33b0),
353 PINGROUP(SDMMC3_DAT7, SDMMC3, SPDIF, INVALID, SDIO3, INVALID, RSVD, INPUT, 0x33b4),
354 PINGROUP(PEX_L0_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33b8),
355 PINGROUP(PEX_L0_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33bc),
356 PINGROUP(PEX_L0_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c0),
357 PINGROUP(PEX_WAKE_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c4),
358 PINGROUP(PEX_L1_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33c8),
359 PINGROUP(PEX_L1_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33cc),
360 PINGROUP(PEX_L1_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d0),
361 PINGROUP(PEX_L2_PRSNT_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d4),
362 PINGROUP(PEX_L2_RST_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33d8),
363 PINGROUP(PEX_L2_CLKREQ_N, PEXCTL, PCIE, HDA, RSVD2, RSVD3, RSVD, INPUT, 0x33dc),
364 PINGROUP(HDMI_CEC, SYS, CEC, RSVD1, RSVD2, RSVD3, RSVD, INPUT, 0x33e0),
365};
366
367void __devinit tegra30_pinmux_init(const struct tegra_pingroup_desc **pg,
368 int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
369 int *pgdrive_max)
370{
371 *pg = tegra_soc_pingroups;
372 *pg_max = TEGRA_MAX_PINGROUP;
373 *pgdrive = tegra_soc_drive_pingroups;
374 *pgdrive_max = TEGRA_MAX_DRIVE_PINGROUP;
375}
376
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index 1d201650d7a..ac35d2b7685 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -21,6 +21,7 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/of_device.h>
24 25
25#include <mach/iomap.h> 26#include <mach/iomap.h>
26#include <mach/pinmux.h> 27#include <mach/pinmux.h>
@@ -33,8 +34,10 @@
33#define SLWR(reg) (((reg) >> 28) & 0x3) 34#define SLWR(reg) (((reg) >> 28) & 0x3)
34#define SLWF(reg) (((reg) >> 30) & 0x3) 35#define SLWF(reg) (((reg) >> 30) & 0x3)
35 36
36static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups; 37static const struct tegra_pingroup_desc *pingroups;
37static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups; 38static const struct tegra_drive_pingroup_desc *drive_pingroups;
39static int pingroup_max;
40static int drive_max;
38 41
39static char *tegra_mux_names[TEGRA_MAX_MUX] = { 42static char *tegra_mux_names[TEGRA_MAX_MUX] = {
40 [TEGRA_MUX_AHB_CLK] = "AHB_CLK", 43 [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
@@ -97,6 +100,49 @@ static char *tegra_mux_names[TEGRA_MAX_MUX] = {
97 [TEGRA_MUX_VI] = "VI", 100 [TEGRA_MUX_VI] = "VI",
98 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK", 101 [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
99 [TEGRA_MUX_XIO] = "XIO", 102 [TEGRA_MUX_XIO] = "XIO",
103 [TEGRA_MUX_BLINK] = "BLINK",
104 [TEGRA_MUX_CEC] = "CEC",
105 [TEGRA_MUX_CLK12] = "CLK12",
106 [TEGRA_MUX_DAP] = "DAP",
107 [TEGRA_MUX_DAPSDMMC2] = "DAPSDMMC2",
108 [TEGRA_MUX_DDR] = "DDR",
109 [TEGRA_MUX_DEV3] = "DEV3",
110 [TEGRA_MUX_DTV] = "DTV",
111 [TEGRA_MUX_VI_ALT1] = "VI_ALT1",
112 [TEGRA_MUX_VI_ALT2] = "VI_ALT2",
113 [TEGRA_MUX_VI_ALT3] = "VI_ALT3",
114 [TEGRA_MUX_EMC_DLL] = "EMC_DLL",
115 [TEGRA_MUX_EXTPERIPH1] = "EXTPERIPH1",
116 [TEGRA_MUX_EXTPERIPH2] = "EXTPERIPH2",
117 [TEGRA_MUX_EXTPERIPH3] = "EXTPERIPH3",
118 [TEGRA_MUX_GMI_ALT] = "GMI_ALT",
119 [TEGRA_MUX_HDA] = "HDA",
120 [TEGRA_MUX_HSI] = "HSI",
121 [TEGRA_MUX_I2C4] = "I2C4",
122 [TEGRA_MUX_I2C5] = "I2C5",
123 [TEGRA_MUX_I2CPWR] = "I2CPWR",
124 [TEGRA_MUX_I2S0] = "I2S0",
125 [TEGRA_MUX_I2S1] = "I2S1",
126 [TEGRA_MUX_I2S2] = "I2S2",
127 [TEGRA_MUX_I2S3] = "I2S3",
128 [TEGRA_MUX_I2S4] = "I2S4",
129 [TEGRA_MUX_NAND_ALT] = "NAND_ALT",
130 [TEGRA_MUX_POPSDIO4] = "POPSDIO4",
131 [TEGRA_MUX_POPSDMMC4] = "POPSDMMC4",
132 [TEGRA_MUX_PWM0] = "PWM0",
133 [TEGRA_MUX_PWM1] = "PWM2",
134 [TEGRA_MUX_PWM2] = "PWM2",
135 [TEGRA_MUX_PWM3] = "PWM3",
136 [TEGRA_MUX_SATA] = "SATA",
137 [TEGRA_MUX_SPI5] = "SPI5",
138 [TEGRA_MUX_SPI6] = "SPI6",
139 [TEGRA_MUX_SYSCLK] = "SYSCLK",
140 [TEGRA_MUX_VGP1] = "VGP1",
141 [TEGRA_MUX_VGP2] = "VGP2",
142 [TEGRA_MUX_VGP3] = "VGP3",
143 [TEGRA_MUX_VGP4] = "VGP4",
144 [TEGRA_MUX_VGP5] = "VGP5",
145 [TEGRA_MUX_VGP6] = "VGP6",
100 [TEGRA_MUX_SAFE] = "<safe>", 146 [TEGRA_MUX_SAFE] = "<safe>",
101}; 147};
102 148
@@ -116,9 +162,9 @@ static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
116 162
117static DEFINE_SPINLOCK(mux_lock); 163static DEFINE_SPINLOCK(mux_lock);
118 164
119static const char *pingroup_name(enum tegra_pingroup pg) 165static const char *pingroup_name(int pg)
120{ 166{
121 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 167 if (pg < 0 || pg >= pingroup_max)
122 return "<UNKNOWN>"; 168 return "<UNKNOWN>";
123 169
124 return pingroups[pg].name; 170 return pingroups[pg].name;
@@ -189,10 +235,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
189 int i; 235 int i;
190 unsigned long reg; 236 unsigned long reg;
191 unsigned long flags; 237 unsigned long flags;
192 enum tegra_pingroup pg = config->pingroup; 238 int pg = config->pingroup;
193 enum tegra_mux_func func = config->func; 239 enum tegra_mux_func func = config->func;
194 240
195 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 241 if (pg < 0 || pg >= pingroup_max)
196 return -ERANGE; 242 return -ERANGE;
197 243
198 if (pingroups[pg].mux_reg < 0) 244 if (pingroups[pg].mux_reg < 0)
@@ -230,13 +276,12 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
230 return 0; 276 return 0;
231} 277}
232 278
233int tegra_pinmux_set_tristate(enum tegra_pingroup pg, 279int tegra_pinmux_set_tristate(int pg, enum tegra_tristate tristate)
234 enum tegra_tristate tristate)
235{ 280{
236 unsigned long reg; 281 unsigned long reg;
237 unsigned long flags; 282 unsigned long flags;
238 283
239 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 284 if (pg < 0 || pg >= pingroup_max)
240 return -ERANGE; 285 return -ERANGE;
241 286
242 if (pingroups[pg].tri_reg < 0) 287 if (pingroups[pg].tri_reg < 0)
@@ -255,13 +300,12 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
255 return 0; 300 return 0;
256} 301}
257 302
258int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, 303int tegra_pinmux_set_pullupdown(int pg, enum tegra_pullupdown pupd)
259 enum tegra_pullupdown pupd)
260{ 304{
261 unsigned long reg; 305 unsigned long reg;
262 unsigned long flags; 306 unsigned long flags;
263 307
264 if (pg < 0 || pg >= TEGRA_MAX_PINGROUP) 308 if (pg < 0 || pg >= pingroup_max)
265 return -ERANGE; 309 return -ERANGE;
266 310
267 if (pingroups[pg].pupd_reg < 0) 311 if (pingroups[pg].pupd_reg < 0)
@@ -287,7 +331,7 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
287 331
288static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config) 332static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
289{ 333{
290 enum tegra_pingroup pingroup = config->pingroup; 334 int pingroup = config->pingroup;
291 enum tegra_mux_func func = config->func; 335 enum tegra_mux_func func = config->func;
292 enum tegra_pullupdown pupd = config->pupd; 336 enum tegra_pullupdown pupd = config->pupd;
293 enum tegra_tristate tristate = config->tristate; 337 enum tegra_tristate tristate = config->tristate;
@@ -323,9 +367,9 @@ void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int l
323 tegra_pinmux_config_pingroup(&config[i]); 367 tegra_pinmux_config_pingroup(&config[i]);
324} 368}
325 369
326static const char *drive_pinmux_name(enum tegra_drive_pingroup pg) 370static const char *drive_pinmux_name(int pg)
327{ 371{
328 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 372 if (pg < 0 || pg >= drive_max)
329 return "<UNKNOWN>"; 373 return "<UNKNOWN>";
330 374
331 return drive_pingroups[pg].name; 375 return drive_pingroups[pg].name;
@@ -352,12 +396,11 @@ static const char *slew_name(unsigned long val)
352 return tegra_slew_names[val]; 396 return tegra_slew_names[val];
353} 397}
354 398
355static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg, 399static int tegra_drive_pinmux_set_hsm(int pg, enum tegra_hsm hsm)
356 enum tegra_hsm hsm)
357{ 400{
358 unsigned long flags; 401 unsigned long flags;
359 u32 reg; 402 u32 reg;
360 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 403 if (pg < 0 || pg >= drive_max)
361 return -ERANGE; 404 return -ERANGE;
362 405
363 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE) 406 if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
@@ -377,12 +420,11 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
377 return 0; 420 return 0;
378} 421}
379 422
380static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg, 423static int tegra_drive_pinmux_set_schmitt(int pg, enum tegra_schmitt schmitt)
381 enum tegra_schmitt schmitt)
382{ 424{
383 unsigned long flags; 425 unsigned long flags;
384 u32 reg; 426 u32 reg;
385 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 427 if (pg < 0 || pg >= drive_max)
386 return -ERANGE; 428 return -ERANGE;
387 429
388 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE) 430 if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
@@ -402,12 +444,11 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
402 return 0; 444 return 0;
403} 445}
404 446
405static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg, 447static int tegra_drive_pinmux_set_drive(int pg, enum tegra_drive drive)
406 enum tegra_drive drive)
407{ 448{
408 unsigned long flags; 449 unsigned long flags;
409 u32 reg; 450 u32 reg;
410 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 451 if (pg < 0 || pg >= drive_max)
411 return -ERANGE; 452 return -ERANGE;
412 453
413 if (drive < 0 || drive >= TEGRA_MAX_DRIVE) 454 if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
@@ -425,12 +466,12 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
425 return 0; 466 return 0;
426} 467}
427 468
428static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg, 469static int tegra_drive_pinmux_set_pull_down(int pg,
429 enum tegra_pull_strength pull_down) 470 enum tegra_pull_strength pull_down)
430{ 471{
431 unsigned long flags; 472 unsigned long flags;
432 u32 reg; 473 u32 reg;
433 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 474 if (pg < 0 || pg >= drive_max)
434 return -ERANGE; 475 return -ERANGE;
435 476
436 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL) 477 if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
@@ -448,12 +489,12 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
448 return 0; 489 return 0;
449} 490}
450 491
451static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg, 492static int tegra_drive_pinmux_set_pull_up(int pg,
452 enum tegra_pull_strength pull_up) 493 enum tegra_pull_strength pull_up)
453{ 494{
454 unsigned long flags; 495 unsigned long flags;
455 u32 reg; 496 u32 reg;
456 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 497 if (pg < 0 || pg >= drive_max)
457 return -ERANGE; 498 return -ERANGE;
458 499
459 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL) 500 if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
@@ -471,12 +512,12 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
471 return 0; 512 return 0;
472} 513}
473 514
474static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg, 515static int tegra_drive_pinmux_set_slew_rising(int pg,
475 enum tegra_slew slew_rising) 516 enum tegra_slew slew_rising)
476{ 517{
477 unsigned long flags; 518 unsigned long flags;
478 u32 reg; 519 u32 reg;
479 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 520 if (pg < 0 || pg >= drive_max)
480 return -ERANGE; 521 return -ERANGE;
481 522
482 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW) 523 if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
@@ -494,12 +535,12 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
494 return 0; 535 return 0;
495} 536}
496 537
497static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg, 538static int tegra_drive_pinmux_set_slew_falling(int pg,
498 enum tegra_slew slew_falling) 539 enum tegra_slew slew_falling)
499{ 540{
500 unsigned long flags; 541 unsigned long flags;
501 u32 reg; 542 u32 reg;
502 if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP) 543 if (pg < 0 || pg >= drive_max)
503 return -ERANGE; 544 return -ERANGE;
504 545
505 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW) 546 if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
@@ -517,7 +558,7 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
517 return 0; 558 return 0;
518} 559}
519 560
520static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup, 561static void tegra_drive_pinmux_config_pingroup(int pingroup,
521 enum tegra_hsm hsm, 562 enum tegra_hsm hsm,
522 enum tegra_schmitt schmitt, 563 enum tegra_schmitt schmitt,
523 enum tegra_drive drive, 564 enum tegra_drive drive,
@@ -596,7 +637,7 @@ void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *conf
596 for (i = 0; i < len; i++) { 637 for (i = 0; i < len; i++) {
597 int err; 638 int err;
598 c = config[i]; 639 c = config[i];
599 if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) { 640 if (c.pingroup < 0 || c.pingroup >= pingroup_max) {
600 WARN_ON(1); 641 WARN_ON(1);
601 continue; 642 continue;
602 } 643 }
@@ -617,7 +658,7 @@ void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config
617 for (i = 0; i < len; i++) { 658 for (i = 0; i < len; i++) {
618 int err; 659 int err;
619 if (config[i].pingroup < 0 || 660 if (config[i].pingroup < 0 ||
620 config[i].pingroup >= TEGRA_MAX_PINGROUP) { 661 config[i].pingroup >= pingroup_max) {
621 WARN_ON(1); 662 WARN_ON(1);
622 continue; 663 continue;
623 } 664 }
@@ -635,7 +676,7 @@ void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *conf
635{ 676{
636 int i; 677 int i;
637 int err; 678 int err;
638 enum tegra_pingroup pingroup; 679 int pingroup;
639 680
640 for (i = 0; i < len; i++) { 681 for (i = 0; i < len; i++) {
641 pingroup = config[i].pingroup; 682 pingroup = config[i].pingroup;
@@ -654,7 +695,7 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
654{ 695{
655 int i; 696 int i;
656 int err; 697 int err;
657 enum tegra_pingroup pingroup; 698 int pingroup;
658 699
659 for (i = 0; i < len; i++) { 700 for (i = 0; i < len; i++) {
660 pingroup = config[i].pingroup; 701 pingroup = config[i].pingroup;
@@ -668,11 +709,36 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
668 } 709 }
669} 710}
670 711
712static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
713#ifdef CONFIG_ARCH_TEGRA_2x_SOC
714 { .compatible = "nvidia,tegra20-pinmux", tegra20_pinmux_init },
715#endif
716#ifdef CONFIG_ARCH_TEGRA_3x_SOC
717 { .compatible = "nvidia,tegra30-pinmux", tegra30_pinmux_init },
718#endif
719 { },
720};
721
671static int __devinit tegra_pinmux_probe(struct platform_device *pdev) 722static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
672{ 723{
673 struct resource *res; 724 struct resource *res;
674 int i; 725 int i;
675 int config_bad = 0; 726 int config_bad = 0;
727 const struct of_device_id *match;
728
729 match = of_match_device(tegra_pinmux_of_match, &pdev->dev);
730
731 if (match)
732 ((pinmux_init)(match->data))(&pingroups, &pingroup_max,
733 &drive_pingroups, &drive_max);
734#ifdef CONFIG_ARCH_TEGRA_2x_SOC
735 else
736 /* no device tree available, so we must be on tegra20 */
737 tegra20_pinmux_init(&pingroups, &pingroup_max,
738 &drive_pingroups, &drive_max);
739#else
740 pr_warn("non Tegra20 platform requires pinmux devicetree node\n");
741#endif
676 742
677 for (i = 0; ; i++) { 743 for (i = 0; ; i++) {
678 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 744 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
@@ -681,7 +747,7 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
681 } 747 }
682 nbanks = i; 748 nbanks = i;
683 749
684 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 750 for (i = 0; i < pingroup_max; i++) {
685 if (pingroups[i].tri_bank >= nbanks) { 751 if (pingroups[i].tri_bank >= nbanks) {
686 dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i); 752 dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
687 config_bad = 1; 753 config_bad = 1;
@@ -698,7 +764,7 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
698 } 764 }
699 } 765 }
700 766
701 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { 767 for (i = 0; i < drive_max; i++) {
702 if (drive_pingroups[i].reg_bank >= nbanks) { 768 if (drive_pingroups[i].reg_bank >= nbanks) {
703 dev_err(&pdev->dev, 769 dev_err(&pdev->dev,
704 "drive pingroup %d: bad reg_bank\n", i); 770 "drive pingroup %d: bad reg_bank\n", i);
@@ -741,11 +807,6 @@ static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
741 return 0; 807 return 0;
742} 808}
743 809
744static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
745 { .compatible = "nvidia,tegra20-pinmux", },
746 { },
747};
748
749static struct platform_driver tegra_pinmux_driver = { 810static struct platform_driver tegra_pinmux_driver = {
750 .driver = { 811 .driver = {
751 .name = "tegra-pinmux", 812 .name = "tegra-pinmux",
@@ -779,7 +840,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
779 int i; 840 int i;
780 int len; 841 int len;
781 842
782 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 843 for (i = 0; i < pingroup_max; i++) {
783 unsigned long reg; 844 unsigned long reg;
784 unsigned long tri; 845 unsigned long tri;
785 unsigned long mux; 846 unsigned long mux;
@@ -850,7 +911,7 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
850 int i; 911 int i;
851 int len; 912 int len;
852 913
853 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) { 914 for (i = 0; i < drive_max; i++) {
854 u32 reg; 915 u32 reg;
855 916
856 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s", 917 seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 371869d8ea0..ff9e6b6c046 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -174,7 +174,7 @@ static int tegra_periph_clk_enable_refcount[3 * 32];
174#define pmc_readl(reg) \ 174#define pmc_readl(reg) \
175 __raw_readl(reg_pmc_base + (reg)) 175 __raw_readl(reg_pmc_base + (reg))
176 176
177unsigned long clk_measure_input_freq(void) 177static unsigned long clk_measure_input_freq(void)
178{ 178{
179 u32 clock_autodetect; 179 u32 clock_autodetect;
180 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET); 180 clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
@@ -278,18 +278,6 @@ static struct clk_ops tegra_clk_m_ops = {
278 .disable = tegra2_clk_m_disable, 278 .disable = tegra2_clk_m_disable,
279}; 279};
280 280
281void tegra2_periph_reset_assert(struct clk *c)
282{
283 BUG_ON(!c->ops->reset);
284 c->ops->reset(c, true);
285}
286
287void tegra2_periph_reset_deassert(struct clk *c)
288{
289 BUG_ON(!c->ops->reset);
290 c->ops->reset(c, false);
291}
292
293/* super clock functions */ 281/* super clock functions */
294/* "super clocks" on tegra have two-stage muxes and a clock skipping 282/* "super clocks" on tegra have two-stage muxes and a clock skipping
295 * super divider. We will ignore the clock skipping divider, since we 283 * super divider. We will ignore the clock skipping divider, since we
@@ -1132,6 +1120,9 @@ static struct clk_ops tegra_periph_clk_ops = {
1132void tegra2_sdmmc_tap_delay(struct clk *c, int delay) 1120void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1133{ 1121{
1134 u32 reg; 1122 u32 reg;
1123 unsigned long flags;
1124
1125 spin_lock_irqsave(&c->spinlock, flags);
1135 1126
1136 delay = clamp(delay, 0, 15); 1127 delay = clamp(delay, 0, 15);
1137 reg = clk_readl(c->reg); 1128 reg = clk_readl(c->reg);
@@ -1139,6 +1130,8 @@ void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1139 reg |= SDMMC_CLK_INT_FB_SEL; 1130 reg |= SDMMC_CLK_INT_FB_SEL;
1140 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT; 1131 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1141 clk_writel(reg, c->reg); 1132 clk_writel(reg, c->reg);
1133
1134 spin_unlock_irqrestore(&c->spinlock, flags);
1142} 1135}
1143 1136
1144/* External memory controller clock ops */ 1137/* External memory controller clock ops */
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 732c724008b..1d1acda4f3e 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -165,20 +165,28 @@ static struct irqaction tegra_timer_irq = {
165static void __init tegra_init_timer(void) 165static void __init tegra_init_timer(void)
166{ 166{
167 struct clk *clk; 167 struct clk *clk;
168 unsigned long rate = clk_measure_input_freq(); 168 unsigned long rate;
169 int ret; 169 int ret;
170 170
171 clk = clk_get_sys("timer", NULL); 171 clk = clk_get_sys("timer", NULL);
172 BUG_ON(IS_ERR(clk)); 172 if (IS_ERR(clk)) {
173 clk_enable(clk); 173 pr_warn("Unable to get timer clock."
174 " Assuming 12Mhz input clock.\n");
175 rate = 12000000;
176 } else {
177 clk_enable(clk);
178 rate = clk_get_rate(clk);
179 }
174 180
175 /* 181 /*
176 * rtc registers are used by read_persistent_clock, keep the rtc clock 182 * rtc registers are used by read_persistent_clock, keep the rtc clock
177 * enabled 183 * enabled
178 */ 184 */
179 clk = clk_get_sys("rtc-tegra", NULL); 185 clk = clk_get_sys("rtc-tegra", NULL);
180 BUG_ON(IS_ERR(clk)); 186 if (IS_ERR(clk))
181 clk_enable(clk); 187 pr_warn("Unable to get rtc-tegra clock\n");
188 else
189 clk_enable(clk);
182 190
183#ifdef CONFIG_HAVE_ARM_TWD 191#ifdef CONFIG_HAVE_ARM_TWD
184 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600); 192 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
index 1cbcd4fc1e1..54d8f34fdee 100644
--- a/arch/arm/mach-u300/Kconfig
+++ b/arch/arm/mach-u300/Kconfig
@@ -7,8 +7,8 @@ comment "ST-Ericsson Mobile Platform Products"
7config MACH_U300 7config MACH_U300
8 bool "U300" 8 bool "U300"
9 select PINCTRL 9 select PINCTRL
10 select PINMUX_U300 10 select PINCTRL_U300
11 select GPIO_U300 11 select PINCTRL_COH901
12 12
13comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" 13comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
14 14
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index 697930761b3..b4c6926a700 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -1605,15 +1605,15 @@ static struct platform_device pinmux_device = {
1605}; 1605};
1606 1606
1607/* Pinmux settings */ 1607/* Pinmux settings */
1608static struct pinmux_map u300_pinmux_map[] = { 1608static struct pinmux_map __initdata u300_pinmux_map[] = {
1609 /* anonymous maps for chip power and EMIFs */ 1609 /* anonymous maps for chip power and EMIFs */
1610 PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"), 1610 PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
1611 PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"), 1611 PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
1612 PINMUX_MAP_PRIMARY_SYS_HOG("EMIF1", "emif1"), 1612 PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
1613 /* per-device maps for MMC/SD, SPI and UART */ 1613 /* per-device maps for MMC/SD, SPI and UART */
1614 PINMUX_MAP_PRIMARY("MMCSD", "mmc0", "mmci"), 1614 PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
1615 PINMUX_MAP_PRIMARY("SPI", "spi0", "pl022"), 1615 PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
1616 PINMUX_MAP_PRIMARY("UART0", "uart0", "uart0"), 1616 PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
1617}; 1617};
1618 1618
1619struct u300_mux_hog { 1619struct u300_mux_hog {
diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h
index 0c2b2021951..bf4c7935aec 100644
--- a/arch/arm/mach-u300/include/mach/gpio-u300.h
+++ b/arch/arm/mach-u300/include/mach/gpio-u300.h
@@ -9,121 +9,6 @@
9#ifndef __MACH_U300_GPIO_U300_H 9#ifndef __MACH_U300_GPIO_U300_H
10#define __MACH_U300_GPIO_U300_H 10#define __MACH_U300_GPIO_U300_H
11 11
12/*
13 * Individual pin assignments for the B26/S26. Notice that the
14 * actual usage of these pins depends on the PAD MUX settings, that
15 * is why the same number can potentially appear several times.
16 * In the reference design each pin is only used for one purpose.
17 * These were determined by inspecting the B26/S26 schematic:
18 * 2/1911-ROA 128 1603
19 */
20#ifdef CONFIG_MACH_U300_BS2X
21#define U300_GPIO_PIN_UART_RX 0
22#define U300_GPIO_PIN_UART_TX 1
23#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
24#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
25#define U300_GPIO_PIN_CAM_SLEEP 4
26#define U300_GPIO_PIN_CAM_REG_EN 5
27#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
28#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
29
30#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
31#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
32#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
33#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
34#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
35#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
36#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
37#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
38
39#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
40#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
41#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
42#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
43#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
44#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
45#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
46#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
47#endif
48
49/*
50 * Individual pin assignments for the B330/S330 and B365/S365.
51 * Notice that the actual usage of these pins depends on the
52 * PAD MUX settings, that is why the same number can potentially
53 * appear several times. In the reference design each pin is only
54 * used for one purpose. These were determined by inspecting the
55 * S365 schematic.
56 */
57#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
58 defined(CONFIG_MACH_U300_BS335)
59#define U300_GPIO_PIN_UART_RX 0
60#define U300_GPIO_PIN_UART_TX 1
61#define U300_GPIO_PIN_UART_CTS 2
62#define U300_GPIO_PIN_UART_RTS 3
63#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
64#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
65#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
66#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
67
68#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
69#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
70#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
71#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
72#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
73#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
74#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
75#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
76
77#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
78#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
79#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
80#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
81#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
82#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
83#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
84#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
85
86#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
87#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
88#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
89#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
90#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
91#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
92#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
93#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
94
95#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
96#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
97#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
98#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
99#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
100#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
101#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
102#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
103
104#ifdef CONFIG_MACH_U300_BS335
105
106#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
107#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
108#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
109#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
110#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
111#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
112#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
113#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
114
115#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
116#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
117#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
118#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
119#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
120#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
121#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
122#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
123#endif
124
125#endif
126
127/** 12/**
128 * enum u300_gpio_variant - the type of U300 GPIO employed 13 * enum u300_gpio_variant - the type of U300 GPIO employed
129 */ 14 */
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h
index db3fbfa1d6e..ee78a26707e 100644
--- a/arch/arm/mach-u300/include/mach/irqs.h
+++ b/arch/arm/mach-u300/include/mach/irqs.h
@@ -110,7 +110,7 @@
110#endif 110#endif
111 111
112/* Maximum 8*7 GPIO lines */ 112/* Maximum 8*7 GPIO lines */
113#ifdef CONFIG_GPIO_U300 113#ifdef CONFIG_PINCTRL_COH901
114#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END) 114#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END)
115#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56) 115#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56)
116#else 116#else
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
deleted file mode 100644
index c808f347a08..00000000000
--- a/arch/arm/mach-u300/include/mach/memory.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 *
3 * arch/arm/mach-u300/include/mach/memory.h
4 *
5 *
6 * Copyright (C) 2007-2009 ST-Ericsson AB
7 * License terms: GNU General Public License (GPL) version 2
8 * Memory virtual/physical mapping constants.
9 * Author: Linus Walleij <linus.walleij@stericsson.com>
10 * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
11 */
12
13#ifndef __MACH_MEMORY_H
14#define __MACH_MEMORY_H
15
16#define PLAT_PHYS_OFFSET UL(0x48000000)
17#define BOOT_PARAMS_OFFSET 0x100
18
19#endif
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 4d482aacc27..05abd6ad9fa 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -18,8 +18,8 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <mach/coh901318.h> 19#include <mach/coh901318.h>
20#include <mach/dma_channels.h> 20#include <mach/dma_channels.h>
21#include <mach/gpio-u300.h>
22 21
22#include "u300-gpio.h"
23#include "mmc.h" 23#include "mmc.h"
24 24
25static struct mmci_platform_data mmc0_plat_data = { 25static struct mmci_platform_data mmc0_plat_data = {
diff --git a/arch/arm/mach-u300/u300-gpio.h b/arch/arm/mach-u300/u300-gpio.h
new file mode 100644
index 00000000000..847dc25300c
--- /dev/null
+++ b/arch/arm/mach-u300/u300-gpio.h
@@ -0,0 +1,114 @@
1/*
2 * Individual pin assignments for the B26/S26. Notice that the
3 * actual usage of these pins depends on the PAD MUX settings, that
4 * is why the same number can potentially appear several times.
5 * In the reference design each pin is only used for one purpose.
6 * These were determined by inspecting the B26/S26 schematic:
7 * 2/1911-ROA 128 1603
8 */
9#ifdef CONFIG_MACH_U300_BS2X
10#define U300_GPIO_PIN_UART_RX 0
11#define U300_GPIO_PIN_UART_TX 1
12#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
13#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
14#define U300_GPIO_PIN_CAM_SLEEP 4
15#define U300_GPIO_PIN_CAM_REG_EN 5
16#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
17#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
18
19#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
20#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
21#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
22#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
23#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
24#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
25#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
26#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
27
28#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
29#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
30#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
31#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
32#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
33#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
34#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
35#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
36#endif
37
38/*
39 * Individual pin assignments for the B330/S330 and B365/S365.
40 * Notice that the actual usage of these pins depends on the
41 * PAD MUX settings, that is why the same number can potentially
42 * appear several times. In the reference design each pin is only
43 * used for one purpose. These were determined by inspecting the
44 * S365 schematic.
45 */
46#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
47 defined(CONFIG_MACH_U300_BS335)
48#define U300_GPIO_PIN_UART_RX 0
49#define U300_GPIO_PIN_UART_TX 1
50#define U300_GPIO_PIN_UART_CTS 2
51#define U300_GPIO_PIN_UART_RTS 3
52#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
53#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
54#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
55#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
56
57#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
58#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
59#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
60#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
61#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
62#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
63#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
64#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
65
66#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
67#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
68#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
69#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
70#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
71#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
72#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
73#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
74
75#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
76#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
77#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
78#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
79#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
80#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
81#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
82#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
83
84#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
85#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
86#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
87#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
88#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
89#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
90#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
91#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
92
93#ifdef CONFIG_MACH_U300_BS335
94
95#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
96#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
97#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
98#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
99#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
100#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
101#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
102#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
103
104#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
105#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
106#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
107#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
108#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
109#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
110#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
111#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
112#endif
113
114#endif
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index def45bda293..f30c69d91d9 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -47,7 +47,7 @@ static void __init u300_init_machine(void)
47 47
48MACHINE_START(U300, MACH_U300_STRING) 48MACHINE_START(U300, MACH_U300_STRING)
49 /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ 49 /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
50 .atag_offset = BOOT_PARAMS_OFFSET, 50 .atag_offset = 0x100,
51 .map_io = u300_map_io, 51 .map_io = u300_map_io,
52 .init_irq = u300_init_irq, 52 .init_irq = u300_init_irq,
53 .handle_irq = vic_handle_irq, 53 .handle_irq = vic_handle_irq,
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 6826faeecc6..23be34b3bb6 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -22,6 +22,12 @@
22#include "ste-dma40-db8500.h" 22#include "ste-dma40-db8500.h"
23 23
24/* 24/*
25 * v2 has a new version of this block that need to be forced, the number found
26 * in hardware is incorrect
27 */
28#define U8500_SDI_V2_PERIPHID 0x10480180
29
30/*
25 * SDI 0 (MicroSD slot) 31 * SDI 0 (MicroSD slot)
26 */ 32 */
27 33
@@ -117,10 +123,7 @@ static void sdi0_configure(void)
117 gpio_direction_output(sdi0_en, 1); 123 gpio_direction_output(sdi0_en, 1);
118 124
119 /* Add the device, force v2 to subrevision 1 */ 125 /* Add the device, force v2 to subrevision 1 */
120 if (cpu_is_u8500v2()) 126 db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
121 db8500_add_sdi0(&mop500_sdi0_data, 0x10480180);
122 else
123 db8500_add_sdi0(&mop500_sdi0_data, 0);
124} 127}
125 128
126void mop500_sdi_tc35892_init(void) 129void mop500_sdi_tc35892_init(void)
@@ -132,6 +135,42 @@ void mop500_sdi_tc35892_init(void)
132} 135}
133 136
134/* 137/*
138 * SDI1 (SDIO WLAN)
139 */
140#ifdef CONFIG_STE_DMA40
141static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
142 .mode = STEDMA40_MODE_LOGICAL,
143 .dir = STEDMA40_PERIPH_TO_MEM,
144 .src_dev_type = DB8500_DMA_DEV32_SD_MM1_RX,
145 .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
146 .src_info.data_width = STEDMA40_WORD_WIDTH,
147 .dst_info.data_width = STEDMA40_WORD_WIDTH,
148};
149
150static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
151 .mode = STEDMA40_MODE_LOGICAL,
152 .dir = STEDMA40_MEM_TO_PERIPH,
153 .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
154 .dst_dev_type = DB8500_DMA_DEV32_SD_MM1_TX,
155 .src_info.data_width = STEDMA40_WORD_WIDTH,
156 .dst_info.data_width = STEDMA40_WORD_WIDTH,
157};
158#endif
159
160static struct mmci_platform_data mop500_sdi1_data = {
161 .ocr_mask = MMC_VDD_29_30,
162 .f_max = 50000000,
163 .capabilities = MMC_CAP_4_BIT_DATA,
164 .gpio_cd = -1,
165 .gpio_wp = -1,
166#ifdef CONFIG_STE_DMA40
167 .dma_filter = stedma40_filter,
168 .dma_rx_param = &sdi1_dma_cfg_rx,
169 .dma_tx_param = &sdi1_dma_cfg_tx,
170#endif
171};
172
173/*
135 * SDI 2 (POP eMMC, not on DB8500ed) 174 * SDI 2 (POP eMMC, not on DB8500ed)
136 */ 175 */
137 176
@@ -158,7 +197,8 @@ static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
158static struct mmci_platform_data mop500_sdi2_data = { 197static struct mmci_platform_data mop500_sdi2_data = {
159 .ocr_mask = MMC_VDD_165_195, 198 .ocr_mask = MMC_VDD_165_195,
160 .f_max = 50000000, 199 .f_max = 50000000,
161 .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, 200 .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
201 MMC_CAP_MMC_HIGHSPEED,
162 .gpio_cd = -1, 202 .gpio_cd = -1,
163 .gpio_wp = -1, 203 .gpio_wp = -1,
164#ifdef CONFIG_STE_DMA40 204#ifdef CONFIG_STE_DMA40
@@ -208,20 +248,10 @@ static struct mmci_platform_data mop500_sdi4_data = {
208 248
209void __init mop500_sdi_init(void) 249void __init mop500_sdi_init(void)
210{ 250{
211 u32 periphid = 0; 251 /* PoP:ed eMMC */
212 252 db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
213 /* v2 has a new version of this block that need to be forced */
214 if (cpu_is_u8500v2())
215 periphid = 0x10480180;
216 /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */
217 if (!cpu_is_u8500v10())
218 mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
219
220 db8500_add_sdi2(&mop500_sdi2_data, periphid);
221
222 /* On-board eMMC */ 253 /* On-board eMMC */
223 db8500_add_sdi4(&mop500_sdi4_data, periphid); 254 db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
224
225 /* 255 /*
226 * On boards with the TC35892 GPIO expander, sdi0 will finally 256 * On boards with the TC35892 GPIO expander, sdi0 will finally
227 * be added when the TC35892 initializes and calls 257 * be added when the TC35892 initializes and calls
@@ -231,13 +261,9 @@ void __init mop500_sdi_init(void)
231 261
232void __init snowball_sdi_init(void) 262void __init snowball_sdi_init(void)
233{ 263{
234 u32 periphid = 0x10480180;
235
236 mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
237
238 /* On-board eMMC */ 264 /* On-board eMMC */
239 db8500_add_sdi4(&mop500_sdi4_data, periphid); 265 db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
240 266 /* External Micro SD slot */
241 mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; 267 mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
242 mop500_sdi0_data.cd_invert = true; 268 mop500_sdi0_data.cd_invert = true;
243 sdi0_en = SNOWBALL_SDMMC_EN_GPIO; 269 sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
@@ -247,17 +273,15 @@ void __init snowball_sdi_init(void)
247 273
248void __init hrefv60_sdi_init(void) 274void __init hrefv60_sdi_init(void)
249{ 275{
250 u32 periphid = 0x10480180; 276 /* PoP:ed eMMC */
251 277 db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
252 mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
253
254 db8500_add_sdi2(&mop500_sdi2_data, periphid);
255
256 /* On-board eMMC */ 278 /* On-board eMMC */
257 db8500_add_sdi4(&mop500_sdi4_data, periphid); 279 db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
258 280 /* External Micro SD slot */
259 mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; 281 mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
260 sdi0_en = HREFV60_SDMMC_EN_GPIO; 282 sdi0_en = HREFV60_SDMMC_EN_GPIO;
261 sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; 283 sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
262 sdi0_configure(); 284 sdi0_configure();
285 /* WLAN SDIO channel */
286 db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
263} 287}
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index de1f5f8f733..9361a529017 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -673,7 +673,7 @@ static void __init hrefv60_init_machine(void)
673 ARRAY_SIZE(mop500_platform_devs)); 673 ARRAY_SIZE(mop500_platform_devs));
674 674
675 mop500_i2c_init(); 675 mop500_i2c_init();
676 mop500_sdi_init(); 676 hrefv60_sdi_init();
677 mop500_spi_init(); 677 mop500_spi_init();
678 mop500_uart_init(); 678 mop500_uart_init();
679 679
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index de18a2a23e6..f926d3db620 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -7,40 +7,77 @@
7#ifndef __BOARD_MOP500_H 7#ifndef __BOARD_MOP500_H
8#define __BOARD_MOP500_H 8#define __BOARD_MOP500_H
9 9
10/* snowball GPIO for MMC card */ 10/* Snowball specific GPIO assignments, this board has no GPIO expander */
11#define SNOWBALL_SDMMC_EN_GPIO 217 11#define SNOWBALL_ACCEL_INT1_GPIO 163
12#define SNOWBALL_SDMMC_1V8_3V_GPIO 228 12#define SNOWBALL_ACCEL_INT2_GPIO 164
13#define SNOWBALL_SDMMC_CD_GPIO 218 13#define SNOWBALL_MAGNET_DRDY_GPIO 165
14#define SNOWBALL_SDMMC_EN_GPIO 217
15#define SNOWBALL_SDMMC_1V8_3V_GPIO 228
16#define SNOWBALL_SDMMC_CD_GPIO 218
14 17
15/* HREFv60-specific GPIO assignments, this board has no GPIO expander */ 18/* HREFv60-specific GPIO assignments, this board has no GPIO expander */
16#define HREFV60_TOUCH_RST_GPIO 143
17#define HREFV60_PROX_SENSE_GPIO 217
18#define HREFV60_HAL_SW_GPIO 145
19#define HREFV60_SDMMC_EN_GPIO 169
20#define HREFV60_SDMMC_1V8_3V_GPIO 5 19#define HREFV60_SDMMC_1V8_3V_GPIO 5
21#define HREFV60_SDMMC_CD_GPIO 95 20#define HREFV60_CAMERA_FLASH_ENABLE 21
22#define HREFV60_ACCEL_INT1_GPIO 82
23#define HREFV60_ACCEL_INT2_GPIO 83
24#define HREFV60_MAGNET_DRDY_GPIO 32 21#define HREFV60_MAGNET_DRDY_GPIO 32
25#define HREFV60_DISP1_RST_GPIO 65 22#define HREFV60_DISP1_RST_GPIO 65
26#define HREFV60_DISP2_RST_GPIO 66 23#define HREFV60_DISP2_RST_GPIO 66
24#define HREFV60_ACCEL_INT1_GPIO 82
25#define HREFV60_ACCEL_INT2_GPIO 83
26#define HREFV60_SDMMC_CD_GPIO 95
27#define HREFV60_XSHUTDOWN_SECONDARY_SENSOR 140
28#define HREFV60_TOUCH_RST_GPIO 143
29#define HREFV60_HAL_SW_GPIO 145
30#define HREFV60_SDMMC_EN_GPIO 169
31#define HREFV60_MMIO_XENON_CHARGE 170
32#define HREFV60_PROX_SENSE_GPIO 217
33
34/* MOP500 generic GPIOs */
35#define CAMERA_FLASH_INT_PIN 7
36#define CYPRESS_TOUCH_INT_PIN 84
37#define XSHUTDOWN_PRIMARY_SENSOR 141
38#define XSHUTDOWN_SECONDARY_SENSOR 142
39#define CYPRESS_TOUCH_RST_GPIO 143
40#define MOP500_HDMI_RST_GPIO 196
41#define CYPRESS_SLAVE_SELECT_GPIO 216
27 42
28/* GPIOs on the TC35892 expander */ 43/* GPIOs on the TC35892 expander */
29#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x)) 44#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x))
45#define GPIO_MAGNET_DRDY MOP500_EGPIO(1)
30#define GPIO_SDMMC_CD MOP500_EGPIO(3) 46#define GPIO_SDMMC_CD MOP500_EGPIO(3)
47#define GPIO_CAMERA_FLASH_ENABLE MOP500_EGPIO(4)
48#define GPIO_MMIO_XENON_CHARGE MOP500_EGPIO(5)
31#define GPIO_PROX_SENSOR MOP500_EGPIO(7) 49#define GPIO_PROX_SENSOR MOP500_EGPIO(7)
50#define GPIO_HAL_SENSOR MOP500_EGPIO(8)
51#define GPIO_ACCEL_INT1 MOP500_EGPIO(10)
52#define GPIO_ACCEL_INT2 MOP500_EGPIO(11)
32#define GPIO_BU21013_CS MOP500_EGPIO(13) 53#define GPIO_BU21013_CS MOP500_EGPIO(13)
54#define MOP500_DISP2_RST_GPIO MOP500_EGPIO(14)
55#define MOP500_DISP1_RST_GPIO MOP500_EGPIO(15)
33#define GPIO_SDMMC_EN MOP500_EGPIO(17) 56#define GPIO_SDMMC_EN MOP500_EGPIO(17)
34#define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18) 57#define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18)
35#define MOP500_EGPIO_END MOP500_EGPIO(24) 58#define MOP500_EGPIO_END MOP500_EGPIO(24)
36 59
37/* GPIOs on the AB8500 mixed-signals circuit */ 60/*
38#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x)) 61 * GPIOs on the AB8500 mixed-signals circuit
62 * Notice that we subtract 1 from the number passed into the macro, this is
63 * because the AB8500 GPIO pins are enumbered starting from 1, so the value in
64 * parens matches the GPIO pin number in the data sheet.
65 */
66#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x) - 1)
67/*Snowball AB8500 GPIO */
68#define SNOWBALL_VSMPS2_1V8_GPIO MOP500_AB8500_PIN_GPIO(1) /* SYSCLKREQ2/GPIO1 */
69#define SNOWBALL_PM_GPIO1_GPIO MOP500_AB8500_PIN_GPIO(2) /* SYSCLKREQ3/GPIO2 */
70#define SNOWBALL_WLAN_CLK_REQ_GPIO MOP500_AB8500_PIN_GPIO(3) /* SYSCLKREQ4/GPIO3 */
71#define SNOWBALL_PM_GPIO4_GPIO MOP500_AB8500_PIN_GPIO(4) /* SYSCLKREQ6/GPIO4 */
72#define SNOWBALL_EN_3V6_GPIO MOP500_AB8500_PIN_GPIO(16) /* PWMOUT3/GPIO16 */
73#define SNOWBALL_PME_ETH_GPIO MOP500_AB8500_PIN_GPIO(24) /* SYSCLKREQ7/GPIO24 */
74#define SNOWBALL_EN_3V3_ETH_GPIO MOP500_AB8500_PIN_GPIO(26) /* GPIO26 */
39 75
40struct i2c_board_info; 76struct i2c_board_info;
41 77
42extern void mop500_sdi_init(void); 78extern void mop500_sdi_init(void);
43extern void snowball_sdi_init(void); 79extern void snowball_sdi_init(void);
80extern void hrefv60_sdi_init(void);
44extern void mop500_sdi_tc35892_init(void); 81extern void mop500_sdi_tc35892_init(void);
45void __init mop500_u8500uib_init(void); 82void __init mop500_u8500uib_init(void);
46void __init mop500_stuib_init(void); 83void __init mop500_stuib_init(void);
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index e832664d1bd..73790753700 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -239,23 +239,6 @@ static void clk_prcmu_disable(struct clk *clk)
239 writel(1 << clk->prcmu_cg_bit, cg_clr_reg); 239 writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
240} 240}
241 241
242/* ED doesn't have the combined set/clr registers */
243static void clk_prcmu_ed_enable(struct clk *clk)
244{
245 void __iomem *addr = __io_address(U8500_PRCMU_BASE)
246 + clk->prcmu_cg_mgt;
247
248 writel(readl(addr) | PRCM_MGT_ENABLE, addr);
249}
250
251static void clk_prcmu_ed_disable(struct clk *clk)
252{
253 void __iomem *addr = __io_address(U8500_PRCMU_BASE)
254 + clk->prcmu_cg_mgt;
255
256 writel(readl(addr) & ~PRCM_MGT_ENABLE, addr);
257}
258
259static struct clkops clk_prcmu_ops = { 242static struct clkops clk_prcmu_ops = {
260 .enable = clk_prcmu_enable, 243 .enable = clk_prcmu_enable,
261 .disable = clk_prcmu_disable, 244 .disable = clk_prcmu_disable,
@@ -267,7 +250,6 @@ static unsigned int clkrst_base[] = {
267 [3] = U8500_CLKRST3_BASE, 250 [3] = U8500_CLKRST3_BASE,
268 [5] = U8500_CLKRST5_BASE, 251 [5] = U8500_CLKRST5_BASE,
269 [6] = U8500_CLKRST6_BASE, 252 [6] = U8500_CLKRST6_BASE,
270 [7] = U8500_CLKRST7_BASE_ED,
271}; 253};
272 254
273static void clk_prcc_enable(struct clk *clk) 255static void clk_prcc_enable(struct clk *clk)
@@ -321,7 +303,6 @@ static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
321static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK); 303static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK);
322static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK); 304static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK);
323static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000); 305static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000);
324static DEFINE_PRCMU_CLK_RATE(per7clk, 0x0, 16, PER7CLK, 100000000);
325static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK); 306static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK);
326static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK); 307static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK);
327static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK); 308static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK);
@@ -351,44 +332,28 @@ static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
351static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); 332static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
352static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); 333static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
353static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); 334static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
354static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); 335static DEFINE_PRCC_CLK(1, spi3, 7, -1, NULL);
355static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL);
356static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); 336static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
357static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); 337static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
358static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); 338static DEFINE_PRCC_CLK(1, msp1, 4, 4, &clk_msp1clk);
359static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk);
360static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); 339static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
361static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); 340static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
362static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); 341static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
363static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); 342static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
364 343
365/* Peripheral Cluster #2 */ 344/* Peripheral Cluster #2 */
366 345static DEFINE_PRCC_CLK(2, gpio1, 11, -1, NULL);
367static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); 346static DEFINE_PRCC_CLK(2, ssitx, 10, 7, NULL);
368static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); 347static DEFINE_PRCC_CLK(2, ssirx, 9, 6, NULL);
369static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); 348static DEFINE_PRCC_CLK(2, spi0, 8, -1, NULL);
370static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); 349static DEFINE_PRCC_CLK(2, sdi3, 7, 5, &clk_sdmmcclk);
371static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); 350static DEFINE_PRCC_CLK(2, sdi1, 6, 4, &clk_sdmmcclk);
372static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); 351static DEFINE_PRCC_CLK(2, msp2, 5, 3, &clk_msp02clk);
373static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); 352static DEFINE_PRCC_CLK(2, sdi4, 4, 2, &clk_sdmmcclk);
374static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); 353static DEFINE_PRCC_CLK(2, pwl, 3, 1, NULL);
375static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); 354static DEFINE_PRCC_CLK(2, spi1, 2, -1, NULL);
376static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); 355static DEFINE_PRCC_CLK(2, spi2, 1, -1, NULL);
377static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); 356static DEFINE_PRCC_CLK(2, i2c3, 0, 0, &clk_i2cclk);
378static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk);
379
380static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL);
381static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL);
382static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL);
383static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL);
384static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk);
385static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk);
386static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk);
387static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk);
388static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL);
389static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL);
390static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL);
391static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk);
392 357
393/* Peripheral Cluster #3 */ 358/* Peripheral Cluster #3 */
394static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); 359static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
@@ -397,49 +362,34 @@ static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
397static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); 362static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
398static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); 363static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
399static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); 364static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
400static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); 365static DEFINE_PRCC_CLK(3, ssp1, 2, 2, &clk_sspclk);
401static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); 366static DEFINE_PRCC_CLK(3, ssp0, 1, 1, &clk_sspclk);
402static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk);
403static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk);
404static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); 367static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
405 368
406/* Peripheral Cluster #4 is in the always on domain */ 369/* Peripheral Cluster #4 is in the always on domain */
407 370
408/* Peripheral Cluster #5 */ 371/* Peripheral Cluster #5 */
409static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); 372static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
410static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); 373static DEFINE_PRCC_CLK(5, usb, 0, 0, NULL);
411static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL);
412 374
413/* Peripheral Cluster #6 */ 375/* Peripheral Cluster #6 */
414 376
415/* MTU ID in data */ 377/* MTU ID in data */
416static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); 378static DEFINE_PRCC_CLK_CUSTOM(6, mtu1, 8, -1, NULL, clk_mtu_get_rate, 1);
417static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); 379static DEFINE_PRCC_CLK_CUSTOM(6, mtu0, 7, -1, NULL, clk_mtu_get_rate, 0);
418static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); 380static DEFINE_PRCC_CLK(6, cfgreg, 6, 6, NULL);
419static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL);
420static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); 381static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL);
421static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); 382static DEFINE_PRCC_CLK(6, unipro, 4, 1, &clk_uniproclk);
422static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL);
423static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); 383static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL);
424static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); 384static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL);
425static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); 385static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL);
426static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); 386static DEFINE_PRCC_CLK(6, rng, 0, 0, &clk_rngclk);
427static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk);
428
429/* Peripheral Cluster #7 */
430
431static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL);
432/* MTU ID in data */
433static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1);
434static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0);
435static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL);
436static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL);
437 387
438static struct clk clk_dummy_apb_pclk = { 388static struct clk clk_dummy_apb_pclk = {
439 .name = "apb_pclk", 389 .name = "apb_pclk",
440}; 390};
441 391
442static struct clk_lookup u8500_common_clks[] = { 392static struct clk_lookup u8500_clks[] = {
443 CLK(dummy_apb_pclk, NULL, "apb_pclk"), 393 CLK(dummy_apb_pclk, NULL, "apb_pclk"),
444 394
445 /* Peripheral Cluster #1 */ 395 /* Peripheral Cluster #1 */
@@ -494,83 +444,41 @@ static struct clk_lookup u8500_common_clks[] = {
494 CLK(dmaclk, "dma40.0", NULL), 444 CLK(dmaclk, "dma40.0", NULL),
495 CLK(b2r2clk, "b2r2", NULL), 445 CLK(b2r2clk, "b2r2", NULL),
496 CLK(tvclk, "tv", NULL), 446 CLK(tvclk, "tv", NULL),
497};
498 447
499static struct clk_lookup u8500_ed_clks[] = {
500 /* Peripheral Cluster #1 */
501 CLK(spi3_ed, "spi3", NULL),
502 CLK(msp1_ed, "msp1", NULL),
503
504 /* Peripheral Cluster #2 */
505 CLK(gpio1_ed, "gpio.6", NULL),
506 CLK(gpio1_ed, "gpio.7", NULL),
507 CLK(ssitx_ed, "ssitx", NULL),
508 CLK(ssirx_ed, "ssirx", NULL),
509 CLK(spi0_ed, "spi0", NULL),
510 CLK(sdi3_ed, "sdi3", NULL),
511 CLK(sdi1_ed, "sdi1", NULL),
512 CLK(msp2_ed, "msp2", NULL),
513 CLK(sdi4_ed, "sdi4", NULL),
514 CLK(pwl_ed, "pwl", NULL),
515 CLK(spi1_ed, "spi1", NULL),
516 CLK(spi2_ed, "spi2", NULL),
517 CLK(i2c3_ed, "nmk-i2c.3", NULL),
518
519 /* Peripheral Cluster #3 */
520 CLK(ssp1_ed, "ssp1", NULL),
521 CLK(ssp0_ed, "ssp0", NULL),
522
523 /* Peripheral Cluster #5 */
524 CLK(usb_ed, "musb-ux500.0", "usb"),
525
526 /* Peripheral Cluster #6 */
527 CLK(dmc_ed, "dmc", NULL),
528 CLK(cryp1_ed, "cryp1", NULL),
529 CLK(rng_ed, "rng", NULL),
530
531 /* Peripheral Cluster #7 */
532 CLK(tzpc0_ed, "tzpc0", NULL),
533 CLK(mtu1_ed, "mtu1", NULL),
534 CLK(mtu0_ed, "mtu0", NULL),
535 CLK(wdg_ed, "wdg", NULL),
536 CLK(cfgreg_ed, "cfgreg", NULL),
537};
538
539static struct clk_lookup u8500_v1_clks[] = {
540 /* Peripheral Cluster #1 */ 448 /* Peripheral Cluster #1 */
541 CLK(i2c4, "nmk-i2c.4", NULL), 449 CLK(i2c4, "nmk-i2c.4", NULL),
542 CLK(spi3_v1, "spi3", NULL), 450 CLK(spi3, "spi3", NULL),
543 CLK(msp1_v1, "msp1", NULL), 451 CLK(msp1, "msp1", NULL),
544 452
545 /* Peripheral Cluster #2 */ 453 /* Peripheral Cluster #2 */
546 CLK(gpio1_v1, "gpio.6", NULL), 454 CLK(gpio1, "gpio.6", NULL),
547 CLK(gpio1_v1, "gpio.7", NULL), 455 CLK(gpio1, "gpio.7", NULL),
548 CLK(ssitx_v1, "ssitx", NULL), 456 CLK(ssitx, "ssitx", NULL),
549 CLK(ssirx_v1, "ssirx", NULL), 457 CLK(ssirx, "ssirx", NULL),
550 CLK(spi0_v1, "spi0", NULL), 458 CLK(spi0, "spi0", NULL),
551 CLK(sdi3_v1, "sdi3", NULL), 459 CLK(sdi3, "sdi3", NULL),
552 CLK(sdi1_v1, "sdi1", NULL), 460 CLK(sdi1, "sdi1", NULL),
553 CLK(msp2_v1, "msp2", NULL), 461 CLK(msp2, "msp2", NULL),
554 CLK(sdi4_v1, "sdi4", NULL), 462 CLK(sdi4, "sdi4", NULL),
555 CLK(pwl_v1, "pwl", NULL), 463 CLK(pwl, "pwl", NULL),
556 CLK(spi1_v1, "spi1", NULL), 464 CLK(spi1, "spi1", NULL),
557 CLK(spi2_v1, "spi2", NULL), 465 CLK(spi2, "spi2", NULL),
558 CLK(i2c3_v1, "nmk-i2c.3", NULL), 466 CLK(i2c3, "nmk-i2c.3", NULL),
559 467
560 /* Peripheral Cluster #3 */ 468 /* Peripheral Cluster #3 */
561 CLK(ssp1_v1, "ssp1", NULL), 469 CLK(ssp1, "ssp1", NULL),
562 CLK(ssp0_v1, "ssp0", NULL), 470 CLK(ssp0, "ssp0", NULL),
563 471
564 /* Peripheral Cluster #5 */ 472 /* Peripheral Cluster #5 */
565 CLK(usb_v1, "musb-ux500.0", "usb"), 473 CLK(usb, "musb-ux500.0", "usb"),
566 474
567 /* Peripheral Cluster #6 */ 475 /* Peripheral Cluster #6 */
568 CLK(mtu1_v1, "mtu1", NULL), 476 CLK(mtu1, "mtu1", NULL),
569 CLK(mtu0_v1, "mtu0", NULL), 477 CLK(mtu0, "mtu0", NULL),
570 CLK(cfgreg_v1, "cfgreg", NULL), 478 CLK(cfgreg, "cfgreg", NULL),
571 CLK(hash1, "hash1", NULL), 479 CLK(hash1, "hash1", NULL),
572 CLK(unipro_v1, "unipro", NULL), 480 CLK(unipro, "unipro", NULL),
573 CLK(rng_v1, "rng", NULL), 481 CLK(rng, "rng", NULL),
574 482
575 /* PRCMU level clock gating */ 483 /* PRCMU level clock gating */
576 484
@@ -743,7 +651,7 @@ err_out:
743late_initcall(clk_debugfs_init); 651late_initcall(clk_debugfs_init);
744#endif /* defined(CONFIG_DEBUG_FS) */ 652#endif /* defined(CONFIG_DEBUG_FS) */
745 653
746unsigned long clk_smp_twd_rate = 400000000; 654unsigned long clk_smp_twd_rate = 500000000;
747 655
748unsigned long clk_smp_twd_get_rate(struct clk *clk) 656unsigned long clk_smp_twd_get_rate(struct clk *clk)
749{ 657{
@@ -769,7 +677,7 @@ static int clk_twd_cpufreq_transition(struct notifier_block *nb,
769 677
770 if (state == CPUFREQ_PRECHANGE) { 678 if (state == CPUFREQ_PRECHANGE) {
771 /* Save frequency in simple Hz */ 679 /* Save frequency in simple Hz */
772 clk_smp_twd_rate = f->new * 1000; 680 clk_smp_twd_rate = (f->new * 1000) / 2;
773 } 681 }
774 682
775 return NOTIFY_OK; 683 return NOTIFY_OK;
@@ -790,11 +698,7 @@ late_initcall(clk_init_smp_twd_cpufreq);
790 698
791int __init clk_init(void) 699int __init clk_init(void)
792{ 700{
793 if (cpu_is_u8500ed()) { 701 if (cpu_is_u5500()) {
794 clk_prcmu_ops.enable = clk_prcmu_ed_enable;
795 clk_prcmu_ops.disable = clk_prcmu_ed_disable;
796 clk_per6clk.rate = 100000000;
797 } else if (cpu_is_u5500()) {
798 /* Clock tree for U5500 not implemented yet */ 702 /* Clock tree for U5500 not implemented yet */
799 clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; 703 clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
800 clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; 704 clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
@@ -802,20 +706,11 @@ int __init clk_init(void)
802 clk_sdmmcclk.rate = 99900000; 706 clk_sdmmcclk.rate = 99900000;
803 } 707 }
804 708
805 clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); 709 clkdev_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
806 if (cpu_is_u8500ed())
807 clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
808 else
809 clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
810
811 clkdev_add(&clk_smp_twd_lookup); 710 clkdev_add(&clk_smp_twd_lookup);
812 711
813#ifdef CONFIG_DEBUG_FS 712#ifdef CONFIG_DEBUG_FS
814 clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); 713 clk_debugfs_add_table(u8500_clks, ARRAY_SIZE(u8500_clks));
815 if (cpu_is_u8500ed())
816 clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
817 else
818 clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
819#endif 714#endif
820 return 0; 715 return 0;
821} 716}
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
index 5323286b265..18aa5c05c69 100644
--- a/arch/arm/mach-ux500/cpu-db5500.c
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -46,26 +46,6 @@ static struct map_desc u5500_io_desc[] __initdata = {
46 __IO_DEV_DESC(U5500_PRCMU_TCDM_BASE, SZ_4K), 46 __IO_DEV_DESC(U5500_PRCMU_TCDM_BASE, SZ_4K),
47}; 47};
48 48
49static struct resource db5500_pmu_resources[] = {
50 [0] = {
51 .start = IRQ_DB5500_PMU0,
52 .end = IRQ_DB5500_PMU0,
53 .flags = IORESOURCE_IRQ,
54 },
55 [1] = {
56 .start = IRQ_DB5500_PMU1,
57 .end = IRQ_DB5500_PMU1,
58 .flags = IORESOURCE_IRQ,
59 },
60};
61
62static struct platform_device db5500_pmu_device = {
63 .name = "arm-pmu",
64 .id = ARM_PMU_DEVICE_CPU,
65 .num_resources = ARRAY_SIZE(db5500_pmu_resources),
66 .resource = db5500_pmu_resources,
67};
68
69static struct resource mbox0_resources[] = { 49static struct resource mbox0_resources[] = {
70 { 50 {
71 .name = "mbox_peer", 51 .name = "mbox_peer",
@@ -151,7 +131,6 @@ static struct platform_device mbox2_device = {
151}; 131};
152 132
153static struct platform_device *db5500_platform_devs[] __initdata = { 133static struct platform_device *db5500_platform_devs[] __initdata = {
154 &db5500_pmu_device,
155 &mbox0_device, 134 &mbox0_device,
156 &mbox1_device, 135 &mbox1_device,
157 &mbox2_device, 136 &mbox2_device,
@@ -192,6 +171,25 @@ void __init u5500_map_io(void)
192 _PRCMU_BASE = __io_address(U5500_PRCMU_BASE); 171 _PRCMU_BASE = __io_address(U5500_PRCMU_BASE);
193} 172}
194 173
174static void __init db5500_pmu_init(void)
175{
176 struct resource res[] = {
177 [0] = {
178 .start = IRQ_DB5500_PMU0,
179 .end = IRQ_DB5500_PMU0,
180 .flags = IORESOURCE_IRQ,
181 },
182 [1] = {
183 .start = IRQ_DB5500_PMU1,
184 .end = IRQ_DB5500_PMU1,
185 .flags = IORESOURCE_IRQ,
186 },
187 };
188
189 platform_device_register_simple("arm-pmu", ARM_PMU_DEVICE_CPU,
190 res, ARRAY_SIZE(res));
191}
192
195static int usb_db5500_rx_dma_cfg[] = { 193static int usb_db5500_rx_dma_cfg[] = {
196 DB5500_DMA_DEV4_USB_OTG_IEP_1_9, 194 DB5500_DMA_DEV4_USB_OTG_IEP_1_9,
197 DB5500_DMA_DEV5_USB_OTG_IEP_2_10, 195 DB5500_DMA_DEV5_USB_OTG_IEP_2_10,
@@ -217,6 +215,7 @@ static int usb_db5500_tx_dma_cfg[] = {
217void __init u5500_init_devices(void) 215void __init u5500_init_devices(void)
218{ 216{
219 db5500_add_gpios(); 217 db5500_add_gpios();
218 db5500_pmu_init();
220 db5500_dma_init(); 219 db5500_dma_init();
221 db5500_add_rtc(); 220 db5500_add_rtc();
222 db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); 221 db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 7f2729c05db..7176ee7491a 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2008-2009 ST-Ericsson 2 * Copyright (C) 2008-2009 ST-Ericsson SA
3 * 3 *
4 * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> 4 * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
5 * 5 *
@@ -53,19 +53,6 @@ static struct map_desc u8500_io_desc[] __initdata = {
53 __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), 53 __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
54 __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), 54 __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
55 __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), 55 __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
56};
57
58static struct map_desc u8500_ed_io_desc[] __initdata = {
59 __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K),
60 __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K),
61};
62
63static struct map_desc u8500_v1_io_desc[] __initdata = {
64 __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
65 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K),
66};
67
68static struct map_desc u8500_v2_io_desc[] __initdata = {
69 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), 56 __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
70}; 57};
71 58
@@ -80,13 +67,6 @@ void __init u8500_map_io(void)
80 67
81 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); 68 iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
82 69
83 if (cpu_is_u8500ed())
84 iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc));
85 else if (cpu_is_u8500v1())
86 iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
87 else if (cpu_is_u8500v2())
88 iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
89
90 _PRCMU_BASE = __io_address(U8500_PRCMU_BASE); 70 _PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
91} 71}
92 72
@@ -155,12 +135,9 @@ static resource_size_t __initdata db8500_gpio_base[] = {
155static void __init db8500_add_gpios(void) 135static void __init db8500_add_gpios(void)
156{ 136{
157 struct nmk_gpio_platform_data pdata = { 137 struct nmk_gpio_platform_data pdata = {
158 /* No custom data yet */ 138 .supports_sleepmode = true,
159 }; 139 };
160 140
161 if (cpu_is_u8500v2())
162 pdata.supports_sleepmode = true;
163
164 dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), 141 dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
165 IRQ_DB8500_GPIO0, &pdata); 142 IRQ_DB8500_GPIO0, &pdata);
166} 143}
@@ -192,9 +169,6 @@ static int usb_db8500_tx_dma_cfg[] = {
192 */ 169 */
193void __init u8500_init_devices(void) 170void __init u8500_init_devices(void)
194{ 171{
195 if (cpu_is_u8500ed())
196 dma40_u8500ed_fixup();
197
198 db8500_add_rtc(); 172 db8500_add_rtc();
199 db8500_add_gpios(); 173 db8500_add_gpios();
200 db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); 174 db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
index 73b17404b19..a7c6cdc9b11 100644
--- a/arch/arm/mach-ux500/devices-db8500.c
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -166,16 +166,6 @@ struct platform_device u8500_dma40_device = {
166 .resource = dma40_resources 166 .resource = dma40_resources
167}; 167};
168 168
169void dma40_u8500ed_fixup(void)
170{
171 dma40_plat_data.memcpy = NULL;
172 dma40_plat_data.memcpy_len = 0;
173 dma40_resources[0].start = U8500_DMA_BASE_ED;
174 dma40_resources[0].end = U8500_DMA_BASE_ED + SZ_4K - 1;
175 dma40_resources[1].start = U8500_DMA_LCPA_BASE_ED;
176 dma40_resources[1].end = U8500_DMA_LCPA_BASE_ED + 2 * SZ_1K - 1;
177}
178
179struct resource keypad_resources[] = { 169struct resource keypad_resources[] = {
180 [0] = { 170 [0] = {
181 .start = U8500_SKE_BASE, 171 .start = U8500_SKE_BASE,
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c
index d35122ebc67..15a0f63b2e2 100644
--- a/arch/arm/mach-ux500/id.c
+++ b/arch/arm/mach-ux500/id.c
@@ -65,6 +65,7 @@ static unsigned int partnumber(unsigned int asicid)
65 * DB8500v1 0x411fc091 0x9001FFF4 0x008500A0 65 * DB8500v1 0x411fc091 0x9001FFF4 0x008500A0
66 * DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1 66 * DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1
67 * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0 67 * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0
68 * DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2
68 * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0 69 * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
69 */ 70 */
70 71
@@ -80,9 +81,10 @@ void __init ux500_map_io(void)
80 addr = 0x9001FFF4; 81 addr = 0x9001FFF4;
81 break; 82 break;
82 83
83 case 0x412fc091: /* DB8500v2 / DB5500v1 */ 84 case 0x412fc091: /* DB8520 / DB8500v2 / DB5500v1 */
84 asicid = ux500_read_asicid(0x9001DBF4); 85 asicid = ux500_read_asicid(0x9001DBF4);
85 if (partnumber(asicid) == 0x8500) 86 if (partnumber(asicid) == 0x8500 ||
87 partnumber(asicid) == 0x8520)
86 /* DB8500v2 */ 88 /* DB8500v2 */
87 break; 89 break;
88 90
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
index 994b5fe6f85..8e714bcb099 100644
--- a/arch/arm/mach-ux500/include/mach/db5500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -65,8 +65,11 @@
65#define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450) 65#define U5500_PRCMU_TIMER_4_BASE (U5500_PER4_BASE + 0x07450)
66#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) 66#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000)
67#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) 67#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000)
68#define U5500_MTIMER_BASE (U5500_PER4_BASE + 0xC000)
68#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) 69#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000)
69#define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000) 70#define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000)
71#define U5500_PRCMU_TCPM_BASE (U5500_PER4_BASE + 0x10000)
72#define U5500_TPIU_BASE (U5500_PER4_BASE + 0x50000)
70 73
71#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000) 74#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000)
72#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000) 75#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000)
@@ -125,6 +128,7 @@
125#define U5500_ACCCON_BASE (0xBFFF1000) 128#define U5500_ACCCON_BASE (0xBFFF1000)
126#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020) 129#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020)
127#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC) 130#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC)
131#define U5500_INTCON_MBOX1_INT_RESET_ADDR (0xBFFD31A4)
128 132
129#define U5500_ESRAM_BASE 0x40000000 133#define U5500_ESRAM_BASE 0x40000000
130#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000 134#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 751b0e6938d..80e10f50282 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -22,7 +22,9 @@
22#define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000 22#define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000
23 23
24#define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET) 24#define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET)
25#define U8500_DMA_LCPA_BASE_ED (U8500_ESRAM_BANK4 + 0x4000) 25
26/* This address fulfills the 256k alignment requirement of the lcla base */
27#define U8500_DMA_LCLA_BASE U8500_ESRAM_BANK4
26 28
27#define U8500_PER3_BASE 0x80000000 29#define U8500_PER3_BASE 0x80000000
28#define U8500_STM_BASE 0x80100000 30#define U8500_STM_BASE 0x80100000
@@ -40,15 +42,14 @@
40#define U8500_ASIC_ID_BASE 0x9001D000 42#define U8500_ASIC_ID_BASE 0x9001D000
41 43
42#define U8500_PER6_BASE 0xa03c0000 44#define U8500_PER6_BASE 0xa03c0000
45#define U8500_PER7_BASE 0xa03d0000
43#define U8500_PER5_BASE 0xa03e0000 46#define U8500_PER5_BASE 0xa03e0000
44#define U8500_PER7_BASE_ED 0xa03d0000
45 47
46#define U8500_SVA_BASE 0xa0100000 48#define U8500_SVA_BASE 0xa0100000
47#define U8500_SIA_BASE 0xa0200000 49#define U8500_SIA_BASE 0xa0200000
48 50
49#define U8500_SGA_BASE 0xa0300000 51#define U8500_SGA_BASE 0xa0300000
50#define U8500_MCDE_BASE 0xa0350000 52#define U8500_MCDE_BASE 0xa0350000
51#define U8500_DMA_BASE_ED 0xa0362000
52#define U8500_DMA_BASE 0x801C0000 /* v1 */ 53#define U8500_DMA_BASE 0x801C0000 /* v1 */
53 54
54#define U8500_SBAG_BASE 0xa0390000 55#define U8500_SBAG_BASE 0xa0390000
@@ -66,13 +67,6 @@
66#define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000) 67#define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000)
67#define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000) 68#define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000)
68 69
69/* per7 base addresses */
70#define U8500_CR_BASE_ED (U8500_PER7_BASE_ED + 0x8000)
71#define U8500_MTU0_BASE_ED (U8500_PER7_BASE_ED + 0xa000)
72#define U8500_MTU1_BASE_ED (U8500_PER7_BASE_ED + 0xb000)
73#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE_ED + 0xc000)
74#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE_ED + 0xf000)
75
76#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) 70#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000)
77#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) 71#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000)
78 72
@@ -102,12 +96,10 @@
102#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000) 96#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000)
103#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) 97#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
104#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) 98#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
105#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
106#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
107#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
108#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) 99#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
109#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000) 100#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
110 101#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
102#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
111 103
112/* per3 base addresses */ 104/* per3 base addresses */
113#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) 105#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000)
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
index 020b6369a30..5f6cb71fc62 100644
--- a/arch/arm/mach-ux500/include/mach/devices.h
+++ b/arch/arm/mach-ux500/include/mach/devices.h
@@ -18,6 +18,4 @@ extern struct amba_device ux500_pl031_device;
18extern struct platform_device u8500_dma40_device; 18extern struct platform_device u8500_dma40_device;
19extern struct platform_device ux500_ske_keypad_device; 19extern struct platform_device ux500_ske_keypad_device;
20 20
21void dma40_u8500ed_fixup(void);
22
23#endif 21#endif
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 470ac52663d..b6ba26a1367 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -10,20 +10,21 @@
10#ifndef __MACH_HARDWARE_H 10#ifndef __MACH_HARDWARE_H
11#define __MACH_HARDWARE_H 11#define __MACH_HARDWARE_H
12 12
13/* macros to get at IO space when running virtually 13/*
14 * Macros to get at IO space when running virtually
14 * We dont map all the peripherals, let ioremap do 15 * We dont map all the peripherals, let ioremap do
15 * this for us. We map only very basic peripherals here. 16 * this for us. We map only very basic peripherals here.
16 */ 17 */
17#define U8500_IO_VIRTUAL 0xf0000000 18#define U8500_IO_VIRTUAL 0xf0000000
18#define U8500_IO_PHYSICAL 0xa0000000 19#define U8500_IO_PHYSICAL 0xa0000000
19 20
20/* this macro is used in assembly, so no cast */ 21/* This macro is used in assembly, so no cast */
21#define IO_ADDRESS(x) \ 22#define IO_ADDRESS(x) \
22 (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL) 23 (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)
23 24
24/* typesafe io address */ 25/* typesafe io address */
25#define __io_address(n) __io(IO_ADDRESS(n)) 26#define __io_address(n) __io(IO_ADDRESS(n))
26/* used by some plat-nomadik code */ 27/* Used by some plat-nomadik code */
27#define io_p2v(n) __io_address(n) 28#define io_p2v(n) __io_address(n)
28 29
29#include <mach/db8500-regs.h> 30#include <mach/db8500-regs.h>
@@ -36,6 +37,5 @@ extern void __iomem *_PRCMU_BASE;
36 37
37#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) 38#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
38 39
39#endif 40#endif /* __ASSEMBLY__ */
40
41#endif /* __MACH_HARDWARE_H */ 41#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
index 02b541a37ee..833d6a6edc9 100644
--- a/arch/arm/mach-ux500/include/mach/id.h
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -47,6 +47,30 @@ static inline bool __attribute_const__ cpu_is_u5500(void)
47} 47}
48 48
49/* 49/*
50 * 5500 revisions
51 */
52
53static inline bool __attribute_const__ cpu_is_u5500v1(void)
54{
55 return cpu_is_u5500() && (dbx500_revision() & 0xf0) == 0xA0;
56}
57
58static inline bool __attribute_const__ cpu_is_u5500v2(void)
59{
60 return (dbx500_id.revision & 0xf0) == 0xB0;
61}
62
63static inline bool __attribute_const__ cpu_is_u5500v20(void)
64{
65 return cpu_is_u5500() && ((dbx500_revision() & 0xf0) == 0xB0);
66}
67
68static inline bool __attribute_const__ cpu_is_u5500v21(void)
69{
70 return cpu_is_u5500() && (dbx500_revision() == 0xB1);
71}
72
73/*
50 * 8500 revisions 74 * 8500 revisions
51 */ 75 */
52 76
diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c
index 430df1a5978..e62956e1203 100644
--- a/arch/arm/mm/iomap.c
+++ b/arch/arm/mm/iomap.c
@@ -35,27 +35,6 @@ EXPORT_SYMBOL(pcibios_min_mem);
35unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; 35unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC;
36EXPORT_SYMBOL(pci_flags); 36EXPORT_SYMBOL(pci_flags);
37 37
38void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
39{
40 resource_size_t start = pci_resource_start(dev, bar);
41 resource_size_t len = pci_resource_len(dev, bar);
42 unsigned long flags = pci_resource_flags(dev, bar);
43
44 if (!len || !start)
45 return NULL;
46 if (maxlen && len > maxlen)
47 len = maxlen;
48 if (flags & IORESOURCE_IO)
49 return ioport_map(start, len);
50 if (flags & IORESOURCE_MEM) {
51 if (flags & IORESOURCE_CACHEABLE)
52 return ioremap(start, len);
53 return ioremap_nocache(start, len);
54 }
55 return NULL;
56}
57EXPORT_SYMBOL(pci_iomap);
58
59void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 38void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
60{ 39{
61 if ((unsigned long)addr >= VMALLOC_START && 40 if ((unsigned long)addr >= VMALLOC_START &&
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 83cca9bcfc9..1bf0df81bdc 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -131,6 +131,12 @@ extern void imx53_evk_common_init(void);
131extern void imx53_qsb_common_init(void); 131extern void imx53_qsb_common_init(void);
132extern void imx53_smd_common_init(void); 132extern void imx53_smd_common_init(void);
133extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); 133extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
134extern void imx6q_pm_init(void);
135extern void imx6q_clock_map_io(void); 134extern void imx6q_clock_map_io(void);
135
136#ifdef CONFIG_PM
137extern void imx6q_pm_init(void);
138#else
139static inline void imx6q_pm_init(void) {}
140#endif
141
136#endif 142#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
index bf64e1e594e..f0726d48df2 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -265,16 +265,20 @@
265#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL) 265#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL)
266#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL) 266#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL)
267#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL) 267#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL)
268#define MX25_PAD_CSI_D2__CSPI3_MOSI IOMUX_PAD(0x318, 0x120, 0x17, 0, 0, NO_PAD_CTRL)
268 269
269#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL) 270#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL)
270#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL) 271#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL)
272#define MX25_PAD_CSI_D3__CSPI3_MISO IOMUX_PAD(0x31c, 0x124, 0x17, 0x4b4, 1, NO_PAD_CTRL)
271 273
272#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL) 274#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL)
273#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL) 275#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL)
274#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL) 276#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL)
277#define MX25_PAD_CSI_D4__CSPI3_SCLK IOMUX_PAD(0x320, 0x128, 0x17, 0, 0, NO_PAD_CTRL)
275 278
276#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL) 279#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL)
277#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL) 280#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL)
281#define MX25_PAD_CSI_D5__CSPI3_RDY IOMUX_PAD(0x324, 0x12c, 0x17, 0, 0, NO_PAD_CTRL)
278 282
279#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL) 283#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL)
280#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL) 284#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL)
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index a4d36d601d5..d78298366a9 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -168,7 +168,7 @@ struct cpu_op {
168 u32 cpu_rate; 168 u32 cpu_rate;
169}; 169};
170 170
171int tzic_enable_wake(int is_idle); 171int tzic_enable_wake(void);
172 172
173extern struct cpu_op *(*get_cpu_op)(int *op); 173extern struct cpu_op *(*get_cpu_op)(int *op);
174#endif 174#endif
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index a3c164c7ba8..98308ec1f32 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -73,7 +73,28 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
73#define tzic_set_irq_fiq NULL 73#define tzic_set_irq_fiq NULL
74#endif 74#endif
75 75
76static unsigned int *wakeup_intr[4]; 76#ifdef CONFIG_PM
77static void tzic_irq_suspend(struct irq_data *d)
78{
79 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
80 int idx = gc->irq_base >> 5;
81
82 __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx));
83}
84
85static void tzic_irq_resume(struct irq_data *d)
86{
87 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
88 int idx = gc->irq_base >> 5;
89
90 __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)),
91 tzic_base + TZIC_WAKEUP0(idx));
92}
93
94#else
95#define tzic_irq_suspend NULL
96#define tzic_irq_resume NULL
97#endif
77 98
78static struct mxc_extra_irq tzic_extra_irq = { 99static struct mxc_extra_irq tzic_extra_irq = {
79#ifdef CONFIG_FIQ 100#ifdef CONFIG_FIQ
@@ -91,12 +112,13 @@ static __init void tzic_init_gc(unsigned int irq_start)
91 handle_level_irq); 112 handle_level_irq);
92 gc->private = &tzic_extra_irq; 113 gc->private = &tzic_extra_irq;
93 gc->wake_enabled = IRQ_MSK(32); 114 gc->wake_enabled = IRQ_MSK(32);
94 wakeup_intr[idx] = &gc->wake_active;
95 115
96 ct = gc->chip_types; 116 ct = gc->chip_types;
97 ct->chip.irq_mask = irq_gc_mask_disable_reg; 117 ct->chip.irq_mask = irq_gc_mask_disable_reg;
98 ct->chip.irq_unmask = irq_gc_unmask_enable_reg; 118 ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
99 ct->chip.irq_set_wake = irq_gc_set_wake; 119 ct->chip.irq_set_wake = irq_gc_set_wake;
120 ct->chip.irq_suspend = tzic_irq_suspend;
121 ct->chip.irq_resume = tzic_irq_resume;
100 ct->regs.disable = TZIC_ENCLEAR0(idx); 122 ct->regs.disable = TZIC_ENCLEAR0(idx);
101 ct->regs.enable = TZIC_ENSET0(idx); 123 ct->regs.enable = TZIC_ENSET0(idx);
102 124
@@ -167,23 +189,19 @@ void __init tzic_init_irq(void __iomem *irqbase)
167/** 189/**
168 * tzic_enable_wake() - enable wakeup interrupt 190 * tzic_enable_wake() - enable wakeup interrupt
169 * 191 *
170 * @param is_idle 1 if called in idle loop (ENSET0 register);
171 * 0 to be used when called from low power entry
172 * @return 0 if successful; non-zero otherwise 192 * @return 0 if successful; non-zero otherwise
173 */ 193 */
174int tzic_enable_wake(int is_idle) 194int tzic_enable_wake(void)
175{ 195{
176 unsigned int i, v; 196 unsigned int i;
177 197
178 __raw_writel(1, tzic_base + TZIC_DSMINT); 198 __raw_writel(1, tzic_base + TZIC_DSMINT);
179 if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) 199 if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
180 return -EAGAIN; 200 return -EAGAIN;
181 201
182 for (i = 0; i < 4; i++) { 202 for (i = 0; i < 4; i++)
183 v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) : 203 __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)),
184 *wakeup_intr[i]; 204 tzic_base + TZIC_WAKEUP0(i));
185 __raw_writel(v, tzic_base + TZIC_WAKEUP0(i));
186 }
187 205
188 return 0; 206 return 0;
189} 207}
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 3df04d944e4..9a584614e7e 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
19 19
20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 20obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
21 21
22obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
23obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o 22obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
24obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o 23obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
25obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o 24obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 2ee6341fffd..06383b51e65 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -22,6 +22,8 @@
22#include <plat/vram.h> 22#include <plat/vram.h>
23#include <plat/dsp.h> 23#include <plat/dsp.h>
24 24
25#include <plat/omap-secure.h>
26
25 27
26#define NO_LENGTH_CHECK 0xffffffff 28#define NO_LENGTH_CHECK 0xffffffff
27 29
@@ -66,6 +68,7 @@ void __init omap_reserve(void)
66 omapfb_reserve_sdram_memblock(); 68 omapfb_reserve_sdram_memblock();
67 omap_vram_reserve_sdram_memblock(); 69 omap_vram_reserve_sdram_memblock();
68 omap_dsp_reserve_sdram_memblock(); 70 omap_dsp_reserve_sdram_memblock();
71 omap_secure_ram_reserve_memblock();
69} 72}
70 73
71void __init omap_init_consistent_dma_size(void) 74void __init omap_init_consistent_dma_size(void)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index c22217c2ee5..002fb4d96bb 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1034,6 +1034,18 @@ dma_addr_t omap_get_dma_src_pos(int lch)
1034 if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) 1034 if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
1035 offset = p->dma_read(CSAC, lch); 1035 offset = p->dma_read(CSAC, lch);
1036 1036
1037 if (!cpu_is_omap15xx()) {
1038 /*
1039 * CDAC == 0 indicates that the DMA transfer on the channel has
1040 * not been started (no data has been transferred so far).
1041 * Return the programmed source start address in this case.
1042 */
1043 if (likely(p->dma_read(CDAC, lch)))
1044 offset = p->dma_read(CSAC, lch);
1045 else
1046 offset = p->dma_read(CSSA, lch);
1047 }
1048
1037 if (cpu_class_is_omap1()) 1049 if (cpu_class_is_omap1())
1038 offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000); 1050 offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
1039 1051
@@ -1062,8 +1074,16 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
1062 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is 1074 * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
1063 * read before the DMA controller finished disabling the channel. 1075 * read before the DMA controller finished disabling the channel.
1064 */ 1076 */
1065 if (!cpu_is_omap15xx() && offset == 0) 1077 if (!cpu_is_omap15xx() && offset == 0) {
1066 offset = p->dma_read(CDAC, lch); 1078 offset = p->dma_read(CDAC, lch);
1079 /*
1080 * CDAC == 0 indicates that the DMA transfer on the channel has
1081 * not been started (no data has been transferred so far).
1082 * Return the programmed destination start address in this case.
1083 */
1084 if (unlikely(!offset))
1085 offset = p->dma_read(CDSA, lch);
1086 }
1067 1087
1068 if (cpu_class_is_omap1()) 1088 if (cpu_class_is_omap1())
1069 offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000); 1089 offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h
new file mode 100644
index 00000000000..06c19bb7bca
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/am33xx.h
@@ -0,0 +1,25 @@
1/*
2 * This file contains the address info for various AM33XX modules.
3 *
4 * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef __ASM_ARCH_AM33XX_H
17#define __ASM_ARCH_AM33XX_H
18
19#define L4_SLOW_AM33XX_BASE 0x48000000
20
21#define AM33XX_SCM_BASE 0x44E10000
22#define AM33XX_CTRL_BASE AM33XX_SCM_BASE
23#define AM33XX_PRCM_BASE 0x44E00000
24
25#endif /* __ASM_ARCH_AM33XX_H */
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index 387a9638991..b299b8d201c 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -40,6 +40,7 @@ struct omap_clk {
40#define CK_443X (1 << 11) 40#define CK_443X (1 << 11)
41#define CK_TI816X (1 << 12) 41#define CK_TI816X (1 << 12)
42#define CK_446X (1 << 13) 42#define CK_446X (1 << 13)
43#define CK_1710 (1 << 15) /* 1710 extra for rate selection */
43 44
44 45
45#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) 46#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index eb73ab40e95..240a7b9fd94 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -59,6 +59,8 @@ struct clkops {
59#define RATE_IN_4430 (1 << 5) 59#define RATE_IN_4430 (1 << 5)
60#define RATE_IN_TI816X (1 << 6) 60#define RATE_IN_TI816X (1 << 6)
61#define RATE_IN_4460 (1 << 7) 61#define RATE_IN_4460 (1 << 7)
62#define RATE_IN_AM33XX (1 << 8)
63#define RATE_IN_TI814X (1 << 9)
62 64
63#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) 65#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
64#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) 66#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
@@ -84,7 +86,7 @@ struct clkops {
84struct clksel_rate { 86struct clksel_rate {
85 u32 val; 87 u32 val;
86 u8 div; 88 u8 div;
87 u8 flags; 89 u16 flags;
88}; 90};
89 91
90/** 92/**
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 408a12f7920..6b51086fce1 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -69,6 +69,7 @@ unsigned int omap_rev(void);
69 * cpu_is_omap343x(): True for OMAP3430 69 * cpu_is_omap343x(): True for OMAP3430
70 * cpu_is_omap443x(): True for OMAP4430 70 * cpu_is_omap443x(): True for OMAP4430
71 * cpu_is_omap446x(): True for OMAP4460 71 * cpu_is_omap446x(): True for OMAP4460
72 * cpu_is_omap447x(): True for OMAP4470
72 */ 73 */
73#define GET_OMAP_CLASS (omap_rev() & 0xff) 74#define GET_OMAP_CLASS (omap_rev() & 0xff)
74 75
@@ -78,6 +79,22 @@ static inline int is_omap ##class (void) \
78 return (GET_OMAP_CLASS == (id)) ? 1 : 0; \ 79 return (GET_OMAP_CLASS == (id)) ? 1 : 0; \
79} 80}
80 81
82#define GET_AM_CLASS ((omap_rev() >> 24) & 0xff)
83
84#define IS_AM_CLASS(class, id) \
85static inline int is_am ##class (void) \
86{ \
87 return (GET_AM_CLASS == (id)) ? 1 : 0; \
88}
89
90#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff)
91
92#define IS_TI_CLASS(class, id) \
93static inline int is_ti ##class (void) \
94{ \
95 return (GET_TI_CLASS == (id)) ? 1 : 0; \
96}
97
81#define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) 98#define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff)
82 99
83#define IS_OMAP_SUBCLASS(subclass, id) \ 100#define IS_OMAP_SUBCLASS(subclass, id) \
@@ -92,12 +109,21 @@ static inline int is_ti ##subclass (void) \
92 return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ 109 return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
93} 110}
94 111
112#define IS_AM_SUBCLASS(subclass, id) \
113static inline int is_am ##subclass (void) \
114{ \
115 return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
116}
117
95IS_OMAP_CLASS(7xx, 0x07) 118IS_OMAP_CLASS(7xx, 0x07)
96IS_OMAP_CLASS(15xx, 0x15) 119IS_OMAP_CLASS(15xx, 0x15)
97IS_OMAP_CLASS(16xx, 0x16) 120IS_OMAP_CLASS(16xx, 0x16)
98IS_OMAP_CLASS(24xx, 0x24) 121IS_OMAP_CLASS(24xx, 0x24)
99IS_OMAP_CLASS(34xx, 0x34) 122IS_OMAP_CLASS(34xx, 0x34)
100IS_OMAP_CLASS(44xx, 0x44) 123IS_OMAP_CLASS(44xx, 0x44)
124IS_AM_CLASS(33xx, 0x33)
125
126IS_TI_CLASS(81xx, 0x81)
101 127
102IS_OMAP_SUBCLASS(242x, 0x242) 128IS_OMAP_SUBCLASS(242x, 0x242)
103IS_OMAP_SUBCLASS(243x, 0x243) 129IS_OMAP_SUBCLASS(243x, 0x243)
@@ -105,8 +131,11 @@ IS_OMAP_SUBCLASS(343x, 0x343)
105IS_OMAP_SUBCLASS(363x, 0x363) 131IS_OMAP_SUBCLASS(363x, 0x363)
106IS_OMAP_SUBCLASS(443x, 0x443) 132IS_OMAP_SUBCLASS(443x, 0x443)
107IS_OMAP_SUBCLASS(446x, 0x446) 133IS_OMAP_SUBCLASS(446x, 0x446)
134IS_OMAP_SUBCLASS(447x, 0x447)
108 135
109IS_TI_SUBCLASS(816x, 0x816) 136IS_TI_SUBCLASS(816x, 0x816)
137IS_TI_SUBCLASS(814x, 0x814)
138IS_AM_SUBCLASS(335x, 0x335)
110 139
111#define cpu_is_omap7xx() 0 140#define cpu_is_omap7xx() 0
112#define cpu_is_omap15xx() 0 141#define cpu_is_omap15xx() 0
@@ -116,10 +145,15 @@ IS_TI_SUBCLASS(816x, 0x816)
116#define cpu_is_omap243x() 0 145#define cpu_is_omap243x() 0
117#define cpu_is_omap34xx() 0 146#define cpu_is_omap34xx() 0
118#define cpu_is_omap343x() 0 147#define cpu_is_omap343x() 0
148#define cpu_is_ti81xx() 0
119#define cpu_is_ti816x() 0 149#define cpu_is_ti816x() 0
150#define cpu_is_ti814x() 0
151#define cpu_is_am33xx() 0
152#define cpu_is_am335x() 0
120#define cpu_is_omap44xx() 0 153#define cpu_is_omap44xx() 0
121#define cpu_is_omap443x() 0 154#define cpu_is_omap443x() 0
122#define cpu_is_omap446x() 0 155#define cpu_is_omap446x() 0
156#define cpu_is_omap447x() 0
123 157
124#if defined(MULTI_OMAP1) 158#if defined(MULTI_OMAP1)
125# if defined(CONFIG_ARCH_OMAP730) 159# if defined(CONFIG_ARCH_OMAP730)
@@ -322,7 +356,11 @@ IS_OMAP_TYPE(3517, 0x3517)
322# undef cpu_is_omap3530 356# undef cpu_is_omap3530
323# undef cpu_is_omap3505 357# undef cpu_is_omap3505
324# undef cpu_is_omap3517 358# undef cpu_is_omap3517
359# undef cpu_is_ti81xx
325# undef cpu_is_ti816x 360# undef cpu_is_ti816x
361# undef cpu_is_ti814x
362# undef cpu_is_am33xx
363# undef cpu_is_am335x
326# define cpu_is_omap3430() is_omap3430() 364# define cpu_is_omap3430() is_omap3430()
327# define cpu_is_omap3503() (cpu_is_omap3430() && \ 365# define cpu_is_omap3503() (cpu_is_omap3430() && \
328 (!omap3_has_iva()) && \ 366 (!omap3_has_iva()) && \
@@ -339,16 +377,22 @@ IS_OMAP_TYPE(3517, 0x3517)
339 !omap3_has_sgx()) 377 !omap3_has_sgx())
340# undef cpu_is_omap3630 378# undef cpu_is_omap3630
341# define cpu_is_omap3630() is_omap363x() 379# define cpu_is_omap3630() is_omap363x()
380# define cpu_is_ti81xx() is_ti81xx()
342# define cpu_is_ti816x() is_ti816x() 381# define cpu_is_ti816x() is_ti816x()
382# define cpu_is_ti814x() is_ti814x()
383# define cpu_is_am33xx() is_am33xx()
384# define cpu_is_am335x() is_am335x()
343#endif 385#endif
344 386
345# if defined(CONFIG_ARCH_OMAP4) 387# if defined(CONFIG_ARCH_OMAP4)
346# undef cpu_is_omap44xx 388# undef cpu_is_omap44xx
347# undef cpu_is_omap443x 389# undef cpu_is_omap443x
348# undef cpu_is_omap446x 390# undef cpu_is_omap446x
391# undef cpu_is_omap447x
349# define cpu_is_omap44xx() is_omap44xx() 392# define cpu_is_omap44xx() is_omap44xx()
350# define cpu_is_omap443x() is_omap443x() 393# define cpu_is_omap443x() is_omap443x()
351# define cpu_is_omap446x() is_omap446x() 394# define cpu_is_omap446x() is_omap446x()
395# define cpu_is_omap447x() is_omap447x()
352# endif 396# endif
353 397
354/* Macros to detect if we have OMAP1 or OMAP2 */ 398/* Macros to detect if we have OMAP1 or OMAP2 */
@@ -386,15 +430,27 @@ IS_OMAP_TYPE(3517, 0x3517)
386#define TI8168_REV_ES1_0 TI816X_CLASS 430#define TI8168_REV_ES1_0 TI816X_CLASS
387#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8)) 431#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8))
388 432
433#define TI814X_CLASS 0x81400034
434#define TI8148_REV_ES1_0 TI814X_CLASS
435#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
436#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
437
438#define AM335X_CLASS 0x33500034
439#define AM335X_REV_ES1_0 AM335X_CLASS
440
389#define OMAP443X_CLASS 0x44300044 441#define OMAP443X_CLASS 0x44300044
390#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) 442#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8))
391#define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) 443#define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8))
392#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) 444#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8))
393#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) 445#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8))
446#define OMAP4430_REV_ES2_3 (OMAP443X_CLASS | (0x23 << 8))
394 447
395#define OMAP446X_CLASS 0x44600044 448#define OMAP446X_CLASS 0x44600044
396#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8)) 449#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8))
397 450
451#define OMAP447X_CLASS 0x44700044
452#define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8))
453
398void omap2_check_revision(void); 454void omap2_check_revision(void);
399 455
400/* 456/*
diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h
index e87efe1499b..e897978371c 100644
--- a/arch/arm/plat-omap/include/plat/hardware.h
+++ b/arch/arm/plat-omap/include/plat/hardware.h
@@ -286,6 +286,7 @@
286#include <plat/omap24xx.h> 286#include <plat/omap24xx.h>
287#include <plat/omap34xx.h> 287#include <plat/omap34xx.h>
288#include <plat/omap44xx.h> 288#include <plat/omap44xx.h>
289#include <plat/ti816x.h> 289#include <plat/ti81xx.h>
290#include <plat/am33xx.h>
290 291
291#endif /* __ASM_ARCH_OMAP_HARDWARE_H */ 292#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
index 1234944a4da..0696bae1818 100644
--- a/arch/arm/plat-omap/include/plat/io.h
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -73,6 +73,9 @@
73#define OMAP4_L3_IO_OFFSET 0xb4000000 73#define OMAP4_L3_IO_OFFSET 0xb4000000
74#define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */ 74#define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
75 75
76#define AM33XX_L4_WK_IO_OFFSET 0xb5000000
77#define AM33XX_L4_WK_IO_ADDRESS(pa) IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET)
78
76#define OMAP4_L3_PER_IO_OFFSET 0xb1100000 79#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
77#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET) 80#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
78 81
@@ -154,6 +157,15 @@
154#define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */ 157#define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */
155 158
156/* 159/*
160 * ----------------------------------------------------------------------------
161 * AM33XX specific IO mapping
162 * ----------------------------------------------------------------------------
163 */
164#define L4_WK_AM33XX_PHYS L4_WK_AM33XX_BASE
165#define L4_WK_AM33XX_VIRT (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET)
166#define L4_WK_AM33XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */
167
168/*
157 * Need to look at the Size 4M for L4. 169 * Need to look at the Size 4M for L4.
158 * VPOM3430 was not working for Int controller 170 * VPOM3430 was not working for Int controller
159 */ 171 */
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index a1d79ee1925..88be3e628b3 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -111,6 +111,32 @@ struct iommu_platform_data {
111 u32 da_end; 111 u32 da_end;
112}; 112};
113 113
114/**
115 * struct iommu_arch_data - omap iommu private data
116 * @name: name of the iommu device
117 * @iommu_dev: handle of the iommu device
118 *
119 * This is an omap iommu private data object, which binds an iommu user
120 * to its iommu device. This object should be placed at the iommu user's
121 * dev_archdata so generic IOMMU API can be used without having to
122 * utilize omap-specific plumbing anymore.
123 */
124struct omap_iommu_arch_data {
125 const char *name;
126 struct omap_iommu *iommu_dev;
127};
128
129/**
130 * dev_to_omap_iommu() - retrieves an omap iommu object from a user device
131 * @dev: iommu client device
132 */
133static inline struct omap_iommu *dev_to_omap_iommu(struct device *dev)
134{
135 struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
136
137 return arch_data->iommu_dev;
138}
139
114/* IOMMU errors */ 140/* IOMMU errors */
115#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) 141#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0)
116#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) 142#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1)
@@ -163,8 +189,8 @@ extern int omap_iommu_set_isr(const char *name,
163 void *priv), 189 void *priv),
164 void *isr_priv); 190 void *isr_priv);
165 191
166extern void omap_iommu_save_ctx(struct omap_iommu *obj); 192extern void omap_iommu_save_ctx(struct device *dev);
167extern void omap_iommu_restore_ctx(struct omap_iommu *obj); 193extern void omap_iommu_restore_ctx(struct device *dev);
168 194
169extern int omap_install_iommu_arch(const struct iommu_functions *ops); 195extern int omap_install_iommu_arch(const struct iommu_functions *ops);
170extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops); 196extern void omap_uninstall_iommu_arch(const struct iommu_functions *ops);
@@ -176,6 +202,5 @@ extern ssize_t
176omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len); 202omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t len);
177extern size_t 203extern size_t
178omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len); 204omap_dump_tlb_entries(struct omap_iommu *obj, char *buf, ssize_t len);
179struct device *omap_find_iommu_device(const char *name);
180 205
181#endif /* __MACH_IOMMU_H */ 206#endif /* __MACH_IOMMU_H */
diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h
index 6af1a91c0f3..498e57cda6c 100644
--- a/arch/arm/plat-omap/include/plat/iovmm.h
+++ b/arch/arm/plat-omap/include/plat/iovmm.h
@@ -72,18 +72,18 @@ struct iovm_struct {
72#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT)) 72#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
73 73
74 74
75extern struct iovm_struct *omap_find_iovm_area(struct omap_iommu *obj, u32 da); 75extern struct iovm_struct *omap_find_iovm_area(struct device *dev, u32 da);
76extern u32 76extern u32
77omap_iommu_vmap(struct iommu_domain *domain, struct omap_iommu *obj, u32 da, 77omap_iommu_vmap(struct iommu_domain *domain, struct device *dev, u32 da,
78 const struct sg_table *sgt, u32 flags); 78 const struct sg_table *sgt, u32 flags);
79extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain, 79extern struct sg_table *omap_iommu_vunmap(struct iommu_domain *domain,
80 struct omap_iommu *obj, u32 da); 80 struct device *dev, u32 da);
81extern u32 81extern u32
82omap_iommu_vmalloc(struct iommu_domain *domain, struct omap_iommu *obj, 82omap_iommu_vmalloc(struct iommu_domain *domain, struct device *dev,
83 u32 da, size_t bytes, u32 flags); 83 u32 da, size_t bytes, u32 flags);
84extern void 84extern void
85omap_iommu_vfree(struct iommu_domain *domain, struct omap_iommu *obj, 85omap_iommu_vfree(struct iommu_domain *domain, struct device *dev,
86 const u32 da); 86 const u32 da);
87extern void *omap_da_to_va(struct omap_iommu *obj, u32 da); 87extern void *omap_da_to_va(struct device *dev, u32 da);
88 88
89#endif /* __IOMMU_MMAP_H */ 89#endif /* __IOMMU_MMAP_H */
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index ebda7382c65..2efd6454bce 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -357,7 +357,7 @@
357#define INT_35XX_EMAC_C0_TX_PULSE_IRQ 69 357#define INT_35XX_EMAC_C0_TX_PULSE_IRQ 69
358#define INT_35XX_EMAC_C0_MISC_PULSE_IRQ 70 358#define INT_35XX_EMAC_C0_MISC_PULSE_IRQ 70
359#define INT_35XX_USBOTG_IRQ 71 359#define INT_35XX_USBOTG_IRQ 71
360#define INT_35XX_UART4 84 360#define INT_35XX_UART4_IRQ 84
361#define INT_35XX_CCDC_VD0_IRQ 88 361#define INT_35XX_CCDC_VD0_IRQ 88
362#define INT_35XX_CCDC_VD1_IRQ 92 362#define INT_35XX_CCDC_VD1_IRQ 92
363#define INT_35XX_CCDC_VD2_IRQ 93 363#define INT_35XX_CCDC_VD2_IRQ 93
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 94cf70afb23..f75946c3293 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -96,6 +96,7 @@ struct omap_mmc_platform_data {
96 */ 96 */
97 u8 wires; /* Used for the MMC driver on omap1 and 2420 */ 97 u8 wires; /* Used for the MMC driver on omap1 and 2420 */
98 u32 caps; /* Used for the MMC driver on 2430 and later */ 98 u32 caps; /* Used for the MMC driver on 2430 and later */
99 u32 pm_caps; /* PM capabilities of the mmc */
99 100
100 /* 101 /*
101 * nomux means "standard" muxing is wrong on this board, and 102 * nomux means "standard" muxing is wrong on this board, and
diff --git a/arch/arm/plat-omap/include/plat/omap-secure.h b/arch/arm/plat-omap/include/plat/omap-secure.h
new file mode 100644
index 00000000000..64f9d1c7f1b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-secure.h
@@ -0,0 +1,13 @@
1#ifndef __OMAP_SECURE_H__
2#define __OMAP_SECURE_H__
3
4#include <linux/types.h>
5
6#ifdef CONFIG_ARCH_OMAP2PLUS
7extern int omap_secure_ram_reserve_memblock(void);
8#else
9static inline void omap_secure_ram_reserve_memblock(void)
10{ }
11#endif
12
13#endif /* __OMAP_SECURE_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index 2682043f5a5..9ff444469f3 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/serial_core.h> 20#include <linux/serial_core.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/pm_qos.h>
22 23
23#include <plat/mux.h> 24#include <plat/mux.h>
24 25
@@ -33,6 +34,8 @@
33 34
34#define OMAP_MODE13X_SPEED 230400 35#define OMAP_MODE13X_SPEED 230400
35 36
37#define OMAP_UART_SCR_TX_EMPTY 0x08
38
36/* WER = 0x7F 39/* WER = 0x7F
37 * Enable module level wakeup in WER reg 40 * Enable module level wakeup in WER reg
38 */ 41 */
@@ -51,18 +54,27 @@
51 54
52#define OMAP_UART_DMA_CH_FREE -1 55#define OMAP_UART_DMA_CH_FREE -1
53 56
54#define RX_TIMEOUT (3 * HZ)
55#define OMAP_MAX_HSUART_PORTS 4 57#define OMAP_MAX_HSUART_PORTS 4
56 58
57#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA 59#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
58 60
61#define UART_ERRATA_i202_MDR1_ACCESS BIT(0)
62#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1)
63
59struct omap_uart_port_info { 64struct omap_uart_port_info {
60 bool dma_enabled; /* To specify DMA Mode */ 65 bool dma_enabled; /* To specify DMA Mode */
61 unsigned int uartclk; /* UART clock rate */ 66 unsigned int uartclk; /* UART clock rate */
62 void __iomem *membase; /* ioremap cookie or NULL */
63 resource_size_t mapbase; /* resource base */
64 unsigned long irqflags; /* request_irq flags */
65 upf_t flags; /* UPF_* flags */ 67 upf_t flags; /* UPF_* flags */
68 u32 errata;
69 unsigned int dma_rx_buf_size;
70 unsigned int dma_rx_timeout;
71 unsigned int autosuspend_timeout;
72 unsigned int dma_rx_poll_rate;
73
74 int (*get_context_loss_count)(struct device *);
75 void (*set_forceidle)(struct platform_device *);
76 void (*set_noidle)(struct platform_device *);
77 void (*enable_wakeup)(struct platform_device *, bool);
66}; 78};
67 79
68struct uart_omap_dma { 80struct uart_omap_dma {
@@ -86,8 +98,9 @@ struct uart_omap_dma {
86 spinlock_t rx_lock; 98 spinlock_t rx_lock;
87 /* timer to poll activity on rx dma */ 99 /* timer to poll activity on rx dma */
88 struct timer_list rx_timer; 100 struct timer_list rx_timer;
89 int rx_buf_size; 101 unsigned int rx_buf_size;
90 int rx_timeout; 102 unsigned int rx_poll_rate;
103 unsigned int rx_timeout;
91}; 104};
92 105
93struct uart_omap_port { 106struct uart_omap_port {
@@ -100,6 +113,10 @@ struct uart_omap_port {
100 unsigned char mcr; 113 unsigned char mcr;
101 unsigned char fcr; 114 unsigned char fcr;
102 unsigned char efr; 115 unsigned char efr;
116 unsigned char dll;
117 unsigned char dlh;
118 unsigned char mdr1;
119 unsigned char scr;
103 120
104 int use_dma; 121 int use_dma;
105 /* 122 /*
@@ -111,6 +128,14 @@ struct uart_omap_port {
111 unsigned char msr_saved_flags; 128 unsigned char msr_saved_flags;
112 char name[20]; 129 char name[20];
113 unsigned long port_activity; 130 unsigned long port_activity;
131 u32 context_loss_cnt;
132 u32 errata;
133 u8 wakeups_enabled;
134
135 struct pm_qos_request pm_qos_request;
136 u32 latency;
137 u32 calc_latency;
138 struct work_struct qos_work;
114}; 139};
115 140
116#endif /* __OMAP_SERIAL_H__ */ 141#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index b9e85886b9d..0d818acf391 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -35,6 +35,8 @@
35#define L4_EMU_34XX_BASE 0x54000000 35#define L4_EMU_34XX_BASE 0x54000000
36#define L3_34XX_BASE 0x68000000 36#define L3_34XX_BASE 0x68000000
37 37
38#define L4_WK_AM33XX_BASE 0x44C00000
39
38#define OMAP3430_32KSYNCT_BASE 0x48320000 40#define OMAP3430_32KSYNCT_BASE 0x48320000
39#define OMAP3430_CM_BASE 0x48004800 41#define OMAP3430_CM_BASE 0x48004800
40#define OMAP3430_PRM_BASE 0x48306800 42#define OMAP3430_PRM_BASE 0x48306800
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index ea2b8a6306e..c0d478e55c8 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -45,6 +45,7 @@
45#define OMAP44XX_WKUPGEN_BASE 0x48281000 45#define OMAP44XX_WKUPGEN_BASE 0x48281000
46#define OMAP44XX_MCPDM_BASE 0x40132000 46#define OMAP44XX_MCPDM_BASE 0x40132000
47#define OMAP44XX_MCPDM_L3_BASE 0x49032000 47#define OMAP44XX_MCPDM_L3_BASE 0x49032000
48#define OMAP44XX_SAR_RAM_BASE 0x4a326000
48 49
49#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) 50#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)
50#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000) 51#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 8b372ede17c..647010109af 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -97,6 +97,7 @@ struct omap_hwmod_mux_info {
97 struct omap_device_pad *pads; 97 struct omap_device_pad *pads;
98 int nr_pads_dynamic; 98 int nr_pads_dynamic;
99 struct omap_device_pad **pads_dynamic; 99 struct omap_device_pad **pads_dynamic;
100 int *irqs;
100 bool enabled; 101 bool enabled;
101}; 102};
102 103
@@ -416,10 +417,13 @@ struct omap_hwmod_omap4_prcm {
416 * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module 417 * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
417 * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP 418 * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
418 * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached 419 * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
420 * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
421 * causes the first call to _enable() to only update the pinmux
419 */ 422 */
420#define _HWMOD_NO_MPU_PORT (1 << 0) 423#define _HWMOD_NO_MPU_PORT (1 << 0)
421#define _HWMOD_WAKEUP_ENABLED (1 << 1) 424#define _HWMOD_WAKEUP_ENABLED (1 << 1)
422#define _HWMOD_SYSCONFIG_LOADED (1 << 2) 425#define _HWMOD_SYSCONFIG_LOADED (1 << 2)
426#define _HWMOD_SKIP_ENABLE (1 << 3)
423 427
424/* 428/*
425 * omap_hwmod._state definitions 429 * omap_hwmod._state definitions
@@ -604,6 +608,8 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
604 608
605int omap_hwmod_no_setup_reset(struct omap_hwmod *oh); 609int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
606 610
611int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
612
607/* 613/*
608 * Chip variant-specific hwmod init routines - XXX should be converted 614 * Chip variant-specific hwmod init routines - XXX should be converted
609 * to use initcalls once the initial boot ordering is straightened out 615 * to use initcalls once the initial boot ordering is straightened out
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index ac44bde5d36..198d1e6a4a6 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -44,6 +44,7 @@
44#define OMAP3_UART2_BASE OMAP2_UART2_BASE 44#define OMAP3_UART2_BASE OMAP2_UART2_BASE
45#define OMAP3_UART3_BASE 0x49020000 45#define OMAP3_UART3_BASE 0x49020000
46#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */ 46#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */
47#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */
47 48
48/* OMAP4 serial ports */ 49/* OMAP4 serial ports */
49#define OMAP4_UART1_BASE OMAP2_UART1_BASE 50#define OMAP4_UART1_BASE OMAP2_UART1_BASE
@@ -51,10 +52,10 @@
51#define OMAP4_UART3_BASE 0x48020000 52#define OMAP4_UART3_BASE 0x48020000
52#define OMAP4_UART4_BASE 0x4806e000 53#define OMAP4_UART4_BASE 0x4806e000
53 54
54/* TI816X serial ports */ 55/* TI81XX serial ports */
55#define TI816X_UART1_BASE 0x48020000 56#define TI81XX_UART1_BASE 0x48020000
56#define TI816X_UART2_BASE 0x48022000 57#define TI81XX_UART2_BASE 0x48022000
57#define TI816X_UART3_BASE 0x48024000 58#define TI81XX_UART3_BASE 0x48024000
58 59
59/* AM3505/3517 UART4 */ 60/* AM3505/3517 UART4 */
60#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ 61#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */
@@ -89,9 +90,9 @@
89#define OMAP4UART2 OMAP2UART2 90#define OMAP4UART2 OMAP2UART2
90#define OMAP4UART3 43 91#define OMAP4UART3 43
91#define OMAP4UART4 44 92#define OMAP4UART4 44
92#define TI816XUART1 81 93#define TI81XXUART1 81
93#define TI816XUART2 82 94#define TI81XXUART2 82
94#define TI816XUART3 83 95#define TI81XXUART3 83
95#define ZOOM_UART 95 /* Only on zoom2/3 */ 96#define ZOOM_UART 95 /* Only on zoom2/3 */
96 97
97/* This is only used by 8250.c for omap1510 */ 98/* This is only used by 8250.c for omap1510 */
@@ -106,15 +107,13 @@
106#ifndef __ASSEMBLER__ 107#ifndef __ASSEMBLER__
107 108
108struct omap_board_data; 109struct omap_board_data;
110struct omap_uart_port_info;
109 111
110extern void omap_serial_init(void); 112extern void omap_serial_init(void);
111extern void omap_serial_init_port(struct omap_board_data *bdata);
112extern int omap_uart_can_sleep(void); 113extern int omap_uart_can_sleep(void);
113extern void omap_uart_check_wakeup(void); 114extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
114extern void omap_uart_prepare_suspend(void); 115extern void omap_serial_init_port(struct omap_board_data *bdata,
115extern void omap_uart_prepare_idle(int num); 116 struct omap_uart_port_info *platform_data);
116extern void omap_uart_resume_idle(int num);
117extern void omap_uart_enable_irqs(int enable);
118#endif 117#endif
119 118
120#endif 119#endif
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index f500fc34d06..75aa1b2bef5 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -95,6 +95,10 @@ static inline void omap_push_sram_idle(void) {}
95 */ 95 */
96#define OMAP2_SRAM_PA 0x40200000 96#define OMAP2_SRAM_PA 0x40200000
97#define OMAP3_SRAM_PA 0x40200000 97#define OMAP3_SRAM_PA 0x40200000
98#ifdef CONFIG_OMAP4_ERRATA_I688
99#define OMAP4_SRAM_PA 0x40304000
100#define OMAP4_SRAM_VA 0xfe404000
101#else
98#define OMAP4_SRAM_PA 0x40300000 102#define OMAP4_SRAM_PA 0x40300000
99 103#endif
100#endif 104#endif
diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti81xx.h
index 50510f5dda1..8f9843f7842 100644
--- a/arch/arm/plat-omap/include/plat/ti816x.h
+++ b/arch/arm/plat-omap/include/plat/ti81xx.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * This file contains the address data for various TI816X modules. 2 * This file contains the address data for various TI81XX modules.
3 * 3 *
4 * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ 4 * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
5 * 5 *
@@ -13,15 +13,15 @@
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 */ 14 */
15 15
16#ifndef __ASM_ARCH_TI816X_H 16#ifndef __ASM_ARCH_TI81XX_H
17#define __ASM_ARCH_TI816X_H 17#define __ASM_ARCH_TI81XX_H
18 18
19#define L4_SLOW_TI816X_BASE 0x48000000 19#define L4_SLOW_TI81XX_BASE 0x48000000
20 20
21#define TI816X_SCM_BASE 0x48140000 21#define TI81XX_SCM_BASE 0x48140000
22#define TI816X_CTRL_BASE TI816X_SCM_BASE 22#define TI81XX_CTRL_BASE TI81XX_SCM_BASE
23#define TI816X_PRCM_BASE 0x48180000 23#define TI81XX_PRCM_BASE 0x48180000
24 24
25#define TI816X_ARM_INTC_BASE 0x48200000 25#define TI81XX_ARM_INTC_BASE 0x48200000
26 26
27#endif /* __ASM_ARCH_TI816X_H */ 27#endif /* __ASM_ARCH_TI81XX_H */
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index 2f472e989ec..6ee90495ca4 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -99,9 +99,9 @@ static inline void flush(void)
99#define DEBUG_LL_ZOOM(mach) \ 99#define DEBUG_LL_ZOOM(mach) \
100 _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) 100 _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART)
101 101
102#define DEBUG_LL_TI816X(p, mach) \ 102#define DEBUG_LL_TI81XX(p, mach) \
103 _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \ 103 _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT, \
104 TI816XUART##p) 104 TI81XXUART##p)
105 105
106static inline void __arch_decomp_setup(unsigned long arch_id) 106static inline void __arch_decomp_setup(unsigned long arch_id)
107{ 107{
@@ -177,7 +177,10 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
177 DEBUG_LL_ZOOM(omap_zoom3); 177 DEBUG_LL_ZOOM(omap_zoom3);
178 178
179 /* TI8168 base boards using UART3 */ 179 /* TI8168 base boards using UART3 */
180 DEBUG_LL_TI816X(3, ti8168evm); 180 DEBUG_LL_TI81XX(3, ti8168evm);
181
182 /* TI8148 base boards using UART1 */
183 DEBUG_LL_TI81XX(1, ti8148evm);
181 184
182 } while (0); 185 } while (0);
183} 186}
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 17d3c939775..dc864b580da 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data);
100 100
101extern void usbhs_init(const struct usbhs_omap_board_data *pdata); 101extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
102 102
103extern int omap_usbhs_enable(struct device *dev);
104extern void omap_usbhs_disable(struct device *dev);
105
106extern int omap4430_phy_power(struct device *dev, int ID, int on); 103extern int omap4430_phy_power(struct device *dev, int ID, int on);
107extern int omap4430_phy_set_clk(struct device *dev, int on); 104extern int omap4430_phy_set_clk(struct device *dev, int on);
108extern int omap4430_phy_init(struct device *dev); 105extern int omap4430_phy_init(struct device *dev);
@@ -114,6 +111,7 @@ extern void am35x_musb_reset(void);
114extern void am35x_musb_phy_power(u8 on); 111extern void am35x_musb_phy_power(u8 on);
115extern void am35x_musb_clear_irq(void); 112extern void am35x_musb_clear_irq(void);
116extern void am35x_set_mode(u8 musb_mode); 113extern void am35x_set_mode(u8 musb_mode);
114extern void ti81xx_musb_phy_power(u8 on);
117 115
118/* 116/*
119 * FIXME correct answer depends on hmc_mode, 117 * FIXME correct answer depends on hmc_mode,
@@ -273,6 +271,37 @@ static inline void omap2_usbfs_init(struct omap_usb_config *pdata)
273#define CONF2_OTGPWRDN (1 << 2) 271#define CONF2_OTGPWRDN (1 << 2)
274#define CONF2_DATPOL (1 << 1) 272#define CONF2_DATPOL (1 << 1)
275 273
274/* TI81XX specific definitions */
275#define USBCTRL0 0x620
276#define USBSTAT0 0x624
277
278/* TI816X PHY controls bits */
279#define TI816X_USBPHY0_NORMAL_MODE (1 << 0)
280#define TI816X_USBPHY_REFCLK_OSC (1 << 8)
281
282/* TI814X PHY controls bits */
283#define USBPHY_CM_PWRDN (1 << 0)
284#define USBPHY_OTG_PWRDN (1 << 1)
285#define USBPHY_CHGDET_DIS (1 << 2)
286#define USBPHY_CHGDET_RSTRT (1 << 3)
287#define USBPHY_SRCONDM (1 << 4)
288#define USBPHY_SINKONDP (1 << 5)
289#define USBPHY_CHGISINK_EN (1 << 6)
290#define USBPHY_CHGVSRC_EN (1 << 7)
291#define USBPHY_DMPULLUP (1 << 8)
292#define USBPHY_DPPULLUP (1 << 9)
293#define USBPHY_CDET_EXTCTL (1 << 10)
294#define USBPHY_GPIO_MODE (1 << 12)
295#define USBPHY_DPOPBUFCTL (1 << 13)
296#define USBPHY_DMOPBUFCTL (1 << 14)
297#define USBPHY_DPINPUT (1 << 15)
298#define USBPHY_DMINPUT (1 << 16)
299#define USBPHY_DPGPIO_PD (1 << 17)
300#define USBPHY_DMGPIO_PD (1 << 18)
301#define USBPHY_OTGVDET_EN (1 << 19)
302#define USBPHY_OTGSESSEND_EN (1 << 20)
303#define USBPHY_DATA_POLARITY (1 << 23)
304
276#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB) 305#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB)
277u32 omap1_usb0_init(unsigned nwires, unsigned is_device); 306u32 omap1_usb0_init(unsigned nwires, unsigned is_device);
278u32 omap1_usb1_init(unsigned nwires); 307u32 omap1_usb1_init(unsigned nwires);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 8b28664d1c6..4243bdcc87b 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -40,7 +40,11 @@
40#define OMAP1_SRAM_PA 0x20000000 40#define OMAP1_SRAM_PA 0x20000000
41#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) 41#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
42#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) 42#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
43#ifdef CONFIG_OMAP4_ERRATA_I688
44#define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA
45#else
43#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) 46#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
47#endif
44 48
45#if defined(CONFIG_ARCH_OMAP2PLUS) 49#if defined(CONFIG_ARCH_OMAP2PLUS)
46#define SRAM_BOOTLOADER_SZ 0x00 50#define SRAM_BOOTLOADER_SZ 0x00
@@ -141,11 +145,9 @@ static void __init omap_detect_sram(void)
141 omap_sram_size = 0x32000; /* 200K */ 145 omap_sram_size = 0x32000; /* 200K */
142 else if (cpu_is_omap15xx()) 146 else if (cpu_is_omap15xx())
143 omap_sram_size = 0x30000; /* 192K */ 147 omap_sram_size = 0x30000; /* 192K */
144 else if (cpu_is_omap1610() || cpu_is_omap1621() || 148 else if (cpu_is_omap1610() || cpu_is_omap1611() ||
145 cpu_is_omap1710()) 149 cpu_is_omap1621() || cpu_is_omap1710())
146 omap_sram_size = 0x4000; /* 16K */ 150 omap_sram_size = 0x4000; /* 16K */
147 else if (cpu_is_omap1611())
148 omap_sram_size = SZ_256K;
149 else { 151 else {
150 pr_err("Could not detect SRAM size\n"); 152 pr_err("Could not detect SRAM size\n");
151 omap_sram_size = 0x4000; 153 omap_sram_size = 0x4000;
@@ -163,6 +165,10 @@ static void __init omap_map_sram(void)
163 if (omap_sram_size == 0) 165 if (omap_sram_size == 0)
164 return; 166 return;
165 167
168#ifdef CONFIG_OMAP4_ERRATA_I688
169 omap_sram_start += PAGE_SIZE;
170 omap_sram_size -= SZ_16K;
171#endif
166 if (cpu_is_omap34xx()) { 172 if (cpu_is_omap34xx()) {
167 /* 173 /*
168 * SRAM must be marked as non-cached on OMAP3 since the 174 * SRAM must be marked as non-cached on OMAP3 since the
@@ -224,6 +230,9 @@ static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
224void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) 230void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
225{ 231{
226 BUG_ON(!_omap_sram_reprogram_clock); 232 BUG_ON(!_omap_sram_reprogram_clock);
233 /* On 730, bit 13 must always be 1 */
234 if (cpu_is_omap7xx())
235 ckctl |= 0x2000;
227 _omap_sram_reprogram_clock(dpllctl, ckctl); 236 _omap_sram_reprogram_clock(dpllctl, ckctl);
228} 237}
229 238
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
index 95a5fc53b6d..c20ce0f5ce3 100644
--- a/arch/arm/plat-orion/Makefile
+++ b/arch/arm/plat-orion/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := irq.o pcie.o time.o common.o mpp.o 5obj-y := irq.o pcie.o time.o common.o mpp.o addr-map.o
6obj-m := 6obj-m :=
7obj-n := 7obj-n :=
8obj- := 8obj- :=
diff --git a/arch/arm/plat-orion/addr-map.c b/arch/arm/plat-orion/addr-map.c
new file mode 100644
index 00000000000..367ca89ac40
--- /dev/null
+++ b/arch/arm/plat-orion/addr-map.c
@@ -0,0 +1,174 @@
1/*
2 * arch/arm/plat-orion/addr-map.c
3 *
4 * Address map functions for Marvell Orion based SoCs
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/mbus.h>
15#include <linux/io.h>
16#include <plat/addr-map.h>
17
18struct mbus_dram_target_info orion_mbus_dram_info;
19
20const struct mbus_dram_target_info *mv_mbus_dram_info(void)
21{
22 return &orion_mbus_dram_info;
23}
24EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
25
26/*
27 * DDR target is the same on all Orion platforms.
28 */
29#define TARGET_DDR 0
30
31/*
32 * Helpers to get DDR bank info
33 */
34#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
35#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
36
37/*
38 * CPU Address Decode Windows registers
39 */
40#define WIN_CTRL_OFF 0x0000
41#define WIN_BASE_OFF 0x0004
42#define WIN_REMAP_LO_OFF 0x0008
43#define WIN_REMAP_HI_OFF 0x000c
44
45/*
46 * Default implementation
47 */
48static void __init __iomem *
49orion_win_cfg_base(const struct orion_addr_map_cfg *cfg, int win)
50{
51 return (void __iomem *)(cfg->bridge_virt_base + (win << 4));
52}
53
54/*
55 * Default implementation
56 */
57static int __init orion_cpu_win_can_remap(const struct orion_addr_map_cfg *cfg,
58 const int win)
59{
60 if (win < cfg->remappable_wins)
61 return 1;
62
63 return 0;
64}
65
66void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
67 const int win, const u32 base,
68 const u32 size, const u8 target,
69 const u8 attr, const int remap)
70{
71 void __iomem *addr = cfg->win_cfg_base(cfg, win);
72 u32 ctrl, base_high, remap_addr;
73
74 if (win >= cfg->num_wins) {
75 printk(KERN_ERR "setup_cpu_win: trying to allocate window "
76 "%d when only %d allowed\n", win, cfg->num_wins);
77 }
78
79 base_high = base & 0xffff0000;
80 ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
81
82 writel(base_high, addr + WIN_BASE_OFF);
83 writel(ctrl, addr + WIN_CTRL_OFF);
84 if (cfg->cpu_win_can_remap(cfg, win)) {
85 if (remap < 0)
86 remap_addr = base;
87 else
88 remap_addr = remap;
89 writel(remap_addr & 0xffff0000, addr + WIN_REMAP_LO_OFF);
90 writel(0, addr + WIN_REMAP_HI_OFF);
91 }
92}
93
94/*
95 * Configure a number of windows.
96 */
97static void __init orion_setup_cpu_wins(const struct orion_addr_map_cfg * cfg,
98 const struct orion_addr_map_info *info)
99{
100 while (info->win != -1) {
101 orion_setup_cpu_win(cfg, info->win, info->base, info->size,
102 info->target, info->attr, info->remap);
103 info++;
104 }
105}
106
107static void __init orion_disable_wins(const struct orion_addr_map_cfg * cfg)
108{
109 void __iomem *addr;
110 int i;
111
112 for (i = 0; i < cfg->num_wins; i++) {
113 addr = cfg->win_cfg_base(cfg, i);
114
115 writel(0, addr + WIN_BASE_OFF);
116 writel(0, addr + WIN_CTRL_OFF);
117 if (cfg->cpu_win_can_remap(cfg, i)) {
118 writel(0, addr + WIN_REMAP_LO_OFF);
119 writel(0, addr + WIN_REMAP_HI_OFF);
120 }
121 }
122}
123
124/*
125 * Disable, clear and configure windows.
126 */
127void __init orion_config_wins(struct orion_addr_map_cfg * cfg,
128 const struct orion_addr_map_info *info)
129{
130 if (!cfg->cpu_win_can_remap)
131 cfg->cpu_win_can_remap = orion_cpu_win_can_remap;
132
133 if (!cfg->win_cfg_base)
134 cfg->win_cfg_base = orion_win_cfg_base;
135
136 orion_disable_wins(cfg);
137
138 if (info)
139 orion_setup_cpu_wins(cfg, info);
140}
141
142/*
143 * Setup MBUS dram target info.
144 */
145void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
146 const u32 ddr_window_cpu_base)
147{
148 void __iomem *addr;
149 int i;
150 int cs;
151
152 orion_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
153
154 addr = (void __iomem *)ddr_window_cpu_base;
155
156 for (i = 0, cs = 0; i < 4; i++) {
157 u32 base = readl(addr + DDR_BASE_CS_OFF(i));
158 u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
159
160 /*
161 * Chip select enabled?
162 */
163 if (size & 1) {
164 struct mbus_dram_window *w;
165
166 w = &orion_mbus_dram_info.cs[cs++];
167 w->cs_index = i;
168 w->mbus_attr = 0xf & ~(1 << i);
169 w->base = base & 0xffff0000;
170 w->size = (size | 0x0000ffff) + 1;
171 }
172 }
173 orion_mbus_dram_info.num_cs = cs;
174}
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
index 9e5451b3c8e..e5a2fde29b1 100644
--- a/arch/arm/plat-orion/common.c
+++ b/arch/arm/plat-orion/common.c
@@ -13,7 +13,6 @@
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/serial_8250.h> 15#include <linux/serial_8250.h>
16#include <linux/mbus.h>
17#include <linux/ata_platform.h> 16#include <linux/ata_platform.h>
18#include <linux/mv643xx_eth.h> 17#include <linux/mv643xx_eth.h>
19#include <linux/mv643xx_i2c.h> 18#include <linux/mv643xx_i2c.h>
@@ -203,13 +202,12 @@ void __init orion_rtc_init(unsigned long mapbase,
203 ****************************************************************************/ 202 ****************************************************************************/
204static __init void ge_complete( 203static __init void ge_complete(
205 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, 204 struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
206 struct mbus_dram_target_info *mbus_dram_info, int tclk, 205 int tclk,
207 struct resource *orion_ge_resource, unsigned long irq, 206 struct resource *orion_ge_resource, unsigned long irq,
208 struct platform_device *orion_ge_shared, 207 struct platform_device *orion_ge_shared,
209 struct mv643xx_eth_platform_data *eth_data, 208 struct mv643xx_eth_platform_data *eth_data,
210 struct platform_device *orion_ge) 209 struct platform_device *orion_ge)
211{ 210{
212 orion_ge_shared_data->dram = mbus_dram_info;
213 orion_ge_shared_data->t_clk = tclk; 211 orion_ge_shared_data->t_clk = tclk;
214 orion_ge_resource->start = irq; 212 orion_ge_resource->start = irq;
215 orion_ge_resource->end = irq; 213 orion_ge_resource->end = irq;
@@ -259,7 +257,6 @@ static struct platform_device orion_ge00 = {
259}; 257};
260 258
261void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, 259void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
262 struct mbus_dram_target_info *mbus_dram_info,
263 unsigned long mapbase, 260 unsigned long mapbase,
264 unsigned long irq, 261 unsigned long irq,
265 unsigned long irq_err, 262 unsigned long irq_err,
@@ -267,7 +264,7 @@ void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
267{ 264{
268 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, 265 fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
269 mapbase + 0x2000, SZ_16K - 1, irq_err); 266 mapbase + 0x2000, SZ_16K - 1, irq_err);
270 ge_complete(&orion_ge00_shared_data, mbus_dram_info, tclk, 267 ge_complete(&orion_ge00_shared_data, tclk,
271 orion_ge00_resources, irq, &orion_ge00_shared, 268 orion_ge00_resources, irq, &orion_ge00_shared,
272 eth_data, &orion_ge00); 269 eth_data, &orion_ge00);
273} 270}
@@ -313,7 +310,6 @@ static struct platform_device orion_ge01 = {
313}; 310};
314 311
315void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, 312void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
316 struct mbus_dram_target_info *mbus_dram_info,
317 unsigned long mapbase, 313 unsigned long mapbase,
318 unsigned long irq, 314 unsigned long irq,
319 unsigned long irq_err, 315 unsigned long irq_err,
@@ -321,7 +317,7 @@ void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
321{ 317{
322 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, 318 fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
323 mapbase + 0x2000, SZ_16K - 1, irq_err); 319 mapbase + 0x2000, SZ_16K - 1, irq_err);
324 ge_complete(&orion_ge01_shared_data, mbus_dram_info, tclk, 320 ge_complete(&orion_ge01_shared_data, tclk,
325 orion_ge01_resources, irq, &orion_ge01_shared, 321 orion_ge01_resources, irq, &orion_ge01_shared,
326 eth_data, &orion_ge01); 322 eth_data, &orion_ge01);
327} 323}
@@ -367,7 +363,6 @@ static struct platform_device orion_ge10 = {
367}; 363};
368 364
369void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, 365void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
370 struct mbus_dram_target_info *mbus_dram_info,
371 unsigned long mapbase, 366 unsigned long mapbase,
372 unsigned long irq, 367 unsigned long irq,
373 unsigned long irq_err, 368 unsigned long irq_err,
@@ -375,7 +370,7 @@ void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
375{ 370{
376 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, 371 fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
377 mapbase + 0x2000, SZ_16K - 1, irq_err); 372 mapbase + 0x2000, SZ_16K - 1, irq_err);
378 ge_complete(&orion_ge10_shared_data, mbus_dram_info, tclk, 373 ge_complete(&orion_ge10_shared_data, tclk,
379 orion_ge10_resources, irq, &orion_ge10_shared, 374 orion_ge10_resources, irq, &orion_ge10_shared,
380 eth_data, &orion_ge10); 375 eth_data, &orion_ge10);
381} 376}
@@ -421,7 +416,6 @@ static struct platform_device orion_ge11 = {
421}; 416};
422 417
423void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, 418void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
424 struct mbus_dram_target_info *mbus_dram_info,
425 unsigned long mapbase, 419 unsigned long mapbase,
426 unsigned long irq, 420 unsigned long irq,
427 unsigned long irq_err, 421 unsigned long irq_err,
@@ -429,7 +423,7 @@ void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
429{ 423{
430 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, 424 fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
431 mapbase + 0x2000, SZ_16K - 1, irq_err); 425 mapbase + 0x2000, SZ_16K - 1, irq_err);
432 ge_complete(&orion_ge11_shared_data, mbus_dram_info, tclk, 426 ge_complete(&orion_ge11_shared_data, tclk,
433 orion_ge11_resources, irq, &orion_ge11_shared, 427 orion_ge11_resources, irq, &orion_ge11_shared,
434 eth_data, &orion_ge11); 428 eth_data, &orion_ge11);
435} 429}
@@ -592,8 +586,6 @@ void __init orion_wdt_init(unsigned long tclk)
592/***************************************************************************** 586/*****************************************************************************
593 * XOR 587 * XOR
594 ****************************************************************************/ 588 ****************************************************************************/
595static struct mv_xor_platform_shared_data orion_xor_shared_data;
596
597static u64 orion_xor_dmamask = DMA_BIT_MASK(32); 589static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
598 590
599void __init orion_xor_init_channels( 591void __init orion_xor_init_channels(
@@ -632,9 +624,6 @@ static struct resource orion_xor0_shared_resources[] = {
632static struct platform_device orion_xor0_shared = { 624static struct platform_device orion_xor0_shared = {
633 .name = MV_XOR_SHARED_NAME, 625 .name = MV_XOR_SHARED_NAME,
634 .id = 0, 626 .id = 0,
635 .dev = {
636 .platform_data = &orion_xor_shared_data,
637 },
638 .num_resources = ARRAY_SIZE(orion_xor0_shared_resources), 627 .num_resources = ARRAY_SIZE(orion_xor0_shared_resources),
639 .resource = orion_xor0_shared_resources, 628 .resource = orion_xor0_shared_resources,
640}; 629};
@@ -687,14 +676,11 @@ static struct platform_device orion_xor01_channel = {
687 }, 676 },
688}; 677};
689 678
690void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info, 679void __init orion_xor0_init(unsigned long mapbase_low,
691 unsigned long mapbase_low,
692 unsigned long mapbase_high, 680 unsigned long mapbase_high,
693 unsigned long irq_0, 681 unsigned long irq_0,
694 unsigned long irq_1) 682 unsigned long irq_1)
695{ 683{
696 orion_xor_shared_data.dram = mbus_dram_info;
697
698 orion_xor0_shared_resources[0].start = mapbase_low; 684 orion_xor0_shared_resources[0].start = mapbase_low;
699 orion_xor0_shared_resources[0].end = mapbase_low + 0xff; 685 orion_xor0_shared_resources[0].end = mapbase_low + 0xff;
700 orion_xor0_shared_resources[1].start = mapbase_high; 686 orion_xor0_shared_resources[1].start = mapbase_high;
@@ -727,9 +713,6 @@ static struct resource orion_xor1_shared_resources[] = {
727static struct platform_device orion_xor1_shared = { 713static struct platform_device orion_xor1_shared = {
728 .name = MV_XOR_SHARED_NAME, 714 .name = MV_XOR_SHARED_NAME,
729 .id = 1, 715 .id = 1,
730 .dev = {
731 .platform_data = &orion_xor_shared_data,
732 },
733 .num_resources = ARRAY_SIZE(orion_xor1_shared_resources), 716 .num_resources = ARRAY_SIZE(orion_xor1_shared_resources),
734 .resource = orion_xor1_shared_resources, 717 .resource = orion_xor1_shared_resources,
735}; 718};
@@ -828,11 +811,9 @@ static struct platform_device orion_ehci = {
828 }, 811 },
829}; 812};
830 813
831void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, 814void __init orion_ehci_init(unsigned long mapbase,
832 unsigned long mapbase,
833 unsigned long irq) 815 unsigned long irq)
834{ 816{
835 orion_ehci_data.dram = mbus_dram_info;
836 fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1, 817 fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1,
837 irq); 818 irq);
838 819
@@ -854,11 +835,9 @@ static struct platform_device orion_ehci_1 = {
854 }, 835 },
855}; 836};
856 837
857void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info, 838void __init orion_ehci_1_init(unsigned long mapbase,
858 unsigned long mapbase,
859 unsigned long irq) 839 unsigned long irq)
860{ 840{
861 orion_ehci_data.dram = mbus_dram_info;
862 fill_resources(&orion_ehci_1, orion_ehci_1_resources, 841 fill_resources(&orion_ehci_1, orion_ehci_1_resources,
863 mapbase, SZ_4K - 1, irq); 842 mapbase, SZ_4K - 1, irq);
864 843
@@ -880,11 +859,9 @@ static struct platform_device orion_ehci_2 = {
880 }, 859 },
881}; 860};
882 861
883void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info, 862void __init orion_ehci_2_init(unsigned long mapbase,
884 unsigned long mapbase,
885 unsigned long irq) 863 unsigned long irq)
886{ 864{
887 orion_ehci_data.dram = mbus_dram_info;
888 fill_resources(&orion_ehci_2, orion_ehci_2_resources, 865 fill_resources(&orion_ehci_2, orion_ehci_2_resources,
889 mapbase, SZ_4K - 1, irq); 866 mapbase, SZ_4K - 1, irq);
890 867
@@ -911,11 +888,9 @@ static struct platform_device orion_sata = {
911}; 888};
912 889
913void __init orion_sata_init(struct mv_sata_platform_data *sata_data, 890void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
914 struct mbus_dram_target_info *mbus_dram_info,
915 unsigned long mapbase, 891 unsigned long mapbase,
916 unsigned long irq) 892 unsigned long irq)
917{ 893{
918 sata_data->dram = mbus_dram_info;
919 orion_sata.dev.platform_data = sata_data; 894 orion_sata.dev.platform_data = sata_data;
920 fill_resources(&orion_sata, orion_sata_resources, 895 fill_resources(&orion_sata, orion_sata_resources,
921 mapbase, 0x5000 - 1, irq); 896 mapbase, 0x5000 - 1, irq);
diff --git a/arch/arm/plat-orion/include/plat/addr-map.h b/arch/arm/plat-orion/include/plat/addr-map.h
new file mode 100644
index 00000000000..fd556f77562
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/addr-map.h
@@ -0,0 +1,53 @@
1/*
2 * arch/arm/plat-orion/include/plat/addr-map.h
3 *
4 * Marvell Orion SoC address map handling.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#ifndef __PLAT_ADDR_MAP_H
12#define __PLAT_ADDR_MAP_H
13
14extern struct mbus_dram_target_info orion_mbus_dram_info;
15
16struct orion_addr_map_cfg {
17 const int num_wins; /* Total number of windows */
18 const int remappable_wins;
19 const u32 bridge_virt_base;
20
21 /* If NULL, the default cpu_win_can_remap will be used, using
22 the value in remappable_wins */
23 int (*cpu_win_can_remap) (const struct orion_addr_map_cfg *cfg,
24 const int win);
25 /* If NULL, the default win_cfg_base will be used, using the
26 value in bridge_virt_base */
27 void __iomem *(*win_cfg_base) (const struct orion_addr_map_cfg *cfg,
28 const int win);
29};
30
31/*
32 * Information needed to setup one address mapping.
33 */
34struct orion_addr_map_info {
35 const int win;
36 const u32 base;
37 const u32 size;
38 const u8 target;
39 const u8 attr;
40 const int remap;
41};
42
43void __init orion_config_wins(struct orion_addr_map_cfg *cfg,
44 const struct orion_addr_map_info *info);
45
46void __init orion_setup_cpu_win(const struct orion_addr_map_cfg *cfg,
47 const int win, const u32 base,
48 const u32 size, const u8 target,
49 const u8 attr, const int remap);
50
51void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
52 const u32 ddr_window_cpu_base);
53#endif
diff --git a/arch/arm/plat-orion/include/plat/audio.h b/arch/arm/plat-orion/include/plat/audio.h
index 9cf1f781329..885f8abd927 100644
--- a/arch/arm/plat-orion/include/plat/audio.h
+++ b/arch/arm/plat-orion/include/plat/audio.h
@@ -1,11 +1,8 @@
1#ifndef __PLAT_AUDIO_H 1#ifndef __PLAT_AUDIO_H
2#define __PLAT_AUDIO_H 2#define __PLAT_AUDIO_H
3 3
4#include <linux/mbus.h>
5
6struct kirkwood_asoc_platform_data { 4struct kirkwood_asoc_platform_data {
7 u32 tclk; 5 u32 tclk;
8 struct mbus_dram_target_info *dram;
9 int burst; 6 int burst;
10}; 7};
11#endif 8#endif
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
index a63c357e2ab..0fe08d77e83 100644
--- a/arch/arm/plat-orion/include/plat/common.h
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -37,28 +37,24 @@ void __init orion_rtc_init(unsigned long mapbase,
37 unsigned long irq); 37 unsigned long irq);
38 38
39void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, 39void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
40 struct mbus_dram_target_info *mbus_dram_info,
41 unsigned long mapbase, 40 unsigned long mapbase,
42 unsigned long irq, 41 unsigned long irq,
43 unsigned long irq_err, 42 unsigned long irq_err,
44 int tclk); 43 int tclk);
45 44
46void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, 45void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
47 struct mbus_dram_target_info *mbus_dram_info,
48 unsigned long mapbase, 46 unsigned long mapbase,
49 unsigned long irq, 47 unsigned long irq,
50 unsigned long irq_err, 48 unsigned long irq_err,
51 int tclk); 49 int tclk);
52 50
53void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, 51void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
54 struct mbus_dram_target_info *mbus_dram_info,
55 unsigned long mapbase, 52 unsigned long mapbase,
56 unsigned long irq, 53 unsigned long irq,
57 unsigned long irq_err, 54 unsigned long irq_err,
58 int tclk); 55 int tclk);
59 56
60void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, 57void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
61 struct mbus_dram_target_info *mbus_dram_info,
62 unsigned long mapbase, 58 unsigned long mapbase,
63 unsigned long irq, 59 unsigned long irq,
64 unsigned long irq_err, 60 unsigned long irq_err,
@@ -82,8 +78,7 @@ void __init orion_spi_1_init(unsigned long mapbase,
82 78
83void __init orion_wdt_init(unsigned long tclk); 79void __init orion_wdt_init(unsigned long tclk);
84 80
85void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info, 81void __init orion_xor0_init(unsigned long mapbase_low,
86 unsigned long mapbase_low,
87 unsigned long mapbase_high, 82 unsigned long mapbase_high,
88 unsigned long irq_0, 83 unsigned long irq_0,
89 unsigned long irq_1); 84 unsigned long irq_1);
@@ -93,20 +88,16 @@ void __init orion_xor1_init(unsigned long mapbase_low,
93 unsigned long irq_0, 88 unsigned long irq_0,
94 unsigned long irq_1); 89 unsigned long irq_1);
95 90
96void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info, 91void __init orion_ehci_init(unsigned long mapbase,
97 unsigned long mapbase,
98 unsigned long irq); 92 unsigned long irq);
99 93
100void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info, 94void __init orion_ehci_1_init(unsigned long mapbase,
101 unsigned long mapbase,
102 unsigned long irq); 95 unsigned long irq);
103 96
104void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info, 97void __init orion_ehci_2_init(unsigned long mapbase,
105 unsigned long mapbase,
106 unsigned long irq); 98 unsigned long irq);
107 99
108void __init orion_sata_init(struct mv_sata_platform_data *sata_data, 100void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
109 struct mbus_dram_target_info *mbus_dram_info,
110 unsigned long mapbase, 101 unsigned long mapbase,
111 unsigned long irq); 102 unsigned long irq);
112 103
diff --git a/arch/arm/plat-orion/include/plat/ehci-orion.h b/arch/arm/plat-orion/include/plat/ehci-orion.h
index 4ec668e7746..6fc78e43042 100644
--- a/arch/arm/plat-orion/include/plat/ehci-orion.h
+++ b/arch/arm/plat-orion/include/plat/ehci-orion.h
@@ -19,7 +19,6 @@ enum orion_ehci_phy_ver {
19}; 19};
20 20
21struct orion_ehci_data { 21struct orion_ehci_data {
22 struct mbus_dram_target_info *dram;
23 enum orion_ehci_phy_ver phy_version; 22 enum orion_ehci_phy_ver phy_version;
24}; 23};
25 24
diff --git a/arch/arm/plat-orion/include/plat/mv_xor.h b/arch/arm/plat-orion/include/plat/mv_xor.h
index bd5f3bdb4ae..2ba1f7d76ee 100644
--- a/arch/arm/plat-orion/include/plat/mv_xor.h
+++ b/arch/arm/plat-orion/include/plat/mv_xor.h
@@ -13,12 +13,6 @@
13#define MV_XOR_SHARED_NAME "mv_xor_shared" 13#define MV_XOR_SHARED_NAME "mv_xor_shared"
14#define MV_XOR_NAME "mv_xor" 14#define MV_XOR_NAME "mv_xor"
15 15
16struct mbus_dram_target_info;
17
18struct mv_xor_platform_shared_data {
19 struct mbus_dram_target_info *dram;
20};
21
22struct mv_xor_platform_data { 16struct mv_xor_platform_data {
23 struct platform_device *shared; 17 struct platform_device *shared;
24 int hw_id; 18 int hw_id;
diff --git a/arch/arm/plat-orion/include/plat/mvsdio.h b/arch/arm/plat-orion/include/plat/mvsdio.h
index 14ca8867600..1190efedcb9 100644
--- a/arch/arm/plat-orion/include/plat/mvsdio.h
+++ b/arch/arm/plat-orion/include/plat/mvsdio.h
@@ -12,7 +12,6 @@
12#include <linux/mbus.h> 12#include <linux/mbus.h>
13 13
14struct mvsdio_platform_data { 14struct mvsdio_platform_data {
15 struct mbus_dram_target_info *dram;
16 unsigned int clock; 15 unsigned int clock;
17 int gpio_card_detect; 16 int gpio_card_detect;
18 int gpio_write_protect; 17 int gpio_write_protect;
diff --git a/arch/arm/plat-orion/include/plat/pcie.h b/arch/arm/plat-orion/include/plat/pcie.h
index cc99163e73f..fe5b9e86274 100644
--- a/arch/arm/plat-orion/include/plat/pcie.h
+++ b/arch/arm/plat-orion/include/plat/pcie.h
@@ -20,8 +20,7 @@ int orion_pcie_x4_mode(void __iomem *base);
20int orion_pcie_get_local_bus_nr(void __iomem *base); 20int orion_pcie_get_local_bus_nr(void __iomem *base);
21void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); 21void orion_pcie_set_local_bus_nr(void __iomem *base, int nr);
22void orion_pcie_reset(void __iomem *base); 22void orion_pcie_reset(void __iomem *base);
23void orion_pcie_setup(void __iomem *base, 23void orion_pcie_setup(void __iomem *base);
24 struct mbus_dram_target_info *dram);
25int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, 24int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus,
26 u32 devfn, int where, int size, u32 *val); 25 u32 devfn, int where, int size, u32 *val);
27int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus, 26int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus,
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
index af2d733c50b..86dbb5bdb17 100644
--- a/arch/arm/plat-orion/pcie.c
+++ b/arch/arm/plat-orion/pcie.c
@@ -13,6 +13,7 @@
13#include <linux/mbus.h> 13#include <linux/mbus.h>
14#include <asm/mach/pci.h> 14#include <asm/mach/pci.h>
15#include <plat/pcie.h> 15#include <plat/pcie.h>
16#include <plat/addr-map.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17 18
18/* 19/*
@@ -175,8 +176,7 @@ static void __init orion_pcie_setup_wins(void __iomem *base,
175 writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1)); 176 writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
176} 177}
177 178
178void __init orion_pcie_setup(void __iomem *base, 179void __init orion_pcie_setup(void __iomem *base)
179 struct mbus_dram_target_info *dram)
180{ 180{
181 u16 cmd; 181 u16 cmd;
182 u32 mask; 182 u32 mask;
@@ -184,7 +184,7 @@ void __init orion_pcie_setup(void __iomem *base,
184 /* 184 /*
185 * Point PCIe unit MBUS decode windows to DRAM space. 185 * Point PCIe unit MBUS decode windows to DRAM space.
186 */ 186 */
187 orion_pcie_setup_wins(base, dram); 187 orion_pcie_setup_wins(base, &orion_mbus_dram_info);
188 188
189 /* 189 /*
190 * Master + slave enable. 190 * Master + slave enable.
diff --git a/arch/arm/plat-pxa/include/plat/gpio-pxa.h b/arch/arm/plat-pxa/include/plat/gpio-pxa.h
deleted file mode 100644
index b6390beff32..00000000000
--- a/arch/arm/plat-pxa/include/plat/gpio-pxa.h
+++ /dev/null
@@ -1,44 +0,0 @@
1#ifndef __PLAT_PXA_GPIO_H
2#define __PLAT_PXA_GPIO_H
3
4struct irq_data;
5
6/*
7 * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
8 * one set of registers. The register offsets are organized below:
9 *
10 * GPLR GPDR GPSR GPCR GRER GFER GEDR
11 * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048
12 * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C
13 * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050
14 *
15 * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148
16 * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C
17 * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150
18 *
19 * NOTE:
20 * BANK 3 is only available on PXA27x and later processors.
21 * BANK 4 and 5 are only available on PXA935
22 */
23
24#define GPIO_BANK(n) (GPIO_REGS_VIRT + BANK_OFF(n))
25
26#define GPLR_OFFSET 0x00
27#define GPDR_OFFSET 0x0C
28#define GPSR_OFFSET 0x18
29#define GPCR_OFFSET 0x24
30#define GRER_OFFSET 0x30
31#define GFER_OFFSET 0x3C
32#define GEDR_OFFSET 0x48
33
34/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
35 * Those cases currently cause holes in the GPIO number space, the
36 * actual number of the last GPIO is recorded by 'pxa_last_gpio'.
37 */
38extern int pxa_last_gpio;
39
40typedef int (*set_wake_t)(struct irq_data *d, unsigned int on);
41
42extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
43
44#endif /* __PLAT_PXA_GPIO_H */
diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h
deleted file mode 100644
index 258f77210b0..00000000000
--- a/arch/arm/plat-pxa/include/plat/gpio.h
+++ /dev/null
@@ -1,30 +0,0 @@
1#ifndef __PLAT_GPIO_H
2#define __PLAT_GPIO_H
3
4#define __ARM_GPIOLIB_COMPLEX
5
6/* The individual machine provides register offsets and NR_BUILTIN_GPIO */
7#include <mach/gpio-pxa.h>
8
9static inline int gpio_get_value(unsigned gpio)
10{
11 if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
12 return GPLR(gpio) & GPIO_bit(gpio);
13 else
14 return __gpio_get_value(gpio);
15}
16
17static inline void gpio_set_value(unsigned gpio, int value)
18{
19 if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
20 if (value)
21 GPSR(gpio) = GPIO_bit(gpio);
22 else
23 GPCR(gpio) = GPIO_bit(gpio);
24 } else
25 __gpio_set_value(gpio, value);
26}
27
28#define gpio_cansleep __gpio_cansleep
29
30#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 53754bcf15a..9fe35348e03 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1437,11 +1437,10 @@ int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
1437 size_t map_sz = sizeof(*nmap) * sel->map_size; 1437 size_t map_sz = sizeof(*nmap) * sel->map_size;
1438 int ptr; 1438 int ptr;
1439 1439
1440 nmap = kmalloc(map_sz, GFP_KERNEL); 1440 nmap = kmemdup(sel->map, map_sz, GFP_KERNEL);
1441 if (nmap == NULL) 1441 if (nmap == NULL)
1442 return -ENOMEM; 1442 return -ENOMEM;
1443 1443
1444 memcpy(nmap, sel->map, map_sz);
1445 memcpy(&dma_sel, sel, sizeof(*sel)); 1444 memcpy(&dma_sel, sel, sizeof(*sel));
1446 1445
1447 dma_sel.map = nmap; 1446 dma_sel.map = nmap;
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 5a21b15b2a9..95e68190d59 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -297,13 +297,6 @@ static struct clksrc_clk clk_usb_bus_host = {
297 297
298static struct clksrc_clk clksrc_clks[] = { 298static struct clksrc_clk clksrc_clks[] = {
299 { 299 {
300 /* ART baud-rate clock sourced from esysclk via a divisor */
301 .clk = {
302 .name = "uartclk",
303 .parent = &clk_esysclk.clk,
304 },
305 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
306 }, {
307 /* camera interface bus-clock, divided down from esysclk */ 300 /* camera interface bus-clock, divided down from esysclk */
308 .clk = { 301 .clk = {
309 .name = "camif-upll", /* same as 2440 name */ 302 .name = "camif-upll", /* same as 2440 name */
@@ -323,6 +316,15 @@ static struct clksrc_clk clksrc_clks[] = {
323 }, 316 },
324}; 317};
325 318
319static struct clksrc_clk clk_esys_uart = {
320 /* ART baud-rate clock sourced from esysclk via a divisor */
321 .clk = {
322 .name = "uartclk",
323 .parent = &clk_esysclk.clk,
324 },
325 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
326};
327
326static struct clk clk_i2s_ext = { 328static struct clk clk_i2s_ext = {
327 .name = "i2s-ext", 329 .name = "i2s-ext",
328}; 330};
@@ -425,12 +427,6 @@ static struct clk init_clocks[] = {
425 .enable = s3c2443_clkcon_enable_h, 427 .enable = s3c2443_clkcon_enable_h,
426 .ctrlbit = S3C2443_HCLKCON_DMA5, 428 .ctrlbit = S3C2443_HCLKCON_DMA5,
427 }, { 429 }, {
428 .name = "hsmmc",
429 .devname = "s3c-sdhci.1",
430 .parent = &clk_h,
431 .enable = s3c2443_clkcon_enable_h,
432 .ctrlbit = S3C2443_HCLKCON_HSMMC,
433 }, {
434 .name = "gpio", 430 .name = "gpio",
435 .parent = &clk_p, 431 .parent = &clk_p,
436 .enable = s3c2443_clkcon_enable_p, 432 .enable = s3c2443_clkcon_enable_p,
@@ -512,6 +508,14 @@ static struct clk init_clocks[] = {
512 } 508 }
513}; 509};
514 510
511static struct clk hsmmc1_clk = {
512 .name = "hsmmc",
513 .devname = "s3c-sdhci.1",
514 .parent = &clk_h,
515 .enable = s3c2443_clkcon_enable_h,
516 .ctrlbit = S3C2443_HCLKCON_HSMMC,
517};
518
515static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0) 519static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
516{ 520{
517 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK; 521 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
@@ -577,6 +581,7 @@ static struct clk *clks[] __initdata = {
577 &clk_epll, 581 &clk_epll,
578 &clk_usb_bus, 582 &clk_usb_bus,
579 &clk_armdiv, 583 &clk_armdiv,
584 &hsmmc1_clk,
580}; 585};
581 586
582static struct clksrc_clk *clksrcs[] __initdata = { 587static struct clksrc_clk *clksrcs[] __initdata = {
@@ -589,6 +594,13 @@ static struct clksrc_clk *clksrcs[] __initdata = {
589 &clk_arm, 594 &clk_arm,
590}; 595};
591 596
597static struct clk_lookup s3c2443_clk_lookup[] = {
598 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
599 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
600 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
601 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
602};
603
592void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 604void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
593 unsigned int *divs, int nr_divs, 605 unsigned int *divs, int nr_divs,
594 int divmask) 606 int divmask)
@@ -618,6 +630,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
618 /* See s3c2443/etc notes on disabling clocks at init time */ 630 /* See s3c2443/etc notes on disabling clocks at init time */
619 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 631 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
620 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 632 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
633 clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
621 634
622 s3c2443_common_setup_clocks(get_mpll); 635 s3c2443_common_setup_clocks(get_mpll);
623} 636}
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 313eb26cfa6..6a2abe67c8b 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -88,12 +88,20 @@ config S5P_GPIO_DRVSTR
88 88
89config SAMSUNG_GPIO_EXTRA 89config SAMSUNG_GPIO_EXTRA
90 int "Number of additional GPIO pins" 90 int "Number of additional GPIO pins"
91 default 128 if SAMSUNG_GPIO_EXTRA128
92 default 64 if SAMSUNG_GPIO_EXTRA64
91 default 0 93 default 0
92 help 94 help
93 Use additional GPIO space in addition to the GPIO's the SOC 95 Use additional GPIO space in addition to the GPIO's the SOC
94 provides. This allows expanding the GPIO space for use with 96 provides. This allows expanding the GPIO space for use with
95 GPIO expanders. 97 GPIO expanders.
96 98
99config SAMSUNG_GPIO_EXTRA64
100 bool
101
102config SAMSUNG_GPIO_EXTRA128
103 bool
104
97config S3C_GPIO_SPACE 105config S3C_GPIO_SPACE
98 int "Space between gpio banks" 106 int "Space between gpio banks"
99 default 0 107 default 0
@@ -226,11 +234,23 @@ config SAMSUNG_DEV_IDE
226 help 234 help
227 Compile in platform device definitions for IDE 235 Compile in platform device definitions for IDE
228 236
229config S3C64XX_DEV_SPI 237config S3C64XX_DEV_SPI0
238 bool
239 help
240 Compile in platform device definitions for S3C64XX's type
241 SPI controller 0
242
243config S3C64XX_DEV_SPI1
244 bool
245 help
246 Compile in platform device definitions for S3C64XX's type
247 SPI controller 1
248
249config S3C64XX_DEV_SPI2
230 bool 250 bool
231 help 251 help
232 Compile in platform device definitions for S3C64XX's type 252 Compile in platform device definitions for S3C64XX's type
233 SPI controllers. 253 SPI controller 2
234 254
235config SAMSUNG_DEV_TS 255config SAMSUNG_DEV_TS
236 bool 256 bool
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 4ca8b571f97..32a6e394db2 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -29,6 +29,7 @@
29#include <linux/mtd/partitions.h> 29#include <linux/mtd/partitions.h>
30#include <linux/mmc/host.h> 30#include <linux/mmc/host.h>
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/platform_data/s3c-hsudc.h>
32 33
33#include <asm/irq.h> 34#include <asm/irq.h>
34#include <asm/pmu.h> 35#include <asm/pmu.h>
@@ -61,6 +62,7 @@
61#include <plat/regs-iic.h> 62#include <plat/regs-iic.h>
62#include <plat/regs-serial.h> 63#include <plat/regs-serial.h>
63#include <plat/regs-spi.h> 64#include <plat/regs-spi.h>
65#include <plat/s3c64xx-spi.h>
64 66
65static u64 samsung_device_dma_mask = DMA_BIT_MASK(32); 67static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
66 68
@@ -1461,3 +1463,129 @@ struct platform_device s3c_device_wdt = {
1461 .resource = s3c_wdt_resource, 1463 .resource = s3c_wdt_resource,
1462}; 1464};
1463#endif /* CONFIG_S3C_DEV_WDT */ 1465#endif /* CONFIG_S3C_DEV_WDT */
1466
1467#ifdef CONFIG_S3C64XX_DEV_SPI0
1468static struct resource s3c64xx_spi0_resource[] = {
1469 [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256),
1470 [1] = DEFINE_RES_DMA(DMACH_SPI0_TX),
1471 [2] = DEFINE_RES_DMA(DMACH_SPI0_RX),
1472 [3] = DEFINE_RES_IRQ(IRQ_SPI0),
1473};
1474
1475struct platform_device s3c64xx_device_spi0 = {
1476 .name = "s3c64xx-spi",
1477 .id = 0,
1478 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
1479 .resource = s3c64xx_spi0_resource,
1480 .dev = {
1481 .dma_mask = &samsung_device_dma_mask,
1482 .coherent_dma_mask = DMA_BIT_MASK(32),
1483 },
1484};
1485
1486void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
1487 int src_clk_nr, int num_cs)
1488{
1489 if (!pd) {
1490 pr_err("%s:Need to pass platform data\n", __func__);
1491 return;
1492 }
1493
1494 /* Reject invalid configuration */
1495 if (!num_cs || src_clk_nr < 0) {
1496 pr_err("%s: Invalid SPI configuration\n", __func__);
1497 return;
1498 }
1499
1500 pd->num_cs = num_cs;
1501 pd->src_clk_nr = src_clk_nr;
1502 if (!pd->cfg_gpio)
1503 pd->cfg_gpio = s3c64xx_spi0_cfg_gpio;
1504
1505 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0);
1506}
1507#endif /* CONFIG_S3C64XX_DEV_SPI0 */
1508
1509#ifdef CONFIG_S3C64XX_DEV_SPI1
1510static struct resource s3c64xx_spi1_resource[] = {
1511 [0] = DEFINE_RES_MEM(S3C_PA_SPI1, SZ_256),
1512 [1] = DEFINE_RES_DMA(DMACH_SPI1_TX),
1513 [2] = DEFINE_RES_DMA(DMACH_SPI1_RX),
1514 [3] = DEFINE_RES_IRQ(IRQ_SPI1),
1515};
1516
1517struct platform_device s3c64xx_device_spi1 = {
1518 .name = "s3c64xx-spi",
1519 .id = 1,
1520 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
1521 .resource = s3c64xx_spi1_resource,
1522 .dev = {
1523 .dma_mask = &samsung_device_dma_mask,
1524 .coherent_dma_mask = DMA_BIT_MASK(32),
1525 },
1526};
1527
1528void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd,
1529 int src_clk_nr, int num_cs)
1530{
1531 if (!pd) {
1532 pr_err("%s:Need to pass platform data\n", __func__);
1533 return;
1534 }
1535
1536 /* Reject invalid configuration */
1537 if (!num_cs || src_clk_nr < 0) {
1538 pr_err("%s: Invalid SPI configuration\n", __func__);
1539 return;
1540 }
1541
1542 pd->num_cs = num_cs;
1543 pd->src_clk_nr = src_clk_nr;
1544 if (!pd->cfg_gpio)
1545 pd->cfg_gpio = s3c64xx_spi1_cfg_gpio;
1546
1547 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1);
1548}
1549#endif /* CONFIG_S3C64XX_DEV_SPI1 */
1550
1551#ifdef CONFIG_S3C64XX_DEV_SPI2
1552static struct resource s3c64xx_spi2_resource[] = {
1553 [0] = DEFINE_RES_MEM(S3C_PA_SPI2, SZ_256),
1554 [1] = DEFINE_RES_DMA(DMACH_SPI2_TX),
1555 [2] = DEFINE_RES_DMA(DMACH_SPI2_RX),
1556 [3] = DEFINE_RES_IRQ(IRQ_SPI2),
1557};
1558
1559struct platform_device s3c64xx_device_spi2 = {
1560 .name = "s3c64xx-spi",
1561 .id = 2,
1562 .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
1563 .resource = s3c64xx_spi2_resource,
1564 .dev = {
1565 .dma_mask = &samsung_device_dma_mask,
1566 .coherent_dma_mask = DMA_BIT_MASK(32),
1567 },
1568};
1569
1570void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
1571 int src_clk_nr, int num_cs)
1572{
1573 if (!pd) {
1574 pr_err("%s:Need to pass platform data\n", __func__);
1575 return;
1576 }
1577
1578 /* Reject invalid configuration */
1579 if (!num_cs || src_clk_nr < 0) {
1580 pr_err("%s: Invalid SPI configuration\n", __func__);
1581 return;
1582 }
1583
1584 pd->num_cs = num_cs;
1585 pd->src_clk_nr = src_clk_nr;
1586 if (!pd->cfg_gpio)
1587 pd->cfg_gpio = s3c64xx_spi2_cfg_gpio;
1588
1589 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2);
1590}
1591#endif /* CONFIG_S3C64XX_DEV_SPI2 */
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 93a994a5dd8..2cded872f22 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -18,23 +18,24 @@
18 18
19#include <mach/dma.h> 19#include <mach/dma.h>
20 20
21static inline bool pl330_filter(struct dma_chan *chan, void *param)
22{
23 struct dma_pl330_peri *peri = chan->private;
24 return peri->peri_id == (unsigned)param;
25}
26
27static unsigned samsung_dmadev_request(enum dma_ch dma_ch, 21static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
28 struct samsung_dma_info *info) 22 struct samsung_dma_info *info)
29{ 23{
30 struct dma_chan *chan; 24 struct dma_chan *chan;
31 dma_cap_mask_t mask; 25 dma_cap_mask_t mask;
32 struct dma_slave_config slave_config; 26 struct dma_slave_config slave_config;
27 void *filter_param;
33 28
34 dma_cap_zero(mask); 29 dma_cap_zero(mask);
35 dma_cap_set(info->cap, mask); 30 dma_cap_set(info->cap, mask);
36 31
37 chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); 32 /*
33 * If a dma channel property of a device node from device tree is
34 * specified, use that as the fliter parameter.
35 */
36 filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
37 (void *)dma_ch;
38 chan = dma_request_channel(mask, pl330_filter, filter_param);
38 39
39 if (info->direction == DMA_FROM_DEVICE) { 40 if (info->direction == DMA_FROM_DEVICE) {
40 memset(&slave_config, 0, sizeof(struct dma_slave_config)); 41 memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index ab633c9c2ae..4214ea0ff8f 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -39,6 +39,7 @@ extern struct platform_device s3c64xx_device_pcm0;
39extern struct platform_device s3c64xx_device_pcm1; 39extern struct platform_device s3c64xx_device_pcm1;
40extern struct platform_device s3c64xx_device_spi0; 40extern struct platform_device s3c64xx_device_spi0;
41extern struct platform_device s3c64xx_device_spi1; 41extern struct platform_device s3c64xx_device_spi1;
42extern struct platform_device s3c64xx_device_spi2;
42 43
43extern struct platform_device s3c_device_adc; 44extern struct platform_device s3c_device_adc;
44extern struct platform_device s3c_device_cfcon; 45extern struct platform_device s3c_device_cfcon;
@@ -98,8 +99,6 @@ extern struct platform_device s5p6450_device_iis1;
98extern struct platform_device s5p6450_device_iis2; 99extern struct platform_device s5p6450_device_iis2;
99extern struct platform_device s5p6450_device_pcm0; 100extern struct platform_device s5p6450_device_pcm0;
100 101
101extern struct platform_device s5p64x0_device_spi0;
102extern struct platform_device s5p64x0_device_spi1;
103 102
104extern struct platform_device s5pc100_device_ac97; 103extern struct platform_device s5pc100_device_ac97;
105extern struct platform_device s5pc100_device_iis0; 104extern struct platform_device s5pc100_device_iis0;
@@ -108,9 +107,6 @@ extern struct platform_device s5pc100_device_iis2;
108extern struct platform_device s5pc100_device_pcm0; 107extern struct platform_device s5pc100_device_pcm0;
109extern struct platform_device s5pc100_device_pcm1; 108extern struct platform_device s5pc100_device_pcm1;
110extern struct platform_device s5pc100_device_spdif; 109extern struct platform_device s5pc100_device_spdif;
111extern struct platform_device s5pc100_device_spi0;
112extern struct platform_device s5pc100_device_spi1;
113extern struct platform_device s5pc100_device_spi2;
114 110
115extern struct platform_device s5pv210_device_ac97; 111extern struct platform_device s5pv210_device_ac97;
116extern struct platform_device s5pv210_device_iis0; 112extern struct platform_device s5pv210_device_iis0;
@@ -120,8 +116,6 @@ extern struct platform_device s5pv210_device_pcm0;
120extern struct platform_device s5pv210_device_pcm1; 116extern struct platform_device s5pv210_device_pcm1;
121extern struct platform_device s5pv210_device_pcm2; 117extern struct platform_device s5pv210_device_pcm2;
122extern struct platform_device s5pv210_device_spdif; 118extern struct platform_device s5pv210_device_spdif;
123extern struct platform_device s5pv210_device_spi0;
124extern struct platform_device s5pv210_device_spi1;
125 119
126extern struct platform_device exynos4_device_ac97; 120extern struct platform_device exynos4_device_ac97;
127extern struct platform_device exynos4_device_ahci; 121extern struct platform_device exynos4_device_ahci;
@@ -129,6 +123,7 @@ extern struct platform_device exynos4_device_dwmci;
129extern struct platform_device exynos4_device_i2s0; 123extern struct platform_device exynos4_device_i2s0;
130extern struct platform_device exynos4_device_i2s1; 124extern struct platform_device exynos4_device_i2s1;
131extern struct platform_device exynos4_device_i2s2; 125extern struct platform_device exynos4_device_i2s2;
126extern struct platform_device exynos4_device_ohci;
132extern struct platform_device exynos4_device_pcm0; 127extern struct platform_device exynos4_device_pcm0;
133extern struct platform_device exynos4_device_pcm1; 128extern struct platform_device exynos4_device_pcm1;
134extern struct platform_device exynos4_device_pcm2; 129extern struct platform_device exynos4_device_pcm2;
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363526c..22eafc310bd 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
31 enum dma_slave_buswidth width; 31 enum dma_slave_buswidth width;
32 dma_addr_t fifo; 32 dma_addr_t fifo;
33 struct s3c2410_dma_client *client; 33 struct s3c2410_dma_client *client;
34 struct property *dt_dmach_prop;
34}; 35};
35 36
36struct samsung_dma_ops { 37struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e595867..c5eaad529de 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
21 * use these just as IDs. 21 * use these just as IDs.
22 */ 22 */
23enum dma_ch { 23enum dma_ch {
24 DMACH_UART0_RX, 24 DMACH_DT_PROP = -1,
25 DMACH_UART0_RX = 0,
25 DMACH_UART0_TX, 26 DMACH_UART0_TX,
26 DMACH_UART1_RX, 27 DMACH_UART1_RX,
27 DMACH_UART1_TX, 28 DMACH_UART1_TX,
diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
index 08d1a7ef97b..df46b776976 100644
--- a/arch/arm/plat-samsung/include/plat/irqs.h
+++ b/arch/arm/plat-samsung/include/plat/irqs.h
@@ -44,13 +44,14 @@
44#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) 44#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
45#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) 45#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
46 46
47#define S5P_TIMER_IRQ(x) (11 + (x)) 47#define S5P_TIMER_IRQ(x) (IRQ_TIMER_BASE + (x))
48 48
49#define IRQ_TIMER0 S5P_TIMER_IRQ(0) 49#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
50#define IRQ_TIMER1 S5P_TIMER_IRQ(1) 50#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
51#define IRQ_TIMER2 S5P_TIMER_IRQ(2) 51#define IRQ_TIMER2 S5P_TIMER_IRQ(2)
52#define IRQ_TIMER3 S5P_TIMER_IRQ(3) 52#define IRQ_TIMER3 S5P_TIMER_IRQ(3)
53#define IRQ_TIMER4 S5P_TIMER_IRQ(4) 53#define IRQ_TIMER4 S5P_TIMER_IRQ(4)
54#define IRQ_TIMER_COUNT (5)
54 55
55#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ 56#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
56 : ((x) - 16 + S5P_EINT_BASE2)) 57 : ((x) - 16 + S5P_EINT_BASE2))
diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/plat-samsung/include/plat/keypad.h
index b59a6483cd8..c81ace332a1 100644
--- a/arch/arm/plat-samsung/include/plat/keypad.h
+++ b/arch/arm/plat-samsung/include/plat/keypad.h
@@ -13,32 +13,7 @@
13#ifndef __PLAT_SAMSUNG_KEYPAD_H 13#ifndef __PLAT_SAMSUNG_KEYPAD_H
14#define __PLAT_SAMSUNG_KEYPAD_H 14#define __PLAT_SAMSUNG_KEYPAD_H
15 15
16#include <linux/input/matrix_keypad.h> 16#include <linux/input/samsung-keypad.h>
17
18#define SAMSUNG_MAX_ROWS 8
19#define SAMSUNG_MAX_COLS 8
20
21/**
22 * struct samsung_keypad_platdata - Platform device data for Samsung Keypad.
23 * @keymap_data: pointer to &matrix_keymap_data.
24 * @rows: number of keypad row supported.
25 * @cols: number of keypad col supported.
26 * @no_autorepeat: disable key autorepeat.
27 * @wakeup: controls whether the device should be set up as wakeup source.
28 * @cfg_gpio: configure the GPIO.
29 *
30 * Initialisation data specific to either the machine or the platform
31 * for the device driver to use or call-back when configuring gpio.
32 */
33struct samsung_keypad_platdata {
34 const struct matrix_keymap_data *keymap_data;
35 unsigned int rows;
36 unsigned int cols;
37 bool no_autorepeat;
38 bool wakeup;
39
40 void (*cfg_gpio)(unsigned int rows, unsigned int cols);
41};
42 17
43/** 18/**
44 * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device. 19 * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device.
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 72073484702..29c26a81884 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -71,6 +71,7 @@
71#define S3C2410_LCON_IRM (1<<6) 71#define S3C2410_LCON_IRM (1<<6)
72 72
73#define S3C2440_UCON_CLKMASK (3<<10) 73#define S3C2440_UCON_CLKMASK (3<<10)
74#define S3C2440_UCON_CLKSHIFT (10)
74#define S3C2440_UCON_PCLK (0<<10) 75#define S3C2440_UCON_PCLK (0<<10)
75#define S3C2440_UCON_UCLK (1<<10) 76#define S3C2440_UCON_UCLK (1<<10)
76#define S3C2440_UCON_PCLK2 (2<<10) 77#define S3C2440_UCON_PCLK2 (2<<10)
@@ -78,6 +79,7 @@
78#define S3C2443_UCON_EPLL (3<<10) 79#define S3C2443_UCON_EPLL (3<<10)
79 80
80#define S3C6400_UCON_CLKMASK (3<<10) 81#define S3C6400_UCON_CLKMASK (3<<10)
82#define S3C6400_UCON_CLKSHIFT (10)
81#define S3C6400_UCON_PCLK (0<<10) 83#define S3C6400_UCON_PCLK (0<<10)
82#define S3C6400_UCON_PCLK2 (2<<10) 84#define S3C6400_UCON_PCLK2 (2<<10)
83#define S3C6400_UCON_UCLK0 (1<<10) 85#define S3C6400_UCON_UCLK0 (1<<10)
@@ -90,11 +92,14 @@
90#define S3C2440_UCON_DIVSHIFT (12) 92#define S3C2440_UCON_DIVSHIFT (12)
91 93
92#define S3C2412_UCON_CLKMASK (3<<10) 94#define S3C2412_UCON_CLKMASK (3<<10)
95#define S3C2412_UCON_CLKSHIFT (10)
93#define S3C2412_UCON_UCLK (1<<10) 96#define S3C2412_UCON_UCLK (1<<10)
94#define S3C2412_UCON_USYSCLK (3<<10) 97#define S3C2412_UCON_USYSCLK (3<<10)
95#define S3C2412_UCON_PCLK (0<<10) 98#define S3C2412_UCON_PCLK (0<<10)
96#define S3C2412_UCON_PCLK2 (2<<10) 99#define S3C2412_UCON_PCLK2 (2<<10)
97 100
101#define S3C2410_UCON_CLKMASK (1 << 10)
102#define S3C2410_UCON_CLKSHIFT (10)
98#define S3C2410_UCON_UCLK (1<<10) 103#define S3C2410_UCON_UCLK (1<<10)
99#define S3C2410_UCON_SBREAK (1<<4) 104#define S3C2410_UCON_SBREAK (1<<4)
100 105
@@ -193,6 +198,7 @@
193 198
194/* Following are specific to S5PV210 */ 199/* Following are specific to S5PV210 */
195#define S5PV210_UCON_CLKMASK (1<<10) 200#define S5PV210_UCON_CLKMASK (1<<10)
201#define S5PV210_UCON_CLKSHIFT (10)
196#define S5PV210_UCON_PCLK (0<<10) 202#define S5PV210_UCON_PCLK (0<<10)
197#define S5PV210_UCON_UCLK (1<<10) 203#define S5PV210_UCON_UCLK (1<<10)
198 204
@@ -221,29 +227,24 @@
221#define S5PV210_UFSTAT_RXMASK (255<<0) 227#define S5PV210_UFSTAT_RXMASK (255<<0)
222#define S5PV210_UFSTAT_RXSHIFT (0) 228#define S5PV210_UFSTAT_RXSHIFT (0)
223 229
224#define NO_NEED_CHECK_CLKSRC 1 230#define S3C2410_UCON_CLKSEL0 (1 << 0)
231#define S3C2410_UCON_CLKSEL1 (1 << 1)
232#define S3C2410_UCON_CLKSEL2 (1 << 2)
233#define S3C2410_UCON_CLKSEL3 (1 << 3)
225 234
226#ifndef __ASSEMBLY__ 235/* Default values for s5pv210 UCON and UFCON uart registers */
236#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
237 S3C2410_UCON_RXILEVEL | \
238 S3C2410_UCON_TXIRQMODE | \
239 S3C2410_UCON_RXIRQMODE | \
240 S3C2410_UCON_RXFIFO_TOI | \
241 S3C2443_UCON_RXERR_IRQEN)
227 242
228/* struct s3c24xx_uart_clksrc 243#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
229 * 244 S5PV210_UFCON_TXTRIG4 | \
230 * this structure defines a named clock source that can be used for the 245 S5PV210_UFCON_RXTRIG4)
231 * uart, so that the best clock can be selected for the requested baud
232 * rate.
233 *
234 * min_baud and max_baud define the range of baud-rates this clock is
235 * acceptable for, if they are both zero, it is assumed any baud rate that
236 * can be generated from this clock will be used.
237 *
238 * divisor gives the divisor from the clock to the one seen by the uart
239*/
240 246
241struct s3c24xx_uart_clksrc { 247#ifndef __ASSEMBLY__
242 const char *name;
243 unsigned int divisor;
244 unsigned int min_baud;
245 unsigned int max_baud;
246};
247 248
248/* configuration structure for per-machine configurations for the 249/* configuration structure for per-machine configurations for the
249 * serial port 250 * serial port
@@ -257,15 +258,13 @@ struct s3c2410_uartcfg {
257 unsigned char unused; 258 unsigned char unused;
258 unsigned short flags; 259 unsigned short flags;
259 upf_t uart_flags; /* default uart flags */ 260 upf_t uart_flags; /* default uart flags */
261 unsigned int clk_sel;
260 262
261 unsigned int has_fracval; 263 unsigned int has_fracval;
262 264
263 unsigned long ucon; /* value of ucon for port */ 265 unsigned long ucon; /* value of ucon for port */
264 unsigned long ulcon; /* value of ulcon for port */ 266 unsigned long ulcon; /* value of ulcon for port */
265 unsigned long ufcon; /* value of ufcon for port */ 267 unsigned long ufcon; /* value of ufcon for port */
266
267 struct s3c24xx_uart_clksrc *clocks;
268 unsigned int clocks_size;
269}; 268};
270 269
271/* s3c24xx_uart_devs 270/* s3c24xx_uart_devs
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index 4c16fa3621b..aea68b60ef9 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -31,7 +31,6 @@ struct s3c64xx_spi_csinfo {
31/** 31/**
32 * struct s3c64xx_spi_info - SPI Controller defining structure 32 * struct s3c64xx_spi_info - SPI Controller defining structure
33 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. 33 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
34 * @src_clk_name: Platform name of the corresponding clock.
35 * @clk_from_cmu: If the SPI clock/prescalar control block is present 34 * @clk_from_cmu: If the SPI clock/prescalar control block is present
36 * by the platform's clock-management-unit and not in SPI controller. 35 * by the platform's clock-management-unit and not in SPI controller.
37 * @num_cs: Number of CS this controller emulates. 36 * @num_cs: Number of CS this controller emulates.
@@ -43,7 +42,6 @@ struct s3c64xx_spi_csinfo {
43 */ 42 */
44struct s3c64xx_spi_info { 43struct s3c64xx_spi_info {
45 int src_clk_nr; 44 int src_clk_nr;
46 char *src_clk_name;
47 bool clk_from_cmu; 45 bool clk_from_cmu;
48 46
49 int num_cs; 47 int num_cs;
@@ -58,18 +56,28 @@ struct s3c64xx_spi_info {
58}; 56};
59 57
60/** 58/**
61 * s3c64xx_spi_set_info - SPI Controller configure callback by the board 59 * s3c64xx_spi_set_platdata - SPI Controller configure callback by the board
62 * initialization code. 60 * initialization code.
63 * @cntrlr: SPI controller number the configuration is for. 61 * @pd: SPI platform data to set.
64 * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. 62 * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
65 * @num_cs: Number of elements in the 'cs' array. 63 * @num_cs: Number of elements in the 'cs' array.
66 * 64 *
67 * Call this from machine init code for each SPI Controller that 65 * Call this from machine init code for each SPI Controller that
68 * has some chips attached to it. 66 * has some chips attached to it.
69 */ 67 */
70extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 68extern void s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
71extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 69 int src_clk_nr, int num_cs);
72extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 70extern void s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd,
73extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs); 71 int src_clk_nr, int num_cs);
72extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
73 int src_clk_nr, int num_cs);
74 74
75/* defined by architecture to configure gpio */
76extern int s3c64xx_spi0_cfg_gpio(struct platform_device *dev);
77extern int s3c64xx_spi1_cfg_gpio(struct platform_device *dev);
78extern int s3c64xx_spi2_cfg_gpio(struct platform_device *dev);
79
80extern struct s3c64xx_spi_info s3c64xx_spi0_pdata;
81extern struct s3c64xx_spi_info s3c64xx_spi1_pdata;
82extern struct s3c64xx_spi_info s3c64xx_spi2_pdata;
75#endif /* __S3C64XX_PLAT_SPI_H */ 83#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index e7b3c752e91..656dc00d30e 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -66,8 +66,6 @@ struct s3c_sdhci_platdata {
66 enum cd_types cd_type; 66 enum cd_types cd_type;
67 enum clk_types clk_type; 67 enum clk_types clk_type;
68 68
69 char **clocks; /* set of clock sources */
70
71 int ext_cd_gpio; 69 int ext_cd_gpio;
72 bool ext_cd_gpio_invert; 70 bool ext_cd_gpio_invert;
73 int (*ext_cd_init)(void (*notify_func)(struct platform_device *, 71 int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
@@ -125,16 +123,17 @@ extern void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
125extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w); 123extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
126extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w); 124extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
127extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w); 125extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
126extern void s5p64x0_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
127extern void s5p64x0_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
128extern void s5p6440_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
129extern void s5p6450_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
128 130
129/* S3C2416 SDHCI setup */ 131/* S3C2416 SDHCI setup */
130 132
131#ifdef CONFIG_S3C2416_SETUP_SDHCI 133#ifdef CONFIG_S3C2416_SETUP_SDHCI
132extern char *s3c2416_hsmmc_clksrcs[4];
133
134static inline void s3c2416_default_sdhci0(void) 134static inline void s3c2416_default_sdhci0(void)
135{ 135{
136#ifdef CONFIG_S3C_DEV_HSMMC 136#ifdef CONFIG_S3C_DEV_HSMMC
137 s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
138 s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; 137 s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
139#endif /* CONFIG_S3C_DEV_HSMMC */ 138#endif /* CONFIG_S3C_DEV_HSMMC */
140} 139}
@@ -142,7 +141,6 @@ static inline void s3c2416_default_sdhci0(void)
142static inline void s3c2416_default_sdhci1(void) 141static inline void s3c2416_default_sdhci1(void)
143{ 142{
144#ifdef CONFIG_S3C_DEV_HSMMC1 143#ifdef CONFIG_S3C_DEV_HSMMC1
145 s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
146 s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; 144 s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
147#endif /* CONFIG_S3C_DEV_HSMMC1 */ 145#endif /* CONFIG_S3C_DEV_HSMMC1 */
148} 146}
@@ -152,15 +150,13 @@ static inline void s3c2416_default_sdhci0(void) { }
152static inline void s3c2416_default_sdhci1(void) { } 150static inline void s3c2416_default_sdhci1(void) { }
153 151
154#endif /* CONFIG_S3C2416_SETUP_SDHCI */ 152#endif /* CONFIG_S3C2416_SETUP_SDHCI */
153
155/* S3C64XX SDHCI setup */ 154/* S3C64XX SDHCI setup */
156 155
157#ifdef CONFIG_S3C64XX_SETUP_SDHCI 156#ifdef CONFIG_S3C64XX_SETUP_SDHCI
158extern char *s3c64xx_hsmmc_clksrcs[4];
159
160static inline void s3c6400_default_sdhci0(void) 157static inline void s3c6400_default_sdhci0(void)
161{ 158{
162#ifdef CONFIG_S3C_DEV_HSMMC 159#ifdef CONFIG_S3C_DEV_HSMMC
163 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
164 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 160 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
165#endif 161#endif
166} 162}
@@ -168,7 +164,6 @@ static inline void s3c6400_default_sdhci0(void)
168static inline void s3c6400_default_sdhci1(void) 164static inline void s3c6400_default_sdhci1(void)
169{ 165{
170#ifdef CONFIG_S3C_DEV_HSMMC1 166#ifdef CONFIG_S3C_DEV_HSMMC1
171 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
172 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 167 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
173#endif 168#endif
174} 169}
@@ -176,7 +171,6 @@ static inline void s3c6400_default_sdhci1(void)
176static inline void s3c6400_default_sdhci2(void) 171static inline void s3c6400_default_sdhci2(void)
177{ 172{
178#ifdef CONFIG_S3C_DEV_HSMMC2 173#ifdef CONFIG_S3C_DEV_HSMMC2
179 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
180 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 174 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
181#endif 175#endif
182} 176}
@@ -184,7 +178,6 @@ static inline void s3c6400_default_sdhci2(void)
184static inline void s3c6410_default_sdhci0(void) 178static inline void s3c6410_default_sdhci0(void)
185{ 179{
186#ifdef CONFIG_S3C_DEV_HSMMC 180#ifdef CONFIG_S3C_DEV_HSMMC
187 s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
188 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio; 181 s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
189#endif 182#endif
190} 183}
@@ -192,7 +185,6 @@ static inline void s3c6410_default_sdhci0(void)
192static inline void s3c6410_default_sdhci1(void) 185static inline void s3c6410_default_sdhci1(void)
193{ 186{
194#ifdef CONFIG_S3C_DEV_HSMMC1 187#ifdef CONFIG_S3C_DEV_HSMMC1
195 s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
196 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio; 188 s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
197#endif 189#endif
198} 190}
@@ -200,7 +192,6 @@ static inline void s3c6410_default_sdhci1(void)
200static inline void s3c6410_default_sdhci2(void) 192static inline void s3c6410_default_sdhci2(void)
201{ 193{
202#ifdef CONFIG_S3C_DEV_HSMMC2 194#ifdef CONFIG_S3C_DEV_HSMMC2
203 s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
204 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio; 195 s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
205#endif 196#endif
206} 197}
@@ -215,15 +206,51 @@ static inline void s3c6400_default_sdhci2(void) { }
215 206
216#endif /* CONFIG_S3C64XX_SETUP_SDHCI */ 207#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
217 208
209/* S5P64X0 SDHCI setup */
210
211#ifdef CONFIG_S5P64X0_SETUP_SDHCI
212static inline void s5p64x0_default_sdhci0(void)
213{
214#ifdef CONFIG_S3C_DEV_HSMMC
215 s3c_hsmmc0_def_platdata.cfg_gpio = s5p64x0_setup_sdhci0_cfg_gpio;
216#endif
217}
218
219static inline void s5p64x0_default_sdhci1(void)
220{
221#ifdef CONFIG_S3C_DEV_HSMMC1
222 s3c_hsmmc1_def_platdata.cfg_gpio = s5p64x0_setup_sdhci1_cfg_gpio;
223#endif
224}
225
226static inline void s5p6440_default_sdhci2(void)
227{
228#ifdef CONFIG_S3C_DEV_HSMMC2
229 s3c_hsmmc2_def_platdata.cfg_gpio = s5p6440_setup_sdhci2_cfg_gpio;
230#endif
231}
232
233static inline void s5p6450_default_sdhci2(void)
234{
235#ifdef CONFIG_S3C_DEV_HSMMC2
236 s3c_hsmmc2_def_platdata.cfg_gpio = s5p6450_setup_sdhci2_cfg_gpio;
237#endif
238}
239
240#else
241static inline void s5p64x0_default_sdhci0(void) { }
242static inline void s5p64x0_default_sdhci1(void) { }
243static inline void s5p6440_default_sdhci2(void) { }
244static inline void s5p6450_default_sdhci2(void) { }
245
246#endif /* CONFIG_S5P64X0_SETUP_SDHCI */
247
218/* S5PC100 SDHCI setup */ 248/* S5PC100 SDHCI setup */
219 249
220#ifdef CONFIG_S5PC100_SETUP_SDHCI 250#ifdef CONFIG_S5PC100_SETUP_SDHCI
221extern char *s5pc100_hsmmc_clksrcs[4];
222
223static inline void s5pc100_default_sdhci0(void) 251static inline void s5pc100_default_sdhci0(void)
224{ 252{
225#ifdef CONFIG_S3C_DEV_HSMMC 253#ifdef CONFIG_S3C_DEV_HSMMC
226 s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
227 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio; 254 s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
228#endif 255#endif
229} 256}
@@ -231,7 +258,6 @@ static inline void s5pc100_default_sdhci0(void)
231static inline void s5pc100_default_sdhci1(void) 258static inline void s5pc100_default_sdhci1(void)
232{ 259{
233#ifdef CONFIG_S3C_DEV_HSMMC1 260#ifdef CONFIG_S3C_DEV_HSMMC1
234 s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
235 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio; 261 s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
236#endif 262#endif
237} 263}
@@ -239,7 +265,6 @@ static inline void s5pc100_default_sdhci1(void)
239static inline void s5pc100_default_sdhci2(void) 265static inline void s5pc100_default_sdhci2(void)
240{ 266{
241#ifdef CONFIG_S3C_DEV_HSMMC2 267#ifdef CONFIG_S3C_DEV_HSMMC2
242 s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
243 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio; 268 s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
244#endif 269#endif
245} 270}
@@ -254,12 +279,9 @@ static inline void s5pc100_default_sdhci2(void) { }
254/* S5PV210 SDHCI setup */ 279/* S5PV210 SDHCI setup */
255 280
256#ifdef CONFIG_S5PV210_SETUP_SDHCI 281#ifdef CONFIG_S5PV210_SETUP_SDHCI
257extern char *s5pv210_hsmmc_clksrcs[4];
258
259static inline void s5pv210_default_sdhci0(void) 282static inline void s5pv210_default_sdhci0(void)
260{ 283{
261#ifdef CONFIG_S3C_DEV_HSMMC 284#ifdef CONFIG_S3C_DEV_HSMMC
262 s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
263 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio; 285 s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
264#endif 286#endif
265} 287}
@@ -267,7 +289,6 @@ static inline void s5pv210_default_sdhci0(void)
267static inline void s5pv210_default_sdhci1(void) 289static inline void s5pv210_default_sdhci1(void)
268{ 290{
269#ifdef CONFIG_S3C_DEV_HSMMC1 291#ifdef CONFIG_S3C_DEV_HSMMC1
270 s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
271 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio; 292 s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
272#endif 293#endif
273} 294}
@@ -275,7 +296,6 @@ static inline void s5pv210_default_sdhci1(void)
275static inline void s5pv210_default_sdhci2(void) 296static inline void s5pv210_default_sdhci2(void)
276{ 297{
277#ifdef CONFIG_S3C_DEV_HSMMC2 298#ifdef CONFIG_S3C_DEV_HSMMC2
278 s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
279 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio; 299 s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
280#endif 300#endif
281} 301}
@@ -283,7 +303,6 @@ static inline void s5pv210_default_sdhci2(void)
283static inline void s5pv210_default_sdhci3(void) 303static inline void s5pv210_default_sdhci3(void)
284{ 304{
285#ifdef CONFIG_S3C_DEV_HSMMC3 305#ifdef CONFIG_S3C_DEV_HSMMC3
286 s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
287 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio; 306 s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
288#endif 307#endif
289} 308}
@@ -298,12 +317,9 @@ static inline void s5pv210_default_sdhci3(void) { }
298 317
299/* EXYNOS4 SDHCI setup */ 318/* EXYNOS4 SDHCI setup */
300#ifdef CONFIG_EXYNOS4_SETUP_SDHCI 319#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
301extern char *exynos4_hsmmc_clksrcs[4];
302
303static inline void exynos4_default_sdhci0(void) 320static inline void exynos4_default_sdhci0(void)
304{ 321{
305#ifdef CONFIG_S3C_DEV_HSMMC 322#ifdef CONFIG_S3C_DEV_HSMMC
306 s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
307 s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio; 323 s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio;
308#endif 324#endif
309} 325}
@@ -311,7 +327,6 @@ static inline void exynos4_default_sdhci0(void)
311static inline void exynos4_default_sdhci1(void) 327static inline void exynos4_default_sdhci1(void)
312{ 328{
313#ifdef CONFIG_S3C_DEV_HSMMC1 329#ifdef CONFIG_S3C_DEV_HSMMC1
314 s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
315 s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio; 330 s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio;
316#endif 331#endif
317} 332}
@@ -319,7 +334,6 @@ static inline void exynos4_default_sdhci1(void)
319static inline void exynos4_default_sdhci2(void) 334static inline void exynos4_default_sdhci2(void)
320{ 335{
321#ifdef CONFIG_S3C_DEV_HSMMC2 336#ifdef CONFIG_S3C_DEV_HSMMC2
322 s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
323 s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio; 337 s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio;
324#endif 338#endif
325} 339}
@@ -327,7 +341,6 @@ static inline void exynos4_default_sdhci2(void)
327static inline void exynos4_default_sdhci3(void) 341static inline void exynos4_default_sdhci3(void)
328{ 342{
329#ifdef CONFIG_S3C_DEV_HSMMC3 343#ifdef CONFIG_S3C_DEV_HSMMC3
330 s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
331 s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio; 344 s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio;
332#endif 345#endif
333} 346}
diff --git a/arch/arm/plat-samsung/include/plat/udc.h b/arch/arm/plat-samsung/include/plat/udc.h
index 8c22d586bef..de8e2288a50 100644
--- a/arch/arm/plat-samsung/include/plat/udc.h
+++ b/arch/arm/plat-samsung/include/plat/udc.h
@@ -37,20 +37,7 @@ struct s3c2410_udc_mach_info {
37 37
38extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *); 38extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
39 39
40/** 40struct s3c24xx_hsudc_platdata;
41 * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
42 * @epnum: Number of endpoints to be instantiated by the controller driver.
43 * @gpio_init: Platform specific USB related GPIO initialization.
44 * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
45 *
46 * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
47 * controllers.
48 */
49struct s3c24xx_hsudc_platdata {
50 unsigned int epnum;
51 void (*gpio_init)(void);
52 void (*gpio_uninit)(void);
53};
54 41
55extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd); 42extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
56 43
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 1f17bde52cd..7c756fb189f 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -109,7 +109,7 @@ struct eth_addr {
109 u8 addr[6]; 109 u8 addr[6];
110}; 110};
111static struct eth_addr __initdata hw_addr[2]; 111static struct eth_addr __initdata hw_addr[2];
112static struct eth_platform_data __initdata eth_data[2]; 112static struct macb_platform_data __initdata eth_data[2];
113 113
114static struct spi_board_info spi0_board_info[] __initdata = { 114static struct spi_board_info spi0_board_info[] __initdata = {
115 { 115 {
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 4643ff5107c..c56ddac85d6 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -105,7 +105,7 @@ struct eth_addr {
105}; 105};
106 106
107static struct eth_addr __initdata hw_addr[2]; 107static struct eth_addr __initdata hw_addr[2];
108static struct eth_platform_data __initdata eth_data[2] = { 108static struct macb_platform_data __initdata eth_data[2] = {
109 { 109 {
110 /* 110 /*
111 * The MDIO pullups on STK1000 are a bit too weak for 111 * The MDIO pullups on STK1000 are a bit too weak for
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 86fab77a5a0..27bd6fbe21c 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -50,7 +50,7 @@ struct eth_addr {
50 u8 addr[6]; 50 u8 addr[6];
51}; 51};
52static struct eth_addr __initdata hw_addr[1]; 52static struct eth_addr __initdata hw_addr[1];
53static struct eth_platform_data __initdata eth_data[1] = { 53static struct macb_platform_data __initdata eth_data[1] = {
54 { 54 {
55 .phy_mask = ~(1U << 1), 55 .phy_mask = ~(1U << 1),
56 }, 56 },
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c
index da14fbdd4e8..9d1efd1cd42 100644
--- a/arch/avr32/boards/hammerhead/setup.c
+++ b/arch/avr32/boards/hammerhead/setup.c
@@ -102,7 +102,7 @@ struct eth_addr {
102}; 102};
103 103
104static struct eth_addr __initdata hw_addr[1]; 104static struct eth_addr __initdata hw_addr[1];
105static struct eth_platform_data __initdata eth_data[1]; 105static struct macb_platform_data __initdata eth_data[1];
106 106
107/* 107/*
108 * The next two functions should go away as the boot loader is 108 * The next two functions should go away as the boot loader is
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
index e61bc948f95..ed137e33579 100644
--- a/arch/avr32/boards/merisc/setup.c
+++ b/arch/avr32/boards/merisc/setup.c
@@ -52,7 +52,7 @@ struct eth_addr {
52}; 52};
53 53
54static struct eth_addr __initdata hw_addr[2]; 54static struct eth_addr __initdata hw_addr[2];
55static struct eth_platform_data __initdata eth_data[2]; 55static struct macb_platform_data __initdata eth_data[2];
56 56
57static int ads7846_get_pendown_state_PB26(void) 57static int ads7846_get_pendown_state_PB26(void)
58{ 58{
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c
index c4da5cba2db..05358aa5ef7 100644
--- a/arch/avr32/boards/mimc200/setup.c
+++ b/arch/avr32/boards/mimc200/setup.c
@@ -86,7 +86,7 @@ struct eth_addr {
86 u8 addr[6]; 86 u8 addr[6];
87}; 87};
88static struct eth_addr __initdata hw_addr[2]; 88static struct eth_addr __initdata hw_addr[2];
89static struct eth_platform_data __initdata eth_data[2]; 89static struct macb_platform_data __initdata eth_data[2];
90 90
91static struct spi_eeprom eeprom_25lc010 = { 91static struct spi_eeprom eeprom_25lc010 = {
92 .name = "25lc010", 92 .name = "25lc010",
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 7fbf0dcb9af..402a7bb7266 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1067,7 +1067,7 @@ void __init at32_setup_serial_console(unsigned int usart_id)
1067 * -------------------------------------------------------------------- */ 1067 * -------------------------------------------------------------------- */
1068 1068
1069#ifdef CONFIG_CPU_AT32AP7000 1069#ifdef CONFIG_CPU_AT32AP7000
1070static struct eth_platform_data macb0_data; 1070static struct macb_platform_data macb0_data;
1071static struct resource macb0_resource[] = { 1071static struct resource macb0_resource[] = {
1072 PBMEM(0xfff01800), 1072 PBMEM(0xfff01800),
1073 IRQ(25), 1073 IRQ(25),
@@ -1076,7 +1076,7 @@ DEFINE_DEV_DATA(macb, 0);
1076DEV_CLK(hclk, macb0, hsb, 8); 1076DEV_CLK(hclk, macb0, hsb, 8);
1077DEV_CLK(pclk, macb0, pbb, 6); 1077DEV_CLK(pclk, macb0, pbb, 6);
1078 1078
1079static struct eth_platform_data macb1_data; 1079static struct macb_platform_data macb1_data;
1080static struct resource macb1_resource[] = { 1080static struct resource macb1_resource[] = {
1081 PBMEM(0xfff01c00), 1081 PBMEM(0xfff01c00),
1082 IRQ(26), 1082 IRQ(26),
@@ -1086,7 +1086,7 @@ DEV_CLK(hclk, macb1, hsb, 9);
1086DEV_CLK(pclk, macb1, pbb, 7); 1086DEV_CLK(pclk, macb1, pbb, 7);
1087 1087
1088struct platform_device *__init 1088struct platform_device *__init
1089at32_add_device_eth(unsigned int id, struct eth_platform_data *data) 1089at32_add_device_eth(unsigned int id, struct macb_platform_data *data)
1090{ 1090{
1091 struct platform_device *pdev; 1091 struct platform_device *pdev;
1092 u32 pin_mask; 1092 u32 pin_mask;
@@ -1163,7 +1163,7 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
1163 return NULL; 1163 return NULL;
1164 } 1164 }
1165 1165
1166 memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data)); 1166 memcpy(pdev->dev.platform_data, data, sizeof(struct macb_platform_data));
1167 platform_device_register(pdev); 1167 platform_device_register(pdev);
1168 1168
1169 return pdev; 1169 return pdev;
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index 5d7ffca7d69..67b111ce332 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/serial.h> 8#include <linux/serial.h>
9#include <linux/platform_data/macb.h>
9 10
10#define GPIO_PIN_NONE (-1) 11#define GPIO_PIN_NONE (-1)
11 12
@@ -42,12 +43,8 @@ struct atmel_uart_data {
42void at32_map_usart(unsigned int hw_id, unsigned int line, int flags); 43void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
43struct platform_device *at32_add_device_usart(unsigned int id); 44struct platform_device *at32_add_device_usart(unsigned int id);
44 45
45struct eth_platform_data {
46 u32 phy_mask;
47 u8 is_rmii;
48};
49struct platform_device * 46struct platform_device *
50at32_add_device_eth(unsigned int id, struct eth_platform_data *data); 47at32_add_device_eth(unsigned int id, struct macb_platform_data *data);
51 48
52struct spi_board_info; 49struct spi_board_info;
53struct platform_device * 50struct platform_device *
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index 5edcb58d6f7..0b7039cf07f 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -80,7 +80,7 @@ CONFIG_I2C_CHARDEV=y
80CONFIG_I2C_BLACKFIN_TWI=y 80CONFIG_I2C_BLACKFIN_TWI=y
81CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 81CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
82CONFIG_SPI=y 82CONFIG_SPI=y
83CONFIG_SPI_BFIN=y 83CONFIG_SPI_BFIN5XX=y
84CONFIG_GPIOLIB=y 84CONFIG_GPIOLIB=y
85CONFIG_GPIO_SYSFS=y 85CONFIG_GPIO_SYSFS=y
86# CONFIG_HWMON is not set 86# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 2e549572d4f..5553205d7cb 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -97,7 +97,7 @@ CONFIG_I2C_CHARDEV=m
97CONFIG_I2C_BLACKFIN_TWI=y 97CONFIG_I2C_BLACKFIN_TWI=y
98CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 98CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
99CONFIG_SPI=y 99CONFIG_SPI=y
100CONFIG_SPI_BFIN=y 100CONFIG_SPI_BFIN5XX=y
101CONFIG_GPIOLIB=y 101CONFIG_GPIOLIB=y
102CONFIG_GPIO_SYSFS=y 102CONFIG_GPIO_SYSFS=y
103CONFIG_WATCHDOG=y 103CONFIG_WATCHDOG=y
diff --git a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
index ad0881ba30a..d95658fc312 100644
--- a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
+++ b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
@@ -68,7 +68,7 @@ CONFIG_I2C_ALGOBIT=y
68CONFIG_I2C_BLACKFIN_TWI=y 68CONFIG_I2C_BLACKFIN_TWI=y
69CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=400 69CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=400
70CONFIG_SPI=y 70CONFIG_SPI=y
71CONFIG_SPI_BFIN=y 71CONFIG_SPI_BFIN5XX=y
72CONFIG_GPIOLIB=y 72CONFIG_GPIOLIB=y
73CONFIG_GPIO_SYSFS=y 73CONFIG_GPIO_SYSFS=y
74# CONFIG_HWMON is not set 74# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
index 8465b3e6b86..498f64a8705 100644
--- a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
@@ -105,7 +105,7 @@ CONFIG_I2C_CHARDEV=m
105CONFIG_I2C_BLACKFIN_TWI=y 105CONFIG_I2C_BLACKFIN_TWI=y
106CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 106CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
107CONFIG_SPI=y 107CONFIG_SPI=y
108CONFIG_SPI_BFIN=y 108CONFIG_SPI_BFIN5XX=y
109CONFIG_GPIOLIB=y 109CONFIG_GPIOLIB=y
110CONFIG_GPIO_SYSFS=y 110CONFIG_GPIO_SYSFS=y
111# CONFIG_HWMON is not set 111# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 5e7321b2604..72e0317565e 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -99,7 +99,7 @@ CONFIG_I2C_CHARDEV=m
99CONFIG_I2C_BLACKFIN_TWI=y 99CONFIG_I2C_BLACKFIN_TWI=y
100CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 100CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
101CONFIG_SPI=y 101CONFIG_SPI=y
102CONFIG_SPI_BFIN=y 102CONFIG_SPI_BFIN5XX=y
103CONFIG_GPIOLIB=y 103CONFIG_GPIOLIB=y
104CONFIG_GPIO_SYSFS=y 104CONFIG_GPIO_SYSFS=y
105# CONFIG_HWMON is not set 105# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index a7eb54bf308..2f075e0b262 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -81,7 +81,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
81# CONFIG_LEGACY_PTYS is not set 81# CONFIG_LEGACY_PTYS is not set
82# CONFIG_HW_RANDOM is not set 82# CONFIG_HW_RANDOM is not set
83CONFIG_SPI=y 83CONFIG_SPI=y
84CONFIG_SPI_BFIN=y 84CONFIG_SPI_BFIN5XX=y
85CONFIG_GPIOLIB=y 85CONFIG_GPIOLIB=y
86CONFIG_GPIO_SYSFS=y 86CONFIG_GPIO_SYSFS=y
87# CONFIG_HWMON is not set 87# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index b90d3792ed5..ab38a82597b 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -84,7 +84,7 @@ CONFIG_I2C=m
84CONFIG_I2C_CHARDEV=m 84CONFIG_I2C_CHARDEV=m
85CONFIG_I2C_GPIO=m 85CONFIG_I2C_GPIO=m
86CONFIG_SPI=y 86CONFIG_SPI=y
87CONFIG_SPI_BFIN=y 87CONFIG_SPI_BFIN5XX=y
88CONFIG_GPIOLIB=y 88CONFIG_GPIOLIB=y
89CONFIG_GPIO_SYSFS=y 89CONFIG_GPIO_SYSFS=y
90# CONFIG_HWMON is not set 90# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 005362537a7..5c802d6bbbc 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -94,7 +94,7 @@ CONFIG_I2C_CHARDEV=m
94CONFIG_I2C_BLACKFIN_TWI=m 94CONFIG_I2C_BLACKFIN_TWI=m
95CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 95CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
96CONFIG_SPI=y 96CONFIG_SPI=y
97CONFIG_SPI_BFIN=y 97CONFIG_SPI_BFIN5XX=y
98CONFIG_GPIOLIB=y 98CONFIG_GPIOLIB=y
99CONFIG_GPIO_SYSFS=y 99CONFIG_GPIO_SYSFS=y
100# CONFIG_HWMON is not set 100# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index 580bf4296a1..972aa6263ad 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -101,7 +101,7 @@ CONFIG_I2C=m
101CONFIG_I2C_BLACKFIN_TWI=m 101CONFIG_I2C_BLACKFIN_TWI=m
102CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 102CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
103CONFIG_SPI=y 103CONFIG_SPI=y
104CONFIG_SPI_BFIN=y 104CONFIG_SPI_BFIN5XX=y
105CONFIG_GPIOLIB=y 105CONFIG_GPIOLIB=y
106CONFIG_GPIO_SYSFS=y 106CONFIG_GPIO_SYSFS=y
107# CONFIG_HWMON is not set 107# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 0e6d841b5d0..7a1e3bf2b04 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -113,7 +113,7 @@ CONFIG_I2C_CHARDEV=y
113CONFIG_I2C_BLACKFIN_TWI=y 113CONFIG_I2C_BLACKFIN_TWI=y
114CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 114CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
115CONFIG_SPI=y 115CONFIG_SPI=y
116CONFIG_SPI_BFIN=y 116CONFIG_SPI_BFIN5XX=y
117CONFIG_GPIOLIB=y 117CONFIG_GPIOLIB=y
118CONFIG_GPIO_SYSFS=y 118CONFIG_GPIO_SYSFS=y
119# CONFIG_HWMON is not set 119# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index 77a27e31d6d..0fdc4ecaa53 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -85,7 +85,7 @@ CONFIG_I2C=y
85CONFIG_I2C_CHARDEV=y 85CONFIG_I2C_CHARDEV=y
86CONFIG_I2C_PCA_PLATFORM=y 86CONFIG_I2C_PCA_PLATFORM=y
87CONFIG_SPI=y 87CONFIG_SPI=y
88CONFIG_SPI_BFIN=y 88CONFIG_SPI_BFIN5XX=y
89CONFIG_SPI_SPIDEV=y 89CONFIG_SPI_SPIDEV=y
90CONFIG_GPIOLIB=y 90CONFIG_GPIOLIB=y
91CONFIG_GPIO_SYSFS=y 91CONFIG_GPIO_SYSFS=y
diff --git a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
index f5ed34e12e0..78adbbf3982 100644
--- a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
@@ -84,7 +84,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
84# CONFIG_LEGACY_PTYS is not set 84# CONFIG_LEGACY_PTYS is not set
85# CONFIG_HW_RANDOM is not set 85# CONFIG_HW_RANDOM is not set
86CONFIG_SPI=y 86CONFIG_SPI=y
87CONFIG_SPI_BFIN=y 87CONFIG_SPI_BFIN5XX=y
88CONFIG_GPIOLIB=y 88CONFIG_GPIOLIB=y
89CONFIG_GPIO_SYSFS=y 89CONFIG_GPIO_SYSFS=y
90# CONFIG_HWMON is not set 90# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index d7ff2aee3fb..d3cd0f561c8 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -86,7 +86,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
86# CONFIG_LEGACY_PTYS is not set 86# CONFIG_LEGACY_PTYS is not set
87# CONFIG_HW_RANDOM is not set 87# CONFIG_HW_RANDOM is not set
88CONFIG_SPI=y 88CONFIG_SPI=y
89CONFIG_SPI_BFIN=y 89CONFIG_SPI_BFIN5XX=y
90CONFIG_GPIOLIB=y 90CONFIG_GPIOLIB=y
91CONFIG_GPIO_SYSFS=y 91CONFIG_GPIO_SYSFS=y
92# CONFIG_HWMON is not set 92# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig
index 85014319672..7b982d0502a 100644
--- a/arch/blackfin/configs/BlackStamp_defconfig
+++ b/arch/blackfin/configs/BlackStamp_defconfig
@@ -80,7 +80,7 @@ CONFIG_I2C=m
80CONFIG_I2C_CHARDEV=m 80CONFIG_I2C_CHARDEV=m
81CONFIG_I2C_GPIO=m 81CONFIG_I2C_GPIO=m
82CONFIG_SPI=y 82CONFIG_SPI=y
83CONFIG_SPI_BFIN=y 83CONFIG_SPI_BFIN5XX=y
84CONFIG_SPI_SPIDEV=m 84CONFIG_SPI_SPIDEV=m
85# CONFIG_HWMON is not set 85# CONFIG_HWMON is not set
86CONFIG_WATCHDOG=y 86CONFIG_WATCHDOG=y
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index dbf750cd2db..c280a50e794 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -88,7 +88,7 @@ CONFIG_I2C_CHARDEV=m
88CONFIG_I2C_BLACKFIN_TWI=m 88CONFIG_I2C_BLACKFIN_TWI=m
89CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 89CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
90CONFIG_SPI=y 90CONFIG_SPI=y
91CONFIG_SPI_BFIN=y 91CONFIG_SPI_BFIN5XX=y
92CONFIG_GPIOLIB=y 92CONFIG_GPIOLIB=y
93CONFIG_GPIO_SYSFS=y 93CONFIG_GPIO_SYSFS=y
94CONFIG_WATCHDOG=y 94CONFIG_WATCHDOG=y
diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig
index 07ffbdae34e..c940a1e3ab3 100644
--- a/arch/blackfin/configs/CM-BF533_defconfig
+++ b/arch/blackfin/configs/CM-BF533_defconfig
@@ -57,7 +57,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
57# CONFIG_LEGACY_PTYS is not set 57# CONFIG_LEGACY_PTYS is not set
58# CONFIG_HW_RANDOM is not set 58# CONFIG_HW_RANDOM is not set
59CONFIG_SPI=y 59CONFIG_SPI=y
60CONFIG_SPI_BFIN=y 60CONFIG_SPI_BFIN5XX=y
61# CONFIG_HWMON is not set 61# CONFIG_HWMON is not set
62# CONFIG_USB_SUPPORT is not set 62# CONFIG_USB_SUPPORT is not set
63CONFIG_MMC=y 63CONFIG_MMC=y
diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig
index 707cbf8a259..2e47df77490 100644
--- a/arch/blackfin/configs/CM-BF537E_defconfig
+++ b/arch/blackfin/configs/CM-BF537E_defconfig
@@ -78,7 +78,7 @@ CONFIG_SERIAL_BFIN_UART1=y
78# CONFIG_LEGACY_PTYS is not set 78# CONFIG_LEGACY_PTYS is not set
79# CONFIG_HW_RANDOM is not set 79# CONFIG_HW_RANDOM is not set
80CONFIG_SPI=y 80CONFIG_SPI=y
81CONFIG_SPI_BFIN=y 81CONFIG_SPI_BFIN5XX=y
82CONFIG_GPIOLIB=y 82CONFIG_GPIOLIB=y
83CONFIG_GPIO_SYSFS=y 83CONFIG_GPIO_SYSFS=y
84CONFIG_USB_GADGET=m 84CONFIG_USB_GADGET=m
diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig
index 4596935eada..6da629ffc2f 100644
--- a/arch/blackfin/configs/CM-BF537U_defconfig
+++ b/arch/blackfin/configs/CM-BF537U_defconfig
@@ -72,7 +72,7 @@ CONFIG_SERIAL_BFIN_UART1=y
72# CONFIG_LEGACY_PTYS is not set 72# CONFIG_LEGACY_PTYS is not set
73# CONFIG_HW_RANDOM is not set 73# CONFIG_HW_RANDOM is not set
74CONFIG_SPI=y 74CONFIG_SPI=y
75CONFIG_SPI_BFIN=y 75CONFIG_SPI_BFIN5XX=y
76CONFIG_GPIOLIB=y 76CONFIG_GPIOLIB=y
77CONFIG_GPIO_SYSFS=y 77CONFIG_GPIO_SYSFS=y
78CONFIG_USB_GADGET=y 78CONFIG_USB_GADGET=y
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index 9f1d08401fc..349922be01f 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -89,7 +89,7 @@ CONFIG_I2C=y
89CONFIG_I2C_CHARDEV=y 89CONFIG_I2C_CHARDEV=y
90CONFIG_I2C_BLACKFIN_TWI=y 90CONFIG_I2C_BLACKFIN_TWI=y
91CONFIG_SPI=y 91CONFIG_SPI=y
92CONFIG_SPI_BFIN=y 92CONFIG_SPI_BFIN5XX=y
93# CONFIG_HWMON is not set 93# CONFIG_HWMON is not set
94CONFIG_WATCHDOG=y 94CONFIG_WATCHDOG=y
95CONFIG_BFIN_WDT=y 95CONFIG_BFIN_WDT=y
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 6c7b21585a4..0456deaa2d6 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -78,7 +78,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
78# CONFIG_LEGACY_PTYS is not set 78# CONFIG_LEGACY_PTYS is not set
79# CONFIG_HW_RANDOM is not set 79# CONFIG_HW_RANDOM is not set
80CONFIG_SPI=y 80CONFIG_SPI=y
81CONFIG_SPI_BFIN=y 81CONFIG_SPI_BFIN5XX=y
82CONFIG_GPIOLIB=y 82CONFIG_GPIOLIB=y
83CONFIG_GPIO_SYSFS=y 83CONFIG_GPIO_SYSFS=y
84CONFIG_USB_GADGET=m 84CONFIG_USB_GADGET=m
diff --git a/arch/blackfin/configs/DNP5370_defconfig b/arch/blackfin/configs/DNP5370_defconfig
index b192acfae38..89162d0fff9 100644
--- a/arch/blackfin/configs/DNP5370_defconfig
+++ b/arch/blackfin/configs/DNP5370_defconfig
@@ -78,7 +78,7 @@ CONFIG_I2C=y
78CONFIG_I2C_CHARDEV=y 78CONFIG_I2C_CHARDEV=y
79CONFIG_I2C_BLACKFIN_TWI=y 79CONFIG_I2C_BLACKFIN_TWI=y
80CONFIG_SPI=y 80CONFIG_SPI=y
81CONFIG_SPI_BFIN=y 81CONFIG_SPI_BFIN5XX=y
82CONFIG_SPI_SPIDEV=y 82CONFIG_SPI_SPIDEV=y
83CONFIG_GPIOLIB=y 83CONFIG_GPIOLIB=y
84CONFIG_GPIO_SYSFS=y 84CONFIG_GPIO_SYSFS=y
diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig
index 06e9f497fae..a26436bf50f 100644
--- a/arch/blackfin/configs/H8606_defconfig
+++ b/arch/blackfin/configs/H8606_defconfig
@@ -68,7 +68,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
68# CONFIG_LEGACY_PTYS is not set 68# CONFIG_LEGACY_PTYS is not set
69# CONFIG_HW_RANDOM is not set 69# CONFIG_HW_RANDOM is not set
70CONFIG_SPI=y 70CONFIG_SPI=y
71CONFIG_SPI_BFIN=y 71CONFIG_SPI_BFIN5XX=y
72CONFIG_SPI_SPIDEV=y 72CONFIG_SPI_SPIDEV=y
73CONFIG_WATCHDOG=y 73CONFIG_WATCHDOG=y
74CONFIG_SOUND=m 74CONFIG_SOUND=m
diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig
index 5e797cf7204..647991514ac 100644
--- a/arch/blackfin/configs/IP0X_defconfig
+++ b/arch/blackfin/configs/IP0X_defconfig
@@ -70,7 +70,7 @@ CONFIG_SERIAL_BFIN_CONSOLE=y
70# CONFIG_LEGACY_PTYS is not set 70# CONFIG_LEGACY_PTYS is not set
71CONFIG_HW_RANDOM=y 71CONFIG_HW_RANDOM=y
72CONFIG_SPI=y 72CONFIG_SPI=y
73CONFIG_SPI_BFIN=y 73CONFIG_SPI_BFIN5XX=y
74# CONFIG_HWMON is not set 74# CONFIG_HWMON is not set
75CONFIG_WATCHDOG=y 75CONFIG_WATCHDOG=y
76CONFIG_USB=y 76CONFIG_USB=y
diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig
index a566a2fe6b9..8fd9b446d65 100644
--- a/arch/blackfin/configs/PNAV-10_defconfig
+++ b/arch/blackfin/configs/PNAV-10_defconfig
@@ -84,7 +84,7 @@ CONFIG_I2C_CHARDEV=y
84CONFIG_I2C_BLACKFIN_TWI=y 84CONFIG_I2C_BLACKFIN_TWI=y
85CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 85CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
86CONFIG_SPI=y 86CONFIG_SPI=y
87CONFIG_SPI_BFIN=y 87CONFIG_SPI_BFIN5XX=y
88CONFIG_FB=y 88CONFIG_FB=y
89CONFIG_FIRMWARE_EDID=y 89CONFIG_FIRMWARE_EDID=y
90CONFIG_BACKLIGHT_LCD_SUPPORT=y 90CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig
index 12e66cd7cda..0520c160230 100644
--- a/arch/blackfin/configs/SRV1_defconfig
+++ b/arch/blackfin/configs/SRV1_defconfig
@@ -71,7 +71,7 @@ CONFIG_I2C_CHARDEV=y
71CONFIG_I2C_BLACKFIN_TWI=y 71CONFIG_I2C_BLACKFIN_TWI=y
72CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 72CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
73CONFIG_SPI=y 73CONFIG_SPI=y
74CONFIG_SPI_BFIN=y 74CONFIG_SPI_BFIN5XX=y
75CONFIG_HWMON=m 75CONFIG_HWMON=m
76CONFIG_WATCHDOG=y 76CONFIG_WATCHDOG=y
77CONFIG_BFIN_WDT=y 77CONFIG_BFIN_WDT=y
diff --git a/arch/blackfin/configs/TCM-BF518_defconfig b/arch/blackfin/configs/TCM-BF518_defconfig
index d496ae9a39b..e4ed865b885 100644
--- a/arch/blackfin/configs/TCM-BF518_defconfig
+++ b/arch/blackfin/configs/TCM-BF518_defconfig
@@ -92,7 +92,7 @@ CONFIG_I2C_CHARDEV=y
92CONFIG_I2C_BLACKFIN_TWI=y 92CONFIG_I2C_BLACKFIN_TWI=y
93CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100 93CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
94CONFIG_SPI=y 94CONFIG_SPI=y
95CONFIG_SPI_BFIN=y 95CONFIG_SPI_BFIN5XX=y
96CONFIG_GPIOLIB=y 96CONFIG_GPIOLIB=y
97CONFIG_GPIO_SYSFS=y 97CONFIG_GPIO_SYSFS=y
98# CONFIG_HWMON is not set 98# CONFIG_HWMON is not set
diff --git a/arch/blackfin/configs/TCM-BF537_defconfig b/arch/blackfin/configs/TCM-BF537_defconfig
index 65f642167a5..c1f45f15295 100644
--- a/arch/blackfin/configs/TCM-BF537_defconfig
+++ b/arch/blackfin/configs/TCM-BF537_defconfig
@@ -70,7 +70,7 @@ CONFIG_SERIAL_BFIN_UART1=y
70# CONFIG_LEGACY_PTYS is not set 70# CONFIG_LEGACY_PTYS is not set
71# CONFIG_HW_RANDOM is not set 71# CONFIG_HW_RANDOM is not set
72CONFIG_SPI=y 72CONFIG_SPI=y
73CONFIG_SPI_BFIN=y 73CONFIG_SPI_BFIN5XX=y
74# CONFIG_HWMON is not set 74# CONFIG_HWMON is not set
75CONFIG_WATCHDOG=y 75CONFIG_WATCHDOG=y
76CONFIG_BFIN_WDT=y 76CONFIG_BFIN_WDT=y
diff --git a/arch/blackfin/include/asm/bfin_serial.h b/arch/blackfin/include/asm/bfin_serial.h
index ecacdf34768..68bcc3d119b 100644
--- a/arch/blackfin/include/asm/bfin_serial.h
+++ b/arch/blackfin/include/asm/bfin_serial.h
@@ -51,9 +51,6 @@ struct bfin_serial_port {
51#elif ANOMALY_05000363 51#elif ANOMALY_05000363
52 unsigned int anomaly_threshold; 52 unsigned int anomaly_threshold;
53#endif 53#endif
54#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
55 int scts;
56#endif
57#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \ 54#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
58 defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS) 55 defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
59 int cts_pin; 56 int cts_pin;
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h
index 05043786da2..e349631c829 100644
--- a/arch/blackfin/include/asm/cpu.h
+++ b/arch/blackfin/include/asm/cpu.h
@@ -14,6 +14,9 @@ struct blackfin_cpudata {
14 struct cpu cpu; 14 struct cpu cpu;
15 unsigned int imemctl; 15 unsigned int imemctl;
16 unsigned int dmemctl; 16 unsigned int dmemctl;
17#ifdef CONFIG_SMP
18 struct task_struct *idle;
19#endif
17}; 20};
18 21
19DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data); 22DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h
index af6c0aa79ba..dc3d144b4bb 100644
--- a/arch/blackfin/include/asm/smp.h
+++ b/arch/blackfin/include/asm/smp.h
@@ -37,7 +37,7 @@ extern unsigned long dcache_invld_count[NR_CPUS];
37#endif 37#endif
38 38
39void smp_icache_flush_range_others(unsigned long start, 39void smp_icache_flush_range_others(unsigned long start,
40 unsigned long end); 40 unsigned long end);
41#ifdef CONFIG_HOTPLUG_CPU 41#ifdef CONFIG_HOTPLUG_CPU
42void coreb_die(void); 42void coreb_die(void);
43void cpu_die(void); 43void cpu_die(void);
@@ -46,4 +46,7 @@ int __cpu_disable(void);
46int __cpu_die(unsigned int cpu); 46int __cpu_die(unsigned int cpu);
47#endif 47#endif
48 48
49void smp_timer_broadcast(const struct cpumask *mask);
50
51
49#endif /* !__ASM_BLACKFIN_SMP_H */ 52#endif /* !__ASM_BLACKFIN_SMP_H */
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index dfa2525a442..d6102c86d03 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -828,10 +828,18 @@ static inline int __init get_mem_size(void)
828 u32 ddrctl = bfin_read_EBIU_DDRCTL1(); 828 u32 ddrctl = bfin_read_EBIU_DDRCTL1();
829 int ret = 0; 829 int ret = 0;
830 switch (ddrctl & 0xc0000) { 830 switch (ddrctl & 0xc0000) {
831 case DEVSZ_64: ret = 64 / 8; 831 case DEVSZ_64:
832 case DEVSZ_128: ret = 128 / 8; 832 ret = 64 / 8;
833 case DEVSZ_256: ret = 256 / 8; 833 break;
834 case DEVSZ_512: ret = 512 / 8; 834 case DEVSZ_128:
835 ret = 128 / 8;
836 break;
837 case DEVSZ_256:
838 ret = 256 / 8;
839 break;
840 case DEVSZ_512:
841 ret = 512 / 8;
842 break;
835 } 843 }
836 switch (ddrctl & 0x30000) { 844 switch (ddrctl & 0x30000) {
837 case DEVWD_4: ret *= 2; 845 case DEVWD_4: ret *= 2;
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 1bcf3a3c57d..d98f2d69b0c 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -219,7 +219,7 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
219 219
220#if defined(CONFIG_TICKSOURCE_CORETMR) 220#if defined(CONFIG_TICKSOURCE_CORETMR)
221/* per-cpu local core timer */ 221/* per-cpu local core timer */
222static DEFINE_PER_CPU(struct clock_event_device, coretmr_events); 222DEFINE_PER_CPU(struct clock_event_device, coretmr_events);
223 223
224static int bfin_coretmr_set_next_event(unsigned long cycles, 224static int bfin_coretmr_set_next_event(unsigned long cycles,
225 struct clock_event_device *evt) 225 struct clock_event_device *evt)
@@ -281,6 +281,7 @@ void bfin_coretmr_init(void)
281#ifdef CONFIG_CORE_TIMER_IRQ_L1 281#ifdef CONFIG_CORE_TIMER_IRQ_L1
282__attribute__((l1_text)) 282__attribute__((l1_text))
283#endif 283#endif
284
284irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id) 285irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
285{ 286{
286 int cpu = smp_processor_id(); 287 int cpu = smp_processor_id();
@@ -306,6 +307,11 @@ void bfin_coretmr_clockevent_init(void)
306 unsigned int cpu = smp_processor_id(); 307 unsigned int cpu = smp_processor_id();
307 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); 308 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
308 309
310#ifdef CONFIG_SMP
311 evt->broadcast = smp_timer_broadcast;
312#endif
313
314
309 evt->name = "bfin_core_timer"; 315 evt->name = "bfin_core_timer";
310 evt->rating = 350; 316 evt->rating = 350;
311 evt->irq = -1; 317 evt->irq = -1;
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index d1c0c0cff3e..a2d96d31bbf 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -61,7 +61,7 @@ static struct physmap_flash_data ezbrd_flash_data = {
61 61
62static struct resource ezbrd_flash_resource = { 62static struct resource ezbrd_flash_resource = {
63 .start = 0x20000000, 63 .start = 0x20000000,
64#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 64#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
65 .end = 0x202fffff, 65 .end = 0x202fffff,
66#else 66#else
67 .end = 0x203fffff, 67 .end = 0x203fffff,
@@ -122,6 +122,8 @@ static struct bfin_mii_bus_platform_data bfin_mii_bus_data = {
122#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE) 122#if defined(CONFIG_NET_DSA_KSZ8893M) || defined(CONFIG_NET_DSA_KSZ8893M_MODULE)
123 .phy_mask = 0xfff7, /* Only probe the port phy connect to the on chip MAC */ 123 .phy_mask = 0xfff7, /* Only probe the port phy connect to the on chip MAC */
124#endif 124#endif
125 .vlan1_mask = 1,
126 .vlan2_mask = 2,
125}; 127};
126 128
127static struct platform_device bfin_mii_bus = { 129static struct platform_device bfin_mii_bus = {
@@ -292,7 +294,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
292}; 294};
293 295
294/* SPI controller data */ 296/* SPI controller data */
295#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 297#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
296/* SPI (0) */ 298/* SPI (0) */
297static struct bfin5xx_spi_master bfin_spi0_info = { 299static struct bfin5xx_spi_master bfin_spi0_info = {
298 .num_chipselect = 6, 300 .num_chipselect = 6,
@@ -715,7 +717,7 @@ static struct platform_device *stamp_devices[] __initdata = {
715#endif 717#endif
716#endif 718#endif
717 719
718#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 720#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
719 &bfin_spi0_device, 721 &bfin_spi0_device,
720 &bfin_spi1_device, 722 &bfin_spi1_device,
721#endif 723#endif
@@ -777,7 +779,7 @@ static int __init ezbrd_init(void)
777 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 779 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
778 /* setup BF518-EZBRD GPIO pin PG11 to AMS2, PG15 to AMS3. */ 780 /* setup BF518-EZBRD GPIO pin PG11 to AMS2, PG15 to AMS3. */
779 peripheral_request(P_AMS2, "ParaFlash"); 781 peripheral_request(P_AMS2, "ParaFlash");
780#if !defined(CONFIG_SPI_BFIN) && !defined(CONFIG_SPI_BFIN_MODULE) 782#if !defined(CONFIG_SPI_BFIN5XX) && !defined(CONFIG_SPI_BFIN5XX_MODULE)
781 peripheral_request(P_AMS3, "ParaFlash"); 783 peripheral_request(P_AMS3, "ParaFlash");
782#endif 784#endif
783 return 0; 785 return 0;
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
index 5470bf89e52..f271310f739 100644
--- a/arch/blackfin/mach-bf518/boards/tcm-bf518.c
+++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -228,7 +228,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
228}; 228};
229 229
230/* SPI controller data */ 230/* SPI controller data */
231#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 231#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
232/* SPI (0) */ 232/* SPI (0) */
233static struct bfin5xx_spi_master bfin_spi0_info = { 233static struct bfin5xx_spi_master bfin_spi0_info = {
234 .num_chipselect = 6, 234 .num_chipselect = 6,
@@ -635,7 +635,7 @@ static struct platform_device *tcm_devices[] __initdata = {
635 &bfin_mac_device, 635 &bfin_mac_device,
636#endif 636#endif
637 637
638#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 638#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
639 &bfin_spi0_device, 639 &bfin_spi0_device,
640 &bfin_spi1_device, 640 &bfin_spi1_device,
641#endif 641#endif
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c
index 5bc6938157a..c8d5d2b7c73 100644
--- a/arch/blackfin/mach-bf527/boards/ad7160eval.c
+++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -334,7 +334,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
334#endif 334#endif
335}; 335};
336 336
337#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 337#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
338/* SPI controller data */ 338/* SPI controller data */
339static struct bfin5xx_spi_master bfin_spi0_info = { 339static struct bfin5xx_spi_master bfin_spi0_info = {
340 .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS, 340 .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
@@ -744,7 +744,7 @@ static struct platform_device *stamp_devices[] __initdata = {
744 &bfin_mac_device, 744 &bfin_mac_device,
745#endif 745#endif
746 746
747#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 747#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
748 &bfin_spi0_device, 748 &bfin_spi0_device,
749#endif 749#endif
750 750
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index cd289698b4d..7330607856e 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -444,7 +444,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
444#endif 444#endif
445}; 445};
446 446
447#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 447#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
448/* SPI controller data */ 448/* SPI controller data */
449static struct bfin5xx_spi_master bfin_spi0_info = { 449static struct bfin5xx_spi_master bfin_spi0_info = {
450 .num_chipselect = 8, 450 .num_chipselect = 8,
@@ -893,7 +893,7 @@ static struct platform_device *cmbf527_devices[] __initdata = {
893 &net2272_bfin_device, 893 &net2272_bfin_device,
894#endif 894#endif
895 895
896#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 896#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
897 &bfin_spi0_device, 897 &bfin_spi0_device,
898#endif 898#endif
899 899
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 9f792eafd1c..db3ecfce830 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -371,7 +371,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
371#endif 371#endif
372}; 372};
373 373
374#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 374#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
375/* SPI controller data */ 375/* SPI controller data */
376static struct bfin5xx_spi_master bfin_spi0_info = { 376static struct bfin5xx_spi_master bfin_spi0_info = {
377 .num_chipselect = 8, 377 .num_chipselect = 8,
@@ -776,7 +776,7 @@ static struct platform_device *stamp_devices[] __initdata = {
776 &bfin_mac_device, 776 &bfin_mac_device,
777#endif 777#endif
778 778
779#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 779#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
780 &bfin_spi0_device, 780 &bfin_spi0_device,
781#endif 781#endif
782 782
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 3ecafff5d2e..dfdd8e6bac7 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -664,7 +664,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
664#endif 664#endif
665}; 665};
666 666
667#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 667#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
668/* SPI controller data */ 668/* SPI controller data */
669static struct bfin5xx_spi_master bfin_spi0_info = { 669static struct bfin5xx_spi_master bfin_spi0_info = {
670 .num_chipselect = 8, 670 .num_chipselect = 8,
@@ -1189,7 +1189,7 @@ static struct platform_device *stamp_devices[] __initdata = {
1189 &net2272_bfin_device, 1189 &net2272_bfin_device,
1190#endif 1190#endif
1191 1191
1192#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1192#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1193 &bfin_spi0_device, 1193 &bfin_spi0_device,
1194#endif 1194#endif
1195 1195
diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c
index 3a92c4318d2..360e97fc529 100644
--- a/arch/blackfin/mach-bf527/boards/tll6527m.c
+++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -448,7 +448,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
448#endif 448#endif
449}; 449};
450 450
451#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 451#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
452/* SPI controller data */ 452/* SPI controller data */
453static struct bfin5xx_spi_master bfin_spi0_info = { 453static struct bfin5xx_spi_master bfin_spi0_info = {
454 .num_chipselect = EXP_GPIO_SPISEL_BASE + 8 + MAX_CTRL_CS, 454 .num_chipselect = EXP_GPIO_SPISEL_BASE + 8 + MAX_CTRL_CS,
@@ -831,7 +831,7 @@ static struct platform_device *tll6527m_devices[] __initdata = {
831 &bfin_mac_device, 831 &bfin_mac_device,
832#endif 832#endif
833 833
834#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 834#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
835 &bfin_spi0_device, 835 &bfin_spi0_device,
836#endif 836#endif
837 837
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 47cadd316e7..6cb7b3ed9b3 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -125,7 +125,7 @@ static struct platform_device net2272_bfin_device = {
125}; 125};
126#endif 126#endif
127 127
128#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 128#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
129/* all SPI peripherals info goes here */ 129/* all SPI peripherals info goes here */
130 130
131#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 131#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -398,7 +398,7 @@ static struct platform_device *h8606_devices[] __initdata = {
398 &net2272_bfin_device, 398 &net2272_bfin_device,
399#endif 399#endif
400 400
401#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 401#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
402 &bfin_spi0_device, 402 &bfin_spi0_device,
403#endif 403#endif
404 404
@@ -428,7 +428,7 @@ static int __init H8606_init(void)
428 printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n"); 428 printk(KERN_INFO "HV Sistemas H8606 board support by http://www.hvsistemas.com\n");
429 printk(KERN_INFO "%s(): registering device resources\n", __func__); 429 printk(KERN_INFO "%s(): registering device resources\n", __func__);
430 platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices)); 430 platform_add_devices(h8606_devices, ARRAY_SIZE(h8606_devices));
431#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 431#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
432 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 432 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
433#endif 433#endif
434 return 0; 434 return 0;
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 18817d57c7a..de44a3765e5 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -146,7 +146,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
146#endif 146#endif
147}; 147};
148 148
149#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 149#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
150/* SPI (0) */ 150/* SPI (0) */
151static struct resource bfin_spi0_resource[] = { 151static struct resource bfin_spi0_resource[] = {
152 [0] = { 152 [0] = {
@@ -422,7 +422,7 @@ static struct platform_device *stamp_devices[] __initdata = {
422#endif 422#endif
423 423
424 424
425#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 425#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
426 &bfin_spi0_device, 426 &bfin_spi0_device,
427#endif 427#endif
428 428
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index 2c8f30ef6a7..fe47e048c4e 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -29,7 +29,7 @@
29 */ 29 */
30const char bfin_board_name[] = "Bluetechnix CM BF533"; 30const char bfin_board_name[] = "Bluetechnix CM BF533";
31 31
32#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 32#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
33/* all SPI peripherals info goes here */ 33/* all SPI peripherals info goes here */
34#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 34#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
35static struct mtd_partition bfin_spi_flash_partitions[] = { 35static struct mtd_partition bfin_spi_flash_partitions[] = {
@@ -536,7 +536,7 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
536 &net2272_bfin_device, 536 &net2272_bfin_device,
537#endif 537#endif
538 538
539#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 539#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
540 &bfin_spi0_device, 540 &bfin_spi0_device,
541#endif 541#endif
542 542
@@ -549,7 +549,7 @@ static int __init cm_bf533_init(void)
549{ 549{
550 printk(KERN_INFO "%s(): registering device resources\n", __func__); 550 printk(KERN_INFO "%s(): registering device resources\n", __func__);
551 platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices)); 551 platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices));
552#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 552#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
553 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 553 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
554#endif 554#endif
555 return 0; 555 return 0;
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 144556e1449..07811c209b9 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -245,7 +245,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
245#endif 245#endif
246}; 246};
247 247
248#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 248#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
249/* SPI (0) */ 249/* SPI (0) */
250static struct resource bfin_spi0_resource[] = { 250static struct resource bfin_spi0_resource[] = {
251 [0] = { 251 [0] = {
@@ -484,7 +484,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
484 &smc91x_device, 484 &smc91x_device,
485#endif 485#endif
486 486
487#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 487#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
488 &bfin_spi0_device, 488 &bfin_spi0_device,
489#endif 489#endif
490 490
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index b597d4e50d5..e303dae4e2d 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -104,7 +104,7 @@ static struct platform_device dm9000_device2 = {
104#endif 104#endif
105 105
106 106
107#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 107#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
108/* all SPI peripherals info goes here */ 108/* all SPI peripherals info goes here */
109 109
110#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) 110#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
@@ -270,7 +270,7 @@ static struct platform_device *ip0x_devices[] __initdata = {
270#endif 270#endif
271#endif 271#endif
272 272
273#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 273#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
274 &spi_bfin_master_device, 274 &spi_bfin_master_device,
275#endif 275#endif
276 276
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 2afd02e14bd..ce88a7165b6 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -219,9 +219,10 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
219 }, 219 },
220#endif 220#endif
221 221
222#if defined(CONFIG_SND_BF5XX_SOC_AD183X) || defined(CONFIG_SND_BF5XX_SOC_AD183X_MODULE) 222#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
223 defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
223 { 224 {
224 .modalias = "ad183x", 225 .modalias = "ad1836",
225 .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ 226 .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
226 .bus_num = 0, 227 .bus_num = 0,
227 .chip_select = 4, 228 .chip_select = 4,
@@ -251,7 +252,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
251#endif 252#endif
252}; 253};
253 254
254#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 255#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
255/* SPI (0) */ 256/* SPI (0) */
256static struct resource bfin_spi0_resource[] = { 257static struct resource bfin_spi0_resource[] = {
257 [0] = { 258 [0] = {
@@ -471,7 +472,7 @@ static struct i2c_gpio_platform_data i2c_gpio_data = {
471 .scl_pin = GPIO_PF3, 472 .scl_pin = GPIO_PF3,
472 .sda_is_open_drain = 0, 473 .sda_is_open_drain = 0,
473 .scl_is_open_drain = 0, 474 .scl_is_open_drain = 0,
474 .udelay = 40, 475 .udelay = 10,
475}; 476};
476 477
477static struct platform_device i2c_gpio_device = { 478static struct platform_device i2c_gpio_device = {
@@ -540,27 +541,150 @@ static struct platform_device bfin_dpmc = {
540 }, 541 },
541}; 542};
542 543
544#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
545 defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) \
546 || defined(CONFIG_SND_BF5XX_AC97) || \
547 defined(CONFIG_SND_BF5XX_AC97_MODULE)
548
549#include <asm/bfin_sport.h>
550
551#define SPORT_REQ(x) \
552 [x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
553 P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
554
555static const u16 bfin_snd_pin[][7] = {
556 SPORT_REQ(0),
557 SPORT_REQ(1),
558};
559
560static struct bfin_snd_platform_data bfin_snd_data[] = {
561 {
562 .pin_req = &bfin_snd_pin[0][0],
563 },
564 {
565 .pin_req = &bfin_snd_pin[1][0],
566 },
567};
568
569#define BFIN_SND_RES(x) \
570 [x] = { \
571 { \
572 .start = SPORT##x##_TCR1, \
573 .end = SPORT##x##_TCR1, \
574 .flags = IORESOURCE_MEM \
575 }, \
576 { \
577 .start = CH_SPORT##x##_RX, \
578 .end = CH_SPORT##x##_RX, \
579 .flags = IORESOURCE_DMA, \
580 }, \
581 { \
582 .start = CH_SPORT##x##_TX, \
583 .end = CH_SPORT##x##_TX, \
584 .flags = IORESOURCE_DMA, \
585 }, \
586 { \
587 .start = IRQ_SPORT##x##_ERROR, \
588 .end = IRQ_SPORT##x##_ERROR, \
589 .flags = IORESOURCE_IRQ, \
590 } \
591 }
592
593static struct resource bfin_snd_resources[][4] = {
594 BFIN_SND_RES(0),
595 BFIN_SND_RES(1),
596};
597#endif
598
543#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 599#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
600static struct platform_device bfin_i2s_pcm = {
601 .name = "bfin-i2s-pcm-audio",
602 .id = -1,
603};
604#endif
605
606#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
607static struct platform_device bfin_tdm_pcm = {
608 .name = "bfin-tdm-pcm-audio",
609 .id = -1,
610};
611#endif
612
613#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
614static struct platform_device bfin_ac97_pcm = {
615 .name = "bfin-ac97-pcm-audio",
616 .id = -1,
617};
618#endif
619
620#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
621 defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
622static const unsigned ad73311_gpio[] = {
623 GPIO_PF4,
624};
625
626static struct platform_device bfin_ad73311_machine = {
627 .name = "bfin-snd-ad73311",
628 .id = 1,
629 .dev = {
630 .platform_data = (void *)ad73311_gpio,
631 },
632};
633#endif
634
635#if defined(CONFIG_SND_SOC_AD73311) || defined(CONFIG_SND_SOC_AD73311_MODULE)
636static struct platform_device bfin_ad73311_codec_device = {
637 .name = "ad73311",
638 .id = -1,
639};
640#endif
641
642#if defined(CONFIG_SND_SOC_AD74111) || defined(CONFIG_SND_SOC_AD74111_MODULE)
643static struct platform_device bfin_ad74111_codec_device = {
644 .name = "ad74111",
645 .id = -1,
646};
647#endif
648
649#if defined(CONFIG_SND_BF5XX_SOC_I2S) || \
650 defined(CONFIG_SND_BF5XX_SOC_I2S_MODULE)
544static struct platform_device bfin_i2s = { 651static struct platform_device bfin_i2s = {
545 .name = "bfin-i2s", 652 .name = "bfin-i2s",
546 .id = CONFIG_SND_BF5XX_SPORT_NUM, 653 .id = CONFIG_SND_BF5XX_SPORT_NUM,
547 /* TODO: add platform data here */ 654 .num_resources =
655 ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
656 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
657 .dev = {
658 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
659 },
548}; 660};
549#endif 661#endif
550 662
551#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) 663#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
664 defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
552static struct platform_device bfin_tdm = { 665static struct platform_device bfin_tdm = {
553 .name = "bfin-tdm", 666 .name = "bfin-tdm",
554 .id = CONFIG_SND_BF5XX_SPORT_NUM, 667 .id = CONFIG_SND_BF5XX_SPORT_NUM,
555 /* TODO: add platform data here */ 668 .num_resources =
669 ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
670 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
671 .dev = {
672 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
673 },
556}; 674};
557#endif 675#endif
558 676
559#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 677#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
678 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
560static struct platform_device bfin_ac97 = { 679static struct platform_device bfin_ac97 = {
561 .name = "bfin-ac97", 680 .name = "bfin-ac97",
562 .id = CONFIG_SND_BF5XX_SPORT_NUM, 681 .id = CONFIG_SND_BF5XX_SPORT_NUM,
563 /* TODO: add platform data here */ 682 .num_resources =
683 ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
684 .resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
685 .dev = {
686 .platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
687 },
564}; 688};
565#endif 689#endif
566 690
@@ -580,7 +704,7 @@ static struct platform_device *stamp_devices[] __initdata = {
580 &net2272_bfin_device, 704 &net2272_bfin_device,
581#endif 705#endif
582 706
583#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 707#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
584 &bfin_spi0_device, 708 &bfin_spi0_device,
585#endif 709#endif
586 710
@@ -596,7 +720,8 @@ static struct platform_device *stamp_devices[] __initdata = {
596#endif 720#endif
597#endif 721#endif
598 722
599#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) 723#if defined(CONFIG_SERIAL_BFIN_SPORT) || \
724 defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
600#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART 725#ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
601 &bfin_sport0_uart_device, 726 &bfin_sport0_uart_device,
602#endif 727#endif
@@ -618,14 +743,42 @@ static struct platform_device *stamp_devices[] __initdata = {
618#endif 743#endif
619 744
620#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 745#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
621 &bfin_i2s, 746 &bfin_i2s_pcm,
622#endif 747#endif
623 748
624#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) 749#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
625 &bfin_tdm, 750 &bfin_tdm_pcm,
626#endif 751#endif
627 752
628#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE) 753#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
754 &bfin_ac97_pcm,
755#endif
756
757#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
758 defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
759 &bfin_ad73311_machine,
760#endif
761
762#if defined(CONFIG_SND_SOC_AD73311) || defined(CONFIG_SND_SOC_AD73311_MODULE)
763 &bfin_ad73311_codec_device,
764#endif
765
766#if defined(CONFIG_SND_SOC_AD74111) || defined(CONFIG_SND_SOC_AD74111_MODULE)
767 &bfin_ad74111_codec_device,
768#endif
769
770#if defined(CONFIG_SND_BF5XX_SOC_I2S) || \
771 defined(CONFIG_SND_BF5XX_SOC_I2S_MODULE)
772 &bfin_i2s,
773#endif
774
775#if defined(CONFIG_SND_BF5XX_SOC_TDM) || \
776 defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
777 &bfin_tdm,
778#endif
779
780#if defined(CONFIG_SND_BF5XX_SOC_AC97) || \
781 defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
629 &bfin_ac97, 782 &bfin_ac97,
630#endif 783#endif
631}; 784};
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 604a430038e..0d4a2f61a97 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -31,7 +31,7 @@
31 */ 31 */
32const char bfin_board_name[] = "Bluetechnix CM BF537E"; 32const char bfin_board_name[] = "Bluetechnix CM BF537E";
33 33
34#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 34#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
35/* all SPI peripherals info goes here */ 35/* all SPI peripherals info goes here */
36 36
37#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 37#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -735,7 +735,7 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
735 &net2272_bfin_device, 735 &net2272_bfin_device,
736#endif 736#endif
737 737
738#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 738#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
739 &bfin_spi0_device, 739 &bfin_spi0_device,
740#endif 740#endif
741 741
@@ -770,7 +770,7 @@ static int __init cm_bf537e_init(void)
770{ 770{
771 printk(KERN_INFO "%s(): registering device resources\n", __func__); 771 printk(KERN_INFO "%s(): registering device resources\n", __func__);
772 platform_add_devices(cm_bf537e_devices, ARRAY_SIZE(cm_bf537e_devices)); 772 platform_add_devices(cm_bf537e_devices, ARRAY_SIZE(cm_bf537e_devices));
773#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 773#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
774 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 774 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
775#endif 775#endif
776 776
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index d916b46a44f..f5536982706 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -32,7 +32,7 @@
32 */ 32 */
33const char bfin_board_name[] = "Bluetechnix CM BF537U"; 33const char bfin_board_name[] = "Bluetechnix CM BF537U";
34 34
35#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 35#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
36/* all SPI peripherals info goes here */ 36/* all SPI peripherals info goes here */
37 37
38#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 38#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -700,7 +700,7 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
700 &net2272_bfin_device, 700 &net2272_bfin_device,
701#endif 701#endif
702 702
703#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 703#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
704 &bfin_spi0_device, 704 &bfin_spi0_device,
705#endif 705#endif
706 706
@@ -747,7 +747,7 @@ static int __init cm_bf537u_init(void)
747{ 747{
748 printk(KERN_INFO "%s(): registering device resources\n", __func__); 748 printk(KERN_INFO "%s(): registering device resources\n", __func__);
749 platform_add_devices(cm_bf537u_devices, ARRAY_SIZE(cm_bf537u_devices)); 749 platform_add_devices(cm_bf537u_devices, ARRAY_SIZE(cm_bf537u_devices));
750#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 750#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
751 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 751 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
752#endif 752#endif
753 753
diff --git a/arch/blackfin/mach-bf537/boards/dnp5370.c b/arch/blackfin/mach-bf537/boards/dnp5370.c
index 5f307228be6..11dadeb33d7 100644
--- a/arch/blackfin/mach-bf537/boards/dnp5370.c
+++ b/arch/blackfin/mach-bf537/boards/dnp5370.c
@@ -125,7 +125,7 @@ static struct platform_device asmb_flash_device = {
125}; 125};
126#endif 126#endif
127 127
128#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 128#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
129 129
130#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE) 130#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
131 131
@@ -370,7 +370,7 @@ static struct platform_device *dnp5370_devices[] __initdata = {
370 &bfin_mac_device, 370 &bfin_mac_device,
371#endif 371#endif
372 372
373#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 373#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
374 &spi_bfin_master_device, 374 &spi_bfin_master_device,
375#endif 375#endif
376 376
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index 3901dd093b9..d2d71282618 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -121,7 +121,7 @@ static struct platform_device net2272_bfin_device = {
121}; 121};
122#endif 122#endif
123 123
124#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 124#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
125/* all SPI peripherals info goes here */ 125/* all SPI peripherals info goes here */
126 126
127#if defined(CONFIG_MTD_M25P80) \ 127#if defined(CONFIG_MTD_M25P80) \
@@ -496,7 +496,7 @@ static struct platform_device *minotaur_devices[] __initdata = {
496 &net2272_bfin_device, 496 &net2272_bfin_device,
497#endif 497#endif
498 498
499#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 499#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
500 &bfin_spi0_device, 500 &bfin_spi0_device,
501#endif 501#endif
502 502
@@ -537,7 +537,7 @@ static int __init minotaur_init(void)
537{ 537{
538 printk(KERN_INFO "%s(): registering device resources\n", __func__); 538 printk(KERN_INFO "%s(): registering device resources\n", __func__);
539 platform_add_devices(minotaur_devices, ARRAY_SIZE(minotaur_devices)); 539 platform_add_devices(minotaur_devices, ARRAY_SIZE(minotaur_devices));
540#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 540#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
541 spi_register_board_info(bfin_spi_board_info, 541 spi_register_board_info(bfin_spi_board_info,
542 ARRAY_SIZE(bfin_spi_board_info)); 542 ARRAY_SIZE(bfin_spi_board_info));
543#endif 543#endif
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index aebd31c845f..6fd84709fc6 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -154,7 +154,7 @@ static struct platform_device net2272_bfin_device = {
154}; 154};
155#endif 155#endif
156 156
157#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 157#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
158/* all SPI peripherals info goes here */ 158/* all SPI peripherals info goes here */
159 159
160#if defined(CONFIG_MTD_M25P80) \ 160#if defined(CONFIG_MTD_M25P80) \
@@ -477,7 +477,7 @@ static struct platform_device *stamp_devices[] __initdata = {
477 &net2272_bfin_device, 477 &net2272_bfin_device,
478#endif 478#endif
479 479
480#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 480#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
481 &bfin_spi0_device, 481 &bfin_spi0_device,
482#endif 482#endif
483 483
@@ -508,7 +508,7 @@ static int __init pnav_init(void)
508{ 508{
509 printk(KERN_INFO "%s(): registering device resources\n", __func__); 509 printk(KERN_INFO "%s(): registering device resources\n", __func__);
510 platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); 510 platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
511#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 511#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
512 spi_register_board_info(bfin_spi_board_info, 512 spi_register_board_info(bfin_spi_board_info,
513 ARRAY_SIZE(bfin_spi_board_info)); 513 ARRAY_SIZE(bfin_spi_board_info));
514#endif 514#endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 7fbb0bbf867..2221173e489 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1420,7 +1420,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
1420#endif 1420#endif
1421}; 1421};
1422 1422
1423#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1423#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1424/* SPI controller data */ 1424/* SPI controller data */
1425static struct bfin5xx_spi_master bfin_spi0_info = { 1425static struct bfin5xx_spi_master bfin_spi0_info = {
1426 .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS, 1426 .num_chipselect = MAX_CTRL_CS + MAX_BLACKFIN_GPIOS,
@@ -1462,7 +1462,7 @@ static struct platform_device bfin_spi0_device = {
1462 1462
1463/* SPORT SPI controller data */ 1463/* SPORT SPI controller data */
1464static struct bfin5xx_spi_master bfin_sport_spi0_info = { 1464static struct bfin5xx_spi_master bfin_sport_spi0_info = {
1465 .num_chipselect = 1, /* master only supports one device */ 1465 .num_chipselect = MAX_BLACKFIN_GPIOS,
1466 .enable_dma = 0, /* master don't support DMA */ 1466 .enable_dma = 0, /* master don't support DMA */
1467 .pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI, 1467 .pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI,
1468 P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0}, 1468 P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0},
@@ -1492,7 +1492,7 @@ static struct platform_device bfin_sport_spi0_device = {
1492}; 1492};
1493 1493
1494static struct bfin5xx_spi_master bfin_sport_spi1_info = { 1494static struct bfin5xx_spi_master bfin_sport_spi1_info = {
1495 .num_chipselect = 1, /* master only supports one device */ 1495 .num_chipselect = MAX_BLACKFIN_GPIOS,
1496 .enable_dma = 0, /* master don't support DMA */ 1496 .enable_dma = 0, /* master don't support DMA */
1497 .pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI, 1497 .pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI,
1498 P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0}, 1498 P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0},
@@ -1558,6 +1558,71 @@ static struct platform_device bfin_lq035q1_device = {
1558}; 1558};
1559#endif 1559#endif
1560 1560
1561#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
1562 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
1563#include <linux/videodev2.h>
1564#include <media/blackfin/bfin_capture.h>
1565#include <media/blackfin/ppi.h>
1566
1567static const unsigned short ppi_req[] = {
1568 P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
1569 P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
1570 P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
1571 0,
1572};
1573
1574static const struct ppi_info ppi_info = {
1575 .type = PPI_TYPE_PPI,
1576 .dma_ch = CH_PPI,
1577 .irq_err = IRQ_PPI_ERROR,
1578 .base = (void __iomem *)PPI_CONTROL,
1579 .pin_req = ppi_req,
1580};
1581
1582#if defined(CONFIG_VIDEO_VS6624) \
1583 || defined(CONFIG_VIDEO_VS6624_MODULE)
1584static struct v4l2_input vs6624_inputs[] = {
1585 {
1586 .index = 0,
1587 .name = "Camera",
1588 .type = V4L2_INPUT_TYPE_CAMERA,
1589 .std = V4L2_STD_UNKNOWN,
1590 },
1591};
1592
1593static struct bcap_route vs6624_routes[] = {
1594 {
1595 .input = 0,
1596 .output = 0,
1597 },
1598};
1599
1600static const unsigned vs6624_ce_pin = GPIO_PF10;
1601
1602static struct bfin_capture_config bfin_capture_data = {
1603 .card_name = "BF537",
1604 .inputs = vs6624_inputs,
1605 .num_inputs = ARRAY_SIZE(vs6624_inputs),
1606 .routes = vs6624_routes,
1607 .i2c_adapter_id = 0,
1608 .board_info = {
1609 .type = "vs6624",
1610 .addr = 0x10,
1611 .platform_data = (void *)&vs6624_ce_pin,
1612 },
1613 .ppi_info = &ppi_info,
1614 .ppi_control = (PACK_EN | DLEN_8 | XFR_TYPE | 0x0020),
1615};
1616#endif
1617
1618static struct platform_device bfin_capture_device = {
1619 .name = "bfin_capture",
1620 .dev = {
1621 .platform_data = &bfin_capture_data,
1622 },
1623};
1624#endif
1625
1561#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 1626#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
1562#ifdef CONFIG_SERIAL_BFIN_UART0 1627#ifdef CONFIG_SERIAL_BFIN_UART0
1563static struct resource bfin_uart0_resources[] = { 1628static struct resource bfin_uart0_resources[] = {
@@ -2716,7 +2781,7 @@ static struct platform_device *stamp_devices[] __initdata = {
2716 &net2272_bfin_device, 2781 &net2272_bfin_device,
2717#endif 2782#endif
2718 2783
2719#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 2784#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
2720 &bfin_spi0_device, 2785 &bfin_spi0_device,
2721#endif 2786#endif
2722 2787
@@ -2733,6 +2798,11 @@ static struct platform_device *stamp_devices[] __initdata = {
2733 &bfin_lq035q1_device, 2798 &bfin_lq035q1_device,
2734#endif 2799#endif
2735 2800
2801#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
2802 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
2803 &bfin_capture_device,
2804#endif
2805
2736#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 2806#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
2737#ifdef CONFIG_SERIAL_BFIN_UART0 2807#ifdef CONFIG_SERIAL_BFIN_UART0
2738 &bfin_uart0_device, 2808 &bfin_uart0_device,
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 6917ce2fa55..988517671a5 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -32,7 +32,7 @@
32 */ 32 */
33const char bfin_board_name[] = "Bluetechnix TCM BF537"; 33const char bfin_board_name[] = "Bluetechnix TCM BF537";
34 34
35#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 35#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
36/* all SPI peripherals info goes here */ 36/* all SPI peripherals info goes here */
37 37
38#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 38#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -702,7 +702,7 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
702 &net2272_bfin_device, 702 &net2272_bfin_device,
703#endif 703#endif
704 704
705#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 705#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
706 &bfin_spi0_device, 706 &bfin_spi0_device,
707#endif 707#endif
708 708
@@ -737,7 +737,7 @@ static int __init tcm_bf537_init(void)
737{ 737{
738 printk(KERN_INFO "%s(): registering device resources\n", __func__); 738 printk(KERN_INFO "%s(): registering device resources\n", __func__);
739 platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); 739 platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
740#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 740#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
741 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 741 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
742#endif 742#endif
743 743
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index 8356eb599f1..1633a6f306c 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -490,7 +490,7 @@ static struct platform_device smc91x_device = {
490}; 490};
491#endif 491#endif
492 492
493#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 493#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
494/* all SPI peripherals info goes here */ 494/* all SPI peripherals info goes here */
495#if defined(CONFIG_MTD_M25P80) \ 495#if defined(CONFIG_MTD_M25P80) \
496 || defined(CONFIG_MTD_M25P80_MODULE) 496 || defined(CONFIG_MTD_M25P80_MODULE)
@@ -874,7 +874,7 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
874#endif 874#endif
875#endif 875#endif
876 876
877#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 877#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
878 &bf538_spi_master0, 878 &bf538_spi_master0,
879 &bf538_spi_master1, 879 &bf538_spi_master1,
880 &bf538_spi_master2, 880 &bf538_spi_master2,
@@ -938,7 +938,7 @@ static int __init ezkit_init(void)
938 printk(KERN_INFO "%s(): registering device resources\n", __func__); 938 printk(KERN_INFO "%s(): registering device resources\n", __func__);
939 platform_add_devices(cm_bf538_devices, ARRAY_SIZE(cm_bf538_devices)); 939 platform_add_devices(cm_bf538_devices, ARRAY_SIZE(cm_bf538_devices));
940 940
941#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 941#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
942 spi_register_board_info(bf538_spi_board_info, 942 spi_register_board_info(bf538_spi_board_info,
943 ARRAY_SIZE(bf538_spi_board_info)); 943 ARRAY_SIZE(bf538_spi_board_info));
944#endif 944#endif
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index 0350eacec21..68af594db48 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -854,7 +854,7 @@ static struct platform_device para_flash_device = {
854}; 854};
855#endif 855#endif
856 856
857#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 857#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
858/* all SPI peripherals info goes here */ 858/* all SPI peripherals info goes here */
859#if defined(CONFIG_MTD_M25P80) \ 859#if defined(CONFIG_MTD_M25P80) \
860 || defined(CONFIG_MTD_M25P80_MODULE) 860 || defined(CONFIG_MTD_M25P80_MODULE)
@@ -1175,7 +1175,7 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
1175 &bf54x_sdh_device, 1175 &bf54x_sdh_device,
1176#endif 1176#endif
1177 1177
1178#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1178#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1179 &bf54x_spi_master0, 1179 &bf54x_spi_master0,
1180 &bf54x_spi_master1, 1180 &bf54x_spi_master1,
1181#endif 1181#endif
@@ -1210,7 +1210,7 @@ static int __init cm_bf548_init(void)
1210 printk(KERN_INFO "%s(): registering device resources\n", __func__); 1210 printk(KERN_INFO "%s(): registering device resources\n", __func__);
1211 platform_add_devices(cm_bf548_devices, ARRAY_SIZE(cm_bf548_devices)); 1211 platform_add_devices(cm_bf548_devices, ARRAY_SIZE(cm_bf548_devices));
1212 1212
1213#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1213#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1214 spi_register_board_info(bf54x_spi_board_info, 1214 spi_register_board_info(bf54x_spi_board_info,
1215 ARRAY_SIZE(bf54x_spi_board_info)); 1215 ARRAY_SIZE(bf54x_spi_board_info));
1216#endif 1216#endif
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index bb868ac0fe2..3ea45f8bd61 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -1110,7 +1110,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
1110 }, 1110 },
1111#endif 1111#endif
1112}; 1112};
1113#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1113#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1114/* SPI (0) */ 1114/* SPI (0) */
1115static struct resource bfin_spi0_resource[] = { 1115static struct resource bfin_spi0_resource[] = {
1116 [0] = { 1116 [0] = {
@@ -1183,6 +1183,71 @@ static struct platform_device bf54x_spi_master1 = {
1183}; 1183};
1184#endif /* spi master and devices */ 1184#endif /* spi master and devices */
1185 1185
1186#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
1187 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
1188#include <linux/videodev2.h>
1189#include <media/blackfin/bfin_capture.h>
1190#include <media/blackfin/ppi.h>
1191
1192static const unsigned short ppi_req[] = {
1193 P_PPI1_D0, P_PPI1_D1, P_PPI1_D2, P_PPI1_D3,
1194 P_PPI1_D4, P_PPI1_D5, P_PPI1_D6, P_PPI1_D7,
1195 P_PPI1_CLK, P_PPI1_FS1, P_PPI1_FS2,
1196 0,
1197};
1198
1199static const struct ppi_info ppi_info = {
1200 .type = PPI_TYPE_EPPI,
1201 .dma_ch = CH_EPPI1,
1202 .irq_err = IRQ_EPPI1_ERROR,
1203 .base = (void __iomem *)EPPI1_STATUS,
1204 .pin_req = ppi_req,
1205};
1206
1207#if defined(CONFIG_VIDEO_VS6624) \
1208 || defined(CONFIG_VIDEO_VS6624_MODULE)
1209static struct v4l2_input vs6624_inputs[] = {
1210 {
1211 .index = 0,
1212 .name = "Camera",
1213 .type = V4L2_INPUT_TYPE_CAMERA,
1214 .std = V4L2_STD_UNKNOWN,
1215 },
1216};
1217
1218static struct bcap_route vs6624_routes[] = {
1219 {
1220 .input = 0,
1221 .output = 0,
1222 },
1223};
1224
1225static const unsigned vs6624_ce_pin = GPIO_PG6;
1226
1227static struct bfin_capture_config bfin_capture_data = {
1228 .card_name = "BF548",
1229 .inputs = vs6624_inputs,
1230 .num_inputs = ARRAY_SIZE(vs6624_inputs),
1231 .routes = vs6624_routes,
1232 .i2c_adapter_id = 0,
1233 .board_info = {
1234 .type = "vs6624",
1235 .addr = 0x10,
1236 .platform_data = (void *)&vs6624_ce_pin,
1237 },
1238 .ppi_info = &ppi_info,
1239 .ppi_control = (POLC | PACKEN | DLEN_8 | XFR_TYPE | 0x20),
1240};
1241#endif
1242
1243static struct platform_device bfin_capture_device = {
1244 .name = "bfin_capture",
1245 .dev = {
1246 .platform_data = &bfin_capture_data,
1247 },
1248};
1249#endif
1250
1186#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) 1251#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
1187static struct resource bfin_twi0_resource[] = { 1252static struct resource bfin_twi0_resource[] = {
1188 [0] = { 1253 [0] = {
@@ -1502,10 +1567,14 @@ static struct platform_device *ezkit_devices[] __initdata = {
1502 &bf54x_sdh_device, 1567 &bf54x_sdh_device,
1503#endif 1568#endif
1504 1569
1505#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 1570#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
1506 &bf54x_spi_master0, 1571 &bf54x_spi_master0,
1507 &bf54x_spi_master1, 1572 &bf54x_spi_master1,
1508#endif 1573#endif
1574#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
1575 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
1576 &bfin_capture_device,
1577#endif
1509 1578
1510#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE) 1579#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
1511 &bf54x_kpad_device, 1580 &bf54x_kpad_device,
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c
index b1b7339b6ba..f6ffd6f054c 100644
--- a/arch/blackfin/mach-bf561/boards/acvilon.c
+++ b/arch/blackfin/mach-bf561/boards/acvilon.c
@@ -372,7 +372,7 @@ static struct bfin5xx_spi_chip data_flash_chip_info = {
372}; 372};
373#endif 373#endif
374 374
375#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 375#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
376/* SPI (0) */ 376/* SPI (0) */
377static struct resource bfin_spi0_resource[] = { 377static struct resource bfin_spi0_resource[] = {
378 [0] = { 378 [0] = {
@@ -475,7 +475,7 @@ static struct platform_device bfin_dpmc = {
475static struct platform_device *acvilon_devices[] __initdata = { 475static struct platform_device *acvilon_devices[] __initdata = {
476 &bfin_dpmc, 476 &bfin_dpmc,
477 477
478#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 478#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
479 &bfin_spi0_device, 479 &bfin_spi0_device,
480#endif 480#endif
481 481
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index c017cf07ed4..d81450f635d 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -29,7 +29,7 @@
29 */ 29 */
30const char bfin_board_name[] = "Bluetechnix CM BF561"; 30const char bfin_board_name[] = "Bluetechnix CM BF561";
31 31
32#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 32#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
33/* all SPI peripherals info goes here */ 33/* all SPI peripherals info goes here */
34 34
35#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) 35#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
@@ -488,7 +488,7 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
488 &net2272_bfin_device, 488 &net2272_bfin_device,
489#endif 489#endif
490 490
491#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 491#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
492 &bfin_spi0_device, 492 &bfin_spi0_device,
493#endif 493#endif
494 494
@@ -523,7 +523,7 @@ static int __init cm_bf561_init(void)
523{ 523{
524 printk(KERN_INFO "%s(): registering device resources\n", __func__); 524 printk(KERN_INFO "%s(): registering device resources\n", __func__);
525 platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices)); 525 platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices));
526#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 526#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
527 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 527 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
528#endif 528#endif
529 529
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 27f22ed381d..838978808a1 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -291,7 +291,7 @@ static struct platform_device ezkit_flash_device = {
291}; 291};
292#endif 292#endif
293 293
294#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 294#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
295/* SPI (0) */ 295/* SPI (0) */
296static struct resource bfin_spi0_resource[] = { 296static struct resource bfin_spi0_resource[] = {
297 [0] = { 297 [0] = {
@@ -383,7 +383,7 @@ static struct i2c_gpio_platform_data i2c_gpio_data = {
383 .scl_pin = GPIO_PF0, 383 .scl_pin = GPIO_PF0,
384 .sda_is_open_drain = 0, 384 .sda_is_open_drain = 0,
385 .scl_is_open_drain = 0, 385 .scl_is_open_drain = 0,
386 .udelay = 40, 386 .udelay = 10,
387}; 387};
388 388
389static struct platform_device i2c_gpio_device = { 389static struct platform_device i2c_gpio_device = {
@@ -422,6 +422,96 @@ static struct platform_device bfin_dpmc = {
422 }, 422 },
423}; 423};
424 424
425#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
426 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
427#include <linux/videodev2.h>
428#include <media/blackfin/bfin_capture.h>
429#include <media/blackfin/ppi.h>
430
431static const unsigned short ppi_req[] = {
432 P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3,
433 P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7,
434 P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
435 0,
436};
437
438static const struct ppi_info ppi_info = {
439 .type = PPI_TYPE_PPI,
440 .dma_ch = CH_PPI0,
441 .irq_err = IRQ_PPI1_ERROR,
442 .base = (void __iomem *)PPI0_CONTROL,
443 .pin_req = ppi_req,
444};
445
446#if defined(CONFIG_VIDEO_ADV7183) \
447 || defined(CONFIG_VIDEO_ADV7183_MODULE)
448#include <media/adv7183.h>
449static struct v4l2_input adv7183_inputs[] = {
450 {
451 .index = 0,
452 .name = "Composite",
453 .type = V4L2_INPUT_TYPE_CAMERA,
454 .std = V4L2_STD_ALL,
455 },
456 {
457 .index = 1,
458 .name = "S-Video",
459 .type = V4L2_INPUT_TYPE_CAMERA,
460 .std = V4L2_STD_ALL,
461 },
462 {
463 .index = 2,
464 .name = "Component",
465 .type = V4L2_INPUT_TYPE_CAMERA,
466 .std = V4L2_STD_ALL,
467 },
468};
469
470static struct bcap_route adv7183_routes[] = {
471 {
472 .input = ADV7183_COMPOSITE4,
473 .output = ADV7183_8BIT_OUT,
474 },
475 {
476 .input = ADV7183_SVIDEO0,
477 .output = ADV7183_8BIT_OUT,
478 },
479 {
480 .input = ADV7183_COMPONENT0,
481 .output = ADV7183_8BIT_OUT,
482 },
483};
484
485
486static const unsigned adv7183_gpio[] = {
487 GPIO_PF13, /* reset pin */
488 GPIO_PF2, /* output enable pin */
489};
490
491static struct bfin_capture_config bfin_capture_data = {
492 .card_name = "BF561",
493 .inputs = adv7183_inputs,
494 .num_inputs = ARRAY_SIZE(adv7183_inputs),
495 .routes = adv7183_routes,
496 .i2c_adapter_id = 0,
497 .board_info = {
498 .type = "adv7183",
499 .addr = 0x20,
500 .platform_data = (void *)adv7183_gpio,
501 },
502 .ppi_info = &ppi_info,
503 .ppi_control = (PACK_EN | DLEN_8 | DMA32 | FLD_SEL),
504};
505#endif
506
507static struct platform_device bfin_capture_device = {
508 .name = "bfin_capture",
509 .dev = {
510 .platform_data = &bfin_capture_data,
511 },
512};
513#endif
514
425#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 515#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
426static struct platform_device bfin_i2s = { 516static struct platform_device bfin_i2s = {
427 .name = "bfin-i2s", 517 .name = "bfin-i2s",
@@ -462,7 +552,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
462 &bfin_isp1760_device, 552 &bfin_isp1760_device,
463#endif 553#endif
464 554
465#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) 555#if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE)
466 &bfin_spi0_device, 556 &bfin_spi0_device,
467#endif 557#endif
468 558
@@ -494,6 +584,11 @@ static struct platform_device *ezkit_devices[] __initdata = {
494 &ezkit_flash_device, 584 &ezkit_flash_device,
495#endif 585#endif
496 586
587#if defined(CONFIG_VIDEO_BLACKFIN_CAPTURE) \
588 || defined(CONFIG_VIDEO_BLACKFIN_CAPTURE_MODULE)
589 &bfin_capture_device,
590#endif
591
497#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) 592#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
498 &bfin_i2s, 593 &bfin_i2s,
499#endif 594#endif
diff --git a/arch/blackfin/mach-bf561/include/mach/pll.h b/arch/blackfin/mach-bf561/include/mach/pll.h
index 7977db2f1c1..00bdacee9cc 100644
--- a/arch/blackfin/mach-bf561/include/mach/pll.h
+++ b/arch/blackfin/mach-bf561/include/mach/pll.h
@@ -16,6 +16,7 @@
16#include <mach/irq.h> 16#include <mach/irq.h>
17 17
18#define SUPPLE_0_WAKEUP ((IRQ_SUPPLE_0 - (IRQ_CORETMR + 1)) % 32) 18#define SUPPLE_0_WAKEUP ((IRQ_SUPPLE_0 - (IRQ_CORETMR + 1)) % 32)
19#define SUPPLE_1_WAKEUP ((IRQ_SUPPLE_1 - (IRQ_CORETMR + 1)) % 32)
19 20
20static inline void 21static inline void
21bfin_iwr_restore(unsigned long iwr0, unsigned long iwr1, unsigned long iwr2) 22bfin_iwr_restore(unsigned long iwr0, unsigned long iwr1, unsigned long iwr2)
@@ -42,7 +43,8 @@ bfin_iwr_save(unsigned long niwr0, unsigned long niwr1, unsigned long niwr2,
42static inline void 43static inline void
43bfin_iwr_set_sup0(unsigned long *iwr0, unsigned long *iwr1, unsigned long *iwr2) 44bfin_iwr_set_sup0(unsigned long *iwr0, unsigned long *iwr1, unsigned long *iwr2)
44{ 45{
45 bfin_iwr_save(0, IWR_ENABLE(SUPPLE_0_WAKEUP), 0, iwr0, iwr1, iwr2); 46 bfin_iwr_save(0, IWR_ENABLE(SUPPLE_0_WAKEUP) |
47 IWR_ENABLE(SUPPLE_1_WAKEUP), 0, iwr0, iwr1, iwr2);
46} 48}
47 49
48#endif 50#endif
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index db22401e760..ab1c617b9cf 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -84,7 +84,7 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
84 84
85 if ((bfin_read_SYSCR() & COREB_SRAM_INIT) == 0) { 85 if ((bfin_read_SYSCR() & COREB_SRAM_INIT) == 0) {
86 /* CoreB already running, sending ipi to wakeup it */ 86 /* CoreB already running, sending ipi to wakeup it */
87 platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0); 87 smp_send_reschedule(cpu);
88 } else { 88 } else {
89 /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */ 89 /* Kick CoreB, which should start execution from CORE_SRAM_BASE. */
90 bfin_write_SYSCR(bfin_read_SYSCR() & ~COREB_SRAM_INIT); 90 bfin_write_SYSCR(bfin_read_SYSCR() & ~COREB_SRAM_INIT);
@@ -114,7 +114,8 @@ void __init platform_request_ipi(int irq, void *handler)
114 int ret; 114 int ret;
115 const char *name = (irq == IRQ_SUPPLE_0) ? supple0 : supple1; 115 const char *name = (irq == IRQ_SUPPLE_0) ? supple0 : supple1;
116 116
117 ret = request_irq(irq, handler, IRQF_PERCPU, name, handler); 117 ret = request_irq(irq, handler, IRQF_PERCPU | IRQF_NO_SUSPEND |
118 IRQF_FORCE_RESUME, name, handler);
118 if (ret) 119 if (ret)
119 panic("Cannot request %s for IPI service", name); 120 panic("Cannot request %s for IPI service", name);
120} 121}
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 0784a52389c..ac8f8a43158 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -14,6 +14,7 @@
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/cache.h> 16#include <linux/cache.h>
17#include <linux/clockchips.h>
17#include <linux/profile.h> 18#include <linux/profile.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/mm.h> 20#include <linux/mm.h>
@@ -47,9 +48,10 @@ unsigned long blackfin_iflush_l1_entry[NR_CPUS];
47 48
48struct blackfin_initial_pda __cpuinitdata initial_pda_coreb; 49struct blackfin_initial_pda __cpuinitdata initial_pda_coreb;
49 50
50#define BFIN_IPI_RESCHEDULE 0 51#define BFIN_IPI_TIMER 0
51#define BFIN_IPI_CALL_FUNC 1 52#define BFIN_IPI_RESCHEDULE 1
52#define BFIN_IPI_CPU_STOP 2 53#define BFIN_IPI_CALL_FUNC 2
54#define BFIN_IPI_CPU_STOP 3
53 55
54struct blackfin_flush_data { 56struct blackfin_flush_data {
55 unsigned long start; 57 unsigned long start;
@@ -160,6 +162,14 @@ static irqreturn_t ipi_handler_int0(int irq, void *dev_instance)
160 return IRQ_HANDLED; 162 return IRQ_HANDLED;
161} 163}
162 164
165DECLARE_PER_CPU(struct clock_event_device, coretmr_events);
166void ipi_timer(void)
167{
168 int cpu = smp_processor_id();
169 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
170 evt->event_handler(evt);
171}
172
163static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) 173static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
164{ 174{
165 struct ipi_message *msg; 175 struct ipi_message *msg;
@@ -176,18 +186,17 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
176 while (msg_queue->count) { 186 while (msg_queue->count) {
177 msg = &msg_queue->ipi_message[msg_queue->head]; 187 msg = &msg_queue->ipi_message[msg_queue->head];
178 switch (msg->type) { 188 switch (msg->type) {
189 case BFIN_IPI_TIMER:
190 ipi_timer();
191 break;
179 case BFIN_IPI_RESCHEDULE: 192 case BFIN_IPI_RESCHEDULE:
180 scheduler_ipi(); 193 scheduler_ipi();
181 break; 194 break;
182 case BFIN_IPI_CALL_FUNC: 195 case BFIN_IPI_CALL_FUNC:
183 spin_unlock_irqrestore(&msg_queue->lock, flags);
184 ipi_call_function(cpu, msg); 196 ipi_call_function(cpu, msg);
185 spin_lock_irqsave(&msg_queue->lock, flags);
186 break; 197 break;
187 case BFIN_IPI_CPU_STOP: 198 case BFIN_IPI_CPU_STOP:
188 spin_unlock_irqrestore(&msg_queue->lock, flags);
189 ipi_cpu_stop(cpu); 199 ipi_cpu_stop(cpu);
190 spin_lock_irqsave(&msg_queue->lock, flags);
191 break; 200 break;
192 default: 201 default:
193 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n", 202 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%lx\n",
@@ -297,8 +306,6 @@ void smp_send_reschedule(int cpu)
297{ 306{
298 cpumask_t callmap; 307 cpumask_t callmap;
299 /* simply trigger an ipi */ 308 /* simply trigger an ipi */
300 if (cpu_is_offline(cpu))
301 return;
302 309
303 cpumask_clear(&callmap); 310 cpumask_clear(&callmap);
304 cpumask_set_cpu(cpu, &callmap); 311 cpumask_set_cpu(cpu, &callmap);
@@ -308,6 +315,16 @@ void smp_send_reschedule(int cpu)
308 return; 315 return;
309} 316}
310 317
318void smp_send_msg(const struct cpumask *mask, unsigned long type)
319{
320 smp_send_message(*mask, type, NULL, NULL, 0);
321}
322
323void smp_timer_broadcast(const struct cpumask *mask)
324{
325 smp_send_msg(mask, BFIN_IPI_TIMER);
326}
327
311void smp_send_stop(void) 328void smp_send_stop(void)
312{ 329{
313 cpumask_t callmap; 330 cpumask_t callmap;
@@ -326,17 +343,24 @@ void smp_send_stop(void)
326int __cpuinit __cpu_up(unsigned int cpu) 343int __cpuinit __cpu_up(unsigned int cpu)
327{ 344{
328 int ret; 345 int ret;
329 static struct task_struct *idle; 346 struct blackfin_cpudata *ci = &per_cpu(cpu_data, cpu);
347 struct task_struct *idle = ci->idle;
330 348
331 if (idle) 349 if (idle) {
332 free_task(idle); 350 free_task(idle);
333 351 idle = NULL;
334 idle = fork_idle(cpu);
335 if (IS_ERR(idle)) {
336 printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
337 return PTR_ERR(idle);
338 } 352 }
339 353
354 if (!idle) {
355 idle = fork_idle(cpu);
356 if (IS_ERR(idle)) {
357 printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
358 return PTR_ERR(idle);
359 }
360 ci->idle = idle;
361 } else {
362 init_idle(idle, cpu);
363 }
340 secondary_stack = task_stack_page(idle) + THREAD_SIZE; 364 secondary_stack = task_stack_page(idle) + THREAD_SIZE;
341 365
342 ret = platform_boot_secondary(cpu, idle); 366 ret = platform_boot_secondary(cpu, idle);
@@ -411,6 +435,7 @@ void __cpuinit secondary_start_kernel(void)
411 435
412 bfin_setup_caches(cpu); 436 bfin_setup_caches(cpu);
413 437
438 notify_cpu_starting(cpu);
414 /* 439 /*
415 * Calibrate loops per jiffy value. 440 * Calibrate loops per jiffy value.
416 * IRQs need to be enabled here - D-cache can be invalidated 441 * IRQs need to be enabled here - D-cache can be invalidated
@@ -453,8 +478,10 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
453 smp_flush_data.start = start; 478 smp_flush_data.start = start;
454 smp_flush_data.end = end; 479 smp_flush_data.end = end;
455 480
456 if (smp_call_function(&ipi_flush_icache, &smp_flush_data, 0)) 481 preempt_disable();
482 if (smp_call_function(&ipi_flush_icache, &smp_flush_data, 1))
457 printk(KERN_WARNING "SMP: failed to run I-cache flush request on other CPUs\n"); 483 printk(KERN_WARNING "SMP: failed to run I-cache flush request on other CPUs\n");
484 preempt_enable();
458} 485}
459EXPORT_SYMBOL_GPL(smp_icache_flush_range_others); 486EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
460 487
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
new file mode 100644
index 00000000000..26e67f0f005
--- /dev/null
+++ b/arch/c6x/Kconfig
@@ -0,0 +1,174 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6config TMS320C6X
7 def_bool y
8 select CLKDEV_LOOKUP
9 select GENERIC_IRQ_SHOW
10 select HAVE_ARCH_TRACEHOOK
11 select HAVE_DMA_API_DEBUG
12 select HAVE_GENERIC_HARDIRQS
13 select HAVE_MEMBLOCK
14 select HAVE_SPARSE_IRQ
15 select OF
16 select OF_EARLY_FLATTREE
17
18config MMU
19 def_bool n
20
21config ZONE_DMA
22 def_bool y
23
24config FPU
25 def_bool n
26
27config HIGHMEM
28 def_bool n
29
30config NUMA
31 def_bool n
32
33config RWSEM_GENERIC_SPINLOCK
34 def_bool y
35
36config RWSEM_XCHGADD_ALGORITHM
37 def_bool n
38
39config GENERIC_CALIBRATE_DELAY
40 def_bool y
41
42config GENERIC_HWEIGHT
43 def_bool y
44
45config GENERIC_CLOCKEVENTS
46 def_bool y
47
48config GENERIC_CLOCKEVENTS_BROADCAST
49 bool
50
51config GENERIC_BUG
52 def_bool y
53
54config COMMON_CLKDEV
55 def_bool y
56
57config C6X_BIG_KERNEL
58 bool "Build a big kernel"
59 help
60 The C6X function call instruction has a limited range of +/- 2MiB.
61 This is sufficient for most kernels, but some kernel configurations
62 with lots of compiled-in functionality may require a larger range
63 for function calls. Use this option to have the compiler generate
64 function calls with 32-bit range. This will make the kernel both
65 larger and slower.
66
67 If unsure, say N.
68
69source "init/Kconfig"
70
71# Use the generic interrupt handling code in kernel/irq/
72
73source "kernel/Kconfig.freezer"
74
75config CMDLINE_BOOL
76 bool "Default bootloader kernel arguments"
77
78config CMDLINE
79 string "Kernel command line"
80 depends on CMDLINE_BOOL
81 default "console=ttyS0,57600"
82 help
83 On some architectures there is currently no way for the boot loader
84 to pass arguments to the kernel. For these architectures, you should
85 supply some command-line options at build time by entering them
86 here.
87
88config CMDLINE_FORCE
89 bool "Force default kernel command string"
90 depends on CMDLINE_BOOL
91 default n
92 help
93 Set this to have arguments from the default kernel command string
94 override those passed by the boot loader.
95
96config CPU_BIG_ENDIAN
97 bool "Build big-endian kernel"
98 default n
99 help
100 Say Y if you plan on running a kernel in big-endian mode.
101 Note that your board must be properly built and your board
102 port must properly enable any big-endian related features
103 of your chipset/board/processor.
104
105config FORCE_MAX_ZONEORDER
106 int "Maximum zone order"
107 default "13"
108 help
109 The kernel memory allocator divides physically contiguous memory
110 blocks into "zones", where each zone is a power of two number of
111 pages. This option selects the largest power of two that the kernel
112 keeps in the memory allocator. If you need to allocate very large
113 blocks of physically contiguous memory, then you may need to
114 increase this value.
115
116 This config option is actually maximum order plus one. For example,
117 a value of 11 means that the largest free memory block is 2^10 pages.
118
119menu "Processor type and features"
120
121source "arch/c6x/platforms/Kconfig"
122
123config TMS320C6X_CACHES_ON
124 bool "L2 cache support"
125 default y
126
127config KERNEL_RAM_BASE_ADDRESS
128 hex "Virtual address of memory base"
129 default 0xe0000000 if SOC_TMS320C6455
130 default 0xe0000000 if SOC_TMS320C6457
131 default 0xe0000000 if SOC_TMS320C6472
132 default 0x80000000
133
134source "mm/Kconfig"
135
136source "kernel/Kconfig.preempt"
137
138source "kernel/Kconfig.hz"
139source "kernel/time/Kconfig"
140
141endmenu
142
143menu "Executable file formats"
144
145source "fs/Kconfig.binfmt"
146
147endmenu
148
149source "net/Kconfig"
150
151source "drivers/Kconfig"
152
153source "fs/Kconfig"
154
155source "security/Kconfig"
156
157source "crypto/Kconfig"
158
159source "lib/Kconfig"
160
161menu "Kernel hacking"
162
163source "lib/Kconfig.debug"
164
165config ACCESS_CHECK
166 bool "Check the user pointer address"
167 default y
168 help
169 Usually the pointer transfer from user space is checked to see if its
170 address is in the kernel space.
171
172 Say N here to disable that check to improve the performance.
173
174endmenu
diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile
new file mode 100644
index 00000000000..1d08dd07027
--- /dev/null
+++ b/arch/c6x/Makefile
@@ -0,0 +1,60 @@
1#
2# linux/arch/c6x/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8
9cflags-y += -mno-dsbt -msdata=none
10
11cflags-$(CONFIG_C6X_BIG_KERNEL) += -mlong-calls
12
13CFLAGS_MODULE += -mlong-calls -mno-dsbt -msdata=none
14
15CHECKFLAGS +=
16
17KBUILD_CFLAGS += $(cflags-y)
18KBUILD_AFLAGS += $(cflags-y)
19
20ifdef CONFIG_CPU_BIG_ENDIAN
21KBUILD_CFLAGS += -mbig-endian
22KBUILD_AFLAGS += -mbig-endian
23LINKFLAGS += -mbig-endian
24KBUILD_LDFLAGS += -mbig-endian
25LDFLAGS += -EB
26endif
27
28head-y := arch/c6x/kernel/head.o
29core-y += arch/c6x/kernel/ arch/c6x/mm/ arch/c6x/platforms/
30libs-y += arch/c6x/lib/
31
32# Default to vmlinux.bin, override when needed
33all: vmlinux.bin
34
35boot := arch/$(ARCH)/boot
36
37# Are we making a dtbImage.<boardname> target? If so, crack out the boardname
38DTB:=$(subst dtbImage.,,$(filter dtbImage.%, $(MAKECMDGOALS)))
39export DTB
40
41ifneq ($(DTB),)
42core-y += $(boot)/
43endif
44
45# With make 3.82 we cannot mix normal and wildcard targets
46
47vmlinux.bin: vmlinux
48 $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
49
50dtbImage.%: vmlinux
51 $(Q)$(MAKE) $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
52
53archclean:
54 $(Q)$(MAKE) $(clean)=$(boot)
55
56define archhelp
57 @echo ' vmlinux.bin - Binary kernel image (arch/$(ARCH)/boot/vmlinux.bin)'
58 @echo ' dtbImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in'
59 @echo ' - stripped elf with fdt blob'
60endef
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
new file mode 100644
index 00000000000..ecca820e604
--- /dev/null
+++ b/arch/c6x/boot/Makefile
@@ -0,0 +1,30 @@
1#
2# Makefile for bootable kernel images
3#
4
5OBJCOPYFLAGS_vmlinux.bin := -O binary
6$(obj)/vmlinux.bin: vmlinux FORCE
7 $(call if_changed,objcopy)
8
9DTC_FLAGS ?= -p 1024
10
11ifneq ($(DTB),)
12obj-y += linked_dtb.o
13endif
14
15$(obj)/%.dtb: $(src)/dts/%.dts FORCE
16 $(call cmd,dtc)
17
18quiet_cmd_cp = CP $< $@$2
19 cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
20
21# Generate builtin.dtb from $(DTB).dtb
22$(obj)/builtin.dtb: $(obj)/$(DTB).dtb
23 $(call if_changed,cp)
24
25$(obj)/linked_dtb.o: $(obj)/builtin.dtb
26
27$(obj)/dtbImage.%: vmlinux
28 $(call if_changed,objcopy)
29
30clean-files := $(obj)/*.dtb
diff --git a/arch/c6x/boot/dts/dsk6455.dts b/arch/c6x/boot/dts/dsk6455.dts
new file mode 100644
index 00000000000..2b71f800618
--- /dev/null
+++ b/arch/c6x/boot/dts/dsk6455.dts
@@ -0,0 +1,62 @@
1/*
2 * arch/c6x/boot/dts/dsk6455.dts
3 *
4 * DSK6455 Evaluation Platform For TMS320C6455
5 * Copyright (C) 2011 Texas Instruments Incorporated
6 *
7 * Author: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 */
15
16/dts-v1/;
17
18/include/ "tms320c6455.dtsi"
19
20/ {
21 model = "Spectrum Digital DSK6455";
22 compatible = "spectrum-digital,dsk6455";
23
24 chosen {
25 bootargs = "root=/dev/nfs ip=dhcp rw";
26 };
27
28 memory {
29 device_type = "memory";
30 reg = <0xE0000000 0x08000000>;
31 };
32
33 soc {
34 megamod_pic: interrupt-controller@1800000 {
35 interrupts = < 12 13 14 15 >;
36 };
37
38 emifa@70000000 {
39 flash@3,0 {
40 #address-cells = <1>;
41 #size-cells = <1>;
42 compatible = "cfi-flash";
43 reg = <0x3 0x0 0x400000>;
44 bank-width = <1>;
45 device-width = <1>;
46 partition@0 {
47 reg = <0x0 0x400000>;
48 label = "NOR";
49 };
50 };
51 };
52
53 timer1: timer@2980000 {
54 interrupt-parent = <&megamod_pic>;
55 interrupts = < 69 >;
56 };
57
58 clock-controller@029a0000 {
59 clock-frequency = <50000000>;
60 };
61 };
62};
diff --git a/arch/c6x/boot/dts/evmc6457.dts b/arch/c6x/boot/dts/evmc6457.dts
new file mode 100644
index 00000000000..0301eb9a8ff
--- /dev/null
+++ b/arch/c6x/boot/dts/evmc6457.dts
@@ -0,0 +1,48 @@
1/*
2 * arch/c6x/boot/dts/evmc6457.dts
3 *
4 * EVMC6457 Evaluation Platform For TMS320C6457
5 *
6 * Copyright (C) 2011 Texas Instruments Incorporated
7 *
8 * Author: Mark Salter <msalter@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 */
16
17/dts-v1/;
18
19/include/ "tms320c6457.dtsi"
20
21/ {
22 model = "eInfochips EVMC6457";
23 compatible = "einfochips,evmc6457";
24
25 chosen {
26 bootargs = "console=hvc root=/dev/nfs ip=dhcp rw";
27 };
28
29 memory {
30 device_type = "memory";
31 reg = <0xE0000000 0x10000000>;
32 };
33
34 soc {
35 megamod_pic: interrupt-controller@1800000 {
36 interrupts = < 12 13 14 15 >;
37 };
38
39 timer0: timer@2940000 {
40 interrupt-parent = <&megamod_pic>;
41 interrupts = < 67 >;
42 };
43
44 clock-controller@29a0000 {
45 clock-frequency = <60000000>;
46 };
47 };
48};
diff --git a/arch/c6x/boot/dts/evmc6472.dts b/arch/c6x/boot/dts/evmc6472.dts
new file mode 100644
index 00000000000..3e207b449a9
--- /dev/null
+++ b/arch/c6x/boot/dts/evmc6472.dts
@@ -0,0 +1,73 @@
1/*
2 * arch/c6x/boot/dts/evmc6472.dts
3 *
4 * EVMC6472 Evaluation Platform For TMS320C6472
5 *
6 * Copyright (C) 2011 Texas Instruments Incorporated
7 *
8 * Author: Mark Salter <msalter@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 */
16
17/dts-v1/;
18
19/include/ "tms320c6472.dtsi"
20
21/ {
22 model = "eInfochips EVMC6472";
23 compatible = "einfochips,evmc6472";
24
25 chosen {
26 bootargs = "console=hvc root=/dev/nfs ip=dhcp rw";
27 };
28
29 memory {
30 device_type = "memory";
31 reg = <0xE0000000 0x10000000>;
32 };
33
34 soc {
35 megamod_pic: interrupt-controller@1800000 {
36 interrupts = < 12 13 14 15 >;
37 };
38
39 timer0: timer@25e0000 {
40 interrupt-parent = <&megamod_pic>;
41 interrupts = < 16 >;
42 };
43
44 timer1: timer@25f0000 {
45 interrupt-parent = <&megamod_pic>;
46 interrupts = < 16 >;
47 };
48
49 timer2: timer@2600000 {
50 interrupt-parent = <&megamod_pic>;
51 interrupts = < 16 >;
52 };
53
54 timer3: timer@2610000 {
55 interrupt-parent = <&megamod_pic>;
56 interrupts = < 16 >;
57 };
58
59 timer4: timer@2620000 {
60 interrupt-parent = <&megamod_pic>;
61 interrupts = < 16 >;
62 };
63
64 timer5: timer@2630000 {
65 interrupt-parent = <&megamod_pic>;
66 interrupts = < 16 >;
67 };
68
69 clock-controller@29a0000 {
70 clock-frequency = <25000000>;
71 };
72 };
73};
diff --git a/arch/c6x/boot/dts/evmc6474.dts b/arch/c6x/boot/dts/evmc6474.dts
new file mode 100644
index 00000000000..4dc291292bc
--- /dev/null
+++ b/arch/c6x/boot/dts/evmc6474.dts
@@ -0,0 +1,58 @@
1/*
2 * arch/c6x/boot/dts/evmc6474.dts
3 *
4 * EVMC6474 Evaluation Platform For TMS320C6474
5 *
6 * Copyright (C) 2011 Texas Instruments Incorporated
7 *
8 * Author: Mark Salter <msalter@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 */
16
17/dts-v1/;
18
19/include/ "tms320c6474.dtsi"
20
21/ {
22 model = "Spectrum Digital EVMC6474";
23 compatible = "spectrum-digital,evmc6474";
24
25 chosen {
26 bootargs = "console=hvc root=/dev/nfs ip=dhcp rw";
27 };
28
29 memory {
30 device_type = "memory";
31 reg = <0x80000000 0x08000000>;
32 };
33
34 soc {
35 megamod_pic: interrupt-controller@1800000 {
36 interrupts = < 12 13 14 15 >;
37 };
38
39 timer3: timer@2940000 {
40 interrupt-parent = <&megamod_pic>;
41 interrupts = < 39 >;
42 };
43
44 timer4: timer@2950000 {
45 interrupt-parent = <&megamod_pic>;
46 interrupts = < 41 >;
47 };
48
49 timer5: timer@2960000 {
50 interrupt-parent = <&megamod_pic>;
51 interrupts = < 43 >;
52 };
53
54 clock-controller@29a0000 {
55 clock-frequency = <50000000>;
56 };
57 };
58};
diff --git a/arch/c6x/boot/dts/tms320c6455.dtsi b/arch/c6x/boot/dts/tms320c6455.dtsi
new file mode 100644
index 00000000000..a804ec1e018
--- /dev/null
+++ b/arch/c6x/boot/dts/tms320c6455.dtsi
@@ -0,0 +1,96 @@
1
2/ {
3 #address-cells = <1>;
4 #size-cells = <1>;
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 cpu@0 {
11 device_type = "cpu";
12 model = "ti,c64x+";
13 reg = <0>;
14 };
15 };
16
17 soc {
18 compatible = "simple-bus";
19 model = "tms320c6455";
20 #address-cells = <1>;
21 #size-cells = <1>;
22 ranges;
23
24 core_pic: interrupt-controller {
25 interrupt-controller;
26 #interrupt-cells = <1>;
27 compatible = "ti,c64x+core-pic";
28 };
29
30 /*
31 * Megamodule interrupt controller
32 */
33 megamod_pic: interrupt-controller@1800000 {
34 compatible = "ti,c64x+megamod-pic";
35 interrupt-controller;
36 #interrupt-cells = <1>;
37 reg = <0x1800000 0x1000>;
38 interrupt-parent = <&core_pic>;
39 };
40
41 cache-controller@1840000 {
42 compatible = "ti,c64x+cache";
43 reg = <0x01840000 0x8400>;
44 };
45
46 emifa@70000000 {
47 compatible = "ti,c64x+emifa", "simple-bus";
48 #address-cells = <2>;
49 #size-cells = <1>;
50 reg = <0x70000000 0x100>;
51 ranges = <0x2 0x0 0xa0000000 0x00000008
52 0x3 0x0 0xb0000000 0x00400000
53 0x4 0x0 0xc0000000 0x10000000
54 0x5 0x0 0xD0000000 0x10000000>;
55
56 ti,dscr-dev-enable = <13>;
57 ti,emifa-burst-priority = <255>;
58 ti,emifa-ce-config = <0x00240120
59 0x00240120
60 0x00240122
61 0x00240122>;
62 };
63
64 timer1: timer@2980000 {
65 compatible = "ti,c64x+timer64";
66 reg = <0x2980000 0x40>;
67 ti,dscr-dev-enable = <4>;
68 };
69
70 clock-controller@029a0000 {
71 compatible = "ti,c6455-pll", "ti,c64x+pll";
72 reg = <0x029a0000 0x200>;
73 ti,c64x+pll-bypass-delay = <1440>;
74 ti,c64x+pll-reset-delay = <15360>;
75 ti,c64x+pll-lock-delay = <24000>;
76 };
77
78 device-state-config-regs@2a80000 {
79 compatible = "ti,c64x+dscr";
80 reg = <0x02a80000 0x41000>;
81
82 ti,dscr-devstat = <0>;
83 ti,dscr-silicon-rev = <8 28 0xf>;
84 ti,dscr-rmii-resets = <0 0x40020 0x00040000>;
85
86 ti,dscr-locked-regs = <0x40008 0x40004 0x0f0a0b00>;
87 ti,dscr-devstate-ctl-regs =
88 <0 12 0x40008 1 0 0 2
89 12 1 0x40008 3 0 30 2
90 13 2 0x4002c 1 0xffffffff 0 1>;
91 ti,dscr-devstate-stat-regs =
92 <0 10 0x40014 1 0 0 3
93 10 2 0x40018 1 0 0 3>;
94 };
95 };
96};
diff --git a/arch/c6x/boot/dts/tms320c6457.dtsi b/arch/c6x/boot/dts/tms320c6457.dtsi
new file mode 100644
index 00000000000..35f40709a71
--- /dev/null
+++ b/arch/c6x/boot/dts/tms320c6457.dtsi
@@ -0,0 +1,68 @@
1
2/ {
3 #address-cells = <1>;
4 #size-cells = <1>;
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 cpu@0 {
11 device_type = "cpu";
12 model = "ti,c64x+";
13 reg = <0>;
14 };
15 };
16
17 soc {
18 compatible = "simple-bus";
19 model = "tms320c6457";
20 #address-cells = <1>;
21 #size-cells = <1>;
22 ranges;
23
24 core_pic: interrupt-controller {
25 interrupt-controller;
26 #interrupt-cells = <1>;
27 compatible = "ti,c64x+core-pic";
28 };
29
30 megamod_pic: interrupt-controller@1800000 {
31 compatible = "ti,c64x+megamod-pic";
32 interrupt-controller;
33 #interrupt-cells = <1>;
34 interrupt-parent = <&core_pic>;
35 reg = <0x1800000 0x1000>;
36 };
37
38 cache-controller@1840000 {
39 compatible = "ti,c64x+cache";
40 reg = <0x01840000 0x8400>;
41 };
42
43 device-state-controller@2880800 {
44 compatible = "ti,c64x+dscr";
45 reg = <0x02880800 0x400>;
46
47 ti,dscr-devstat = <0x20>;
48 ti,dscr-silicon-rev = <0x18 28 0xf>;
49 ti,dscr-mac-fuse-regs = <0x114 3 4 5 6
50 0x118 0 0 1 2>;
51 ti,dscr-kick-regs = <0x38 0x83E70B13
52 0x3c 0x95A4F1E0>;
53 };
54
55 timer0: timer@2940000 {
56 compatible = "ti,c64x+timer64";
57 reg = <0x2940000 0x40>;
58 };
59
60 clock-controller@29a0000 {
61 compatible = "ti,c6457-pll", "ti,c64x+pll";
62 reg = <0x029a0000 0x200>;
63 ti,c64x+pll-bypass-delay = <300>;
64 ti,c64x+pll-reset-delay = <24000>;
65 ti,c64x+pll-lock-delay = <50000>;
66 };
67 };
68};
diff --git a/arch/c6x/boot/dts/tms320c6472.dtsi b/arch/c6x/boot/dts/tms320c6472.dtsi
new file mode 100644
index 00000000000..b488aaec65c
--- /dev/null
+++ b/arch/c6x/boot/dts/tms320c6472.dtsi
@@ -0,0 +1,134 @@
1
2/ {
3 #address-cells = <1>;
4 #size-cells = <1>;
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 cpu@0 {
11 device_type = "cpu";
12 reg = <0>;
13 model = "ti,c64x+";
14 };
15 cpu@1 {
16 device_type = "cpu";
17 reg = <1>;
18 model = "ti,c64x+";
19 };
20 cpu@2 {
21 device_type = "cpu";
22 reg = <2>;
23 model = "ti,c64x+";
24 };
25 cpu@3 {
26 device_type = "cpu";
27 reg = <3>;
28 model = "ti,c64x+";
29 };
30 cpu@4 {
31 device_type = "cpu";
32 reg = <4>;
33 model = "ti,c64x+";
34 };
35 cpu@5 {
36 device_type = "cpu";
37 reg = <5>;
38 model = "ti,c64x+";
39 };
40 };
41
42 soc {
43 compatible = "simple-bus";
44 model = "tms320c6472";
45 #address-cells = <1>;
46 #size-cells = <1>;
47 ranges;
48
49 core_pic: interrupt-controller {
50 compatible = "ti,c64x+core-pic";
51 interrupt-controller;
52 #interrupt-cells = <1>;
53 };
54
55 megamod_pic: interrupt-controller@1800000 {
56 compatible = "ti,c64x+megamod-pic";
57 interrupt-controller;
58 #interrupt-cells = <1>;
59 reg = <0x1800000 0x1000>;
60 interrupt-parent = <&core_pic>;
61 };
62
63 cache-controller@1840000 {
64 compatible = "ti,c64x+cache";
65 reg = <0x01840000 0x8400>;
66 };
67
68 timer0: timer@25e0000 {
69 compatible = "ti,c64x+timer64";
70 ti,core-mask = < 0x01 >;
71 reg = <0x25e0000 0x40>;
72 };
73
74 timer1: timer@25f0000 {
75 compatible = "ti,c64x+timer64";
76 ti,core-mask = < 0x02 >;
77 reg = <0x25f0000 0x40>;
78 };
79
80 timer2: timer@2600000 {
81 compatible = "ti,c64x+timer64";
82 ti,core-mask = < 0x04 >;
83 reg = <0x2600000 0x40>;
84 };
85
86 timer3: timer@2610000 {
87 compatible = "ti,c64x+timer64";
88 ti,core-mask = < 0x08 >;
89 reg = <0x2610000 0x40>;
90 };
91
92 timer4: timer@2620000 {
93 compatible = "ti,c64x+timer64";
94 ti,core-mask = < 0x10 >;
95 reg = <0x2620000 0x40>;
96 };
97
98 timer5: timer@2630000 {
99 compatible = "ti,c64x+timer64";
100 ti,core-mask = < 0x20 >;
101 reg = <0x2630000 0x40>;
102 };
103
104 clock-controller@29a0000 {
105 compatible = "ti,c6472-pll", "ti,c64x+pll";
106 reg = <0x029a0000 0x200>;
107 ti,c64x+pll-bypass-delay = <200>;
108 ti,c64x+pll-reset-delay = <12000>;
109 ti,c64x+pll-lock-delay = <80000>;
110 };
111
112 device-state-controller@2a80000 {
113 compatible = "ti,c64x+dscr";
114 reg = <0x02a80000 0x1000>;
115
116 ti,dscr-devstat = <0>;
117 ti,dscr-silicon-rev = <0x70c 16 0xff>;
118
119 ti,dscr-mac-fuse-regs = <0x700 1 2 3 4
120 0x704 5 6 0 0>;
121
122 ti,dscr-rmii-resets = <0x208 1
123 0x20c 1>;
124
125 ti,dscr-locked-regs = <0x200 0x204 0x0a1e183a
126 0x40c 0x420 0xbea7
127 0x41c 0x420 0xbea7>;
128
129 ti,dscr-privperm = <0x41c 0xaaaaaaaa>;
130
131 ti,dscr-devstate-ctl-regs = <0 13 0x200 1 0 0 1>;
132 };
133 };
134};
diff --git a/arch/c6x/boot/dts/tms320c6474.dtsi b/arch/c6x/boot/dts/tms320c6474.dtsi
new file mode 100644
index 00000000000..cc601bf348a
--- /dev/null
+++ b/arch/c6x/boot/dts/tms320c6474.dtsi
@@ -0,0 +1,89 @@
1
2/ {
3 #address-cells = <1>;
4 #size-cells = <1>;
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 cpu@0 {
11 device_type = "cpu";
12 reg = <0>;
13 model = "ti,c64x+";
14 };
15 cpu@1 {
16 device_type = "cpu";
17 reg = <1>;
18 model = "ti,c64x+";
19 };
20 cpu@2 {
21 device_type = "cpu";
22 reg = <2>;
23 model = "ti,c64x+";
24 };
25 };
26
27 soc {
28 compatible = "simple-bus";
29 model = "tms320c6474";
30 #address-cells = <1>;
31 #size-cells = <1>;
32 ranges;
33
34 core_pic: interrupt-controller {
35 interrupt-controller;
36 #interrupt-cells = <1>;
37 compatible = "ti,c64x+core-pic";
38 };
39
40 megamod_pic: interrupt-controller@1800000 {
41 compatible = "ti,c64x+megamod-pic";
42 interrupt-controller;
43 #interrupt-cells = <1>;
44 reg = <0x1800000 0x1000>;
45 interrupt-parent = <&core_pic>;
46 };
47
48 cache-controller@1840000 {
49 compatible = "ti,c64x+cache";
50 reg = <0x01840000 0x8400>;
51 };
52
53 timer3: timer@2940000 {
54 compatible = "ti,c64x+timer64";
55 ti,core-mask = < 0x04 >;
56 reg = <0x2940000 0x40>;
57 };
58
59 timer4: timer@2950000 {
60 compatible = "ti,c64x+timer64";
61 ti,core-mask = < 0x02 >;
62 reg = <0x2950000 0x40>;
63 };
64
65 timer5: timer@2960000 {
66 compatible = "ti,c64x+timer64";
67 ti,core-mask = < 0x01 >;
68 reg = <0x2960000 0x40>;
69 };
70
71 device-state-controller@2880800 {
72 compatible = "ti,c64x+dscr";
73 reg = <0x02880800 0x400>;
74
75 ti,dscr-devstat = <0x004>;
76 ti,dscr-silicon-rev = <0x014 28 0xf>;
77 ti,dscr-mac-fuse-regs = <0x34 3 4 5 6
78 0x38 0 0 1 2>;
79 };
80
81 clock-controller@29a0000 {
82 compatible = "ti,c6474-pll", "ti,c64x+pll";
83 reg = <0x029a0000 0x200>;
84 ti,c64x+pll-bypass-delay = <120>;
85 ti,c64x+pll-reset-delay = <30000>;
86 ti,c64x+pll-lock-delay = <60000>;
87 };
88 };
89};
diff --git a/arch/c6x/boot/linked_dtb.S b/arch/c6x/boot/linked_dtb.S
new file mode 100644
index 00000000000..57a4454eaec
--- /dev/null
+++ b/arch/c6x/boot/linked_dtb.S
@@ -0,0 +1,2 @@
1.section __fdt_blob,"a"
2.incbin "arch/c6x/boot/builtin.dtb"
diff --git a/arch/c6x/configs/dsk6455_defconfig b/arch/c6x/configs/dsk6455_defconfig
new file mode 100644
index 00000000000..4663487c67a
--- /dev/null
+++ b/arch/c6x/configs/dsk6455_defconfig
@@ -0,0 +1,44 @@
1CONFIG_SOC_TMS320C6455=y
2CONFIG_EXPERIMENTAL=y
3# CONFIG_LOCALVERSION_AUTO is not set
4CONFIG_SYSVIPC=y
5CONFIG_SPARSE_IRQ=y
6CONFIG_LOG_BUF_SHIFT=14
7CONFIG_NAMESPACES=y
8# CONFIG_UTS_NS is not set
9# CONFIG_USER_NS is not set
10# CONFIG_PID_NS is not set
11CONFIG_BLK_DEV_INITRD=y
12CONFIG_CC_OPTIMIZE_FOR_SIZE=y
13CONFIG_EXPERT=y
14# CONFIG_FUTEX is not set
15# CONFIG_SLUB_DEBUG is not set
16CONFIG_MODULES=y
17CONFIG_MODULE_FORCE_LOAD=y
18CONFIG_MODULE_UNLOAD=y
19CONFIG_MODULE_FORCE_UNLOAD=y
20CONFIG_CMDLINE_BOOL=y
21CONFIG_CMDLINE=""
22CONFIG_NO_HZ=y
23CONFIG_HIGH_RES_TIMERS=y
24CONFIG_BLK_DEV_LOOP=y
25CONFIG_BLK_DEV_RAM=y
26CONFIG_BLK_DEV_RAM_COUNT=2
27CONFIG_BLK_DEV_RAM_SIZE=17000
28CONFIG_MISC_DEVICES=y
29# CONFIG_INPUT is not set
30# CONFIG_SERIO is not set
31# CONFIG_VT is not set
32# CONFIG_HW_RANDOM is not set
33# CONFIG_HWMON is not set
34# CONFIG_USB_SUPPORT is not set
35# CONFIG_IOMMU_SUPPORT is not set
36# CONFIG_MISC_FILESYSTEMS is not set
37CONFIG_CRC16=y
38# CONFIG_ENABLE_MUST_CHECK is not set
39# CONFIG_SCHED_DEBUG is not set
40# CONFIG_DEBUG_BUGVERBOSE is not set
41CONFIG_MTD=y
42CONFIG_MTD_CFI=y
43CONFIG_MTD_CFI_AMDSTD=y
44CONFIG_MTD_PHYSMAP_OF=y
diff --git a/arch/c6x/configs/evmc6457_defconfig b/arch/c6x/configs/evmc6457_defconfig
new file mode 100644
index 00000000000..bba40e195ec
--- /dev/null
+++ b/arch/c6x/configs/evmc6457_defconfig
@@ -0,0 +1,41 @@
1CONFIG_SOC_TMS320C6457=y
2CONFIG_EXPERIMENTAL=y
3# CONFIG_LOCALVERSION_AUTO is not set
4CONFIG_SYSVIPC=y
5CONFIG_SPARSE_IRQ=y
6CONFIG_LOG_BUF_SHIFT=14
7CONFIG_NAMESPACES=y
8# CONFIG_UTS_NS is not set
9# CONFIG_USER_NS is not set
10# CONFIG_PID_NS is not set
11CONFIG_BLK_DEV_INITRD=y
12CONFIG_CC_OPTIMIZE_FOR_SIZE=y
13CONFIG_EXPERT=y
14# CONFIG_FUTEX is not set
15# CONFIG_SLUB_DEBUG is not set
16CONFIG_MODULES=y
17CONFIG_MODULE_FORCE_LOAD=y
18CONFIG_MODULE_UNLOAD=y
19CONFIG_MODULE_FORCE_UNLOAD=y
20CONFIG_CMDLINE_BOOL=y
21CONFIG_CMDLINE=""
22CONFIG_BOARD_EVM6457=y
23CONFIG_NO_HZ=y
24CONFIG_HIGH_RES_TIMERS=y
25CONFIG_BLK_DEV_LOOP=y
26CONFIG_BLK_DEV_RAM=y
27CONFIG_BLK_DEV_RAM_COUNT=2
28CONFIG_BLK_DEV_RAM_SIZE=17000
29CONFIG_MISC_DEVICES=y
30# CONFIG_INPUT is not set
31# CONFIG_SERIO is not set
32# CONFIG_VT is not set
33# CONFIG_HW_RANDOM is not set
34# CONFIG_HWMON is not set
35# CONFIG_USB_SUPPORT is not set
36# CONFIG_IOMMU_SUPPORT is not set
37# CONFIG_MISC_FILESYSTEMS is not set
38CONFIG_CRC16=y
39# CONFIG_ENABLE_MUST_CHECK is not set
40# CONFIG_SCHED_DEBUG is not set
41# CONFIG_DEBUG_BUGVERBOSE is not set
diff --git a/arch/c6x/configs/evmc6472_defconfig b/arch/c6x/configs/evmc6472_defconfig
new file mode 100644
index 00000000000..8c46155f6d3
--- /dev/null
+++ b/arch/c6x/configs/evmc6472_defconfig
@@ -0,0 +1,42 @@
1CONFIG_SOC_TMS320C6472=y
2CONFIG_EXPERIMENTAL=y
3# CONFIG_LOCALVERSION_AUTO is not set
4CONFIG_SYSVIPC=y
5CONFIG_SPARSE_IRQ=y
6CONFIG_LOG_BUF_SHIFT=14
7CONFIG_NAMESPACES=y
8# CONFIG_UTS_NS is not set
9# CONFIG_USER_NS is not set
10# CONFIG_PID_NS is not set
11CONFIG_BLK_DEV_INITRD=y
12CONFIG_CC_OPTIMIZE_FOR_SIZE=y
13CONFIG_EXPERT=y
14# CONFIG_FUTEX is not set
15# CONFIG_SLUB_DEBUG is not set
16CONFIG_MODULES=y
17CONFIG_MODULE_FORCE_LOAD=y
18CONFIG_MODULE_UNLOAD=y
19CONFIG_MODULE_FORCE_UNLOAD=y
20CONFIG_CMDLINE_BOOL=y
21CONFIG_CMDLINE=""
22# CONFIG_CMDLINE_FORCE is not set
23CONFIG_BOARD_EVM6472=y
24CONFIG_NO_HZ=y
25CONFIG_HIGH_RES_TIMERS=y
26CONFIG_BLK_DEV_LOOP=y
27CONFIG_BLK_DEV_RAM=y
28CONFIG_BLK_DEV_RAM_COUNT=2
29CONFIG_BLK_DEV_RAM_SIZE=17000
30CONFIG_MISC_DEVICES=y
31# CONFIG_INPUT is not set
32# CONFIG_SERIO is not set
33# CONFIG_VT is not set
34# CONFIG_HW_RANDOM is not set
35# CONFIG_HWMON is not set
36# CONFIG_USB_SUPPORT is not set
37# CONFIG_IOMMU_SUPPORT is not set
38# CONFIG_MISC_FILESYSTEMS is not set
39CONFIG_CRC16=y
40# CONFIG_ENABLE_MUST_CHECK is not set
41# CONFIG_SCHED_DEBUG is not set
42# CONFIG_DEBUG_BUGVERBOSE is not set
diff --git a/arch/c6x/configs/evmc6474_defconfig b/arch/c6x/configs/evmc6474_defconfig
new file mode 100644
index 00000000000..15533f63231
--- /dev/null
+++ b/arch/c6x/configs/evmc6474_defconfig
@@ -0,0 +1,42 @@
1CONFIG_SOC_TMS320C6474=y
2CONFIG_EXPERIMENTAL=y
3# CONFIG_LOCALVERSION_AUTO is not set
4CONFIG_SYSVIPC=y
5CONFIG_SPARSE_IRQ=y
6CONFIG_LOG_BUF_SHIFT=14
7CONFIG_NAMESPACES=y
8# CONFIG_UTS_NS is not set
9# CONFIG_USER_NS is not set
10# CONFIG_PID_NS is not set
11CONFIG_BLK_DEV_INITRD=y
12CONFIG_CC_OPTIMIZE_FOR_SIZE=y
13CONFIG_EXPERT=y
14# CONFIG_FUTEX is not set
15# CONFIG_SLUB_DEBUG is not set
16CONFIG_MODULES=y
17CONFIG_MODULE_FORCE_LOAD=y
18CONFIG_MODULE_UNLOAD=y
19CONFIG_MODULE_FORCE_UNLOAD=y
20CONFIG_CMDLINE_BOOL=y
21CONFIG_CMDLINE=""
22# CONFIG_CMDLINE_FORCE is not set
23CONFIG_BOARD_EVM6474=y
24CONFIG_NO_HZ=y
25CONFIG_HIGH_RES_TIMERS=y
26CONFIG_BLK_DEV_LOOP=y
27CONFIG_BLK_DEV_RAM=y
28CONFIG_BLK_DEV_RAM_COUNT=2
29CONFIG_BLK_DEV_RAM_SIZE=17000
30CONFIG_MISC_DEVICES=y
31# CONFIG_INPUT is not set
32# CONFIG_SERIO is not set
33# CONFIG_VT is not set
34# CONFIG_HW_RANDOM is not set
35# CONFIG_HWMON is not set
36# CONFIG_USB_SUPPORT is not set
37# CONFIG_IOMMU_SUPPORT is not set
38# CONFIG_MISC_FILESYSTEMS is not set
39CONFIG_CRC16=y
40# CONFIG_ENABLE_MUST_CHECK is not set
41# CONFIG_SCHED_DEBUG is not set
42# CONFIG_DEBUG_BUGVERBOSE is not set
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
new file mode 100644
index 00000000000..13dcf78adf9
--- /dev/null
+++ b/arch/c6x/include/asm/Kbuild
@@ -0,0 +1,54 @@
1include include/asm-generic/Kbuild.asm
2
3generic-y += atomic.h
4generic-y += auxvec.h
5generic-y += bitsperlong.h
6generic-y += bug.h
7generic-y += bugs.h
8generic-y += cputime.h
9generic-y += current.h
10generic-y += device.h
11generic-y += div64.h
12generic-y += dma.h
13generic-y += emergency-restart.h
14generic-y += errno.h
15generic-y += fb.h
16generic-y += fcntl.h
17generic-y += futex.h
18generic-y += hw_irq.h
19generic-y += io.h
20generic-y += ioctl.h
21generic-y += ioctls.h
22generic-y += ipcbuf.h
23generic-y += irq_regs.h
24generic-y += kdebug.h
25generic-y += kmap_types.h
26generic-y += local.h
27generic-y += mman.h
28generic-y += mmu_context.h
29generic-y += msgbuf.h
30generic-y += param.h
31generic-y += pci.h
32generic-y += percpu.h
33generic-y += pgalloc.h
34generic-y += poll.h
35generic-y += posix_types.h
36generic-y += resource.h
37generic-y += scatterlist.h
38generic-y += segment.h
39generic-y += sembuf.h
40generic-y += shmbuf.h
41generic-y += shmparam.h
42generic-y += siginfo.h
43generic-y += socket.h
44generic-y += sockios.h
45generic-y += stat.h
46generic-y += statfs.h
47generic-y += termbits.h
48generic-y += termios.h
49generic-y += tlbflush.h
50generic-y += topology.h
51generic-y += types.h
52generic-y += ucontext.h
53generic-y += user.h
54generic-y += vga.h
diff --git a/arch/c6x/include/asm/asm-offsets.h b/arch/c6x/include/asm/asm-offsets.h
new file mode 100644
index 00000000000..d370ee36a18
--- /dev/null
+++ b/arch/c6x/include/asm/asm-offsets.h
@@ -0,0 +1 @@
#include <generated/asm-offsets.h>
diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h
new file mode 100644
index 00000000000..39ab7e874d9
--- /dev/null
+++ b/arch/c6x/include/asm/bitops.h
@@ -0,0 +1,105 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_BITOPS_H
12#define _ASM_C6X_BITOPS_H
13
14#ifdef __KERNEL__
15
16#include <linux/bitops.h>
17
18#include <asm/system.h>
19#include <asm/byteorder.h>
20
21/*
22 * clear_bit() doesn't provide any barrier for the compiler.
23 */
24#define smp_mb__before_clear_bit() barrier()
25#define smp_mb__after_clear_bit() barrier()
26
27/*
28 * We are lucky, DSP is perfect for bitops: do it in 3 cycles
29 */
30
31/**
32 * __ffs - find first bit in word.
33 * @word: The word to search
34 *
35 * Undefined if no bit exists, so code should check against 0 first.
36 * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31.
37 *
38 */
39static inline unsigned long __ffs(unsigned long x)
40{
41 asm (" bitr .M1 %0,%0\n"
42 " nop\n"
43 " lmbd .L1 1,%0,%0\n"
44 : "+a"(x));
45
46 return x;
47}
48
49/*
50 * ffz - find first zero in word.
51 * @word: The word to search
52 *
53 * Undefined if no zero exists, so code should check against ~0UL first.
54 */
55#define ffz(x) __ffs(~(x))
56
57/**
58 * fls - find last (most-significant) bit set
59 * @x: the word to search
60 *
61 * This is defined the same way as ffs.
62 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
63 */
64static inline int fls(int x)
65{
66 if (!x)
67 return 0;
68
69 asm (" lmbd .L1 1,%0,%0\n" : "+a"(x));
70
71 return 32 - x;
72}
73
74/**
75 * ffs - find first bit set
76 * @x: the word to search
77 *
78 * This is defined the same way as
79 * the libc and compiler builtin ffs routines, therefore
80 * differs in spirit from the above ffz (man ffs).
81 * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32.
82 */
83static inline int ffs(int x)
84{
85 if (!x)
86 return 0;
87
88 return __ffs(x) + 1;
89}
90
91#include <asm-generic/bitops/__fls.h>
92#include <asm-generic/bitops/fls64.h>
93#include <asm-generic/bitops/find.h>
94
95#include <asm-generic/bitops/sched.h>
96#include <asm-generic/bitops/hweight.h>
97#include <asm-generic/bitops/lock.h>
98
99#include <asm-generic/bitops/atomic.h>
100#include <asm-generic/bitops/non-atomic.h>
101#include <asm-generic/bitops/le.h>
102#include <asm-generic/bitops/ext2-atomic.h>
103
104#endif /* __KERNEL__ */
105#endif /* _ASM_C6X_BITOPS_H */
diff --git a/arch/c6x/include/asm/byteorder.h b/arch/c6x/include/asm/byteorder.h
new file mode 100644
index 00000000000..166038db342
--- /dev/null
+++ b/arch/c6x/include/asm/byteorder.h
@@ -0,0 +1,12 @@
1#ifndef _ASM_C6X_BYTEORDER_H
2#define _ASM_C6X_BYTEORDER_H
3
4#include <asm/types.h>
5
6#ifdef _BIG_ENDIAN
7#include <linux/byteorder/big_endian.h>
8#else /* _BIG_ENDIAN */
9#include <linux/byteorder/little_endian.h>
10#endif /* _BIG_ENDIAN */
11
12#endif /* _ASM_BYTEORDER_H */
diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h
new file mode 100644
index 00000000000..6d521d96d94
--- /dev/null
+++ b/arch/c6x/include/asm/cache.h
@@ -0,0 +1,90 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_CACHE_H
12#define _ASM_C6X_CACHE_H
13
14#include <linux/irqflags.h>
15
16/*
17 * Cache line size
18 */
19#define L1D_CACHE_BYTES 64
20#define L1P_CACHE_BYTES 32
21#define L2_CACHE_BYTES 128
22
23/*
24 * L2 used as cache
25 */
26#define L2MODE_SIZE L2MODE_256K_CACHE
27
28/*
29 * For practical reasons the L1_CACHE_BYTES defines should not be smaller than
30 * the L2 line size
31 */
32#define L1_CACHE_BYTES L2_CACHE_BYTES
33
34#define L2_CACHE_ALIGN_LOW(x) \
35 (((x) & ~(L2_CACHE_BYTES - 1)))
36#define L2_CACHE_ALIGN_UP(x) \
37 (((x) + (L2_CACHE_BYTES - 1)) & ~(L2_CACHE_BYTES - 1))
38#define L2_CACHE_ALIGN_CNT(x) \
39 (((x) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))
40
41#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
42#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES
43
44/*
45 * This is the granularity of hardware cacheability control.
46 */
47#define CACHEABILITY_ALIGN 0x01000000
48
49/*
50 * Align a physical address to MAR regions
51 */
52#define CACHE_REGION_START(v) \
53 (((u32) (v)) & ~(CACHEABILITY_ALIGN - 1))
54#define CACHE_REGION_END(v) \
55 (((u32) (v) + (CACHEABILITY_ALIGN - 1)) & ~(CACHEABILITY_ALIGN - 1))
56
57extern void __init c6x_cache_init(void);
58
59extern void enable_caching(unsigned long start, unsigned long end);
60extern void disable_caching(unsigned long start, unsigned long end);
61
62extern void L1_cache_off(void);
63extern void L1_cache_on(void);
64
65extern void L1P_cache_global_invalidate(void);
66extern void L1D_cache_global_invalidate(void);
67extern void L1D_cache_global_writeback(void);
68extern void L1D_cache_global_writeback_invalidate(void);
69extern void L2_cache_set_mode(unsigned int mode);
70extern void L2_cache_global_writeback_invalidate(void);
71extern void L2_cache_global_writeback(void);
72
73extern void L1P_cache_block_invalidate(unsigned int start, unsigned int end);
74extern void L1D_cache_block_invalidate(unsigned int start, unsigned int end);
75extern void L1D_cache_block_writeback_invalidate(unsigned int start,
76 unsigned int end);
77extern void L1D_cache_block_writeback(unsigned int start, unsigned int end);
78extern void L2_cache_block_invalidate(unsigned int start, unsigned int end);
79extern void L2_cache_block_writeback(unsigned int start, unsigned int end);
80extern void L2_cache_block_writeback_invalidate(unsigned int start,
81 unsigned int end);
82extern void L2_cache_block_invalidate_nowait(unsigned int start,
83 unsigned int end);
84extern void L2_cache_block_writeback_nowait(unsigned int start,
85 unsigned int end);
86
87extern void L2_cache_block_writeback_invalidate_nowait(unsigned int start,
88 unsigned int end);
89
90#endif /* _ASM_C6X_CACHE_H */
diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h
new file mode 100644
index 00000000000..df5db90dbe5
--- /dev/null
+++ b/arch/c6x/include/asm/cacheflush.h
@@ -0,0 +1,65 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_CACHEFLUSH_H
12#define _ASM_C6X_CACHEFLUSH_H
13
14#include <linux/spinlock.h>
15
16#include <asm/setup.h>
17#include <asm/cache.h>
18#include <asm/mman.h>
19#include <asm/page.h>
20#include <asm/string.h>
21
22/*
23 * virtually-indexed cache management (our cache is physically indexed)
24 */
25#define flush_cache_all() do {} while (0)
26#define flush_cache_mm(mm) do {} while (0)
27#define flush_cache_dup_mm(mm) do {} while (0)
28#define flush_cache_range(mm, start, end) do {} while (0)
29#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
30#define flush_cache_vmap(start, end) do {} while (0)
31#define flush_cache_vunmap(start, end) do {} while (0)
32#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
33#define flush_dcache_page(page) do {} while (0)
34#define flush_dcache_mmap_lock(mapping) do {} while (0)
35#define flush_dcache_mmap_unlock(mapping) do {} while (0)
36
37/*
38 * physically-indexed cache management
39 */
40#define flush_icache_range(s, e) \
41do { \
42 L1D_cache_block_writeback((s), (e)); \
43 L1P_cache_block_invalidate((s), (e)); \
44} while (0)
45
46#define flush_icache_page(vma, page) \
47do { \
48 if ((vma)->vm_flags & PROT_EXEC) \
49 L1D_cache_block_writeback_invalidate(page_address(page), \
50 (unsigned long) page_address(page) + PAGE_SIZE)); \
51 L1P_cache_block_invalidate(page_address(page), \
52 (unsigned long) page_address(page) + PAGE_SIZE)); \
53} while (0)
54
55
56#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
57do { \
58 memcpy(dst, src, len); \
59 flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
60} while (0)
61
62#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
63 memcpy(dst, src, len)
64
65#endif /* _ASM_C6X_CACHEFLUSH_H */
diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h
new file mode 100644
index 00000000000..7246816d6e4
--- /dev/null
+++ b/arch/c6x/include/asm/checksum.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#ifndef _ASM_C6X_CHECKSUM_H
10#define _ASM_C6X_CHECKSUM_H
11
12static inline __wsum
13csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
14 unsigned short proto, __wsum sum)
15{
16 unsigned long long tmp;
17
18 asm ("add .d1 %1,%5,%1\n"
19 "|| addu .l1 %3,%4,%0\n"
20 "addu .l1 %2,%0,%0\n"
21#ifndef CONFIG_CPU_BIG_ENDIAN
22 "|| shl .s1 %1,8,%1\n"
23#endif
24 "addu .l1 %1,%0,%0\n"
25 "add .l1 %P0,%p0,%2\n"
26 : "=&a"(tmp), "+a"(len), "+a"(sum)
27 : "a" (saddr), "a" (daddr), "a" (proto));
28 return sum;
29}
30#define csum_tcpudp_nofold csum_tcpudp_nofold
31
32#include <asm-generic/checksum.h>
33
34#endif /* _ASM_C6X_CHECKSUM_H */
diff --git a/arch/c6x/include/asm/clkdev.h b/arch/c6x/include/asm/clkdev.h
new file mode 100644
index 00000000000..76a070b1c2e
--- /dev/null
+++ b/arch/c6x/include/asm/clkdev.h
@@ -0,0 +1,22 @@
1#ifndef _ASM_CLKDEV_H
2#define _ASM_CLKDEV_H
3
4#include <linux/slab.h>
5
6struct clk;
7
8static inline int __clk_get(struct clk *clk)
9{
10 return 1;
11}
12
13static inline void __clk_put(struct clk *clk)
14{
15}
16
17static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
18{
19 return kzalloc(size, GFP_KERNEL);
20}
21
22#endif /* _ASM_CLKDEV_H */
diff --git a/arch/c6x/include/asm/clock.h b/arch/c6x/include/asm/clock.h
new file mode 100644
index 00000000000..bcf42b2b4b1
--- /dev/null
+++ b/arch/c6x/include/asm/clock.h
@@ -0,0 +1,148 @@
1/*
2 * TI C64X clock definitions
3 *
4 * Copyright (C) 2010, 2011 Texas Instruments.
5 * Contributed by: Mark Salter <msalter@redhat.com>
6 *
7 * Copied heavily from arm/mach-davinci/clock.h, so:
8 *
9 * Copyright (C) 2006-2007 Texas Instruments.
10 * Copyright (C) 2008-2009 Deep Root Systems, LLC
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#ifndef _ASM_C6X_CLOCK_H
18#define _ASM_C6X_CLOCK_H
19
20#ifndef __ASSEMBLER__
21
22#include <linux/list.h>
23
24/* PLL/Reset register offsets */
25#define PLLCTL 0x100
26#define PLLM 0x110
27#define PLLPRE 0x114
28#define PLLDIV1 0x118
29#define PLLDIV2 0x11c
30#define PLLDIV3 0x120
31#define PLLPOST 0x128
32#define PLLCMD 0x138
33#define PLLSTAT 0x13c
34#define PLLALNCTL 0x140
35#define PLLDCHANGE 0x144
36#define PLLCKEN 0x148
37#define PLLCKSTAT 0x14c
38#define PLLSYSTAT 0x150
39#define PLLDIV4 0x160
40#define PLLDIV5 0x164
41#define PLLDIV6 0x168
42#define PLLDIV7 0x16c
43#define PLLDIV8 0x170
44#define PLLDIV9 0x174
45#define PLLDIV10 0x178
46#define PLLDIV11 0x17c
47#define PLLDIV12 0x180
48#define PLLDIV13 0x184
49#define PLLDIV14 0x188
50#define PLLDIV15 0x18c
51#define PLLDIV16 0x190
52
53/* PLLM register bits */
54#define PLLM_PLLM_MASK 0xff
55#define PLLM_VAL(x) ((x) - 1)
56
57/* PREDIV register bits */
58#define PLLPREDIV_EN BIT(15)
59#define PLLPREDIV_VAL(x) ((x) - 1)
60
61/* PLLCTL register bits */
62#define PLLCTL_PLLEN BIT(0)
63#define PLLCTL_PLLPWRDN BIT(1)
64#define PLLCTL_PLLRST BIT(3)
65#define PLLCTL_PLLDIS BIT(4)
66#define PLLCTL_PLLENSRC BIT(5)
67#define PLLCTL_CLKMODE BIT(8)
68
69/* PLLCMD register bits */
70#define PLLCMD_GOSTAT BIT(0)
71
72/* PLLSTAT register bits */
73#define PLLSTAT_GOSTAT BIT(0)
74
75/* PLLDIV register bits */
76#define PLLDIV_EN BIT(15)
77#define PLLDIV_RATIO_MASK 0x1f
78#define PLLDIV_RATIO(x) ((x) - 1)
79
80struct pll_data;
81
82struct clk {
83 struct list_head node;
84 struct module *owner;
85 const char *name;
86 unsigned long rate;
87 int usecount;
88 u32 flags;
89 struct clk *parent;
90 struct list_head children; /* list of children */
91 struct list_head childnode; /* parent's child list node */
92 struct pll_data *pll_data;
93 u32 div;
94 unsigned long (*recalc) (struct clk *);
95 int (*set_rate) (struct clk *clk, unsigned long rate);
96 int (*round_rate) (struct clk *clk, unsigned long rate);
97};
98
99/* Clock flags: SoC-specific flags start at BIT(16) */
100#define ALWAYS_ENABLED BIT(1)
101#define CLK_PLL BIT(2) /* PLL-derived clock */
102#define PRE_PLL BIT(3) /* source is before PLL mult/div */
103#define FIXED_DIV_PLL BIT(4) /* fixed divisor from PLL */
104#define FIXED_RATE_PLL BIT(5) /* fixed ouput rate PLL */
105
106#define MAX_PLL_SYSCLKS 16
107
108struct pll_data {
109 void __iomem *base;
110 u32 num;
111 u32 flags;
112 u32 input_rate;
113 u32 bypass_delay; /* in loops */
114 u32 reset_delay; /* in loops */
115 u32 lock_delay; /* in loops */
116 struct clk sysclks[MAX_PLL_SYSCLKS + 1];
117};
118
119/* pll_data flag bit */
120#define PLL_HAS_PRE BIT(0)
121#define PLL_HAS_MUL BIT(1)
122#define PLL_HAS_POST BIT(2)
123
124#define CLK(dev, con, ck) \
125 { \
126 .dev_id = dev, \
127 .con_id = con, \
128 .clk = ck, \
129 } \
130
131extern void c6x_clks_init(struct clk_lookup *clocks);
132extern int clk_register(struct clk *clk);
133extern void clk_unregister(struct clk *clk);
134extern void c64x_setup_clocks(void);
135
136extern struct pll_data c6x_soc_pll1;
137
138extern struct clk clkin1;
139extern struct clk c6x_core_clk;
140extern struct clk c6x_i2c_clk;
141extern struct clk c6x_watchdog_clk;
142extern struct clk c6x_mcbsp1_clk;
143extern struct clk c6x_mcbsp2_clk;
144extern struct clk c6x_mdio_clk;
145
146#endif
147
148#endif /* _ASM_C6X_CLOCK_H */
diff --git a/arch/c6x/include/asm/delay.h b/arch/c6x/include/asm/delay.h
new file mode 100644
index 00000000000..f314c2e9eb5
--- /dev/null
+++ b/arch/c6x/include/asm/delay.h
@@ -0,0 +1,67 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_DELAY_H
12#define _ASM_C6X_DELAY_H
13
14#include <linux/kernel.h>
15
16extern unsigned int ticks_per_ns_scaled;
17
18static inline void __delay(unsigned long loops)
19{
20 uint32_t tmp;
21
22 /* 6 cycles per loop */
23 asm volatile (" mv .s1 %0,%1\n"
24 "0: [%1] b .s1 0b\n"
25 " add .l1 -6,%0,%0\n"
26 " cmplt .l1 1,%0,%1\n"
27 " nop 3\n"
28 : "+a"(loops), "=A"(tmp));
29}
30
31static inline void _c6x_tickdelay(unsigned int x)
32{
33 uint32_t cnt, endcnt;
34
35 asm volatile (" mvc .s2 TSCL,%0\n"
36 " add .s2x %0,%1,%2\n"
37 " || mvk .l2 1,B0\n"
38 "0: [B0] b .s2 0b\n"
39 " mvc .s2 TSCL,%0\n"
40 " sub .s2 %0,%2,%0\n"
41 " cmpgt .l2 0,%0,B0\n"
42 " nop 2\n"
43 : "=b"(cnt), "+a"(x), "=b"(endcnt) : : "B0");
44}
45
46/* use scaled math to avoid slow division */
47#define C6X_NDELAY_SCALE 10
48
49static inline void _ndelay(unsigned int n)
50{
51 _c6x_tickdelay((ticks_per_ns_scaled * n) >> C6X_NDELAY_SCALE);
52}
53
54static inline void _udelay(unsigned int n)
55{
56 while (n >= 10) {
57 _ndelay(10000);
58 n -= 10;
59 }
60 while (n-- > 0)
61 _ndelay(1000);
62}
63
64#define udelay(x) _udelay((unsigned int)(x))
65#define ndelay(x) _ndelay((unsigned int)(x))
66
67#endif /* _ASM_C6X_DELAY_H */
diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h
new file mode 100644
index 00000000000..03579fd99db
--- /dev/null
+++ b/arch/c6x/include/asm/dma-mapping.h
@@ -0,0 +1,91 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot <aurelien.jacquiot@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#ifndef _ASM_C6X_DMA_MAPPING_H
13#define _ASM_C6X_DMA_MAPPING_H
14
15#include <linux/dma-debug.h>
16#include <asm-generic/dma-coherent.h>
17
18#define dma_supported(d, m) 1
19
20static inline int dma_set_mask(struct device *dev, u64 dma_mask)
21{
22 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
23 return -EIO;
24
25 *dev->dma_mask = dma_mask;
26
27 return 0;
28}
29
30/*
31 * DMA errors are defined by all-bits-set in the DMA address.
32 */
33static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
34{
35 return dma_addr == ~0;
36}
37
38extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
39 size_t size, enum dma_data_direction dir);
40
41extern void dma_unmap_single(struct device *dev, dma_addr_t handle,
42 size_t size, enum dma_data_direction dir);
43
44extern int dma_map_sg(struct device *dev, struct scatterlist *sglist,
45 int nents, enum dma_data_direction direction);
46
47extern void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
48 int nents, enum dma_data_direction direction);
49
50static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
51 unsigned long offset, size_t size,
52 enum dma_data_direction dir)
53{
54 dma_addr_t handle;
55
56 handle = dma_map_single(dev, page_address(page) + offset, size, dir);
57
58 debug_dma_map_page(dev, page, offset, size, dir, handle, false);
59
60 return handle;
61}
62
63static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
64 size_t size, enum dma_data_direction dir)
65{
66 dma_unmap_single(dev, handle, size, dir);
67
68 debug_dma_unmap_page(dev, handle, size, dir, false);
69}
70
71extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
72 size_t size, enum dma_data_direction dir);
73
74extern void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
75 size_t size,
76 enum dma_data_direction dir);
77
78extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
79 int nents, enum dma_data_direction dir);
80
81extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
82 int nents, enum dma_data_direction dir);
83
84extern void coherent_mem_init(u32 start, u32 size);
85extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
86extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
87
88#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
89#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
90
91#endif /* _ASM_C6X_DMA_MAPPING_H */
diff --git a/arch/c6x/include/asm/dscr.h b/arch/c6x/include/asm/dscr.h
new file mode 100644
index 00000000000..561ba833204
--- /dev/null
+++ b/arch/c6x/include/asm/dscr.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 */
10#ifndef _ASM_C6X_DSCR_H
11#define _ASM_C6X_DSCR_H
12
13enum dscr_devstate_t {
14 DSCR_DEVSTATE_ENABLED,
15 DSCR_DEVSTATE_DISABLED,
16};
17
18/*
19 * Set the device state of the device with the given ID.
20 *
21 * Individual drivers should use this to enable or disable the
22 * hardware device. The devid used to identify the device being
23 * controlled should be a property in the device's tree node.
24 */
25extern void dscr_set_devstate(int devid, enum dscr_devstate_t state);
26
27/*
28 * Assert or de-assert an RMII reset.
29 */
30extern void dscr_rmii_reset(int id, int assert);
31
32extern void dscr_probe(void);
33
34#endif /* _ASM_C6X_DSCR_H */
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
new file mode 100644
index 00000000000..d57865ba2c4
--- /dev/null
+++ b/arch/c6x/include/asm/elf.h
@@ -0,0 +1,113 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_ELF_H
12#define _ASM_C6X_ELF_H
13
14/*
15 * ELF register definitions..
16 */
17#include <asm/ptrace.h>
18
19typedef unsigned long elf_greg_t;
20typedef unsigned long elf_fpreg_t;
21
22#define ELF_NGREG 58
23#define ELF_NFPREG 1
24
25typedef elf_greg_t elf_gregset_t[ELF_NGREG];
26typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
27
28/*
29 * This is used to ensure we don't load something for the wrong architecture.
30 */
31#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000)
32
33#define elf_check_const_displacement(x) (1)
34
35/*
36 * These are used to set parameters in the core dumps.
37 */
38#ifdef __LITTLE_ENDIAN__
39#define ELF_DATA ELFDATA2LSB
40#else
41#define ELF_DATA ELFDATA2MSB
42#endif
43
44#define ELF_CLASS ELFCLASS32
45#define ELF_ARCH EM_TI_C6000
46
47/* Nothing for now. Need to setup DP... */
48#define ELF_PLAT_INIT(_r)
49
50#define USE_ELF_CORE_DUMP
51#define ELF_EXEC_PAGESIZE 4096
52
53#define ELF_CORE_COPY_REGS(_dest, _regs) \
54 memcpy((char *) &_dest, (char *) _regs, \
55 sizeof(struct pt_regs));
56
57/* This yields a mask that user programs can use to figure out what
58 instruction set this cpu supports. */
59
60#define ELF_HWCAP (0)
61
62/* This yields a string that ld.so will use to load implementation
63 specific libraries for optimization. This is more specific in
64 intent than poking at uname or /proc/cpuinfo. */
65
66#define ELF_PLATFORM (NULL)
67
68#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
69
70/* C6X specific section types */
71#define SHT_C6000_UNWIND 0x70000001
72#define SHT_C6000_PREEMPTMAP 0x70000002
73#define SHT_C6000_ATTRIBUTES 0x70000003
74
75/* C6X specific DT_ tags */
76#define DT_C6000_DSBT_BASE 0x70000000
77#define DT_C6000_DSBT_SIZE 0x70000001
78#define DT_C6000_PREEMPTMAP 0x70000002
79#define DT_C6000_DSBT_INDEX 0x70000003
80
81/* C6X specific relocs */
82#define R_C6000_NONE 0
83#define R_C6000_ABS32 1
84#define R_C6000_ABS16 2
85#define R_C6000_ABS8 3
86#define R_C6000_PCR_S21 4
87#define R_C6000_PCR_S12 5
88#define R_C6000_PCR_S10 6
89#define R_C6000_PCR_S7 7
90#define R_C6000_ABS_S16 8
91#define R_C6000_ABS_L16 9
92#define R_C6000_ABS_H16 10
93#define R_C6000_SBR_U15_B 11
94#define R_C6000_SBR_U15_H 12
95#define R_C6000_SBR_U15_W 13
96#define R_C6000_SBR_S16 14
97#define R_C6000_SBR_L16_B 15
98#define R_C6000_SBR_L16_H 16
99#define R_C6000_SBR_L16_W 17
100#define R_C6000_SBR_H16_B 18
101#define R_C6000_SBR_H16_H 19
102#define R_C6000_SBR_H16_W 20
103#define R_C6000_SBR_GOT_U15_W 21
104#define R_C6000_SBR_GOT_L16_W 22
105#define R_C6000_SBR_GOT_H16_W 23
106#define R_C6000_DSBT_INDEX 24
107#define R_C6000_PREL31 25
108#define R_C6000_COPY 26
109#define R_C6000_ALIGN 253
110#define R_C6000_FPHEAD 254
111#define R_C6000_NOCMP 255
112
113#endif /*_ASM_C6X_ELF_H */
diff --git a/arch/c6x/include/asm/ftrace.h b/arch/c6x/include/asm/ftrace.h
new file mode 100644
index 00000000000..3701958d3d1
--- /dev/null
+++ b/arch/c6x/include/asm/ftrace.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_C6X_FTRACE_H
2#define _ASM_C6X_FTRACE_H
3
4/* empty */
5
6#endif /* _ASM_C6X_FTRACE_H */
diff --git a/arch/c6x/include/asm/hardirq.h b/arch/c6x/include/asm/hardirq.h
new file mode 100644
index 00000000000..9621954f98f
--- /dev/null
+++ b/arch/c6x/include/asm/hardirq.h
@@ -0,0 +1,20 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _ASM_C6X_HARDIRQ_H
13#define _ASM_C6X_HARDIRQ_H
14
15extern void ack_bad_irq(int irq);
16#define ack_bad_irq ack_bad_irq
17
18#include <asm-generic/hardirq.h>
19
20#endif /* _ASM_C6X_HARDIRQ_H */
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
new file mode 100644
index 00000000000..a6ae3c9d9c4
--- /dev/null
+++ b/arch/c6x/include/asm/irq.h
@@ -0,0 +1,302 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Large parts taken directly from powerpc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef _ASM_C6X_IRQ_H
14#define _ASM_C6X_IRQ_H
15
16#include <linux/threads.h>
17#include <linux/list.h>
18#include <linux/radix-tree.h>
19#include <asm/percpu.h>
20
21#define irq_canonicalize(irq) (irq)
22
23/*
24 * The C64X+ core has 16 IRQ vectors. One each is used by Reset and NMI. Two
25 * are reserved. The remaining 12 vectors are used to route SoC interrupts.
26 * These interrupt vectors are prioritized with IRQ 4 having the highest
27 * priority and IRQ 15 having the lowest.
28 *
29 * The C64x+ megamodule provides a PIC which combines SoC IRQ sources into a
30 * single core IRQ vector. There are four combined sources, each of which
31 * feed into one of the 12 general interrupt vectors. The remaining 8 vectors
32 * can each route a single SoC interrupt directly.
33 */
34#define NR_PRIORITY_IRQS 16
35
36#define NR_IRQS_LEGACY NR_PRIORITY_IRQS
37
38/* Total number of virq in the platform */
39#define NR_IRQS 256
40
41/* This number is used when no interrupt has been assigned */
42#define NO_IRQ 0
43
44/* This type is the placeholder for a hardware interrupt number. It has to
45 * be big enough to enclose whatever representation is used by a given
46 * platform.
47 */
48typedef unsigned long irq_hw_number_t;
49
50/* Interrupt controller "host" data structure. This could be defined as a
51 * irq domain controller. That is, it handles the mapping between hardware
52 * and virtual interrupt numbers for a given interrupt domain. The host
53 * structure is generally created by the PIC code for a given PIC instance
54 * (though a host can cover more than one PIC if they have a flat number
55 * model). It's the host callbacks that are responsible for setting the
56 * irq_chip on a given irq_desc after it's been mapped.
57 *
58 * The host code and data structures are fairly agnostic to the fact that
59 * we use an open firmware device-tree. We do have references to struct
60 * device_node in two places: in irq_find_host() to find the host matching
61 * a given interrupt controller node, and of course as an argument to its
62 * counterpart host->ops->match() callback. However, those are treated as
63 * generic pointers by the core and the fact that it's actually a device-node
64 * pointer is purely a convention between callers and implementation. This
65 * code could thus be used on other architectures by replacing those two
66 * by some sort of arch-specific void * "token" used to identify interrupt
67 * controllers.
68 */
69struct irq_host;
70struct radix_tree_root;
71struct device_node;
72
73/* Functions below are provided by the host and called whenever a new mapping
74 * is created or an old mapping is disposed. The host can then proceed to
75 * whatever internal data structures management is required. It also needs
76 * to setup the irq_desc when returning from map().
77 */
78struct irq_host_ops {
79 /* Match an interrupt controller device node to a host, returns
80 * 1 on a match
81 */
82 int (*match)(struct irq_host *h, struct device_node *node);
83
84 /* Create or update a mapping between a virtual irq number and a hw
85 * irq number. This is called only once for a given mapping.
86 */
87 int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
88
89 /* Dispose of such a mapping */
90 void (*unmap)(struct irq_host *h, unsigned int virq);
91
92 /* Translate device-tree interrupt specifier from raw format coming
93 * from the firmware to a irq_hw_number_t (interrupt line number) and
94 * type (sense) that can be passed to set_irq_type(). In the absence
95 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
96 * will return the hw number in the first cell and IRQ_TYPE_NONE for
97 * the type (which amount to keeping whatever default value the
98 * interrupt controller has for that line)
99 */
100 int (*xlate)(struct irq_host *h, struct device_node *ctrler,
101 const u32 *intspec, unsigned int intsize,
102 irq_hw_number_t *out_hwirq, unsigned int *out_type);
103};
104
105struct irq_host {
106 struct list_head link;
107
108 /* type of reverse mapping technique */
109 unsigned int revmap_type;
110#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */
111#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
112#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
113#define IRQ_HOST_MAP_TREE 3 /* radix tree */
114 union {
115 struct {
116 unsigned int size;
117 unsigned int *revmap;
118 } linear;
119 struct radix_tree_root tree;
120 } revmap_data;
121 struct irq_host_ops *ops;
122 void *host_data;
123 irq_hw_number_t inval_irq;
124
125 /* Optional device node pointer */
126 struct device_node *of_node;
127};
128
129struct irq_data;
130extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
131extern irq_hw_number_t virq_to_hw(unsigned int virq);
132extern bool virq_is_host(unsigned int virq, struct irq_host *host);
133
134/**
135 * irq_alloc_host - Allocate a new irq_host data structure
136 * @of_node: optional device-tree node of the interrupt controller
137 * @revmap_type: type of reverse mapping to use
138 * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
139 * @ops: map/unmap host callbacks
140 * @inval_irq: provide a hw number in that host space that is always invalid
141 *
142 * Allocates and initialize and irq_host structure. Note that in the case of
143 * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
144 * for all legacy interrupts except 0 (which is always the invalid irq for
145 * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
146 * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
147 * later during boot automatically (the reverse mapping will use the slow path
148 * until that happens).
149 */
150extern struct irq_host *irq_alloc_host(struct device_node *of_node,
151 unsigned int revmap_type,
152 unsigned int revmap_arg,
153 struct irq_host_ops *ops,
154 irq_hw_number_t inval_irq);
155
156
157/**
158 * irq_find_host - Locates a host for a given device node
159 * @node: device-tree node of the interrupt controller
160 */
161extern struct irq_host *irq_find_host(struct device_node *node);
162
163
164/**
165 * irq_set_default_host - Set a "default" host
166 * @host: default host pointer
167 *
168 * For convenience, it's possible to set a "default" host that will be used
169 * whenever NULL is passed to irq_create_mapping(). It makes life easier for
170 * platforms that want to manipulate a few hard coded interrupt numbers that
171 * aren't properly represented in the device-tree.
172 */
173extern void irq_set_default_host(struct irq_host *host);
174
175
176/**
177 * irq_set_virq_count - Set the maximum number of virt irqs
178 * @count: number of linux virtual irqs, capped with NR_IRQS
179 *
180 * This is mainly for use by platforms like iSeries who want to program
181 * the virtual irq number in the controller to avoid the reverse mapping
182 */
183extern void irq_set_virq_count(unsigned int count);
184
185
186/**
187 * irq_create_mapping - Map a hardware interrupt into linux virq space
188 * @host: host owning this hardware interrupt or NULL for default host
189 * @hwirq: hardware irq number in that host space
190 *
191 * Only one mapping per hardware interrupt is permitted. Returns a linux
192 * virq number.
193 * If the sense/trigger is to be specified, set_irq_type() should be called
194 * on the number returned from that call.
195 */
196extern unsigned int irq_create_mapping(struct irq_host *host,
197 irq_hw_number_t hwirq);
198
199
200/**
201 * irq_dispose_mapping - Unmap an interrupt
202 * @virq: linux virq number of the interrupt to unmap
203 */
204extern void irq_dispose_mapping(unsigned int virq);
205
206/**
207 * irq_find_mapping - Find a linux virq from an hw irq number.
208 * @host: host owning this hardware interrupt
209 * @hwirq: hardware irq number in that host space
210 *
211 * This is a slow path, for use by generic code. It's expected that an
212 * irq controller implementation directly calls the appropriate low level
213 * mapping function.
214 */
215extern unsigned int irq_find_mapping(struct irq_host *host,
216 irq_hw_number_t hwirq);
217
218/**
219 * irq_create_direct_mapping - Allocate a virq for direct mapping
220 * @host: host to allocate the virq for or NULL for default host
221 *
222 * This routine is used for irq controllers which can choose the hardware
223 * interrupt numbers they generate. In such a case it's simplest to use
224 * the linux virq as the hardware interrupt number.
225 */
226extern unsigned int irq_create_direct_mapping(struct irq_host *host);
227
228/**
229 * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
230 * @host: host owning this hardware interrupt
231 * @virq: linux irq number
232 * @hwirq: hardware irq number in that host space
233 *
234 * This is for use by irq controllers that use a radix tree reverse
235 * mapping for fast lookup.
236 */
237extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
238 irq_hw_number_t hwirq);
239
240/**
241 * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
242 * @host: host owning this hardware interrupt
243 * @hwirq: hardware irq number in that host space
244 *
245 * This is a fast path, for use by irq controller code that uses radix tree
246 * revmaps
247 */
248extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
249 irq_hw_number_t hwirq);
250
251/**
252 * irq_linear_revmap - Find a linux virq from a hw irq number.
253 * @host: host owning this hardware interrupt
254 * @hwirq: hardware irq number in that host space
255 *
256 * This is a fast path, for use by irq controller code that uses linear
257 * revmaps. It does fallback to the slow path if the revmap doesn't exist
258 * yet and will create the revmap entry with appropriate locking
259 */
260
261extern unsigned int irq_linear_revmap(struct irq_host *host,
262 irq_hw_number_t hwirq);
263
264
265
266/**
267 * irq_alloc_virt - Allocate virtual irq numbers
268 * @host: host owning these new virtual irqs
269 * @count: number of consecutive numbers to allocate
270 * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
271 *
272 * This is a low level function that is used internally by irq_create_mapping()
273 * and that can be used by some irq controllers implementations for things
274 * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
275 */
276extern unsigned int irq_alloc_virt(struct irq_host *host,
277 unsigned int count,
278 unsigned int hint);
279
280/**
281 * irq_free_virt - Free virtual irq numbers
282 * @virq: virtual irq number of the first interrupt to free
283 * @count: number of interrupts to free
284 *
285 * This function is the opposite of irq_alloc_virt. It will not clear reverse
286 * maps, this should be done previously by unmap'ing the interrupt. In fact,
287 * all interrupts covered by the range being freed should have been unmapped
288 * prior to calling this.
289 */
290extern void irq_free_virt(unsigned int virq, unsigned int count);
291
292extern void __init init_pic_c64xplus(void);
293
294extern void init_IRQ(void);
295
296struct pt_regs;
297
298extern asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs);
299
300extern unsigned long irq_err_count;
301
302#endif /* _ASM_C6X_IRQ_H */
diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h
new file mode 100644
index 00000000000..cf78e09e18c
--- /dev/null
+++ b/arch/c6x/include/asm/irqflags.h
@@ -0,0 +1,72 @@
1/*
2 * C6X IRQ flag handling
3 *
4 * Copyright (C) 2010 Texas Instruments Incorporated
5 * Written by Mark Salter (msalter@redhat.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public Licence
9 * as published by the Free Software Foundation; either version
10 * 2 of the Licence, or (at your option) any later version.
11 */
12
13#ifndef _ASM_IRQFLAGS_H
14#define _ASM_IRQFLAGS_H
15
16#ifndef __ASSEMBLY__
17
18/* read interrupt enabled status */
19static inline unsigned long arch_local_save_flags(void)
20{
21 unsigned long flags;
22
23 asm volatile (" mvc .s2 CSR,%0\n" : "=b"(flags));
24 return flags;
25}
26
27/* set interrupt enabled status */
28static inline void arch_local_irq_restore(unsigned long flags)
29{
30 asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags));
31}
32
33/* unconditionally enable interrupts */
34static inline void arch_local_irq_enable(void)
35{
36 unsigned long flags = arch_local_save_flags();
37 flags |= 1;
38 arch_local_irq_restore(flags);
39}
40
41/* unconditionally disable interrupts */
42static inline void arch_local_irq_disable(void)
43{
44 unsigned long flags = arch_local_save_flags();
45 flags &= ~1;
46 arch_local_irq_restore(flags);
47}
48
49/* get status and disable interrupts */
50static inline unsigned long arch_local_irq_save(void)
51{
52 unsigned long flags;
53
54 flags = arch_local_save_flags();
55 arch_local_irq_restore(flags & ~1);
56 return flags;
57}
58
59/* test flags */
60static inline int arch_irqs_disabled_flags(unsigned long flags)
61{
62 return (flags & 1) == 0;
63}
64
65/* test hardware interrupt enable bit */
66static inline int arch_irqs_disabled(void)
67{
68 return arch_irqs_disabled_flags(arch_local_save_flags());
69}
70
71#endif /* __ASSEMBLY__ */
72#endif /* __ASM_IRQFLAGS_H */
diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h
new file mode 100644
index 00000000000..376925c47d5
--- /dev/null
+++ b/arch/c6x/include/asm/linkage.h
@@ -0,0 +1,30 @@
1#ifndef _ASM_C6X_LINKAGE_H
2#define _ASM_C6X_LINKAGE_H
3
4#ifdef __ASSEMBLER__
5
6#define __ALIGN .align 2
7#define __ALIGN_STR ".align 2"
8
9#ifndef __DSBT__
10#define ENTRY(name) \
11 .global name @ \
12 __ALIGN @ \
13name:
14#else
15#define ENTRY(name) \
16 .global name @ \
17 .hidden name @ \
18 __ALIGN @ \
19name:
20#endif
21
22#define ENDPROC(name) \
23 .type name, @function @ \
24 .size name, . - name
25
26#endif
27
28#include <asm-generic/linkage.h>
29
30#endif /* _ASM_C6X_LINKAGE_H */
diff --git a/arch/c6x/include/asm/megamod-pic.h b/arch/c6x/include/asm/megamod-pic.h
new file mode 100644
index 00000000000..eca0a867803
--- /dev/null
+++ b/arch/c6x/include/asm/megamod-pic.h
@@ -0,0 +1,9 @@
1#ifndef _C6X_MEGAMOD_PIC_H
2#define _C6X_MEGAMOD_PIC_H
3
4#ifdef __KERNEL__
5
6extern void __init megamod_pic_init(void);
7
8#endif /* __KERNEL__ */
9#endif /* _C6X_MEGAMOD_PIC_H */
diff --git a/arch/c6x/include/asm/mmu.h b/arch/c6x/include/asm/mmu.h
new file mode 100644
index 00000000000..41592bf1606
--- /dev/null
+++ b/arch/c6x/include/asm/mmu.h
@@ -0,0 +1,18 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_MMU_H
12#define _ASM_C6X_MMU_H
13
14typedef struct {
15 unsigned long end_brk;
16} mm_context_t;
17
18#endif /* _ASM_C6X_MMU_H */
diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h
new file mode 100644
index 00000000000..a453f9744f4
--- /dev/null
+++ b/arch/c6x/include/asm/module.h
@@ -0,0 +1,33 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Updated for 2.6.34 by: Mark Salter (msalter@redhat.com)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef _ASM_C6X_MODULE_H
14#define _ASM_C6X_MODULE_H
15
16#define Elf_Shdr Elf32_Shdr
17#define Elf_Sym Elf32_Sym
18#define Elf_Ehdr Elf32_Ehdr
19#define Elf_Addr Elf32_Addr
20#define Elf_Word Elf32_Word
21
22/*
23 * This file contains the C6x architecture specific module code.
24 */
25struct mod_arch_specific {
26};
27
28struct loaded_sections {
29 unsigned int new_vaddr;
30 unsigned int loaded;
31};
32
33#endif /* _ASM_C6X_MODULE_H */
diff --git a/arch/c6x/include/asm/mutex.h b/arch/c6x/include/asm/mutex.h
new file mode 100644
index 00000000000..7a7248e0462
--- /dev/null
+++ b/arch/c6x/include/asm/mutex.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_C6X_MUTEX_H
2#define _ASM_C6X_MUTEX_H
3
4#include <asm-generic/mutex-null.h>
5
6#endif /* _ASM_C6X_MUTEX_H */
diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h
new file mode 100644
index 00000000000..d18e2b0c7ae
--- /dev/null
+++ b/arch/c6x/include/asm/page.h
@@ -0,0 +1,11 @@
1#ifndef _ASM_C6X_PAGE_H
2#define _ASM_C6X_PAGE_H
3
4#define VM_DATA_DEFAULT_FLAGS \
5 (VM_READ | VM_WRITE | \
6 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
7 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
8
9#include <asm-generic/page.h>
10
11#endif /* _ASM_C6X_PAGE_H */
diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h
new file mode 100644
index 00000000000..68c8af4f1f9
--- /dev/null
+++ b/arch/c6x/include/asm/pgtable.h
@@ -0,0 +1,81 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_PGTABLE_H
12#define _ASM_C6X_PGTABLE_H
13
14#include <asm-generic/4level-fixup.h>
15
16#include <asm/setup.h>
17#include <asm/page.h>
18
19/*
20 * All 32bit addresses are effectively valid for vmalloc...
21 * Sort of meaningless for non-VM targets.
22 */
23#define VMALLOC_START 0
24#define VMALLOC_END 0xffffffff
25
26#define pgd_present(pgd) (1)
27#define pgd_none(pgd) (0)
28#define pgd_bad(pgd) (0)
29#define pgd_clear(pgdp)
30#define kern_addr_valid(addr) (1)
31
32#define pmd_offset(a, b) ((void *)0)
33#define pmd_none(x) (!pmd_val(x))
34#define pmd_present(x) (pmd_val(x))
35#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
36#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK)
37
38#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
39#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
40#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
41#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
42#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
43#define pgprot_noncached(prot) (prot)
44
45extern void paging_init(void);
46
47#define __swp_type(x) (0)
48#define __swp_offset(x) (0)
49#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
50#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
51#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
52
53static inline int pte_file(pte_t pte)
54{
55 return 0;
56}
57
58#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
59#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
60
61/*
62 * ZERO_PAGE is a global shared page that is always zero: used
63 * for zero-mapped memory areas etc..
64 */
65#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
66extern unsigned long empty_zero_page;
67
68#define swapper_pg_dir ((pgd_t *) 0)
69
70/*
71 * No page table caches to initialise
72 */
73#define pgtable_cache_init() do { } while (0)
74#define io_remap_pfn_range remap_pfn_range
75
76#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
77 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
78
79#include <asm-generic/pgtable.h>
80
81#endif /* _ASM_C6X_PGTABLE_H */
diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h
new file mode 100644
index 00000000000..8154c4ee8c9
--- /dev/null
+++ b/arch/c6x/include/asm/processor.h
@@ -0,0 +1,132 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Updated for 2.6.34: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef _ASM_C6X_PROCESSOR_H
14#define _ASM_C6X_PROCESSOR_H
15
16#include <asm/ptrace.h>
17#include <asm/page.h>
18#include <asm/current.h>
19
20/*
21 * Default implementation of macro that returns current
22 * instruction pointer ("program counter").
23 */
24#define current_text_addr() \
25({ \
26 void *__pc; \
27 asm("mvc .S2 pce1,%0\n" : "=b"(__pc)); \
28 __pc; \
29})
30
31/*
32 * User space process size. This is mostly meaningless for NOMMU
33 * but some C6X processors may have RAM addresses up to 0xFFFFFFFF.
34 * Since calls like mmap() can return an address or an error, we
35 * have to allow room for error returns when code does something
36 * like:
37 *
38 * addr = do_mmap(...)
39 * if ((unsigned long)addr >= TASK_SIZE)
40 * ... its an error code, not an address ...
41 *
42 * Here, we allow for 4096 error codes which means we really can't
43 * use the last 4K page on systems with RAM extending all the way
44 * to the end of the 32-bit address space.
45 */
46#define TASK_SIZE 0xFFFFF000
47
48/*
49 * This decides where the kernel will search for a free chunk of vm
50 * space during mmap's. We won't be using it
51 */
52#define TASK_UNMAPPED_BASE 0
53
54struct thread_struct {
55 unsigned long long b15_14;
56 unsigned long long a15_14;
57 unsigned long long b13_12;
58 unsigned long long a13_12;
59 unsigned long long b11_10;
60 unsigned long long a11_10;
61 unsigned long long ricl_icl;
62 unsigned long usp; /* user stack pointer */
63 unsigned long pc; /* kernel pc */
64 unsigned long wchan;
65};
66
67#define INIT_THREAD \
68{ \
69 .usp = 0, \
70 .wchan = 0, \
71}
72
73#define INIT_MMAP { \
74 &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \
75 NULL, NULL }
76
77#define task_pt_regs(task) \
78 ((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1)
79
80#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
81#define free_kernel_stack(page) free_page((page))
82
83
84/* Forward declaration, a strange C thing */
85struct task_struct;
86
87extern void start_thread(struct pt_regs *regs, unsigned int pc,
88 unsigned long usp);
89
90/* Free all resources held by a thread. */
91static inline void release_thread(struct task_struct *dead_task)
92{
93}
94
95/* Prepare to copy thread state - unlazy all lazy status */
96#define prepare_to_copy(tsk) do { } while (0)
97
98extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
99
100#define copy_segments(tsk, mm) do { } while (0)
101#define release_segments(mm) do { } while (0)
102
103/*
104 * saved PC of a blocked thread.
105 */
106#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc)
107
108/*
109 * saved kernel SP and DP of a blocked thread.
110 */
111#ifdef _BIG_ENDIAN
112#define thread_saved_ksp(tsk) \
113 (*(unsigned long *)&(tsk)->thread.b15_14)
114#define thread_saved_dp(tsk) \
115 (*(((unsigned long *)&(tsk)->thread.b15_14) + 1))
116#else
117#define thread_saved_ksp(tsk) \
118 (*(((unsigned long *)&(tsk)->thread.b15_14) + 1))
119#define thread_saved_dp(tsk) \
120 (*(unsigned long *)&(tsk)->thread.b15_14)
121#endif
122
123extern unsigned long get_wchan(struct task_struct *p);
124
125#define KSTK_EIP(tsk) (task_pt_regs(task)->pc)
126#define KSTK_ESP(tsk) (task_pt_regs(task)->sp)
127
128#define cpu_relax() do { } while (0)
129
130extern const struct seq_operations cpuinfo_op;
131
132#endif /* ASM_C6X_PROCESSOR_H */
diff --git a/arch/c6x/include/asm/procinfo.h b/arch/c6x/include/asm/procinfo.h
new file mode 100644
index 00000000000..c139d1e71f8
--- /dev/null
+++ b/arch/c6x/include/asm/procinfo.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Incorporated
3 * Author: Mark Salter (msalter@redhat.com)
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef _ASM_C6X_PROCINFO_H
11#define _ASM_C6X_PROCINFO_H
12
13#ifdef __KERNEL__
14
15struct proc_info_list {
16 unsigned int cpu_val;
17 unsigned int cpu_mask;
18 const char *arch_name;
19 const char *elf_name;
20 unsigned int elf_hwcap;
21};
22
23#else /* __KERNEL__ */
24#include <asm/elf.h>
25#warning "Please include asm/elf.h instead"
26#endif /* __KERNEL__ */
27
28#endif /* _ASM_C6X_PROCINFO_H */
diff --git a/arch/c6x/include/asm/prom.h b/arch/c6x/include/asm/prom.h
new file mode 100644
index 00000000000..b4ec95f0751
--- /dev/null
+++ b/arch/c6x/include/asm/prom.h
@@ -0,0 +1 @@
/* dummy prom.h; here to make linux/of.h's #includes happy */
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h
new file mode 100644
index 00000000000..21e8d7931fe
--- /dev/null
+++ b/arch/c6x/include/asm/ptrace.h
@@ -0,0 +1,174 @@
1/*
2 * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated
3 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
4 *
5 * Updated for 2.6.34: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_PTRACE_H
12#define _ASM_C6X_PTRACE_H
13
14#define BKPT_OPCODE 0x56454314 /* illegal opcode */
15
16#ifdef _BIG_ENDIAN
17#define PT_LO(odd, even) odd
18#define PT_HI(odd, even) even
19#else
20#define PT_LO(odd, even) even
21#define PT_HI(odd, even) odd
22#endif
23
24#define PT_A4_ORG PT_LO(1, 0)
25#define PT_TSR PT_HI(1, 0)
26#define PT_ILC PT_LO(3, 2)
27#define PT_RILC PT_HI(3, 2)
28#define PT_CSR PT_LO(5, 4)
29#define PT_PC PT_HI(5, 4)
30#define PT_B16 PT_LO(7, 6)
31#define PT_B17 PT_HI(7, 6)
32#define PT_B18 PT_LO(9, 8)
33#define PT_B19 PT_HI(9, 8)
34#define PT_B20 PT_LO(11, 10)
35#define PT_B21 PT_HI(11, 10)
36#define PT_B22 PT_LO(13, 12)
37#define PT_B23 PT_HI(13, 12)
38#define PT_B24 PT_LO(15, 14)
39#define PT_B25 PT_HI(15, 14)
40#define PT_B26 PT_LO(17, 16)
41#define PT_B27 PT_HI(17, 16)
42#define PT_B28 PT_LO(19, 18)
43#define PT_B29 PT_HI(19, 18)
44#define PT_B30 PT_LO(21, 20)
45#define PT_B31 PT_HI(21, 20)
46#define PT_B0 PT_LO(23, 22)
47#define PT_B1 PT_HI(23, 22)
48#define PT_B2 PT_LO(25, 24)
49#define PT_B3 PT_HI(25, 24)
50#define PT_B4 PT_LO(27, 26)
51#define PT_B5 PT_HI(27, 26)
52#define PT_B6 PT_LO(29, 28)
53#define PT_B7 PT_HI(29, 28)
54#define PT_B8 PT_LO(31, 30)
55#define PT_B9 PT_HI(31, 30)
56#define PT_B10 PT_LO(33, 32)
57#define PT_B11 PT_HI(33, 32)
58#define PT_B12 PT_LO(35, 34)
59#define PT_B13 PT_HI(35, 34)
60#define PT_A16 PT_LO(37, 36)
61#define PT_A17 PT_HI(37, 36)
62#define PT_A18 PT_LO(39, 38)
63#define PT_A19 PT_HI(39, 38)
64#define PT_A20 PT_LO(41, 40)
65#define PT_A21 PT_HI(41, 40)
66#define PT_A22 PT_LO(43, 42)
67#define PT_A23 PT_HI(43, 42)
68#define PT_A24 PT_LO(45, 44)
69#define PT_A25 PT_HI(45, 44)
70#define PT_A26 PT_LO(47, 46)
71#define PT_A27 PT_HI(47, 46)
72#define PT_A28 PT_LO(49, 48)
73#define PT_A29 PT_HI(49, 48)
74#define PT_A30 PT_LO(51, 50)
75#define PT_A31 PT_HI(51, 50)
76#define PT_A0 PT_LO(53, 52)
77#define PT_A1 PT_HI(53, 52)
78#define PT_A2 PT_LO(55, 54)
79#define PT_A3 PT_HI(55, 54)
80#define PT_A4 PT_LO(57, 56)
81#define PT_A5 PT_HI(57, 56)
82#define PT_A6 PT_LO(59, 58)
83#define PT_A7 PT_HI(59, 58)
84#define PT_A8 PT_LO(61, 60)
85#define PT_A9 PT_HI(61, 60)
86#define PT_A10 PT_LO(63, 62)
87#define PT_A11 PT_HI(63, 62)
88#define PT_A12 PT_LO(65, 64)
89#define PT_A13 PT_HI(65, 64)
90#define PT_A14 PT_LO(67, 66)
91#define PT_A15 PT_HI(67, 66)
92#define PT_B14 PT_LO(69, 68)
93#define PT_B15 PT_HI(69, 68)
94
95#define NR_PTREGS 70
96
97#define PT_DP PT_B14 /* Data Segment Pointer (B14) */
98#define PT_SP PT_B15 /* Stack Pointer (B15) */
99
100#ifndef __ASSEMBLY__
101
102#ifdef _BIG_ENDIAN
103#define REG_PAIR(odd, even) unsigned long odd; unsigned long even
104#else
105#define REG_PAIR(odd, even) unsigned long even; unsigned long odd
106#endif
107
108/*
109 * this struct defines the way the registers are stored on the
110 * stack during a system call. fields defined with REG_PAIR
111 * are saved and restored using double-word memory operations
112 * which means the word ordering of the pair depends on endianess.
113 */
114struct pt_regs {
115 REG_PAIR(tsr, orig_a4);
116 REG_PAIR(rilc, ilc);
117 REG_PAIR(pc, csr);
118
119 REG_PAIR(b17, b16);
120 REG_PAIR(b19, b18);
121 REG_PAIR(b21, b20);
122 REG_PAIR(b23, b22);
123 REG_PAIR(b25, b24);
124 REG_PAIR(b27, b26);
125 REG_PAIR(b29, b28);
126 REG_PAIR(b31, b30);
127
128 REG_PAIR(b1, b0);
129 REG_PAIR(b3, b2);
130 REG_PAIR(b5, b4);
131 REG_PAIR(b7, b6);
132 REG_PAIR(b9, b8);
133 REG_PAIR(b11, b10);
134 REG_PAIR(b13, b12);
135
136 REG_PAIR(a17, a16);
137 REG_PAIR(a19, a18);
138 REG_PAIR(a21, a20);
139 REG_PAIR(a23, a22);
140 REG_PAIR(a25, a24);
141 REG_PAIR(a27, a26);
142 REG_PAIR(a29, a28);
143 REG_PAIR(a31, a30);
144
145 REG_PAIR(a1, a0);
146 REG_PAIR(a3, a2);
147 REG_PAIR(a5, a4);
148 REG_PAIR(a7, a6);
149 REG_PAIR(a9, a8);
150 REG_PAIR(a11, a10);
151 REG_PAIR(a13, a12);
152
153 REG_PAIR(a15, a14);
154 REG_PAIR(sp, dp);
155};
156
157#ifdef __KERNEL__
158
159#include <linux/linkage.h>
160
161#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0)
162
163#define instruction_pointer(regs) ((regs)->pc)
164#define profile_pc(regs) instruction_pointer(regs)
165#define user_stack_pointer(regs) ((regs)->sp)
166
167extern void show_regs(struct pt_regs *);
168
169extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs);
170extern asmlinkage void syscall_trace_exit(struct pt_regs *regs);
171
172#endif /* __KERNEL__ */
173#endif /* __ASSEMBLY__ */
174#endif /* _ASM_C6X_PTRACE_H */
diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h
new file mode 100644
index 00000000000..f703989d837
--- /dev/null
+++ b/arch/c6x/include/asm/sections.h
@@ -0,0 +1,12 @@
1#ifndef _ASM_C6X_SECTIONS_H
2#define _ASM_C6X_SECTIONS_H
3
4#include <asm-generic/sections.h>
5
6extern char _vectors_start[];
7extern char _vectors_end[];
8
9extern char _data_lma[];
10extern char _fdt_start[], _fdt_end[];
11
12#endif /* _ASM_C6X_SECTIONS_H */
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h
new file mode 100644
index 00000000000..1808f279f82
--- /dev/null
+++ b/arch/c6x/include/asm/setup.h
@@ -0,0 +1,32 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_SETUP_H
12#define _ASM_C6X_SETUP_H
13
14#define COMMAND_LINE_SIZE 1024
15
16#ifndef __ASSEMBLY__
17extern char c6x_command_line[COMMAND_LINE_SIZE];
18
19extern int c6x_add_memory(phys_addr_t start, unsigned long size);
20
21extern unsigned long ram_start;
22extern unsigned long ram_end;
23
24extern int c6x_num_cores;
25extern unsigned int c6x_silicon_rev;
26extern unsigned int c6x_devstat;
27extern unsigned char c6x_fuse_mac[6];
28
29extern void machine_init(unsigned long dt_ptr);
30
31#endif /* !__ASSEMBLY__ */
32#endif /* _ASM_C6X_SETUP_H */
diff --git a/arch/c6x/include/asm/sigcontext.h b/arch/c6x/include/asm/sigcontext.h
new file mode 100644
index 00000000000..eb702f39cde
--- /dev/null
+++ b/arch/c6x/include/asm/sigcontext.h
@@ -0,0 +1,80 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_SIGCONTEXT_H
12#define _ASM_C6X_SIGCONTEXT_H
13
14
15struct sigcontext {
16 unsigned long sc_mask; /* old sigmask */
17 unsigned long sc_sp; /* old user stack pointer */
18
19 unsigned long sc_a4;
20 unsigned long sc_b4;
21 unsigned long sc_a6;
22 unsigned long sc_b6;
23 unsigned long sc_a8;
24 unsigned long sc_b8;
25
26 unsigned long sc_a0;
27 unsigned long sc_a1;
28 unsigned long sc_a2;
29 unsigned long sc_a3;
30 unsigned long sc_a5;
31 unsigned long sc_a7;
32 unsigned long sc_a9;
33
34 unsigned long sc_b0;
35 unsigned long sc_b1;
36 unsigned long sc_b2;
37 unsigned long sc_b3;
38 unsigned long sc_b5;
39 unsigned long sc_b7;
40 unsigned long sc_b9;
41
42 unsigned long sc_a16;
43 unsigned long sc_a17;
44 unsigned long sc_a18;
45 unsigned long sc_a19;
46 unsigned long sc_a20;
47 unsigned long sc_a21;
48 unsigned long sc_a22;
49 unsigned long sc_a23;
50 unsigned long sc_a24;
51 unsigned long sc_a25;
52 unsigned long sc_a26;
53 unsigned long sc_a27;
54 unsigned long sc_a28;
55 unsigned long sc_a29;
56 unsigned long sc_a30;
57 unsigned long sc_a31;
58
59 unsigned long sc_b16;
60 unsigned long sc_b17;
61 unsigned long sc_b18;
62 unsigned long sc_b19;
63 unsigned long sc_b20;
64 unsigned long sc_b21;
65 unsigned long sc_b22;
66 unsigned long sc_b23;
67 unsigned long sc_b24;
68 unsigned long sc_b25;
69 unsigned long sc_b26;
70 unsigned long sc_b27;
71 unsigned long sc_b28;
72 unsigned long sc_b29;
73 unsigned long sc_b30;
74 unsigned long sc_b31;
75
76 unsigned long sc_csr;
77 unsigned long sc_pc;
78};
79
80#endif /* _ASM_C6X_SIGCONTEXT_H */
diff --git a/arch/c6x/include/asm/signal.h b/arch/c6x/include/asm/signal.h
new file mode 100644
index 00000000000..f1cd870596a
--- /dev/null
+++ b/arch/c6x/include/asm/signal.h
@@ -0,0 +1,17 @@
1#ifndef _ASM_C6X_SIGNAL_H
2#define _ASM_C6X_SIGNAL_H
3
4#include <asm-generic/signal.h>
5
6#ifndef __ASSEMBLY__
7#include <linux/linkage.h>
8
9struct pt_regs;
10
11extern asmlinkage int do_rt_sigreturn(struct pt_regs *regs);
12extern asmlinkage void do_notify_resume(struct pt_regs *regs,
13 u32 thread_info_flags,
14 int syscall);
15#endif
16
17#endif /* _ASM_C6X_SIGNAL_H */
diff --git a/arch/c6x/include/asm/soc.h b/arch/c6x/include/asm/soc.h
new file mode 100644
index 00000000000..43f50159e59
--- /dev/null
+++ b/arch/c6x/include/asm/soc.h
@@ -0,0 +1,35 @@
1/*
2 * Miscellaneous SoC-specific hooks.
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 *
6 * Author: Mark Salter <msalter@redhat.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12#ifndef _ASM_C6X_SOC_H
13#define _ASM_C6X_SOC_H
14
15struct soc_ops {
16 /* Return active exception event or -1 if none */
17 int (*get_exception)(void);
18
19 /* Assert an event */
20 void (*assert_event)(unsigned int evt);
21};
22
23extern struct soc_ops soc_ops;
24
25extern int soc_get_exception(void);
26extern void soc_assert_event(unsigned int event);
27extern int soc_mac_addr(unsigned int index, u8 *addr);
28
29/*
30 * for mmio on SoC devices. regs are always same byte order as cpu.
31 */
32#define soc_readl(addr) __raw_readl(addr)
33#define soc_writel(b, addr) __raw_writel((b), (addr))
34
35#endif /* _ASM_C6X_SOC_H */
diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h
new file mode 100644
index 00000000000..b21517c80a1
--- /dev/null
+++ b/arch/c6x/include/asm/string.h
@@ -0,0 +1,21 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_STRING_H
12#define _ASM_C6X_STRING_H
13
14#include <asm/page.h>
15#include <linux/linkage.h>
16
17asmlinkage extern void *memcpy(void *to, const void *from, size_t n);
18
19#define __HAVE_ARCH_MEMCPY
20
21#endif /* _ASM_C6X_STRING_H */
diff --git a/arch/c6x/include/asm/swab.h b/arch/c6x/include/asm/swab.h
new file mode 100644
index 00000000000..fd4bb0520e5
--- /dev/null
+++ b/arch/c6x/include/asm/swab.h
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#ifndef _ASM_C6X_SWAB_H
10#define _ASM_C6X_SWAB_H
11
12static inline __attribute_const__ __u16 __c6x_swab16(__u16 val)
13{
14 asm("swap4 .l1 %0,%0\n" : "+a"(val));
15 return val;
16}
17
18static inline __attribute_const__ __u32 __c6x_swab32(__u32 val)
19{
20 asm("swap4 .l1 %0,%0\n"
21 "swap2 .l1 %0,%0\n"
22 : "+a"(val));
23 return val;
24}
25
26static inline __attribute_const__ __u64 __c6x_swab64(__u64 val)
27{
28 asm(" swap2 .s1 %p0,%P0\n"
29 "|| swap2 .l1 %P0,%p0\n"
30 " swap4 .l1 %p0,%p0\n"
31 " swap4 .l1 %P0,%P0\n"
32 : "+a"(val));
33 return val;
34}
35
36static inline __attribute_const__ __u32 __c6x_swahw32(__u32 val)
37{
38 asm("swap2 .l1 %0,%0\n" : "+a"(val));
39 return val;
40}
41
42static inline __attribute_const__ __u32 __c6x_swahb32(__u32 val)
43{
44 asm("swap4 .l1 %0,%0\n" : "+a"(val));
45 return val;
46}
47
48#define __arch_swab16 __c6x_swab16
49#define __arch_swab32 __c6x_swab32
50#define __arch_swab64 __c6x_swab64
51#define __arch_swahw32 __c6x_swahw32
52#define __arch_swahb32 __c6x_swahb32
53
54#endif /* _ASM_C6X_SWAB_H */
diff --git a/arch/c6x/include/asm/syscall.h b/arch/c6x/include/asm/syscall.h
new file mode 100644
index 00000000000..ae2be315ee9
--- /dev/null
+++ b/arch/c6x/include/asm/syscall.h
@@ -0,0 +1,123 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __ASM_C6X_SYSCALL_H
12#define __ASM_C6X_SYSCALL_H
13
14#include <linux/err.h>
15#include <linux/sched.h>
16
17static inline int syscall_get_nr(struct task_struct *task,
18 struct pt_regs *regs)
19{
20 return regs->b0;
21}
22
23static inline void syscall_rollback(struct task_struct *task,
24 struct pt_regs *regs)
25{
26 /* do nothing */
27}
28
29static inline long syscall_get_error(struct task_struct *task,
30 struct pt_regs *regs)
31{
32 return IS_ERR_VALUE(regs->a4) ? regs->a4 : 0;
33}
34
35static inline long syscall_get_return_value(struct task_struct *task,
36 struct pt_regs *regs)
37{
38 return regs->a4;
39}
40
41static inline void syscall_set_return_value(struct task_struct *task,
42 struct pt_regs *regs,
43 int error, long val)
44{
45 regs->a4 = error ?: val;
46}
47
48static inline void syscall_get_arguments(struct task_struct *task,
49 struct pt_regs *regs, unsigned int i,
50 unsigned int n, unsigned long *args)
51{
52 switch (i) {
53 case 0:
54 if (!n--)
55 break;
56 *args++ = regs->a4;
57 case 1:
58 if (!n--)
59 break;
60 *args++ = regs->b4;
61 case 2:
62 if (!n--)
63 break;
64 *args++ = regs->a6;
65 case 3:
66 if (!n--)
67 break;
68 *args++ = regs->b6;
69 case 4:
70 if (!n--)
71 break;
72 *args++ = regs->a8;
73 case 5:
74 if (!n--)
75 break;
76 *args++ = regs->b8;
77 case 6:
78 if (!n--)
79 break;
80 default:
81 BUG();
82 }
83}
84
85static inline void syscall_set_arguments(struct task_struct *task,
86 struct pt_regs *regs,
87 unsigned int i, unsigned int n,
88 const unsigned long *args)
89{
90 switch (i) {
91 case 0:
92 if (!n--)
93 break;
94 regs->a4 = *args++;
95 case 1:
96 if (!n--)
97 break;
98 regs->b4 = *args++;
99 case 2:
100 if (!n--)
101 break;
102 regs->a6 = *args++;
103 case 3:
104 if (!n--)
105 break;
106 regs->b6 = *args++;
107 case 4:
108 if (!n--)
109 break;
110 regs->a8 = *args++;
111 case 5:
112 if (!n--)
113 break;
114 regs->a9 = *args++;
115 case 6:
116 if (!n)
117 break;
118 default:
119 BUG();
120 }
121}
122
123#endif /* __ASM_C6X_SYSCALLS_H */
diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h
new file mode 100644
index 00000000000..aed53da703c
--- /dev/null
+++ b/arch/c6x/include/asm/syscalls.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation, version 2.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12 * NON INFRINGEMENT. See the GNU General Public License for
13 * more details.
14 */
15
16#ifndef __ASM_C6X_SYSCALLS_H
17#define __ASM_C6X_SYSCALLS_H
18
19#include <linux/compiler.h>
20#include <linux/linkage.h>
21#include <linux/types.h>
22
23/* The array of function pointers for syscalls. */
24extern void *sys_call_table[];
25
26/* The following are trampolines in entry.S to handle 64-bit arguments */
27extern long sys_pread_c6x(unsigned int fd, char __user *buf,
28 size_t count, off_t pos_low, off_t pos_high);
29extern long sys_pwrite_c6x(unsigned int fd, const char __user *buf,
30 size_t count, off_t pos_low, off_t pos_high);
31extern long sys_truncate64_c6x(const char __user *path,
32 off_t length_low, off_t length_high);
33extern long sys_ftruncate64_c6x(unsigned int fd,
34 off_t length_low, off_t length_high);
35extern long sys_fadvise64_c6x(int fd, u32 offset_lo, u32 offset_hi,
36 u32 len, int advice);
37extern long sys_fadvise64_64_c6x(int fd, u32 offset_lo, u32 offset_hi,
38 u32 len_lo, u32 len_hi, int advice);
39extern long sys_fallocate_c6x(int fd, int mode,
40 u32 offset_lo, u32 offset_hi,
41 u32 len_lo, u32 len_hi);
42extern int sys_cache_sync(unsigned long s, unsigned long e);
43
44struct pt_regs;
45
46extern asmlinkage long sys_c6x_clone(struct pt_regs *regs);
47extern asmlinkage long sys_c6x_execve(const char __user *name,
48 const char __user *const __user *argv,
49 const char __user *const __user *envp,
50 struct pt_regs *regs);
51
52
53#include <asm-generic/syscalls.h>
54
55#endif /* __ASM_C6X_SYSCALLS_H */
diff --git a/arch/c6x/include/asm/system.h b/arch/c6x/include/asm/system.h
new file mode 100644
index 00000000000..e076dc0eacc
--- /dev/null
+++ b/arch/c6x/include/asm/system.h
@@ -0,0 +1,168 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_SYSTEM_H
12#define _ASM_C6X_SYSTEM_H
13
14#include <linux/linkage.h>
15#include <linux/irqflags.h>
16
17#define prepare_to_switch() do { } while (0)
18
19struct task_struct;
20struct thread_struct;
21asmlinkage void *__switch_to(struct thread_struct *prev,
22 struct thread_struct *next,
23 struct task_struct *tsk);
24
25#define switch_to(prev, next, last) \
26 do { \
27 current->thread.wchan = (u_long) __builtin_return_address(0); \
28 (last) = __switch_to(&(prev)->thread, \
29 &(next)->thread, (prev)); \
30 mb(); \
31 current->thread.wchan = 0; \
32 } while (0)
33
34/* Reset the board */
35#define HARD_RESET_NOW()
36
37#define get_creg(reg) \
38 ({ unsigned int __x; \
39 asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; })
40
41#define set_creg(reg, v) \
42 do { unsigned int __x = (unsigned int)(v); \
43 asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \
44 } while (0)
45
46#define or_creg(reg, n) \
47 do { unsigned __x, __n = (unsigned)(n); \
48 asm volatile ("mvc .s2 " #reg ",%0\n" \
49 "or .l2 %1,%0,%0\n" \
50 "mvc .s2 %0," #reg "\n" \
51 "nop\n" \
52 : "=&b"(__x) : "b"(__n)); \
53 } while (0)
54
55#define and_creg(reg, n) \
56 do { unsigned __x, __n = (unsigned)(n); \
57 asm volatile ("mvc .s2 " #reg ",%0\n" \
58 "and .l2 %1,%0,%0\n" \
59 "mvc .s2 %0," #reg "\n" \
60 "nop\n" \
61 : "=&b"(__x) : "b"(__n)); \
62 } while (0)
63
64#define get_coreid() (get_creg(DNUM) & 0xff)
65
66/* Set/get IST */
67#define set_ist(x) set_creg(ISTP, x)
68#define get_ist() get_creg(ISTP)
69
70/*
71 * Exception management
72 */
73asmlinkage void enable_exception(void);
74#define disable_exception()
75#define get_except_type() get_creg(EFR)
76#define ack_exception(type) set_creg(ECR, 1 << (type))
77#define get_iexcept() get_creg(IERR)
78#define set_iexcept(mask) set_creg(IERR, (mask))
79
80/*
81 * Misc. functions
82 */
83#define nop() asm("NOP\n");
84#define mb() barrier()
85#define rmb() barrier()
86#define wmb() barrier()
87#define set_mb(var, value) do { var = value; mb(); } while (0)
88#define set_wmb(var, value) do { var = value; wmb(); } while (0)
89
90#define smp_mb() barrier()
91#define smp_rmb() barrier()
92#define smp_wmb() barrier()
93#define smp_read_barrier_depends() do { } while (0)
94
95#define xchg(ptr, x) \
96 ((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \
97 sizeof(*(ptr))))
98#define tas(ptr) xchg((ptr), 1)
99
100unsigned int _lmbd(unsigned int, unsigned int);
101unsigned int _bitr(unsigned int);
102
103struct __xchg_dummy { unsigned int a[100]; };
104#define __xg(x) ((volatile struct __xchg_dummy *)(x))
105
106static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size)
107{
108 unsigned int tmp;
109 unsigned long flags;
110
111 local_irq_save(flags);
112
113 switch (size) {
114 case 1:
115 tmp = 0;
116 tmp = *((unsigned char *) ptr);
117 *((unsigned char *) ptr) = (unsigned char) x;
118 break;
119 case 2:
120 tmp = 0;
121 tmp = *((unsigned short *) ptr);
122 *((unsigned short *) ptr) = x;
123 break;
124 case 4:
125 tmp = 0;
126 tmp = *((unsigned int *) ptr);
127 *((unsigned int *) ptr) = x;
128 break;
129 }
130 local_irq_restore(flags);
131 return tmp;
132}
133
134#include <asm-generic/cmpxchg-local.h>
135
136/*
137 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
138 * them available.
139 */
140#define cmpxchg_local(ptr, o, n) \
141 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
142 (unsigned long)(o), \
143 (unsigned long)(n), \
144 sizeof(*(ptr))))
145#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
146
147#include <asm-generic/cmpxchg.h>
148
149#define _extu(x, s, e) \
150 ({ unsigned int __x; \
151 asm volatile ("extu .S2 %3,%1,%2,%0\n" : \
152 "=b"(__x) : "n"(s), "n"(e), "b"(x)); \
153 __x; })
154
155
156extern unsigned int c6x_core_freq;
157
158struct pt_regs;
159
160extern void die(char *str, struct pt_regs *fp, int nr);
161extern asmlinkage int process_exception(struct pt_regs *regs);
162extern void time_init(void);
163extern void free_initmem(void);
164
165extern void (*c6x_restart)(void);
166extern void (*c6x_halt)(void);
167
168#endif /* _ASM_C6X_SYSTEM_H */
diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h
new file mode 100644
index 00000000000..fd99148cda9
--- /dev/null
+++ b/arch/c6x/include/asm/thread_info.h
@@ -0,0 +1,121 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Updated for 2.6.3x: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef _ASM_C6X_THREAD_INFO_H
14#define _ASM_C6X_THREAD_INFO_H
15
16#ifdef __KERNEL__
17
18#include <asm/page.h>
19
20#ifdef CONFIG_4KSTACKS
21#define THREAD_SIZE 4096
22#define THREAD_SHIFT 12
23#define THREAD_ORDER 0
24#else
25#define THREAD_SIZE 8192
26#define THREAD_SHIFT 13
27#define THREAD_ORDER 1
28#endif
29
30#define THREAD_START_SP (THREAD_SIZE - 8)
31
32#ifndef __ASSEMBLY__
33
34typedef struct {
35 unsigned long seg;
36} mm_segment_t;
37
38/*
39 * low level task data.
40 */
41struct thread_info {
42 struct task_struct *task; /* main task structure */
43 struct exec_domain *exec_domain; /* execution domain */
44 unsigned long flags; /* low level flags */
45 int cpu; /* cpu we're on */
46 int preempt_count; /* 0 = preemptable, <0 = BUG */
47 mm_segment_t addr_limit; /* thread address space */
48 struct restart_block restart_block;
49};
50
51/*
52 * macros/functions for gaining access to the thread information structure
53 *
54 * preempt_count needs to be 1 initially, until the scheduler is functional.
55 */
56#define INIT_THREAD_INFO(tsk) \
57{ \
58 .task = &tsk, \
59 .exec_domain = &default_exec_domain, \
60 .flags = 0, \
61 .cpu = 0, \
62 .preempt_count = INIT_PREEMPT_COUNT, \
63 .addr_limit = KERNEL_DS, \
64 .restart_block = { \
65 .fn = do_no_restart_syscall, \
66 }, \
67}
68
69#define init_thread_info (init_thread_union.thread_info)
70#define init_stack (init_thread_union.stack)
71
72/* get the thread information struct of current task */
73static inline __attribute__((const))
74struct thread_info *current_thread_info(void)
75{
76 struct thread_info *ti;
77 asm volatile (" clr .s2 B15,0,%1,%0\n"
78 : "=b" (ti)
79 : "Iu5" (THREAD_SHIFT - 1));
80 return ti;
81}
82
83#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
84
85/* thread information allocation */
86#ifdef CONFIG_DEBUG_STACK_USAGE
87#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
88#else
89#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK)
90#endif
91
92#define alloc_thread_info_node(tsk, node) \
93 ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER))
94
95#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
96#define get_thread_info(ti) get_task_struct((ti)->task)
97#define put_thread_info(ti) put_task_struct((ti)->task)
98#endif /* __ASSEMBLY__ */
99
100#define PREEMPT_ACTIVE 0x10000000
101
102/*
103 * thread information flag bit numbers
104 * - pending work-to-be-done flags are in LSW
105 * - other flags in MSW
106 */
107#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
108#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
109#define TIF_SIGPENDING 2 /* signal pending */
110#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
111#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
112
113#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */
114#define TIF_MEMDIE 17 /* OOM killer killed process */
115
116#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */
117#define TIF_ALLWORK_MASK 0x00007FFF /* work on any return to u-space */
118
119#endif /* __KERNEL__ */
120
121#endif /* _ASM_C6X_THREAD_INFO_H */
diff --git a/arch/c6x/include/asm/timer64.h b/arch/c6x/include/asm/timer64.h
new file mode 100644
index 00000000000..bbe27bb9887
--- /dev/null
+++ b/arch/c6x/include/asm/timer64.h
@@ -0,0 +1,6 @@
1#ifndef _C6X_TIMER64_H
2#define _C6X_TIMER64_H
3
4extern void __init timer64_init(void);
5
6#endif /* _C6X_TIMER64_H */
diff --git a/arch/c6x/include/asm/timex.h b/arch/c6x/include/asm/timex.h
new file mode 100644
index 00000000000..508c3ec971f
--- /dev/null
+++ b/arch/c6x/include/asm/timex.h
@@ -0,0 +1,33 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Modified for 2.6.34: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#ifndef _ASM_C6X_TIMEX_H
14#define _ASM_C6X_TIMEX_H
15
16#define CLOCK_TICK_RATE ((1000 * 1000000UL) / 6)
17
18/* 64-bit timestamp */
19typedef unsigned long long cycles_t;
20
21static inline cycles_t get_cycles(void)
22{
23 unsigned l, h;
24
25 asm volatile (" dint\n"
26 " mvc .s2 TSCL,%0\n"
27 " mvc .s2 TSCH,%1\n"
28 " rint\n"
29 : "=b"(l), "=b"(h));
30 return ((cycles_t)h << 32) | l;
31}
32
33#endif /* _ASM_C6X_TIMEX_H */
diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h
new file mode 100644
index 00000000000..8709e5e29d2
--- /dev/null
+++ b/arch/c6x/include/asm/tlb.h
@@ -0,0 +1,8 @@
1#ifndef _ASM_C6X_TLB_H
2#define _ASM_C6X_TLB_H
3
4#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
5
6#include <asm-generic/tlb.h>
7
8#endif /* _ASM_C6X_TLB_H */
diff --git a/arch/c6x/include/asm/traps.h b/arch/c6x/include/asm/traps.h
new file mode 100644
index 00000000000..62124d7b1b5
--- /dev/null
+++ b/arch/c6x/include/asm/traps.h
@@ -0,0 +1,36 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef _ASM_C6X_TRAPS_H
12#define _ASM_C6X_TRAPS_H
13
14#define EXCEPT_TYPE_NXF 31 /* NMI */
15#define EXCEPT_TYPE_EXC 30 /* external exception */
16#define EXCEPT_TYPE_IXF 1 /* internal exception */
17#define EXCEPT_TYPE_SXF 0 /* software exception */
18
19#define EXCEPT_CAUSE_LBX (1 << 7) /* loop buffer exception */
20#define EXCEPT_CAUSE_PRX (1 << 6) /* privilege exception */
21#define EXCEPT_CAUSE_RAX (1 << 5) /* resource access exception */
22#define EXCEPT_CAUSE_RCX (1 << 4) /* resource conflict exception */
23#define EXCEPT_CAUSE_OPX (1 << 3) /* opcode exception */
24#define EXCEPT_CAUSE_EPX (1 << 2) /* execute packet exception */
25#define EXCEPT_CAUSE_FPX (1 << 1) /* fetch packet exception */
26#define EXCEPT_CAUSE_IFX (1 << 0) /* instruction fetch exception */
27
28struct exception_info {
29 char *kernel_str;
30 int signo;
31 int code;
32};
33
34extern int (*c6x_nmi_handler)(struct pt_regs *regs);
35
36#endif /* _ASM_C6X_TRAPS_H */
diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h
new file mode 100644
index 00000000000..453dd263bee
--- /dev/null
+++ b/arch/c6x/include/asm/uaccess.h
@@ -0,0 +1,107 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#ifndef _ASM_C6X_UACCESS_H
10#define _ASM_C6X_UACCESS_H
11
12#include <linux/types.h>
13#include <linux/compiler.h>
14#include <linux/string.h>
15
16#ifdef CONFIG_ACCESS_CHECK
17#define __access_ok _access_ok
18#endif
19
20/*
21 * __copy_from_user/copy_to_user are based on ones in asm-generic/uaccess.h
22 *
23 * C6X supports unaligned 32 and 64 bit loads and stores.
24 */
25static inline __must_check long __copy_from_user(void *to,
26 const void __user *from, unsigned long n)
27{
28 u32 tmp32;
29 u64 tmp64;
30
31 if (__builtin_constant_p(n)) {
32 switch (n) {
33 case 1:
34 *(u8 *)to = *(u8 __force *)from;
35 return 0;
36 case 4:
37 asm volatile ("ldnw .d1t1 *%2,%0\n"
38 "nop 4\n"
39 "stnw .d1t1 %0,*%1\n"
40 : "=&a"(tmp32)
41 : "A"(to), "a"(from)
42 : "memory");
43 return 0;
44 case 8:
45 asm volatile ("ldndw .d1t1 *%2,%0\n"
46 "nop 4\n"
47 "stndw .d1t1 %0,*%1\n"
48 : "=&a"(tmp64)
49 : "a"(to), "a"(from)
50 : "memory");
51 return 0;
52 default:
53 break;
54 }
55 }
56
57 memcpy(to, (const void __force *)from, n);
58 return 0;
59}
60
61static inline __must_check long __copy_to_user(void __user *to,
62 const void *from, unsigned long n)
63{
64 u32 tmp32;
65 u64 tmp64;
66
67 if (__builtin_constant_p(n)) {
68 switch (n) {
69 case 1:
70 *(u8 __force *)to = *(u8 *)from;
71 return 0;
72 case 4:
73 asm volatile ("ldnw .d1t1 *%2,%0\n"
74 "nop 4\n"
75 "stnw .d1t1 %0,*%1\n"
76 : "=&a"(tmp32)
77 : "a"(to), "a"(from)
78 : "memory");
79 return 0;
80 case 8:
81 asm volatile ("ldndw .d1t1 *%2,%0\n"
82 "nop 4\n"
83 "stndw .d1t1 %0,*%1\n"
84 : "=&a"(tmp64)
85 : "a"(to), "a"(from)
86 : "memory");
87 return 0;
88 default:
89 break;
90 }
91 }
92
93 memcpy((void __force *)to, from, n);
94 return 0;
95}
96
97#define __copy_to_user __copy_to_user
98#define __copy_from_user __copy_from_user
99
100extern int _access_ok(unsigned long addr, unsigned long size);
101#ifdef CONFIG_ACCESS_CHECK
102#define __access_ok _access_ok
103#endif
104
105#include <asm-generic/uaccess.h>
106
107#endif /* _ASM_C6X_UACCESS_H */
diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h
new file mode 100644
index 00000000000..b976cb740ea
--- /dev/null
+++ b/arch/c6x/include/asm/unaligned.h
@@ -0,0 +1,170 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 * Rewritten for 2.6.3x: Mark Salter <msalter@redhat.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef _ASM_C6X_UNALIGNED_H
13#define _ASM_C6X_UNALIGNED_H
14
15#include <linux/swab.h>
16
17/*
18 * The C64x+ can do unaligned word and dword accesses in hardware
19 * using special load/store instructions.
20 */
21
22static inline u16 get_unaligned_le16(const void *p)
23{
24 const u8 *_p = p;
25 return _p[0] | _p[1] << 8;
26}
27
28static inline u16 get_unaligned_be16(const void *p)
29{
30 const u8 *_p = p;
31 return _p[0] << 8 | _p[1];
32}
33
34static inline void put_unaligned_le16(u16 val, void *p)
35{
36 u8 *_p = p;
37 _p[0] = val;
38 _p[1] = val >> 8;
39}
40
41static inline void put_unaligned_be16(u16 val, void *p)
42{
43 u8 *_p = p;
44 _p[0] = val >> 8;
45 _p[1] = val;
46}
47
48static inline u32 get_unaligned32(const void *p)
49{
50 u32 val = (u32) p;
51 asm (" ldnw .d1t1 *%0,%0\n"
52 " nop 4\n"
53 : "+a"(val));
54 return val;
55}
56
57static inline void put_unaligned32(u32 val, void *p)
58{
59 asm volatile (" stnw .d2t1 %0,*%1\n"
60 : : "a"(val), "b"(p) : "memory");
61}
62
63static inline u64 get_unaligned64(const void *p)
64{
65 u64 val;
66 asm volatile (" ldndw .d1t1 *%1,%0\n"
67 " nop 4\n"
68 : "=a"(val) : "a"(p));
69 return val;
70}
71
72static inline void put_unaligned64(u64 val, const void *p)
73{
74 asm volatile (" stndw .d2t1 %0,*%1\n"
75 : : "a"(val), "b"(p) : "memory");
76}
77
78#ifdef CONFIG_CPU_BIG_ENDIAN
79
80#define get_unaligned_le32(p) __swab32(get_unaligned32(p))
81#define get_unaligned_le64(p) __swab64(get_unaligned64(p))
82#define get_unaligned_be32(p) get_unaligned32(p)
83#define get_unaligned_be64(p) get_unaligned64(p)
84#define put_unaligned_le32(v, p) put_unaligned32(__swab32(v), (p))
85#define put_unaligned_le64(v, p) put_unaligned64(__swab64(v), (p))
86#define put_unaligned_be32(v, p) put_unaligned32((v), (p))
87#define put_unaligned_be64(v, p) put_unaligned64((v), (p))
88#define get_unaligned __get_unaligned_be
89#define put_unaligned __put_unaligned_be
90
91#else
92
93#define get_unaligned_le32(p) get_unaligned32(p)
94#define get_unaligned_le64(p) get_unaligned64(p)
95#define get_unaligned_be32(p) __swab32(get_unaligned32(p))
96#define get_unaligned_be64(p) __swab64(get_unaligned64(p))
97#define put_unaligned_le32(v, p) put_unaligned32((v), (p))
98#define put_unaligned_le64(v, p) put_unaligned64((v), (p))
99#define put_unaligned_be32(v, p) put_unaligned32(__swab32(v), (p))
100#define put_unaligned_be64(v, p) put_unaligned64(__swab64(v), (p))
101#define get_unaligned __get_unaligned_le
102#define put_unaligned __put_unaligned_le
103
104#endif
105
106/*
107 * Cause a link-time error if we try an unaligned access other than
108 * 1,2,4 or 8 bytes long
109 */
110extern int __bad_unaligned_access_size(void);
111
112#define __get_unaligned_le(ptr) (typeof(*(ptr)))({ \
113 sizeof(*(ptr)) == 1 ? *(ptr) : \
114 (sizeof(*(ptr)) == 2 ? get_unaligned_le16((ptr)) : \
115 (sizeof(*(ptr)) == 4 ? get_unaligned_le32((ptr)) : \
116 (sizeof(*(ptr)) == 8 ? get_unaligned_le64((ptr)) : \
117 __bad_unaligned_access_size()))); \
118 })
119
120#define __get_unaligned_be(ptr) (__force typeof(*(ptr)))({ \
121 sizeof(*(ptr)) == 1 ? *(ptr) : \
122 (sizeof(*(ptr)) == 2 ? get_unaligned_be16((ptr)) : \
123 (sizeof(*(ptr)) == 4 ? get_unaligned_be32((ptr)) : \
124 (sizeof(*(ptr)) == 8 ? get_unaligned_be64((ptr)) : \
125 __bad_unaligned_access_size()))); \
126 })
127
128#define __put_unaligned_le(val, ptr) ({ \
129 void *__gu_p = (ptr); \
130 switch (sizeof(*(ptr))) { \
131 case 1: \
132 *(u8 *)__gu_p = (__force u8)(val); \
133 break; \
134 case 2: \
135 put_unaligned_le16((__force u16)(val), __gu_p); \
136 break; \
137 case 4: \
138 put_unaligned_le32((__force u32)(val), __gu_p); \
139 break; \
140 case 8: \
141 put_unaligned_le64((__force u64)(val), __gu_p); \
142 break; \
143 default: \
144 __bad_unaligned_access_size(); \
145 break; \
146 } \
147 (void)0; })
148
149#define __put_unaligned_be(val, ptr) ({ \
150 void *__gu_p = (ptr); \
151 switch (sizeof(*(ptr))) { \
152 case 1: \
153 *(u8 *)__gu_p = (__force u8)(val); \
154 break; \
155 case 2: \
156 put_unaligned_be16((__force u16)(val), __gu_p); \
157 break; \
158 case 4: \
159 put_unaligned_be32((__force u32)(val), __gu_p); \
160 break; \
161 case 8: \
162 put_unaligned_be64((__force u64)(val), __gu_p); \
163 break; \
164 default: \
165 __bad_unaligned_access_size(); \
166 break; \
167 } \
168 (void)0; })
169
170#endif /* _ASM_C6X_UNALIGNED_H */
diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h
new file mode 100644
index 00000000000..6d54ea4262e
--- /dev/null
+++ b/arch/c6x/include/asm/unistd.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 *
4 * Based on arch/tile version.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation, version 2.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for
14 * more details.
15 */
16#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL)
17#define _ASM_C6X_UNISTD_H
18
19/* Use the standard ABI for syscalls. */
20#include <asm-generic/unistd.h>
21
22/* C6X-specific syscalls. */
23#define __NR_cache_sync (__NR_arch_specific_syscall + 0)
24__SYSCALL(__NR_cache_sync, sys_cache_sync)
25
26#endif /* _ASM_C6X_UNISTD_H */
diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile
new file mode 100644
index 00000000000..580a515a944
--- /dev/null
+++ b/arch/c6x/kernel/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for arch/c6x/kernel/
3#
4
5extra-y := head.o vmlinux.lds
6
7obj-y := process.o traps.o irq.o signal.o ptrace.o
8obj-y += setup.o sys_c6x.o time.o devicetree.o
9obj-y += switch_to.o entry.o vectors.o c6x_ksyms.o
10obj-y += soc.o dma.o
11
12obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c
new file mode 100644
index 00000000000..759ad6d207b
--- /dev/null
+++ b/arch/c6x/kernel/asm-offsets.c
@@ -0,0 +1,123 @@
1/*
2 * Generate definitions needed by assembly language modules.
3 * This code generates raw asm output which is post-processed
4 * to extract and format the required data.
5 */
6
7#include <linux/sched.h>
8#include <linux/thread_info.h>
9#include <asm/procinfo.h>
10#include <linux/kbuild.h>
11#include <linux/unistd.h>
12
13void foo(void)
14{
15 OFFSET(REGS_A16, pt_regs, a16);
16 OFFSET(REGS_A17, pt_regs, a17);
17 OFFSET(REGS_A18, pt_regs, a18);
18 OFFSET(REGS_A19, pt_regs, a19);
19 OFFSET(REGS_A20, pt_regs, a20);
20 OFFSET(REGS_A21, pt_regs, a21);
21 OFFSET(REGS_A22, pt_regs, a22);
22 OFFSET(REGS_A23, pt_regs, a23);
23 OFFSET(REGS_A24, pt_regs, a24);
24 OFFSET(REGS_A25, pt_regs, a25);
25 OFFSET(REGS_A26, pt_regs, a26);
26 OFFSET(REGS_A27, pt_regs, a27);
27 OFFSET(REGS_A28, pt_regs, a28);
28 OFFSET(REGS_A29, pt_regs, a29);
29 OFFSET(REGS_A30, pt_regs, a30);
30 OFFSET(REGS_A31, pt_regs, a31);
31
32 OFFSET(REGS_B16, pt_regs, b16);
33 OFFSET(REGS_B17, pt_regs, b17);
34 OFFSET(REGS_B18, pt_regs, b18);
35 OFFSET(REGS_B19, pt_regs, b19);
36 OFFSET(REGS_B20, pt_regs, b20);
37 OFFSET(REGS_B21, pt_regs, b21);
38 OFFSET(REGS_B22, pt_regs, b22);
39 OFFSET(REGS_B23, pt_regs, b23);
40 OFFSET(REGS_B24, pt_regs, b24);
41 OFFSET(REGS_B25, pt_regs, b25);
42 OFFSET(REGS_B26, pt_regs, b26);
43 OFFSET(REGS_B27, pt_regs, b27);
44 OFFSET(REGS_B28, pt_regs, b28);
45 OFFSET(REGS_B29, pt_regs, b29);
46 OFFSET(REGS_B30, pt_regs, b30);
47 OFFSET(REGS_B31, pt_regs, b31);
48
49 OFFSET(REGS_A0, pt_regs, a0);
50 OFFSET(REGS_A1, pt_regs, a1);
51 OFFSET(REGS_A2, pt_regs, a2);
52 OFFSET(REGS_A3, pt_regs, a3);
53 OFFSET(REGS_A4, pt_regs, a4);
54 OFFSET(REGS_A5, pt_regs, a5);
55 OFFSET(REGS_A6, pt_regs, a6);
56 OFFSET(REGS_A7, pt_regs, a7);
57 OFFSET(REGS_A8, pt_regs, a8);
58 OFFSET(REGS_A9, pt_regs, a9);
59 OFFSET(REGS_A10, pt_regs, a10);
60 OFFSET(REGS_A11, pt_regs, a11);
61 OFFSET(REGS_A12, pt_regs, a12);
62 OFFSET(REGS_A13, pt_regs, a13);
63 OFFSET(REGS_A14, pt_regs, a14);
64 OFFSET(REGS_A15, pt_regs, a15);
65
66 OFFSET(REGS_B0, pt_regs, b0);
67 OFFSET(REGS_B1, pt_regs, b1);
68 OFFSET(REGS_B2, pt_regs, b2);
69 OFFSET(REGS_B3, pt_regs, b3);
70 OFFSET(REGS_B4, pt_regs, b4);
71 OFFSET(REGS_B5, pt_regs, b5);
72 OFFSET(REGS_B6, pt_regs, b6);
73 OFFSET(REGS_B7, pt_regs, b7);
74 OFFSET(REGS_B8, pt_regs, b8);
75 OFFSET(REGS_B9, pt_regs, b9);
76 OFFSET(REGS_B10, pt_regs, b10);
77 OFFSET(REGS_B11, pt_regs, b11);
78 OFFSET(REGS_B12, pt_regs, b12);
79 OFFSET(REGS_B13, pt_regs, b13);
80 OFFSET(REGS_DP, pt_regs, dp);
81 OFFSET(REGS_SP, pt_regs, sp);
82
83 OFFSET(REGS_TSR, pt_regs, tsr);
84 OFFSET(REGS_ORIG_A4, pt_regs, orig_a4);
85
86 DEFINE(REGS__END, sizeof(struct pt_regs));
87 BLANK();
88
89 OFFSET(THREAD_PC, thread_struct, pc);
90 OFFSET(THREAD_B15_14, thread_struct, b15_14);
91 OFFSET(THREAD_A15_14, thread_struct, a15_14);
92 OFFSET(THREAD_B13_12, thread_struct, b13_12);
93 OFFSET(THREAD_A13_12, thread_struct, a13_12);
94 OFFSET(THREAD_B11_10, thread_struct, b11_10);
95 OFFSET(THREAD_A11_10, thread_struct, a11_10);
96 OFFSET(THREAD_RICL_ICL, thread_struct, ricl_icl);
97 BLANK();
98
99 OFFSET(TASK_STATE, task_struct, state);
100 BLANK();
101
102 OFFSET(THREAD_INFO_FLAGS, thread_info, flags);
103 OFFSET(THREAD_INFO_PREEMPT_COUNT, thread_info, preempt_count);
104 BLANK();
105
106 /* These would be unneccessary if we ran asm files
107 * through the preprocessor.
108 */
109 DEFINE(KTHREAD_SIZE, THREAD_SIZE);
110 DEFINE(KTHREAD_SHIFT, THREAD_SHIFT);
111 DEFINE(KTHREAD_START_SP, THREAD_START_SP);
112 DEFINE(ENOSYS_, ENOSYS);
113 DEFINE(NR_SYSCALLS_, __NR_syscalls);
114
115 DEFINE(_TIF_SYSCALL_TRACE, (1<<TIF_SYSCALL_TRACE));
116 DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
117 DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
118 DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
119 DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
120
121 DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
122 DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
123}
diff --git a/arch/c6x/kernel/c6x_ksyms.c b/arch/c6x/kernel/c6x_ksyms.c
new file mode 100644
index 00000000000..0ba3e0bba3e
--- /dev/null
+++ b/arch/c6x/kernel/c6x_ksyms.c
@@ -0,0 +1,66 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#include <linux/module.h>
13#include <asm/checksum.h>
14#include <linux/io.h>
15
16/*
17 * libgcc functions - used internally by the compiler...
18 */
19extern int __c6xabi_divi(int dividend, int divisor);
20EXPORT_SYMBOL(__c6xabi_divi);
21
22extern unsigned __c6xabi_divu(unsigned dividend, unsigned divisor);
23EXPORT_SYMBOL(__c6xabi_divu);
24
25extern int __c6xabi_remi(int dividend, int divisor);
26EXPORT_SYMBOL(__c6xabi_remi);
27
28extern unsigned __c6xabi_remu(unsigned dividend, unsigned divisor);
29EXPORT_SYMBOL(__c6xabi_remu);
30
31extern int __c6xabi_divremi(int dividend, int divisor);
32EXPORT_SYMBOL(__c6xabi_divremi);
33
34extern unsigned __c6xabi_divremu(unsigned dividend, unsigned divisor);
35EXPORT_SYMBOL(__c6xabi_divremu);
36
37extern unsigned long long __c6xabi_mpyll(unsigned long long src1,
38 unsigned long long src2);
39EXPORT_SYMBOL(__c6xabi_mpyll);
40
41extern long long __c6xabi_negll(long long src);
42EXPORT_SYMBOL(__c6xabi_negll);
43
44extern unsigned long long __c6xabi_llshl(unsigned long long src1, uint src2);
45EXPORT_SYMBOL(__c6xabi_llshl);
46
47extern long long __c6xabi_llshr(long long src1, uint src2);
48EXPORT_SYMBOL(__c6xabi_llshr);
49
50extern unsigned long long __c6xabi_llshru(unsigned long long src1, uint src2);
51EXPORT_SYMBOL(__c6xabi_llshru);
52
53extern void __c6xabi_strasgi(int *dst, const int *src, unsigned cnt);
54EXPORT_SYMBOL(__c6xabi_strasgi);
55
56extern void __c6xabi_push_rts(void);
57EXPORT_SYMBOL(__c6xabi_push_rts);
58
59extern void __c6xabi_pop_rts(void);
60EXPORT_SYMBOL(__c6xabi_pop_rts);
61
62extern void __c6xabi_strasgi_64plus(int *dst, const int *src, unsigned cnt);
63EXPORT_SYMBOL(__c6xabi_strasgi_64plus);
64
65/* lib functions */
66EXPORT_SYMBOL(memcpy);
diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c
new file mode 100644
index 00000000000..bdb56f09d0a
--- /dev/null
+++ b/arch/c6x/kernel/devicetree.c
@@ -0,0 +1,53 @@
1/*
2 * Architecture specific OF callbacks.
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 * Author: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#include <linux/init.h>
13#include <linux/of.h>
14#include <linux/of_fdt.h>
15#include <linux/initrd.h>
16#include <linux/memblock.h>
17
18void __init early_init_devtree(void *params)
19{
20 /* Setup flat device-tree pointer */
21 initial_boot_params = params;
22
23 /* Retrieve various informations from the /chosen node of the
24 * device-tree, including the platform type, initrd location and
25 * size and more ...
26 */
27 of_scan_flat_dt(early_init_dt_scan_chosen, c6x_command_line);
28
29 /* Scan memory nodes and rebuild MEMBLOCKs */
30 of_scan_flat_dt(early_init_dt_scan_root, NULL);
31 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
32}
33
34
35#ifdef CONFIG_BLK_DEV_INITRD
36void __init early_init_dt_setup_initrd_arch(unsigned long start,
37 unsigned long end)
38{
39 initrd_start = (unsigned long)__va(start);
40 initrd_end = (unsigned long)__va(end);
41 initrd_below_start_ok = 1;
42}
43#endif
44
45void __init early_init_dt_add_memory_arch(u64 base, u64 size)
46{
47 c6x_add_memory(base, size);
48}
49
50void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
51{
52 return __va(memblock_alloc(size, align));
53}
diff --git a/arch/c6x/kernel/dma.c b/arch/c6x/kernel/dma.c
new file mode 100644
index 00000000000..ab7b12de144
--- /dev/null
+++ b/arch/c6x/kernel/dma.c
@@ -0,0 +1,153 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/module.h>
10#include <linux/dma-mapping.h>
11#include <linux/mm.h>
12#include <linux/mm_types.h>
13#include <linux/scatterlist.h>
14
15#include <asm/cacheflush.h>
16
17static void c6x_dma_sync(dma_addr_t handle, size_t size,
18 enum dma_data_direction dir)
19{
20 unsigned long paddr = handle;
21
22 BUG_ON(!valid_dma_direction(dir));
23
24 switch (dir) {
25 case DMA_FROM_DEVICE:
26 L2_cache_block_invalidate(paddr, paddr + size);
27 break;
28 case DMA_TO_DEVICE:
29 L2_cache_block_writeback(paddr, paddr + size);
30 break;
31 case DMA_BIDIRECTIONAL:
32 L2_cache_block_writeback_invalidate(paddr, paddr + size);
33 break;
34 default:
35 break;
36 }
37}
38
39dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
40 enum dma_data_direction dir)
41{
42 dma_addr_t addr = virt_to_phys(ptr);
43
44 c6x_dma_sync(addr, size, dir);
45
46 debug_dma_map_page(dev, virt_to_page(ptr),
47 (unsigned long)ptr & ~PAGE_MASK, size,
48 dir, addr, true);
49 return addr;
50}
51EXPORT_SYMBOL(dma_map_single);
52
53
54void dma_unmap_single(struct device *dev, dma_addr_t handle,
55 size_t size, enum dma_data_direction dir)
56{
57 c6x_dma_sync(handle, size, dir);
58
59 debug_dma_unmap_page(dev, handle, size, dir, true);
60}
61EXPORT_SYMBOL(dma_unmap_single);
62
63
64int dma_map_sg(struct device *dev, struct scatterlist *sglist,
65 int nents, enum dma_data_direction dir)
66{
67 struct scatterlist *sg;
68 int i;
69
70 for_each_sg(sglist, sg, nents, i)
71 sg->dma_address = dma_map_single(dev, sg_virt(sg), sg->length,
72 dir);
73
74 debug_dma_map_sg(dev, sglist, nents, nents, dir);
75
76 return nents;
77}
78EXPORT_SYMBOL(dma_map_sg);
79
80
81void dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
82 int nents, enum dma_data_direction dir)
83{
84 struct scatterlist *sg;
85 int i;
86
87 for_each_sg(sglist, sg, nents, i)
88 dma_unmap_single(dev, sg_dma_address(sg), sg->length, dir);
89
90 debug_dma_unmap_sg(dev, sglist, nents, dir);
91}
92EXPORT_SYMBOL(dma_unmap_sg);
93
94void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
95 size_t size, enum dma_data_direction dir)
96{
97 c6x_dma_sync(handle, size, dir);
98
99 debug_dma_sync_single_for_cpu(dev, handle, size, dir);
100}
101EXPORT_SYMBOL(dma_sync_single_for_cpu);
102
103
104void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
105 size_t size, enum dma_data_direction dir)
106{
107 c6x_dma_sync(handle, size, dir);
108
109 debug_dma_sync_single_for_device(dev, handle, size, dir);
110}
111EXPORT_SYMBOL(dma_sync_single_for_device);
112
113
114void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
115 int nents, enum dma_data_direction dir)
116{
117 struct scatterlist *sg;
118 int i;
119
120 for_each_sg(sglist, sg, nents, i)
121 dma_sync_single_for_cpu(dev, sg_dma_address(sg),
122 sg->length, dir);
123
124 debug_dma_sync_sg_for_cpu(dev, sglist, nents, dir);
125}
126EXPORT_SYMBOL(dma_sync_sg_for_cpu);
127
128
129void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
130 int nents, enum dma_data_direction dir)
131{
132 struct scatterlist *sg;
133 int i;
134
135 for_each_sg(sglist, sg, nents, i)
136 dma_sync_single_for_device(dev, sg_dma_address(sg),
137 sg->length, dir);
138
139 debug_dma_sync_sg_for_device(dev, sglist, nents, dir);
140}
141EXPORT_SYMBOL(dma_sync_sg_for_device);
142
143
144/* Number of entries preallocated for DMA-API debugging */
145#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
146
147static int __init dma_init(void)
148{
149 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
150
151 return 0;
152}
153fs_initcall(dma_init);
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S
new file mode 100644
index 00000000000..3e977ccda82
--- /dev/null
+++ b/arch/c6x/kernel/entry.S
@@ -0,0 +1,803 @@
1;
2; Port on Texas Instruments TMS320C6x architecture
3;
4; Copyright (C) 2004-2011 Texas Instruments Incorporated
5; Author: Aurelien Jacquiot (aurelien.jacquiot@virtuallogix.com)
6; Updated for 2.6.34: Mark Salter <msalter@redhat.com>
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License version 2 as
10; published by the Free Software Foundation.
11;
12
13#include <linux/sys.h>
14#include <linux/linkage.h>
15#include <asm/thread_info.h>
16#include <asm/asm-offsets.h>
17#include <asm/unistd.h>
18#include <asm/errno.h>
19
20; Registers naming
21#define DP B14
22#define SP B15
23
24#ifndef CONFIG_PREEMPT
25#define resume_kernel restore_all
26#endif
27
28 .altmacro
29
30 .macro MASK_INT reg
31 MVC .S2 CSR,reg
32 CLR .S2 reg,0,0,reg
33 MVC .S2 reg,CSR
34 .endm
35
36 .macro UNMASK_INT reg
37 MVC .S2 CSR,reg
38 SET .S2 reg,0,0,reg
39 MVC .S2 reg,CSR
40 .endm
41
42 .macro GET_THREAD_INFO reg
43 SHR .S1X SP,THREAD_SHIFT,reg
44 SHL .S1 reg,THREAD_SHIFT,reg
45 .endm
46
47 ;;
48 ;; This defines the normal kernel pt_regs layout.
49 ;;
50 .macro SAVE_ALL __rp __tsr
51 STW .D2T2 B0,*SP--[2] ; save original B0
52 MVKL .S2 current_ksp,B0
53 MVKH .S2 current_ksp,B0
54 LDW .D2T2 *B0,B1 ; KSP
55
56 NOP 3
57 STW .D2T2 B1,*+SP[1] ; save original B1
58 XOR .D2 SP,B1,B0 ; (SP ^ KSP)
59 LDW .D2T2 *+SP[1],B1 ; restore B0/B1
60 LDW .D2T2 *++SP[2],B0
61 SHR .S2 B0,THREAD_SHIFT,B0 ; 0 if already using kstack
62 [B0] STDW .D2T2 SP:DP,*--B1[1] ; user: save user sp/dp kstack
63 [B0] MV .S2 B1,SP ; and switch to kstack
64||[!B0] STDW .D2T2 SP:DP,*--SP[1] ; kernel: save on current stack
65
66 SUBAW .D2 SP,2,SP
67
68 ADD .D1X SP,-8,A15
69 || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14
70
71 STDW .D2T2 B13:B12,*SP--[1]
72 || STDW .D1T1 A13:A12,*A15--[1]
73 || MVC .S2 __rp,B13
74
75 STDW .D2T2 B11:B10,*SP--[1]
76 || STDW .D1T1 A11:A10,*A15--[1]
77 || MVC .S2 CSR,B12
78
79 STDW .D2T2 B9:B8,*SP--[1]
80 || STDW .D1T1 A9:A8,*A15--[1]
81 || MVC .S2 RILC,B11
82 STDW .D2T2 B7:B6,*SP--[1]
83 || STDW .D1T1 A7:A6,*A15--[1]
84 || MVC .S2 ILC,B10
85
86 STDW .D2T2 B5:B4,*SP--[1]
87 || STDW .D1T1 A5:A4,*A15--[1]
88
89 STDW .D2T2 B3:B2,*SP--[1]
90 || STDW .D1T1 A3:A2,*A15--[1]
91 || MVC .S2 __tsr,B5
92
93 STDW .D2T2 B1:B0,*SP--[1]
94 || STDW .D1T1 A1:A0,*A15--[1]
95 || MV .S1X B5,A5
96
97 STDW .D2T2 B31:B30,*SP--[1]
98 || STDW .D1T1 A31:A30,*A15--[1]
99 STDW .D2T2 B29:B28,*SP--[1]
100 || STDW .D1T1 A29:A28,*A15--[1]
101 STDW .D2T2 B27:B26,*SP--[1]
102 || STDW .D1T1 A27:A26,*A15--[1]
103 STDW .D2T2 B25:B24,*SP--[1]
104 || STDW .D1T1 A25:A24,*A15--[1]
105 STDW .D2T2 B23:B22,*SP--[1]
106 || STDW .D1T1 A23:A22,*A15--[1]
107 STDW .D2T2 B21:B20,*SP--[1]
108 || STDW .D1T1 A21:A20,*A15--[1]
109 STDW .D2T2 B19:B18,*SP--[1]
110 || STDW .D1T1 A19:A18,*A15--[1]
111 STDW .D2T2 B17:B16,*SP--[1]
112 || STDW .D1T1 A17:A16,*A15--[1]
113
114 STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR
115
116 STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC
117 STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4
118
119 ;; We left an unused word on the stack just above pt_regs.
120 ;; It is used to save whether or not this frame is due to
121 ;; a syscall. It is cleared here, but the syscall handler
122 ;; sets it to a non-zero value.
123 MVK .L2 0,B1
124 STW .D2T2 B1,*+SP(REGS__END+8) ; clear syscall flag
125 .endm
126
127 .macro RESTORE_ALL __rp __tsr
128 LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9)
129 LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
130 LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
131
132 ADDAW .D1X SP,30,A15
133
134 LDDW .D1T1 *++A15[1],A17:A16
135 || LDDW .D2T2 *++SP[1],B17:B16
136 LDDW .D1T1 *++A15[1],A19:A18
137 || LDDW .D2T2 *++SP[1],B19:B18
138 LDDW .D1T1 *++A15[1],A21:A20
139 || LDDW .D2T2 *++SP[1],B21:B20
140 LDDW .D1T1 *++A15[1],A23:A22
141 || LDDW .D2T2 *++SP[1],B23:B22
142 LDDW .D1T1 *++A15[1],A25:A24
143 || LDDW .D2T2 *++SP[1],B25:B24
144 LDDW .D1T1 *++A15[1],A27:A26
145 || LDDW .D2T2 *++SP[1],B27:B26
146 LDDW .D1T1 *++A15[1],A29:A28
147 || LDDW .D2T2 *++SP[1],B29:B28
148 LDDW .D1T1 *++A15[1],A31:A30
149 || LDDW .D2T2 *++SP[1],B31:B30
150
151 LDDW .D1T1 *++A15[1],A1:A0
152 || LDDW .D2T2 *++SP[1],B1:B0
153
154 LDDW .D1T1 *++A15[1],A3:A2
155 || LDDW .D2T2 *++SP[1],B3:B2
156 || MVC .S2 B9,__tsr
157 LDDW .D1T1 *++A15[1],A5:A4
158 || LDDW .D2T2 *++SP[1],B5:B4
159 || MVC .S2 B11,RILC
160 LDDW .D1T1 *++A15[1],A7:A6
161 || LDDW .D2T2 *++SP[1],B7:B6
162 || MVC .S2 B10,ILC
163
164 LDDW .D1T1 *++A15[1],A9:A8
165 || LDDW .D2T2 *++SP[1],B9:B8
166 || MVC .S2 B13,__rp
167
168 LDDW .D1T1 *++A15[1],A11:A10
169 || LDDW .D2T2 *++SP[1],B11:B10
170 || MVC .S2 B12,CSR
171
172 LDDW .D1T1 *++A15[1],A13:A12
173 || LDDW .D2T2 *++SP[1],B13:B12
174
175 MV .D2X A15,SP
176 || MVKL .S1 current_ksp,A15
177 MVKH .S1 current_ksp,A15
178 || ADDAW .D1X SP,6,A14
179 STW .D1T1 A14,*A15 ; save kernel stack pointer
180
181 LDDW .D2T1 *++SP[1],A15:A14
182
183 B .S2 __rp ; return from interruption
184 LDDW .D2T2 *+SP[1],SP:DP
185 NOP 4
186 .endm
187
188 .section .text
189
190 ;;
191 ;; Jump to schedule() then return to ret_from_exception
192 ;;
193_reschedule:
194#ifdef CONFIG_C6X_BIG_KERNEL
195 MVKL .S1 schedule,A0
196 MVKH .S1 schedule,A0
197 B .S2X A0
198#else
199 B .S1 schedule
200#endif
201 ADDKPC .S2 ret_from_exception,B3,4
202
203 ;;
204 ;; Called before syscall handler when process is being debugged
205 ;;
206tracesys_on:
207#ifdef CONFIG_C6X_BIG_KERNEL
208 MVKL .S1 syscall_trace_entry,A0
209 MVKH .S1 syscall_trace_entry,A0
210 B .S2X A0
211#else
212 B .S1 syscall_trace_entry
213#endif
214 ADDKPC .S2 ret_from_syscall_trace,B3,3
215 ADD .S1X 8,SP,A4
216
217ret_from_syscall_trace:
218 ;; tracing returns (possibly new) syscall number
219 MV .D2X A4,B0
220 || MVK .S2 __NR_syscalls,B1
221 CMPLTU .L2 B0,B1,B1
222
223 [!B1] BNOP .S2 ret_from_syscall_function,5
224 || MVK .S1 -ENOSYS,A4
225
226 ;; reload syscall args from (possibly modified) stack frame
227 ;; and get syscall handler addr from sys_call_table:
228 LDW .D2T2 *+SP(REGS_B4+8),B4
229 || MVKL .S2 sys_call_table,B1
230 LDW .D2T1 *+SP(REGS_A6+8),A6
231 || MVKH .S2 sys_call_table,B1
232 LDW .D2T2 *+B1[B0],B0
233 || MVKL .S2 ret_from_syscall_function,B3
234 LDW .D2T2 *+SP(REGS_B6+8),B6
235 || MVKH .S2 ret_from_syscall_function,B3
236 LDW .D2T1 *+SP(REGS_A8+8),A8
237 LDW .D2T2 *+SP(REGS_B8+8),B8
238 NOP
239 ; B0 = sys_call_table[__NR_*]
240 BNOP .S2 B0,5 ; branch to syscall handler
241 || LDW .D2T1 *+SP(REGS_ORIG_A4+8),A4
242
243syscall_exit_work:
244 AND .D1 _TIF_SYSCALL_TRACE,A2,A0
245 [!A0] BNOP .S1 work_pending,5
246 [A0] B .S2 syscall_trace_exit
247 ADDKPC .S2 resume_userspace,B3,1
248 MVC .S2 CSR,B1
249 SET .S2 B1,0,0,B1
250 MVC .S2 B1,CSR ; enable ints
251
252work_pending:
253 AND .D1 _TIF_NEED_RESCHED,A2,A0
254 [!A0] BNOP .S1 work_notifysig,5
255
256work_resched:
257#ifdef CONFIG_C6X_BIG_KERNEL
258 MVKL .S1 schedule,A1
259 MVKH .S1 schedule,A1
260 B .S2X A1
261#else
262 B .S2 schedule
263#endif
264 ADDKPC .S2 work_rescheduled,B3,4
265work_rescheduled:
266 ;; make sure we don't miss an interrupt setting need_resched or
267 ;; sigpending between sampling and the rti
268 MASK_INT B2
269 GET_THREAD_INFO A12
270 LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
271 MVK .S1 _TIF_WORK_MASK,A1
272 MVK .S1 _TIF_NEED_RESCHED,A3
273 NOP 2
274 AND .D1 A1,A2,A0
275 || AND .S1 A3,A2,A1
276 [!A0] BNOP .S1 restore_all,5
277 [A1] BNOP .S1 work_resched,5
278
279work_notifysig:
280 B .S2 do_notify_resume
281 LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag
282 ADDKPC .S2 resume_userspace,B3,1
283 ADD .S1X 8,SP,A4 ; pt_regs pointer is first arg
284 MV .D2X A2,B4 ; thread_info flags is second arg
285
286 ;;
287 ;; On C64x+, the return way from exception and interrupt
288 ;; is a little bit different
289 ;;
290ENTRY(ret_from_exception)
291#ifdef CONFIG_PREEMPT
292 MASK_INT B2
293#endif
294
295ENTRY(ret_from_interrupt)
296 ;;
297 ;; Check if we are comming from user mode.
298 ;;
299 LDW .D2T2 *+SP(REGS_TSR+8),B0
300 MVK .S2 0x40,B1
301 NOP 3
302 AND .D2 B0,B1,B0
303 [!B0] BNOP .S2 resume_kernel,5
304
305resume_userspace:
306 ;; make sure we don't miss an interrupt setting need_resched or
307 ;; sigpending between sampling and the rti
308 MASK_INT B2
309 GET_THREAD_INFO A12
310 LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
311 MVK .S1 _TIF_WORK_MASK,A1
312 MVK .S1 _TIF_NEED_RESCHED,A3
313 NOP 2
314 AND .D1 A1,A2,A0
315 [A0] BNOP .S1 work_pending,5
316 BNOP .S1 restore_all,5
317
318 ;;
319 ;; System call handling
320 ;; B0 = syscall number (in sys_call_table)
321 ;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function
322 ;; A4 is the return value register
323 ;;
324system_call_saved:
325 MVK .L2 1,B2
326 STW .D2T2 B2,*+SP(REGS__END+8) ; set syscall flag
327 MVC .S2 B2,ECR ; ack the software exception
328
329 UNMASK_INT B2 ; re-enable global IT
330
331system_call_saved_noack:
332 ;; Check system call number
333 MVK .S2 __NR_syscalls,B1
334#ifdef CONFIG_C6X_BIG_KERNEL
335 || MVKL .S1 sys_ni_syscall,A0
336#endif
337 CMPLTU .L2 B0,B1,B1
338#ifdef CONFIG_C6X_BIG_KERNEL
339 || MVKH .S1 sys_ni_syscall,A0
340#endif
341
342 ;; Check for ptrace
343 GET_THREAD_INFO A12
344
345#ifdef CONFIG_C6X_BIG_KERNEL
346 [!B1] B .S2X A0
347#else
348 [!B1] B .S2 sys_ni_syscall
349#endif
350 [!B1] ADDKPC .S2 ret_from_syscall_function,B3,4
351
352 ;; Get syscall handler addr from sys_call_table
353 ;; call tracesys_on or call syscall handler
354 LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
355 || MVKL .S2 sys_call_table,B1
356 MVKH .S2 sys_call_table,B1
357 LDW .D2T2 *+B1[B0],B0
358 NOP 2
359 ; A2 = thread_info flags
360 AND .D1 _TIF_SYSCALL_TRACE,A2,A2
361 [A2] BNOP .S1 tracesys_on,5
362 ;; B0 = _sys_call_table[__NR_*]
363 B .S2 B0
364 ADDKPC .S2 ret_from_syscall_function,B3,4
365
366ret_from_syscall_function:
367 STW .D2T1 A4,*+SP(REGS_A4+8) ; save return value in A4
368 ; original A4 is in orig_A4
369syscall_exit:
370 ;; make sure we don't miss an interrupt setting need_resched or
371 ;; sigpending between sampling and the rti
372 MASK_INT B2
373 LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
374 MVK .S1 _TIF_ALLWORK_MASK,A1
375 NOP 3
376 AND .D1 A1,A2,A2 ; check for work to do
377 [A2] BNOP .S1 syscall_exit_work,5
378
379restore_all:
380 RESTORE_ALL NRP,NTSR
381
382 ;;
383 ;; After a fork we jump here directly from resume,
384 ;; so that A4 contains the previous task structure.
385 ;;
386ENTRY(ret_from_fork)
387#ifdef CONFIG_C6X_BIG_KERNEL
388 MVKL .S1 schedule_tail,A0
389 MVKH .S1 schedule_tail,A0
390 B .S2X A0
391#else
392 B .S2 schedule_tail
393#endif
394 ADDKPC .S2 ret_from_fork_2,B3,4
395ret_from_fork_2:
396 ;; return 0 in A4 for child process
397 GET_THREAD_INFO A12
398 BNOP .S2 syscall_exit,3
399 MVK .L2 0,B0
400 STW .D2T2 B0,*+SP(REGS_A4+8)
401ENDPROC(ret_from_fork)
402
403 ;;
404 ;; These are the interrupt handlers, responsible for calling __do_IRQ()
405 ;; int6 is used for syscalls (see _system_call entry)
406 ;;
407 .macro SAVE_ALL_INT
408 SAVE_ALL IRP,ITSR
409 .endm
410
411 .macro CALL_INT int
412#ifdef CONFIG_C6X_BIG_KERNEL
413 MVKL .S1 c6x_do_IRQ,A0
414 MVKH .S1 c6x_do_IRQ,A0
415 BNOP .S2X A0,1
416 MVK .S1 int,A4
417 ADDAW .D2 SP,2,B4
418 MVKL .S2 ret_from_interrupt,B3
419 MVKH .S2 ret_from_interrupt,B3
420#else
421 CALLP .S2 c6x_do_IRQ,B3
422 || MVK .S1 int,A4
423 || ADDAW .D2 SP,2,B4
424 B .S1 ret_from_interrupt
425 NOP 5
426#endif
427 .endm
428
429ENTRY(_int4_handler)
430 SAVE_ALL_INT
431 CALL_INT 4
432ENDPROC(_int4_handler)
433
434ENTRY(_int5_handler)
435 SAVE_ALL_INT
436 CALL_INT 5
437ENDPROC(_int5_handler)
438
439ENTRY(_int6_handler)
440 SAVE_ALL_INT
441 CALL_INT 6
442ENDPROC(_int6_handler)
443
444ENTRY(_int7_handler)
445 SAVE_ALL_INT
446 CALL_INT 7
447ENDPROC(_int7_handler)
448
449ENTRY(_int8_handler)
450 SAVE_ALL_INT
451 CALL_INT 8
452ENDPROC(_int8_handler)
453
454ENTRY(_int9_handler)
455 SAVE_ALL_INT
456 CALL_INT 9
457ENDPROC(_int9_handler)
458
459ENTRY(_int10_handler)
460 SAVE_ALL_INT
461 CALL_INT 10
462ENDPROC(_int10_handler)
463
464ENTRY(_int11_handler)
465 SAVE_ALL_INT
466 CALL_INT 11
467ENDPROC(_int11_handler)
468
469ENTRY(_int12_handler)
470 SAVE_ALL_INT
471 CALL_INT 12
472ENDPROC(_int12_handler)
473
474ENTRY(_int13_handler)
475 SAVE_ALL_INT
476 CALL_INT 13
477ENDPROC(_int13_handler)
478
479ENTRY(_int14_handler)
480 SAVE_ALL_INT
481 CALL_INT 14
482ENDPROC(_int14_handler)
483
484ENTRY(_int15_handler)
485 SAVE_ALL_INT
486 CALL_INT 15
487ENDPROC(_int15_handler)
488
489 ;;
490 ;; Handler for uninitialized and spurious interrupts
491 ;;
492ENTRY(_bad_interrupt)
493 B .S2 IRP
494 NOP 5
495ENDPROC(_bad_interrupt)
496
497 ;;
498 ;; Entry for NMI/exceptions/syscall
499 ;;
500ENTRY(_nmi_handler)
501 SAVE_ALL NRP,NTSR
502
503 MVC .S2 EFR,B2
504 CMPEQ .L2 1,B2,B2
505 || MVC .S2 TSR,B1
506 CLR .S2 B1,10,10,B1
507 MVC .S2 B1,TSR
508#ifdef CONFIG_C6X_BIG_KERNEL
509 [!B2] MVKL .S1 process_exception,A0
510 [!B2] MVKH .S1 process_exception,A0
511 [!B2] B .S2X A0
512#else
513 [!B2] B .S2 process_exception
514#endif
515 [B2] B .S2 system_call_saved
516 [!B2] ADDAW .D2 SP,2,B1
517 [!B2] MV .D1X B1,A4
518 ADDKPC .S2 ret_from_trap,B3,2
519
520ret_from_trap:
521 MV .D2X A4,B0
522 [!B0] BNOP .S2 ret_from_exception,5
523
524#ifdef CONFIG_C6X_BIG_KERNEL
525 MVKL .S2 system_call_saved_noack,B3
526 MVKH .S2 system_call_saved_noack,B3
527#endif
528 LDW .D2T2 *+SP(REGS_B0+8),B0
529 LDW .D2T1 *+SP(REGS_A4+8),A4
530 LDW .D2T2 *+SP(REGS_B4+8),B4
531 LDW .D2T1 *+SP(REGS_A6+8),A6
532 LDW .D2T2 *+SP(REGS_B6+8),B6
533 LDW .D2T1 *+SP(REGS_A8+8),A8
534#ifdef CONFIG_C6X_BIG_KERNEL
535 || B .S2 B3
536#else
537 || B .S2 system_call_saved_noack
538#endif
539 LDW .D2T2 *+SP(REGS_B8+8),B8
540 NOP 4
541ENDPROC(_nmi_handler)
542
543 ;;
544 ;; Jump to schedule() then return to ret_from_isr
545 ;;
546#ifdef CONFIG_PREEMPT
547resume_kernel:
548 GET_THREAD_INFO A12
549 LDW .D1T1 *+A12(THREAD_INFO_PREEMPT_COUNT),A1
550 NOP 4
551 [A1] BNOP .S2 restore_all,5
552
553preempt_schedule:
554 GET_THREAD_INFO A2
555 LDW .D1T1 *+A2(THREAD_INFO_FLAGS),A1
556#ifdef CONFIG_C6X_BIG_KERNEL
557 MVKL .S2 preempt_schedule_irq,B0
558 MVKH .S2 preempt_schedule_irq,B0
559 NOP 2
560#else
561 NOP 4
562#endif
563 AND .D1 _TIF_NEED_RESCHED,A1,A1
564 [!A1] BNOP .S2 restore_all,5
565#ifdef CONFIG_C6X_BIG_KERNEL
566 B .S2 B0
567#else
568 B .S2 preempt_schedule_irq
569#endif
570 ADDKPC .S2 preempt_schedule,B3,4
571#endif /* CONFIG_PREEMPT */
572
573ENTRY(enable_exception)
574 DINT
575 MVC .S2 TSR,B0
576 MVC .S2 B3,NRP
577 MVK .L2 0xc,B1
578 OR .D2 B0,B1,B0
579 MVC .S2 B0,TSR ; Set GEE and XEN in TSR
580 B .S2 NRP
581 NOP 5
582ENDPROC(enable_exception)
583
584ENTRY(sys_sigaltstack)
585#ifdef CONFIG_C6X_BIG_KERNEL
586 MVKL .S1 do_sigaltstack,A0 ; branch to do_sigaltstack
587 MVKH .S1 do_sigaltstack,A0
588 B .S2X A0
589#else
590 B .S2 do_sigaltstack
591#endif
592 LDW .D2T1 *+SP(REGS_SP+8),A6
593 NOP 4
594ENDPROC(sys_sigaltstack)
595
596 ;; kernel_execve
597ENTRY(kernel_execve)
598 MVK .S2 __NR_execve,B0
599 SWE
600 BNOP .S2 B3,5
601ENDPROC(kernel_execve)
602
603 ;;
604 ;; Special system calls
605 ;; return address is in B3
606 ;;
607ENTRY(sys_clone)
608 ADD .D1X SP,8,A4
609#ifdef CONFIG_C6X_BIG_KERNEL
610 || MVKL .S1 sys_c6x_clone,A0
611 MVKH .S1 sys_c6x_clone,A0
612 BNOP .S2X A0,5
613#else
614 || B .S2 sys_c6x_clone
615 NOP 5
616#endif
617ENDPROC(sys_clone)
618
619ENTRY(sys_rt_sigreturn)
620 ADD .D1X SP,8,A4
621#ifdef CONFIG_C6X_BIG_KERNEL
622 || MVKL .S1 do_rt_sigreturn,A0
623 MVKH .S1 do_rt_sigreturn,A0
624 BNOP .S2X A0,5
625#else
626 || B .S2 do_rt_sigreturn
627 NOP 5
628#endif
629ENDPROC(sys_rt_sigreturn)
630
631ENTRY(sys_execve)
632 ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter
633 ; & adjust regs stack addr
634 LDW .D2T2 *+SP(REGS_B4+8),B4
635
636 ;; c6x_execve(char *name, char **argv,
637 ;; char **envp, struct pt_regs *regs)
638#ifdef CONFIG_C6X_BIG_KERNEL
639 || MVKL .S1 sys_c6x_execve,A0
640 MVKH .S1 sys_c6x_execve,A0
641 B .S2X A0
642#else
643 || B .S2 sys_c6x_execve
644#endif
645 STW .D2T2 B3,*SP--[2]
646 ADDKPC .S2 ret_from_c6x_execve,B3,3
647
648ret_from_c6x_execve:
649 LDW .D2T2 *++SP[2],B3
650 NOP 4
651 BNOP .S2 B3,5
652ENDPROC(sys_execve)
653
654ENTRY(sys_pread_c6x)
655 MV .D2X A8,B7
656#ifdef CONFIG_C6X_BIG_KERNEL
657 || MVKL .S1 sys_pread64,A0
658 MVKH .S1 sys_pread64,A0
659 BNOP .S2X A0,5
660#else
661 || B .S2 sys_pread64
662 NOP 5
663#endif
664ENDPROC(sys_pread_c6x)
665
666ENTRY(sys_pwrite_c6x)
667 MV .D2X A8,B7
668#ifdef CONFIG_C6X_BIG_KERNEL
669 || MVKL .S1 sys_pwrite64,A0
670 MVKH .S1 sys_pwrite64,A0
671 BNOP .S2X A0,5
672#else
673 || B .S2 sys_pwrite64
674 NOP 5
675#endif
676ENDPROC(sys_pwrite_c6x)
677
678;; On Entry
679;; A4 - path
680;; B4 - offset_lo (LE), offset_hi (BE)
681;; A6 - offset_lo (BE), offset_hi (LE)
682ENTRY(sys_truncate64_c6x)
683#ifdef CONFIG_CPU_BIG_ENDIAN
684 MV .S2 B4,B5
685 MV .D2X A6,B4
686#else
687 MV .D2X A6,B5
688#endif
689#ifdef CONFIG_C6X_BIG_KERNEL
690 || MVKL .S1 sys_truncate64,A0
691 MVKH .S1 sys_truncate64,A0
692 BNOP .S2X A0,5
693#else
694 || B .S2 sys_truncate64
695 NOP 5
696#endif
697ENDPROC(sys_truncate64_c6x)
698
699;; On Entry
700;; A4 - fd
701;; B4 - offset_lo (LE), offset_hi (BE)
702;; A6 - offset_lo (BE), offset_hi (LE)
703ENTRY(sys_ftruncate64_c6x)
704#ifdef CONFIG_CPU_BIG_ENDIAN
705 MV .S2 B4,B5
706 MV .D2X A6,B4
707#else
708 MV .D2X A6,B5
709#endif
710#ifdef CONFIG_C6X_BIG_KERNEL
711 || MVKL .S1 sys_ftruncate64,A0
712 MVKH .S1 sys_ftruncate64,A0
713 BNOP .S2X A0,5
714#else
715 || B .S2 sys_ftruncate64
716 NOP 5
717#endif
718ENDPROC(sys_ftruncate64_c6x)
719
720#ifdef __ARCH_WANT_SYSCALL_OFF_T
721;; On Entry
722;; A4 - fd
723;; B4 - offset_lo (LE), offset_hi (BE)
724;; A6 - offset_lo (BE), offset_hi (LE)
725;; B6 - len
726;; A8 - advice
727ENTRY(sys_fadvise64_c6x)
728#ifdef CONFIG_C6X_BIG_KERNEL
729 MVKL .S1 sys_fadvise64,A0
730 MVKH .S1 sys_fadvise64,A0
731 BNOP .S2X A0,2
732#else
733 B .S2 sys_fadvise64
734 NOP 2
735#endif
736#ifdef CONFIG_CPU_BIG_ENDIAN
737 MV .L2 B4,B5
738 || MV .D2X A6,B4
739#else
740 MV .D2X A6,B5
741#endif
742 MV .D1X B6,A6
743 MV .D2X A8,B6
744#endif
745ENDPROC(sys_fadvise64_c6x)
746
747;; On Entry
748;; A4 - fd
749;; B4 - offset_lo (LE), offset_hi (BE)
750;; A6 - offset_lo (BE), offset_hi (LE)
751;; B6 - len_lo (LE), len_hi (BE)
752;; A8 - len_lo (BE), len_hi (LE)
753;; B8 - advice
754ENTRY(sys_fadvise64_64_c6x)
755#ifdef CONFIG_C6X_BIG_KERNEL
756 MVKL .S1 sys_fadvise64_64,A0
757 MVKH .S1 sys_fadvise64_64,A0
758 BNOP .S2X A0,2
759#else
760 B .S2 sys_fadvise64_64
761 NOP 2
762#endif
763#ifdef CONFIG_CPU_BIG_ENDIAN
764 MV .L2 B4,B5
765 || MV .D2X A6,B4
766 MV .L1 A8,A6
767 || MV .D1X B6,A7
768#else
769 MV .D2X A6,B5
770 MV .L1 A8,A7
771 || MV .D1X B6,A6
772#endif
773 MV .L2 B8,B6
774ENDPROC(sys_fadvise64_64_c6x)
775
776;; On Entry
777;; A4 - fd
778;; B4 - mode
779;; A6 - offset_hi
780;; B6 - offset_lo
781;; A8 - len_hi
782;; B8 - len_lo
783ENTRY(sys_fallocate_c6x)
784#ifdef CONFIG_C6X_BIG_KERNEL
785 MVKL .S1 sys_fallocate,A0
786 MVKH .S1 sys_fallocate,A0
787 BNOP .S2X A0,1
788#else
789 B .S2 sys_fallocate
790 NOP
791#endif
792 MV .D1 A6,A7
793 MV .D1X B6,A6
794 MV .D2X A8,B7
795 MV .D2 B8,B6
796ENDPROC(sys_fallocate_c6x)
797
798 ;; put this in .neardata for faster access when using DSBT mode
799 .section .neardata,"aw",@progbits
800 .global current_ksp
801 .hidden current_ksp
802current_ksp:
803 .word init_thread_union + THREAD_START_SP
diff --git a/arch/c6x/kernel/head.S b/arch/c6x/kernel/head.S
new file mode 100644
index 00000000000..133eab6edf6
--- /dev/null
+++ b/arch/c6x/kernel/head.S
@@ -0,0 +1,84 @@
1;
2; Port on Texas Instruments TMS320C6x architecture
3;
4; Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6;
7; This program is free software; you can redistribute it and/or modify
8; it under the terms of the GNU General Public License version 2 as
9; published by the Free Software Foundation.
10;
11#include <linux/linkage.h>
12#include <linux/of_fdt.h>
13#include <asm/asm-offsets.h>
14
15 __HEAD
16ENTRY(_c_int00)
17 ;; Save magic and pointer
18 MV .S1 A4,A10
19 MV .S2 B4,B10
20 MVKL .S2 __bss_start,B5
21 MVKH .S2 __bss_start,B5
22 MVKL .S2 __bss_stop,B6
23 MVKH .S2 __bss_stop,B6
24 SUB .L2 B6,B5,B6 ; bss size
25
26 ;; Set the stack pointer
27 MVKL .S2 current_ksp,B0
28 MVKH .S2 current_ksp,B0
29 LDW .D2T2 *B0,B15
30
31 ;; clear bss
32 SHR .S2 B6,3,B0 ; number of dwords to clear
33 ZERO .L2 B13
34 ZERO .L2 B12
35bss_loop:
36 BDEC .S2 bss_loop,B0
37 NOP 3
38 CMPLT .L2 B0,0,B1
39 [!B1] STDW .D2T2 B13:B12,*B5++[1]
40
41 NOP 4
42 AND .D2 ~7,B15,B15
43
44 ;; Clear GIE and PGIE
45 MVC .S2 CSR,B2
46 CLR .S2 B2,0,1,B2
47 MVC .S2 B2,CSR
48 MVC .S2 TSR,B2
49 CLR .S2 B2,0,1,B2
50 MVC .S2 B2,TSR
51 MVC .S2 ITSR,B2
52 CLR .S2 B2,0,1,B2
53 MVC .S2 B2,ITSR
54 MVC .S2 NTSR,B2
55 CLR .S2 B2,0,1,B2
56 MVC .S2 B2,NTSR
57
58 ;; pass DTB pointer to machine_init (or zero if none)
59 MVKL .S1 OF_DT_HEADER,A0
60 MVKH .S1 OF_DT_HEADER,A0
61 CMPEQ .L1 A10,A0,A0
62 [A0] MV .S1X B10,A4
63 [!A0] MVK .S1 0,A4
64
65#ifdef CONFIG_C6X_BIG_KERNEL
66 MVKL .S1 machine_init,A0
67 MVKH .S1 machine_init,A0
68 B .S2X A0
69 ADDKPC .S2 0f,B3,4
700:
71#else
72 CALLP .S2 machine_init,B3
73#endif
74
75 ;; Jump to Linux init
76#ifdef CONFIG_C6X_BIG_KERNEL
77 MVKL .S1 start_kernel,A0
78 MVKH .S1 start_kernel,A0
79 B .S2X A0
80#else
81 B .S2 start_kernel
82#endif
83 NOP 5
84L1: BNOP .S2 L1,5
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
new file mode 100644
index 00000000000..0929e4b2b24
--- /dev/null
+++ b/arch/c6x/kernel/irq.c
@@ -0,0 +1,728 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 *
4 * This borrows heavily from powerpc version, which is:
5 *
6 * Derived from arch/i386/kernel/irq.c
7 * Copyright (C) 1992 Linus Torvalds
8 * Adapted from arch/i386 by Gary Thomas
9 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
10 * Updated and modified by Cort Dougan <cort@fsmlabs.com>
11 * Copyright (C) 1996-2001 Cort Dougan
12 * Adapted for Power Macintosh by Paul Mackerras
13 * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 */
20#include <linux/slab.h>
21#include <linux/seq_file.h>
22#include <linux/radix-tree.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/of_irq.h>
26#include <linux/interrupt.h>
27#include <linux/kernel_stat.h>
28
29#include <asm/megamod-pic.h>
30
31unsigned long irq_err_count;
32
33static DEFINE_RAW_SPINLOCK(core_irq_lock);
34
35static void mask_core_irq(struct irq_data *data)
36{
37 unsigned int prio = data->irq;
38
39 BUG_ON(prio < 4 || prio >= NR_PRIORITY_IRQS);
40
41 raw_spin_lock(&core_irq_lock);
42 and_creg(IER, ~(1 << prio));
43 raw_spin_unlock(&core_irq_lock);
44}
45
46static void unmask_core_irq(struct irq_data *data)
47{
48 unsigned int prio = data->irq;
49
50 raw_spin_lock(&core_irq_lock);
51 or_creg(IER, 1 << prio);
52 raw_spin_unlock(&core_irq_lock);
53}
54
55static struct irq_chip core_chip = {
56 .name = "core",
57 .irq_mask = mask_core_irq,
58 .irq_unmask = unmask_core_irq,
59};
60
61asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
62{
63 struct pt_regs *old_regs = set_irq_regs(regs);
64
65 irq_enter();
66
67 BUG_ON(prio < 4 || prio >= NR_PRIORITY_IRQS);
68
69 generic_handle_irq(prio);
70
71 irq_exit();
72
73 set_irq_regs(old_regs);
74}
75
76static struct irq_host *core_host;
77
78static int core_host_map(struct irq_host *h, unsigned int virq,
79 irq_hw_number_t hw)
80{
81 if (hw < 4 || hw >= NR_PRIORITY_IRQS)
82 return -EINVAL;
83
84 irq_set_status_flags(virq, IRQ_LEVEL);
85 irq_set_chip_and_handler(virq, &core_chip, handle_level_irq);
86 return 0;
87}
88
89static struct irq_host_ops core_host_ops = {
90 .map = core_host_map,
91};
92
93void __init init_IRQ(void)
94{
95 struct device_node *np;
96
97 /* Mask all priority IRQs */
98 and_creg(IER, ~0xfff0);
99
100 np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
101 if (np != NULL) {
102 /* create the core host */
103 core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0,
104 &core_host_ops, 0);
105 if (core_host)
106 irq_set_default_host(core_host);
107 of_node_put(np);
108 }
109
110 printk(KERN_INFO "Core interrupt controller initialized\n");
111
112 /* now we're ready for other SoC controllers */
113 megamod_pic_init();
114
115 /* Clear all general IRQ flags */
116 set_creg(ICR, 0xfff0);
117}
118
119void ack_bad_irq(int irq)
120{
121 printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
122 irq_err_count++;
123}
124
125int arch_show_interrupts(struct seq_file *p, int prec)
126{
127 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
128 return 0;
129}
130
131/*
132 * IRQ controller and virtual interrupts
133 */
134
135/* The main irq map itself is an array of NR_IRQ entries containing the
136 * associate host and irq number. An entry with a host of NULL is free.
137 * An entry can be allocated if it's free, the allocator always then sets
138 * hwirq first to the host's invalid irq number and then fills ops.
139 */
140struct irq_map_entry {
141 irq_hw_number_t hwirq;
142 struct irq_host *host;
143};
144
145static LIST_HEAD(irq_hosts);
146static DEFINE_RAW_SPINLOCK(irq_big_lock);
147static DEFINE_MUTEX(revmap_trees_mutex);
148static struct irq_map_entry irq_map[NR_IRQS];
149static unsigned int irq_virq_count = NR_IRQS;
150static struct irq_host *irq_default_host;
151
152irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
153{
154 return irq_map[d->irq].hwirq;
155}
156EXPORT_SYMBOL_GPL(irqd_to_hwirq);
157
158irq_hw_number_t virq_to_hw(unsigned int virq)
159{
160 return irq_map[virq].hwirq;
161}
162EXPORT_SYMBOL_GPL(virq_to_hw);
163
164bool virq_is_host(unsigned int virq, struct irq_host *host)
165{
166 return irq_map[virq].host == host;
167}
168EXPORT_SYMBOL_GPL(virq_is_host);
169
170static int default_irq_host_match(struct irq_host *h, struct device_node *np)
171{
172 return h->of_node != NULL && h->of_node == np;
173}
174
175struct irq_host *irq_alloc_host(struct device_node *of_node,
176 unsigned int revmap_type,
177 unsigned int revmap_arg,
178 struct irq_host_ops *ops,
179 irq_hw_number_t inval_irq)
180{
181 struct irq_host *host;
182 unsigned int size = sizeof(struct irq_host);
183 unsigned int i;
184 unsigned int *rmap;
185 unsigned long flags;
186
187 /* Allocate structure and revmap table if using linear mapping */
188 if (revmap_type == IRQ_HOST_MAP_LINEAR)
189 size += revmap_arg * sizeof(unsigned int);
190 host = kzalloc(size, GFP_KERNEL);
191 if (host == NULL)
192 return NULL;
193
194 /* Fill structure */
195 host->revmap_type = revmap_type;
196 host->inval_irq = inval_irq;
197 host->ops = ops;
198 host->of_node = of_node_get(of_node);
199
200 if (host->ops->match == NULL)
201 host->ops->match = default_irq_host_match;
202
203 raw_spin_lock_irqsave(&irq_big_lock, flags);
204
205 /* Check for the priority controller. */
206 if (revmap_type == IRQ_HOST_MAP_PRIORITY) {
207 if (irq_map[0].host != NULL) {
208 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
209 of_node_put(host->of_node);
210 kfree(host);
211 return NULL;
212 }
213 irq_map[0].host = host;
214 }
215
216 list_add(&host->link, &irq_hosts);
217 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
218
219 /* Additional setups per revmap type */
220 switch (revmap_type) {
221 case IRQ_HOST_MAP_PRIORITY:
222 /* 0 is always the invalid number for priority */
223 host->inval_irq = 0;
224 /* setup us as the host for all priority interrupts */
225 for (i = 1; i < NR_PRIORITY_IRQS; i++) {
226 irq_map[i].hwirq = i;
227 smp_wmb();
228 irq_map[i].host = host;
229 smp_wmb();
230
231 ops->map(host, i, i);
232 }
233 break;
234 case IRQ_HOST_MAP_LINEAR:
235 rmap = (unsigned int *)(host + 1);
236 for (i = 0; i < revmap_arg; i++)
237 rmap[i] = NO_IRQ;
238 host->revmap_data.linear.size = revmap_arg;
239 smp_wmb();
240 host->revmap_data.linear.revmap = rmap;
241 break;
242 case IRQ_HOST_MAP_TREE:
243 INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
244 break;
245 default:
246 break;
247 }
248
249 pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
250
251 return host;
252}
253
254struct irq_host *irq_find_host(struct device_node *node)
255{
256 struct irq_host *h, *found = NULL;
257 unsigned long flags;
258
259 /* We might want to match the legacy controller last since
260 * it might potentially be set to match all interrupts in
261 * the absence of a device node. This isn't a problem so far
262 * yet though...
263 */
264 raw_spin_lock_irqsave(&irq_big_lock, flags);
265 list_for_each_entry(h, &irq_hosts, link)
266 if (h->ops->match(h, node)) {
267 found = h;
268 break;
269 }
270 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
271 return found;
272}
273EXPORT_SYMBOL_GPL(irq_find_host);
274
275void irq_set_default_host(struct irq_host *host)
276{
277 pr_debug("irq: Default host set to @0x%p\n", host);
278
279 irq_default_host = host;
280}
281
282void irq_set_virq_count(unsigned int count)
283{
284 pr_debug("irq: Trying to set virq count to %d\n", count);
285
286 BUG_ON(count < NR_PRIORITY_IRQS);
287 if (count < NR_IRQS)
288 irq_virq_count = count;
289}
290
291static int irq_setup_virq(struct irq_host *host, unsigned int virq,
292 irq_hw_number_t hwirq)
293{
294 int res;
295
296 res = irq_alloc_desc_at(virq, 0);
297 if (res != virq) {
298 pr_debug("irq: -> allocating desc failed\n");
299 goto error;
300 }
301
302 /* map it */
303 smp_wmb();
304 irq_map[virq].hwirq = hwirq;
305 smp_mb();
306
307 if (host->ops->map(host, virq, hwirq)) {
308 pr_debug("irq: -> mapping failed, freeing\n");
309 goto errdesc;
310 }
311
312 irq_clear_status_flags(virq, IRQ_NOREQUEST);
313
314 return 0;
315
316errdesc:
317 irq_free_descs(virq, 1);
318error:
319 irq_free_virt(virq, 1);
320 return -1;
321}
322
323unsigned int irq_create_direct_mapping(struct irq_host *host)
324{
325 unsigned int virq;
326
327 if (host == NULL)
328 host = irq_default_host;
329
330 BUG_ON(host == NULL);
331 WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
332
333 virq = irq_alloc_virt(host, 1, 0);
334 if (virq == NO_IRQ) {
335 pr_debug("irq: create_direct virq allocation failed\n");
336 return NO_IRQ;
337 }
338
339 pr_debug("irq: create_direct obtained virq %d\n", virq);
340
341 if (irq_setup_virq(host, virq, virq))
342 return NO_IRQ;
343
344 return virq;
345}
346
347unsigned int irq_create_mapping(struct irq_host *host,
348 irq_hw_number_t hwirq)
349{
350 unsigned int virq, hint;
351
352 pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
353
354 /* Look for default host if nececssary */
355 if (host == NULL)
356 host = irq_default_host;
357 if (host == NULL) {
358 printk(KERN_WARNING "irq_create_mapping called for"
359 " NULL host, hwirq=%lx\n", hwirq);
360 WARN_ON(1);
361 return NO_IRQ;
362 }
363 pr_debug("irq: -> using host @%p\n", host);
364
365 /* Check if mapping already exists */
366 virq = irq_find_mapping(host, hwirq);
367 if (virq != NO_IRQ) {
368 pr_debug("irq: -> existing mapping on virq %d\n", virq);
369 return virq;
370 }
371
372 /* Allocate a virtual interrupt number */
373 hint = hwirq % irq_virq_count;
374 virq = irq_alloc_virt(host, 1, hint);
375 if (virq == NO_IRQ) {
376 pr_debug("irq: -> virq allocation failed\n");
377 return NO_IRQ;
378 }
379
380 if (irq_setup_virq(host, virq, hwirq))
381 return NO_IRQ;
382
383 pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
384 hwirq, host->of_node ? host->of_node->full_name : "null", virq);
385
386 return virq;
387}
388EXPORT_SYMBOL_GPL(irq_create_mapping);
389
390unsigned int irq_create_of_mapping(struct device_node *controller,
391 const u32 *intspec, unsigned int intsize)
392{
393 struct irq_host *host;
394 irq_hw_number_t hwirq;
395 unsigned int type = IRQ_TYPE_NONE;
396 unsigned int virq;
397
398 if (controller == NULL)
399 host = irq_default_host;
400 else
401 host = irq_find_host(controller);
402 if (host == NULL) {
403 printk(KERN_WARNING "irq: no irq host found for %s !\n",
404 controller->full_name);
405 return NO_IRQ;
406 }
407
408 /* If host has no translation, then we assume interrupt line */
409 if (host->ops->xlate == NULL)
410 hwirq = intspec[0];
411 else {
412 if (host->ops->xlate(host, controller, intspec, intsize,
413 &hwirq, &type))
414 return NO_IRQ;
415 }
416
417 /* Create mapping */
418 virq = irq_create_mapping(host, hwirq);
419 if (virq == NO_IRQ)
420 return virq;
421
422 /* Set type if specified and different than the current one */
423 if (type != IRQ_TYPE_NONE &&
424 type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
425 irq_set_irq_type(virq, type);
426 return virq;
427}
428EXPORT_SYMBOL_GPL(irq_create_of_mapping);
429
430void irq_dispose_mapping(unsigned int virq)
431{
432 struct irq_host *host;
433 irq_hw_number_t hwirq;
434
435 if (virq == NO_IRQ)
436 return;
437
438 /* Never unmap priority interrupts */
439 if (virq < NR_PRIORITY_IRQS)
440 return;
441
442 host = irq_map[virq].host;
443 if (WARN_ON(host == NULL))
444 return;
445
446 irq_set_status_flags(virq, IRQ_NOREQUEST);
447
448 /* remove chip and handler */
449 irq_set_chip_and_handler(virq, NULL, NULL);
450
451 /* Make sure it's completed */
452 synchronize_irq(virq);
453
454 /* Tell the PIC about it */
455 if (host->ops->unmap)
456 host->ops->unmap(host, virq);
457 smp_mb();
458
459 /* Clear reverse map */
460 hwirq = irq_map[virq].hwirq;
461 switch (host->revmap_type) {
462 case IRQ_HOST_MAP_LINEAR:
463 if (hwirq < host->revmap_data.linear.size)
464 host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
465 break;
466 case IRQ_HOST_MAP_TREE:
467 mutex_lock(&revmap_trees_mutex);
468 radix_tree_delete(&host->revmap_data.tree, hwirq);
469 mutex_unlock(&revmap_trees_mutex);
470 break;
471 }
472
473 /* Destroy map */
474 smp_mb();
475 irq_map[virq].hwirq = host->inval_irq;
476
477 irq_free_descs(virq, 1);
478 /* Free it */
479 irq_free_virt(virq, 1);
480}
481EXPORT_SYMBOL_GPL(irq_dispose_mapping);
482
483unsigned int irq_find_mapping(struct irq_host *host,
484 irq_hw_number_t hwirq)
485{
486 unsigned int i;
487 unsigned int hint = hwirq % irq_virq_count;
488
489 /* Look for default host if nececssary */
490 if (host == NULL)
491 host = irq_default_host;
492 if (host == NULL)
493 return NO_IRQ;
494
495 /* Slow path does a linear search of the map */
496 i = hint;
497 do {
498 if (irq_map[i].host == host &&
499 irq_map[i].hwirq == hwirq)
500 return i;
501 i++;
502 if (i >= irq_virq_count)
503 i = 4;
504 } while (i != hint);
505 return NO_IRQ;
506}
507EXPORT_SYMBOL_GPL(irq_find_mapping);
508
509unsigned int irq_radix_revmap_lookup(struct irq_host *host,
510 irq_hw_number_t hwirq)
511{
512 struct irq_map_entry *ptr;
513 unsigned int virq;
514
515 if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
516 return irq_find_mapping(host, hwirq);
517
518 /*
519 * The ptr returned references the static global irq_map.
520 * but freeing an irq can delete nodes along the path to
521 * do the lookup via call_rcu.
522 */
523 rcu_read_lock();
524 ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
525 rcu_read_unlock();
526
527 /*
528 * If found in radix tree, then fine.
529 * Else fallback to linear lookup - this should not happen in practice
530 * as it means that we failed to insert the node in the radix tree.
531 */
532 if (ptr)
533 virq = ptr - irq_map;
534 else
535 virq = irq_find_mapping(host, hwirq);
536
537 return virq;
538}
539
540void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
541 irq_hw_number_t hwirq)
542{
543 if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
544 return;
545
546 if (virq != NO_IRQ) {
547 mutex_lock(&revmap_trees_mutex);
548 radix_tree_insert(&host->revmap_data.tree, hwirq,
549 &irq_map[virq]);
550 mutex_unlock(&revmap_trees_mutex);
551 }
552}
553
554unsigned int irq_linear_revmap(struct irq_host *host,
555 irq_hw_number_t hwirq)
556{
557 unsigned int *revmap;
558
559 if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
560 return irq_find_mapping(host, hwirq);
561
562 /* Check revmap bounds */
563 if (unlikely(hwirq >= host->revmap_data.linear.size))
564 return irq_find_mapping(host, hwirq);
565
566 /* Check if revmap was allocated */
567 revmap = host->revmap_data.linear.revmap;
568 if (unlikely(revmap == NULL))
569 return irq_find_mapping(host, hwirq);
570
571 /* Fill up revmap with slow path if no mapping found */
572 if (unlikely(revmap[hwirq] == NO_IRQ))
573 revmap[hwirq] = irq_find_mapping(host, hwirq);
574
575 return revmap[hwirq];
576}
577
578unsigned int irq_alloc_virt(struct irq_host *host,
579 unsigned int count,
580 unsigned int hint)
581{
582 unsigned long flags;
583 unsigned int i, j, found = NO_IRQ;
584
585 if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS))
586 return NO_IRQ;
587
588 raw_spin_lock_irqsave(&irq_big_lock, flags);
589
590 /* Use hint for 1 interrupt if any */
591 if (count == 1 && hint >= NR_PRIORITY_IRQS &&
592 hint < irq_virq_count && irq_map[hint].host == NULL) {
593 found = hint;
594 goto hint_found;
595 }
596
597 /* Look for count consecutive numbers in the allocatable
598 * (non-legacy) space
599 */
600 for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) {
601 if (irq_map[i].host != NULL)
602 j = 0;
603 else
604 j++;
605
606 if (j == count) {
607 found = i - count + 1;
608 break;
609 }
610 }
611 if (found == NO_IRQ) {
612 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
613 return NO_IRQ;
614 }
615 hint_found:
616 for (i = found; i < (found + count); i++) {
617 irq_map[i].hwirq = host->inval_irq;
618 smp_wmb();
619 irq_map[i].host = host;
620 }
621 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
622 return found;
623}
624
625void irq_free_virt(unsigned int virq, unsigned int count)
626{
627 unsigned long flags;
628 unsigned int i;
629
630 WARN_ON(virq < NR_PRIORITY_IRQS);
631 WARN_ON(count == 0 || (virq + count) > irq_virq_count);
632
633 if (virq < NR_PRIORITY_IRQS) {
634 if (virq + count < NR_PRIORITY_IRQS)
635 return;
636 count -= NR_PRIORITY_IRQS - virq;
637 virq = NR_PRIORITY_IRQS;
638 }
639
640 if (count > irq_virq_count || virq > irq_virq_count - count) {
641 if (virq > irq_virq_count)
642 return;
643 count = irq_virq_count - virq;
644 }
645
646 raw_spin_lock_irqsave(&irq_big_lock, flags);
647 for (i = virq; i < (virq + count); i++) {
648 struct irq_host *host;
649
650 host = irq_map[i].host;
651 irq_map[i].hwirq = host->inval_irq;
652 smp_wmb();
653 irq_map[i].host = NULL;
654 }
655 raw_spin_unlock_irqrestore(&irq_big_lock, flags);
656}
657
658#ifdef CONFIG_VIRQ_DEBUG
659static int virq_debug_show(struct seq_file *m, void *private)
660{
661 unsigned long flags;
662 struct irq_desc *desc;
663 const char *p;
664 static const char none[] = "none";
665 void *data;
666 int i;
667
668 seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
669 "chip name", "chip data", "host name");
670
671 for (i = 1; i < nr_irqs; i++) {
672 desc = irq_to_desc(i);
673 if (!desc)
674 continue;
675
676 raw_spin_lock_irqsave(&desc->lock, flags);
677
678 if (desc->action && desc->action->handler) {
679 struct irq_chip *chip;
680
681 seq_printf(m, "%5d ", i);
682 seq_printf(m, "0x%05lx ", irq_map[i].hwirq);
683
684 chip = irq_desc_get_chip(desc);
685 if (chip && chip->name)
686 p = chip->name;
687 else
688 p = none;
689 seq_printf(m, "%-15s ", p);
690
691 data = irq_desc_get_chip_data(desc);
692 seq_printf(m, "0x%16p ", data);
693
694 if (irq_map[i].host && irq_map[i].host->of_node)
695 p = irq_map[i].host->of_node->full_name;
696 else
697 p = none;
698 seq_printf(m, "%s\n", p);
699 }
700
701 raw_spin_unlock_irqrestore(&desc->lock, flags);
702 }
703
704 return 0;
705}
706
707static int virq_debug_open(struct inode *inode, struct file *file)
708{
709 return single_open(file, virq_debug_show, inode->i_private);
710}
711
712static const struct file_operations virq_debug_fops = {
713 .open = virq_debug_open,
714 .read = seq_read,
715 .llseek = seq_lseek,
716 .release = single_release,
717};
718
719static int __init irq_debugfs_init(void)
720{
721 if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
722 NULL, &virq_debug_fops) == NULL)
723 return -ENOMEM;
724
725 return 0;
726}
727device_initcall(irq_debugfs_init);
728#endif /* CONFIG_VIRQ_DEBUG */
diff --git a/arch/c6x/kernel/module.c b/arch/c6x/kernel/module.c
new file mode 100644
index 00000000000..5fc03f18f56
--- /dev/null
+++ b/arch/c6x/kernel/module.c
@@ -0,0 +1,123 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2005, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Thomas Charleux (thomas.charleux@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#include <linux/moduleloader.h>
13#include <linux/elf.h>
14#include <linux/vmalloc.h>
15#include <linux/kernel.h>
16
17static inline int fixup_pcr(u32 *ip, Elf32_Addr dest, u32 maskbits, int shift)
18{
19 u32 opcode;
20 long ep = (long)ip & ~31;
21 long delta = ((long)dest - ep) >> 2;
22 long mask = (1 << maskbits) - 1;
23
24 if ((delta >> (maskbits - 1)) == 0 ||
25 (delta >> (maskbits - 1)) == -1) {
26 opcode = *ip;
27 opcode &= ~(mask << shift);
28 opcode |= ((delta & mask) << shift);
29 *ip = opcode;
30
31 pr_debug("REL PCR_S%d[%p] dest[%p] opcode[%08x]\n",
32 maskbits, ip, (void *)dest, opcode);
33
34 return 0;
35 }
36 pr_err("PCR_S%d reloc %p -> %p out of range!\n",
37 maskbits, ip, (void *)dest);
38
39 return -1;
40}
41
42/*
43 * apply a RELA relocation
44 */
45int apply_relocate_add(Elf32_Shdr *sechdrs,
46 const char *strtab,
47 unsigned int symindex,
48 unsigned int relsec,
49 struct module *me)
50{
51 Elf32_Rela *rel = (void *) sechdrs[relsec].sh_addr;
52 Elf_Sym *sym;
53 u32 *location, opcode;
54 unsigned int i;
55 Elf32_Addr v;
56 Elf_Addr offset = 0;
57
58 pr_debug("Applying relocate section %u to %u with offset 0x%x\n",
59 relsec, sechdrs[relsec].sh_info, offset);
60
61 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
62 /* This is where to make the change */
63 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
64 + rel[i].r_offset - offset;
65
66 /* This is the symbol it is referring to. Note that all
67 undefined symbols have been resolved. */
68 sym = (Elf_Sym *)sechdrs[symindex].sh_addr
69 + ELF32_R_SYM(rel[i].r_info);
70
71 /* this is the adjustment to be made */
72 v = sym->st_value + rel[i].r_addend;
73
74 switch (ELF32_R_TYPE(rel[i].r_info)) {
75 case R_C6000_ABS32:
76 pr_debug("RELA ABS32: [%p] = 0x%x\n", location, v);
77 *location = v;
78 break;
79 case R_C6000_ABS16:
80 pr_debug("RELA ABS16: [%p] = 0x%x\n", location, v);
81 *(u16 *)location = v;
82 break;
83 case R_C6000_ABS8:
84 pr_debug("RELA ABS8: [%p] = 0x%x\n", location, v);
85 *(u8 *)location = v;
86 break;
87 case R_C6000_ABS_L16:
88 opcode = *location;
89 opcode &= ~0x7fff80;
90 opcode |= ((v & 0xffff) << 7);
91 pr_debug("RELA ABS_L16[%p] v[0x%x] opcode[0x%x]\n",
92 location, v, opcode);
93 *location = opcode;
94 break;
95 case R_C6000_ABS_H16:
96 opcode = *location;
97 opcode &= ~0x7fff80;
98 opcode |= ((v >> 9) & 0x7fff80);
99 pr_debug("RELA ABS_H16[%p] v[0x%x] opcode[0x%x]\n",
100 location, v, opcode);
101 *location = opcode;
102 break;
103 case R_C6000_PCR_S21:
104 if (fixup_pcr(location, v, 21, 7))
105 return -ENOEXEC;
106 break;
107 case R_C6000_PCR_S12:
108 if (fixup_pcr(location, v, 12, 16))
109 return -ENOEXEC;
110 break;
111 case R_C6000_PCR_S10:
112 if (fixup_pcr(location, v, 10, 13))
113 return -ENOEXEC;
114 break;
115 default:
116 pr_err("module %s: Unknown RELA relocation: %u\n",
117 me->name, ELF32_R_TYPE(rel[i].r_info));
118 return -ENOEXEC;
119 }
120 }
121
122 return 0;
123}
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c
new file mode 100644
index 00000000000..7ca8c41b03c
--- /dev/null
+++ b/arch/c6x/kernel/process.c
@@ -0,0 +1,265 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#include <linux/module.h>
13#include <linux/unistd.h>
14#include <linux/ptrace.h>
15#include <linux/init_task.h>
16#include <linux/tick.h>
17#include <linux/mqueue.h>
18#include <linux/syscalls.h>
19#include <linux/reboot.h>
20
21#include <asm/syscalls.h>
22
23/* hooks for board specific support */
24void (*c6x_restart)(void);
25void (*c6x_halt)(void);
26
27extern asmlinkage void ret_from_fork(void);
28
29static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
30static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
31
32/*
33 * Initial thread structure.
34 */
35union thread_union init_thread_union __init_task_data = {
36 INIT_THREAD_INFO(init_task)
37};
38
39/*
40 * Initial task structure.
41 */
42struct task_struct init_task = INIT_TASK(init_task);
43EXPORT_SYMBOL(init_task);
44
45/*
46 * power off function, if any
47 */
48void (*pm_power_off)(void);
49EXPORT_SYMBOL(pm_power_off);
50
51static void c6x_idle(void)
52{
53 unsigned long tmp;
54
55 /*
56 * Put local_irq_enable and idle in same execute packet
57 * to make them atomic and avoid race to idle with
58 * interrupts enabled.
59 */
60 asm volatile (" mvc .s2 CSR,%0\n"
61 " or .d2 1,%0,%0\n"
62 " mvc .s2 %0,CSR\n"
63 "|| idle\n"
64 : "=b"(tmp));
65}
66
67/*
68 * The idle loop for C64x
69 */
70void cpu_idle(void)
71{
72 /* endless idle loop with no priority at all */
73 while (1) {
74 tick_nohz_idle_enter();
75 rcu_idle_enter();
76 while (1) {
77 local_irq_disable();
78 if (need_resched()) {
79 local_irq_enable();
80 break;
81 }
82 c6x_idle(); /* enables local irqs */
83 }
84 rcu_idle_exit();
85 tick_nohz_idle_exit();
86
87 preempt_enable_no_resched();
88 schedule();
89 preempt_disable();
90 }
91}
92
93static void halt_loop(void)
94{
95 printk(KERN_EMERG "System Halted, OK to turn off power\n");
96 local_irq_disable();
97 while (1)
98 asm volatile("idle\n");
99}
100
101void machine_restart(char *__unused)
102{
103 if (c6x_restart)
104 c6x_restart();
105 halt_loop();
106}
107
108void machine_halt(void)
109{
110 if (c6x_halt)
111 c6x_halt();
112 halt_loop();
113}
114
115void machine_power_off(void)
116{
117 if (pm_power_off)
118 pm_power_off();
119 halt_loop();
120}
121
122static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
123{
124 do_exit(fn(arg));
125}
126
127/*
128 * Create a kernel thread
129 */
130int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
131{
132 struct pt_regs regs;
133
134 /*
135 * copy_thread sets a4 to zero (child return from fork)
136 * so we can't just set things up to directly return to
137 * fn.
138 */
139 memset(&regs, 0, sizeof(regs));
140 regs.b4 = (unsigned long) arg;
141 regs.a6 = (unsigned long) fn;
142 regs.pc = (unsigned long) kernel_thread_helper;
143 local_save_flags(regs.csr);
144 regs.csr |= 1;
145 regs.tsr = 5; /* Set GEE and GIE in TSR */
146
147 /* Ok, create the new process.. */
148 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs,
149 0, NULL, NULL);
150}
151EXPORT_SYMBOL(kernel_thread);
152
153void flush_thread(void)
154{
155}
156
157void exit_thread(void)
158{
159}
160
161SYSCALL_DEFINE1(c6x_clone, struct pt_regs *, regs)
162{
163 unsigned long clone_flags;
164 unsigned long newsp;
165
166 /* syscall puts clone_flags in A4 and usp in B4 */
167 clone_flags = regs->orig_a4;
168 if (regs->b4)
169 newsp = regs->b4;
170 else
171 newsp = regs->sp;
172
173 return do_fork(clone_flags, newsp, regs, 0, (int __user *)regs->a6,
174 (int __user *)regs->b6);
175}
176
177/*
178 * Do necessary setup to start up a newly executed thread.
179 */
180void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp)
181{
182 /*
183 * The binfmt loader will setup a "full" stack, but the C6X
184 * operates an "empty" stack. So we adjust the usp so that
185 * argc doesn't get destroyed if an interrupt is taken before
186 * it is read from the stack.
187 *
188 * NB: Library startup code needs to match this.
189 */
190 usp -= 8;
191
192 set_fs(USER_DS);
193 regs->pc = pc;
194 regs->sp = usp;
195 regs->tsr |= 0x40; /* set user mode */
196 current->thread.usp = usp;
197}
198
199/*
200 * Copy a new thread context in its stack.
201 */
202int copy_thread(unsigned long clone_flags, unsigned long usp,
203 unsigned long ustk_size,
204 struct task_struct *p, struct pt_regs *regs)
205{
206 struct pt_regs *childregs;
207
208 childregs = task_pt_regs(p);
209
210 *childregs = *regs;
211 childregs->a4 = 0;
212
213 if (usp == -1)
214 /* case of __kernel_thread: we return to supervisor space */
215 childregs->sp = (unsigned long)(childregs + 1);
216 else
217 /* Otherwise use the given stack */
218 childregs->sp = usp;
219
220 /* Set usp/ksp */
221 p->thread.usp = childregs->sp;
222 /* switch_to uses stack to save/restore 14 callee-saved regs */
223 thread_saved_ksp(p) = (unsigned long)childregs - 8;
224 p->thread.pc = (unsigned int) ret_from_fork;
225 p->thread.wchan = (unsigned long) ret_from_fork;
226#ifdef __DSBT__
227 {
228 unsigned long dp;
229
230 asm volatile ("mv .S2 b14,%0\n" : "=b"(dp));
231
232 thread_saved_dp(p) = dp;
233 if (usp == -1)
234 childregs->dp = dp;
235 }
236#endif
237 return 0;
238}
239
240/*
241 * c6x_execve() executes a new program.
242 */
243SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
244 const char __user *const __user *, argv,
245 const char __user *const __user *, envp,
246 struct pt_regs *, regs)
247{
248 int error;
249 char *filename;
250
251 filename = getname(name);
252 error = PTR_ERR(filename);
253 if (IS_ERR(filename))
254 goto out;
255
256 error = do_execve(filename, argv, envp, regs);
257 putname(filename);
258out:
259 return error;
260}
261
262unsigned long get_wchan(struct task_struct *p)
263{
264 return p->thread.wchan;
265}
diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c
new file mode 100644
index 00000000000..3c494e84444
--- /dev/null
+++ b/arch/c6x/kernel/ptrace.c
@@ -0,0 +1,187 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Updated for 2.6.34: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/ptrace.h>
14#include <linux/tracehook.h>
15#include <linux/regset.h>
16#include <linux/elf.h>
17
18#include <asm/cacheflush.h>
19
20#define PT_REG_SIZE (sizeof(struct pt_regs))
21
22/*
23 * Called by kernel/ptrace.c when detaching.
24 */
25void ptrace_disable(struct task_struct *child)
26{
27 /* nothing to do */
28}
29
30/*
31 * Get a register number from live pt_regs for the specified task.
32 */
33static inline long get_reg(struct task_struct *task, int regno)
34{
35 long *addr = (long *)task_pt_regs(task);
36
37 if (regno == PT_TSR || regno == PT_CSR)
38 return 0;
39
40 return addr[regno];
41}
42
43/*
44 * Write contents of register REGNO in task TASK.
45 */
46static inline int put_reg(struct task_struct *task,
47 int regno,
48 unsigned long data)
49{
50 unsigned long *addr = (unsigned long *)task_pt_regs(task);
51
52 if (regno != PT_TSR && regno != PT_CSR)
53 addr[regno] = data;
54
55 return 0;
56}
57
58/* regset get/set implementations */
59
60static int gpr_get(struct task_struct *target,
61 const struct user_regset *regset,
62 unsigned int pos, unsigned int count,
63 void *kbuf, void __user *ubuf)
64{
65 struct pt_regs *regs = task_pt_regs(target);
66
67 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
68 regs,
69 0, sizeof(*regs));
70}
71
72static int gpr_set(struct task_struct *target,
73 const struct user_regset *regset,
74 unsigned int pos, unsigned int count,
75 const void *kbuf, const void __user *ubuf)
76{
77 int ret;
78 struct pt_regs *regs = task_pt_regs(target);
79
80 /* Don't copyin TSR or CSR */
81 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
82 &regs,
83 0, PT_TSR * sizeof(long));
84 if (ret)
85 return ret;
86
87 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
88 PT_TSR * sizeof(long),
89 (PT_TSR + 1) * sizeof(long));
90 if (ret)
91 return ret;
92
93 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
94 &regs,
95 (PT_TSR + 1) * sizeof(long),
96 PT_CSR * sizeof(long));
97 if (ret)
98 return ret;
99
100 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
101 PT_CSR * sizeof(long),
102 (PT_CSR + 1) * sizeof(long));
103 if (ret)
104 return ret;
105
106 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
107 &regs,
108 (PT_CSR + 1) * sizeof(long), -1);
109 return ret;
110}
111
112enum c6x_regset {
113 REGSET_GPR,
114};
115
116static const struct user_regset c6x_regsets[] = {
117 [REGSET_GPR] = {
118 .core_note_type = NT_PRSTATUS,
119 .n = ELF_NGREG,
120 .size = sizeof(u32),
121 .align = sizeof(u32),
122 .get = gpr_get,
123 .set = gpr_set
124 },
125};
126
127static const struct user_regset_view user_c6x_native_view = {
128 .name = "tic6x",
129 .e_machine = EM_TI_C6000,
130 .regsets = c6x_regsets,
131 .n = ARRAY_SIZE(c6x_regsets),
132};
133
134const struct user_regset_view *task_user_regset_view(struct task_struct *task)
135{
136 return &user_c6x_native_view;
137}
138
139/*
140 * Perform ptrace request
141 */
142long arch_ptrace(struct task_struct *child, long request,
143 unsigned long addr, unsigned long data)
144{
145 int ret = 0;
146
147 switch (request) {
148 /*
149 * write the word at location addr.
150 */
151 case PTRACE_POKETEXT:
152 ret = generic_ptrace_pokedata(child, addr, data);
153 if (ret == 0 && request == PTRACE_POKETEXT)
154 flush_icache_range(addr, addr + 4);
155 break;
156 default:
157 ret = ptrace_request(child, request, addr, data);
158 break;
159 }
160
161 return ret;
162}
163
164/*
165 * handle tracing of system call entry
166 * - return the revised system call number or ULONG_MAX to cause ENOSYS
167 */
168asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs)
169{
170 if (tracehook_report_syscall_entry(regs))
171 /* tracing decided this syscall should not happen, so
172 * We'll return a bogus call number to get an ENOSYS
173 * error, but leave the original number in
174 * regs->orig_a4
175 */
176 return ULONG_MAX;
177
178 return regs->b0;
179}
180
181/*
182 * handle tracing of system call exit
183 */
184asmlinkage void syscall_trace_exit(struct pt_regs *regs)
185{
186 tracehook_report_syscall_exit(regs, 0);
187}
diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c
new file mode 100644
index 00000000000..0c07921747f
--- /dev/null
+++ b/arch/c6x/kernel/setup.c
@@ -0,0 +1,510 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/dma-mapping.h>
12#include <linux/memblock.h>
13#include <linux/seq_file.h>
14#include <linux/bootmem.h>
15#include <linux/clkdev.h>
16#include <linux/initrd.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/of_fdt.h>
20#include <linux/string.h>
21#include <linux/errno.h>
22#include <linux/cache.h>
23#include <linux/delay.h>
24#include <linux/sched.h>
25#include <linux/clk.h>
26#include <linux/cpu.h>
27#include <linux/fs.h>
28#include <linux/of.h>
29
30
31#include <asm/sections.h>
32#include <asm/div64.h>
33#include <asm/setup.h>
34#include <asm/dscr.h>
35#include <asm/clock.h>
36#include <asm/soc.h>
37
38static const char *c6x_soc_name;
39
40int c6x_num_cores;
41EXPORT_SYMBOL_GPL(c6x_num_cores);
42
43unsigned int c6x_silicon_rev;
44EXPORT_SYMBOL_GPL(c6x_silicon_rev);
45
46/*
47 * Device status register. This holds information
48 * about device configuration needed by some drivers.
49 */
50unsigned int c6x_devstat;
51EXPORT_SYMBOL_GPL(c6x_devstat);
52
53/*
54 * Some SoCs have fuse registers holding a unique MAC
55 * address. This is parsed out of the device tree with
56 * the resulting MAC being held here.
57 */
58unsigned char c6x_fuse_mac[6];
59
60unsigned long memory_start;
61unsigned long memory_end;
62
63unsigned long ram_start;
64unsigned long ram_end;
65
66/* Uncached memory for DMA consistent use (memdma=) */
67static unsigned long dma_start __initdata;
68static unsigned long dma_size __initdata;
69
70char c6x_command_line[COMMAND_LINE_SIZE];
71
72#if defined(CONFIG_CMDLINE_BOOL)
73static const char default_command_line[COMMAND_LINE_SIZE] __section(.cmdline) =
74 CONFIG_CMDLINE;
75#endif
76
77struct cpuinfo_c6x {
78 const char *cpu_name;
79 const char *cpu_voltage;
80 const char *mmu;
81 const char *fpu;
82 char *cpu_rev;
83 unsigned int core_id;
84 char __cpu_rev[5];
85};
86
87static DEFINE_PER_CPU(struct cpuinfo_c6x, cpu_data);
88
89unsigned int ticks_per_ns_scaled;
90EXPORT_SYMBOL(ticks_per_ns_scaled);
91
92unsigned int c6x_core_freq;
93
94static void __init get_cpuinfo(void)
95{
96 unsigned cpu_id, rev_id, csr;
97 struct clk *coreclk = clk_get_sys(NULL, "core");
98 unsigned long core_khz;
99 u64 tmp;
100 struct cpuinfo_c6x *p;
101 struct device_node *node, *np;
102
103 p = &per_cpu(cpu_data, smp_processor_id());
104
105 if (!IS_ERR(coreclk))
106 c6x_core_freq = clk_get_rate(coreclk);
107 else {
108 printk(KERN_WARNING
109 "Cannot find core clock frequency. Using 700MHz\n");
110 c6x_core_freq = 700000000;
111 }
112
113 core_khz = c6x_core_freq / 1000;
114
115 tmp = (uint64_t)core_khz << C6X_NDELAY_SCALE;
116 do_div(tmp, 1000000);
117 ticks_per_ns_scaled = tmp;
118
119 csr = get_creg(CSR);
120 cpu_id = csr >> 24;
121 rev_id = (csr >> 16) & 0xff;
122
123 p->mmu = "none";
124 p->fpu = "none";
125 p->cpu_voltage = "unknown";
126
127 switch (cpu_id) {
128 case 0:
129 p->cpu_name = "C67x";
130 p->fpu = "yes";
131 break;
132 case 2:
133 p->cpu_name = "C62x";
134 break;
135 case 8:
136 p->cpu_name = "C64x";
137 break;
138 case 12:
139 p->cpu_name = "C64x";
140 break;
141 case 16:
142 p->cpu_name = "C64x+";
143 p->cpu_voltage = "1.2";
144 break;
145 default:
146 p->cpu_name = "unknown";
147 break;
148 }
149
150 if (cpu_id < 16) {
151 switch (rev_id) {
152 case 0x1:
153 if (cpu_id > 8) {
154 p->cpu_rev = "DM640/DM641/DM642/DM643";
155 p->cpu_voltage = "1.2 - 1.4";
156 } else {
157 p->cpu_rev = "C6201";
158 p->cpu_voltage = "2.5";
159 }
160 break;
161 case 0x2:
162 p->cpu_rev = "C6201B/C6202/C6211";
163 p->cpu_voltage = "1.8";
164 break;
165 case 0x3:
166 p->cpu_rev = "C6202B/C6203/C6204/C6205";
167 p->cpu_voltage = "1.5";
168 break;
169 case 0x201:
170 p->cpu_rev = "C6701 revision 0 (early CPU)";
171 p->cpu_voltage = "1.8";
172 break;
173 case 0x202:
174 p->cpu_rev = "C6701/C6711/C6712";
175 p->cpu_voltage = "1.8";
176 break;
177 case 0x801:
178 p->cpu_rev = "C64x";
179 p->cpu_voltage = "1.5";
180 break;
181 default:
182 p->cpu_rev = "unknown";
183 }
184 } else {
185 p->cpu_rev = p->__cpu_rev;
186 snprintf(p->__cpu_rev, sizeof(p->__cpu_rev), "0x%x", cpu_id);
187 }
188
189 p->core_id = get_coreid();
190
191 node = of_find_node_by_name(NULL, "cpus");
192 if (node) {
193 for_each_child_of_node(node, np)
194 if (!strcmp("cpu", np->name))
195 ++c6x_num_cores;
196 of_node_put(node);
197 }
198
199 node = of_find_node_by_name(NULL, "soc");
200 if (node) {
201 if (of_property_read_string(node, "model", &c6x_soc_name))
202 c6x_soc_name = "unknown";
203 of_node_put(node);
204 } else
205 c6x_soc_name = "unknown";
206
207 printk(KERN_INFO "CPU%d: %s rev %s, %s volts, %uMHz\n",
208 p->core_id, p->cpu_name, p->cpu_rev,
209 p->cpu_voltage, c6x_core_freq / 1000000);
210}
211
212/*
213 * Early parsing of the command line
214 */
215static u32 mem_size __initdata;
216
217/* "mem=" parsing. */
218static int __init early_mem(char *p)
219{
220 if (!p)
221 return -EINVAL;
222
223 mem_size = memparse(p, &p);
224 /* don't remove all of memory when handling "mem={invalid}" */
225 if (mem_size == 0)
226 return -EINVAL;
227
228 return 0;
229}
230early_param("mem", early_mem);
231
232/* "memdma=<size>[@<address>]" parsing. */
233static int __init early_memdma(char *p)
234{
235 if (!p)
236 return -EINVAL;
237
238 dma_size = memparse(p, &p);
239 if (*p == '@')
240 dma_start = memparse(p, &p);
241
242 return 0;
243}
244early_param("memdma", early_memdma);
245
246int __init c6x_add_memory(phys_addr_t start, unsigned long size)
247{
248 static int ram_found __initdata;
249
250 /* We only handle one bank (the one with PAGE_OFFSET) for now */
251 if (ram_found)
252 return -EINVAL;
253
254 if (start > PAGE_OFFSET || PAGE_OFFSET >= (start + size))
255 return 0;
256
257 ram_start = start;
258 ram_end = start + size;
259
260 ram_found = 1;
261 return 0;
262}
263
264/*
265 * Do early machine setup and device tree parsing. This is called very
266 * early on the boot process.
267 */
268notrace void __init machine_init(unsigned long dt_ptr)
269{
270 struct boot_param_header *dtb = __va(dt_ptr);
271 struct boot_param_header *fdt = (struct boot_param_header *)_fdt_start;
272
273 /* interrupts must be masked */
274 set_creg(IER, 2);
275
276 /*
277 * Set the Interrupt Service Table (IST) to the beginning of the
278 * vector table.
279 */
280 set_ist(_vectors_start);
281
282 lockdep_init();
283
284 /*
285 * dtb is passed in from bootloader.
286 * fdt is linked in blob.
287 */
288 if (dtb && dtb != fdt)
289 fdt = dtb;
290
291 /* Do some early initialization based on the flat device tree */
292 early_init_devtree(fdt);
293
294 /* parse_early_param needs a boot_command_line */
295 strlcpy(boot_command_line, c6x_command_line, COMMAND_LINE_SIZE);
296 parse_early_param();
297}
298
299void __init setup_arch(char **cmdline_p)
300{
301 int bootmap_size;
302 struct memblock_region *reg;
303
304 printk(KERN_INFO "Initializing kernel\n");
305
306 /* Initialize command line */
307 *cmdline_p = c6x_command_line;
308
309 memory_end = ram_end;
310 memory_end &= ~(PAGE_SIZE - 1);
311
312 if (mem_size && (PAGE_OFFSET + PAGE_ALIGN(mem_size)) < memory_end)
313 memory_end = PAGE_OFFSET + PAGE_ALIGN(mem_size);
314
315 /* add block that this kernel can use */
316 memblock_add(PAGE_OFFSET, memory_end - PAGE_OFFSET);
317
318 /* reserve kernel text/data/bss */
319 memblock_reserve(PAGE_OFFSET,
320 PAGE_ALIGN((unsigned long)&_end - PAGE_OFFSET));
321
322 if (dma_size) {
323 /* align to cacheability granularity */
324 dma_size = CACHE_REGION_END(dma_size);
325
326 if (!dma_start)
327 dma_start = memory_end - dma_size;
328
329 /* align to cacheability granularity */
330 dma_start = CACHE_REGION_START(dma_start);
331
332 /* reserve DMA memory taken from kernel memory */
333 if (memblock_is_region_memory(dma_start, dma_size))
334 memblock_reserve(dma_start, dma_size);
335 }
336
337 memory_start = PAGE_ALIGN((unsigned int) &_end);
338
339 printk(KERN_INFO "Memory Start=%08lx, Memory End=%08lx\n",
340 memory_start, memory_end);
341
342#ifdef CONFIG_BLK_DEV_INITRD
343 /*
344 * Reserve initrd memory if in kernel memory.
345 */
346 if (initrd_start < initrd_end)
347 if (memblock_is_region_memory(initrd_start,
348 initrd_end - initrd_start))
349 memblock_reserve(initrd_start,
350 initrd_end - initrd_start);
351#endif
352
353 init_mm.start_code = (unsigned long) &_stext;
354 init_mm.end_code = (unsigned long) &_etext;
355 init_mm.end_data = memory_start;
356 init_mm.brk = memory_start;
357
358 /*
359 * Give all the memory to the bootmap allocator, tell it to put the
360 * boot mem_map at the start of memory
361 */
362 bootmap_size = init_bootmem_node(NODE_DATA(0),
363 memory_start >> PAGE_SHIFT,
364 PAGE_OFFSET >> PAGE_SHIFT,
365 memory_end >> PAGE_SHIFT);
366 memblock_reserve(memory_start, bootmap_size);
367
368 unflatten_device_tree();
369
370 c6x_cache_init();
371
372 /* Set the whole external memory as non-cacheable */
373 disable_caching(ram_start, ram_end - 1);
374
375 /* Set caching of external RAM used by Linux */
376 for_each_memblock(memory, reg)
377 enable_caching(CACHE_REGION_START(reg->base),
378 CACHE_REGION_START(reg->base + reg->size - 1));
379
380#ifdef CONFIG_BLK_DEV_INITRD
381 /*
382 * Enable caching for initrd which falls outside kernel memory.
383 */
384 if (initrd_start < initrd_end) {
385 if (!memblock_is_region_memory(initrd_start,
386 initrd_end - initrd_start))
387 enable_caching(CACHE_REGION_START(initrd_start),
388 CACHE_REGION_START(initrd_end - 1));
389 }
390#endif
391
392 /*
393 * Disable caching for dma coherent memory taken from kernel memory.
394 */
395 if (dma_size && memblock_is_region_memory(dma_start, dma_size))
396 disable_caching(dma_start,
397 CACHE_REGION_START(dma_start + dma_size - 1));
398
399 /* Initialize the coherent memory allocator */
400 coherent_mem_init(dma_start, dma_size);
401
402 /*
403 * Free all memory as a starting point.
404 */
405 free_bootmem(PAGE_OFFSET, memory_end - PAGE_OFFSET);
406
407 /*
408 * Then reserve memory which is already being used.
409 */
410 for_each_memblock(reserved, reg) {
411 pr_debug("reserved - 0x%08x-0x%08x\n",
412 (u32) reg->base, (u32) reg->size);
413 reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
414 }
415
416 max_low_pfn = PFN_DOWN(memory_end);
417 min_low_pfn = PFN_UP(memory_start);
418 max_mapnr = max_low_pfn - min_low_pfn;
419
420 /* Get kmalloc into gear */
421 paging_init();
422
423 /*
424 * Probe for Device State Configuration Registers.
425 * We have to do this early in case timer needs to be enabled
426 * through DSCR.
427 */
428 dscr_probe();
429
430 /* We do this early for timer and core clock frequency */
431 c64x_setup_clocks();
432
433 /* Get CPU info */
434 get_cpuinfo();
435
436#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
437 conswitchp = &dummy_con;
438#endif
439}
440
441#define cpu_to_ptr(n) ((void *)((long)(n)+1))
442#define ptr_to_cpu(p) ((long)(p) - 1)
443
444static int show_cpuinfo(struct seq_file *m, void *v)
445{
446 int n = ptr_to_cpu(v);
447 struct cpuinfo_c6x *p = &per_cpu(cpu_data, n);
448
449 if (n == 0) {
450 seq_printf(m,
451 "soc\t\t: %s\n"
452 "soc revision\t: 0x%x\n"
453 "soc cores\t: %d\n",
454 c6x_soc_name, c6x_silicon_rev, c6x_num_cores);
455 }
456
457 seq_printf(m,
458 "\n"
459 "processor\t: %d\n"
460 "cpu\t\t: %s\n"
461 "core revision\t: %s\n"
462 "core voltage\t: %s\n"
463 "core id\t\t: %d\n"
464 "mmu\t\t: %s\n"
465 "fpu\t\t: %s\n"
466 "cpu MHz\t\t: %u\n"
467 "bogomips\t: %lu.%02lu\n\n",
468 n,
469 p->cpu_name, p->cpu_rev, p->cpu_voltage,
470 p->core_id, p->mmu, p->fpu,
471 (c6x_core_freq + 500000) / 1000000,
472 (loops_per_jiffy/(500000/HZ)),
473 (loops_per_jiffy/(5000/HZ))%100);
474
475 return 0;
476}
477
478static void *c_start(struct seq_file *m, loff_t *pos)
479{
480 return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL;
481}
482static void *c_next(struct seq_file *m, void *v, loff_t *pos)
483{
484 ++*pos;
485 return NULL;
486}
487static void c_stop(struct seq_file *m, void *v)
488{
489}
490
491const struct seq_operations cpuinfo_op = {
492 c_start,
493 c_stop,
494 c_next,
495 show_cpuinfo
496};
497
498static struct cpu cpu_devices[NR_CPUS];
499
500static int __init topology_init(void)
501{
502 int i;
503
504 for_each_present_cpu(i)
505 register_cpu(&cpu_devices[i], i);
506
507 return 0;
508}
509
510subsys_initcall(topology_init);
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
new file mode 100644
index 00000000000..304f675826e
--- /dev/null
+++ b/arch/c6x/kernel/signal.c
@@ -0,0 +1,377 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * Updated for 2.6.34: Mark Salter <msalter@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kernel.h>
15#include <linux/uaccess.h>
16#include <linux/syscalls.h>
17#include <linux/tracehook.h>
18
19#include <asm/ucontext.h>
20#include <asm/cacheflush.h>
21
22
23#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
24
25/*
26 * Do a signal return, undo the signal stack.
27 */
28
29#define RETCODE_SIZE (9 << 2) /* 9 instructions = 36 bytes */
30
31struct rt_sigframe {
32 struct siginfo __user *pinfo;
33 void __user *puc;
34 struct siginfo info;
35 struct ucontext uc;
36 unsigned long retcode[RETCODE_SIZE >> 2];
37};
38
39static int restore_sigcontext(struct pt_regs *regs,
40 struct sigcontext __user *sc)
41{
42 int err = 0;
43
44 /* The access_ok check was done by caller, so use __get_user here */
45#define COPY(x) (err |= __get_user(regs->x, &sc->sc_##x))
46
47 COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
48 COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
49 COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
50
51 COPY(a16); COPY(a17); COPY(a18); COPY(a19);
52 COPY(a20); COPY(a21); COPY(a22); COPY(a23);
53 COPY(a24); COPY(a25); COPY(a26); COPY(a27);
54 COPY(a28); COPY(a29); COPY(a30); COPY(a31);
55 COPY(b16); COPY(b17); COPY(b18); COPY(b19);
56 COPY(b20); COPY(b21); COPY(b22); COPY(b23);
57 COPY(b24); COPY(b25); COPY(b26); COPY(b27);
58 COPY(b28); COPY(b29); COPY(b30); COPY(b31);
59
60 COPY(csr); COPY(pc);
61
62#undef COPY
63
64 return err;
65}
66
67asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
68{
69 struct rt_sigframe __user *frame;
70 sigset_t set;
71
72 /*
73 * Since we stacked the signal on a dword boundary,
74 * 'sp' should be dword aligned here. If it's
75 * not, then the user is trying to mess with us.
76 */
77 if (regs->sp & 7)
78 goto badframe;
79
80 frame = (struct rt_sigframe __user *) ((unsigned long) regs->sp + 8);
81
82 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
83 goto badframe;
84 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
85 goto badframe;
86
87 sigdelsetmask(&set, ~_BLOCKABLE);
88 spin_lock_irq(&current->sighand->siglock);
89 current->blocked = set;
90 recalc_sigpending();
91 spin_unlock_irq(&current->sighand->siglock);
92
93 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
94 goto badframe;
95
96 return regs->a4;
97
98badframe:
99 force_sig(SIGSEGV, current);
100 return 0;
101}
102
103static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
104 unsigned long mask)
105{
106 int err = 0;
107
108 err |= __put_user(mask, &sc->sc_mask);
109
110 /* The access_ok check was done by caller, so use __put_user here */
111#define COPY(x) (err |= __put_user(regs->x, &sc->sc_##x))
112
113 COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
114 COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
115 COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
116
117 COPY(a16); COPY(a17); COPY(a18); COPY(a19);
118 COPY(a20); COPY(a21); COPY(a22); COPY(a23);
119 COPY(a24); COPY(a25); COPY(a26); COPY(a27);
120 COPY(a28); COPY(a29); COPY(a30); COPY(a31);
121 COPY(b16); COPY(b17); COPY(b18); COPY(b19);
122 COPY(b20); COPY(b21); COPY(b22); COPY(b23);
123 COPY(b24); COPY(b25); COPY(b26); COPY(b27);
124 COPY(b28); COPY(b29); COPY(b30); COPY(b31);
125
126 COPY(csr); COPY(pc);
127
128#undef COPY
129
130 return err;
131}
132
133static inline void __user *get_sigframe(struct k_sigaction *ka,
134 struct pt_regs *regs,
135 unsigned long framesize)
136{
137 unsigned long sp = regs->sp;
138
139 /*
140 * This is the X/Open sanctioned signal stack switching.
141 */
142 if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
143 sp = current->sas_ss_sp + current->sas_ss_size;
144
145 /*
146 * No matter what happens, 'sp' must be dword
147 * aligned. Otherwise, nasty things will happen
148 */
149 return (void __user *)((sp - framesize) & ~7);
150}
151
152static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
153 sigset_t *set, struct pt_regs *regs)
154{
155 struct rt_sigframe __user *frame;
156 unsigned long __user *retcode;
157 int err = 0;
158
159 frame = get_sigframe(ka, regs, sizeof(*frame));
160
161 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
162 goto segv_and_exit;
163
164 err |= __put_user(&frame->info, &frame->pinfo);
165 err |= __put_user(&frame->uc, &frame->puc);
166 err |= copy_siginfo_to_user(&frame->info, info);
167
168 /* Clear all the bits of the ucontext we don't use. */
169 err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
170
171 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
172 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
173
174 /* Set up to return from userspace */
175 retcode = (unsigned long __user *) &frame->retcode;
176
177 /* The access_ok check was done above, so use __put_user here */
178#define COPY(x) (err |= __put_user(x, retcode++))
179
180 COPY(0x0000002AUL | (__NR_rt_sigreturn << 7));
181 /* MVK __NR_rt_sigreturn,B0 */
182 COPY(0x10000000UL); /* SWE */
183 COPY(0x00006000UL); /* NOP 4 */
184 COPY(0x00006000UL); /* NOP 4 */
185 COPY(0x00006000UL); /* NOP 4 */
186 COPY(0x00006000UL); /* NOP 4 */
187 COPY(0x00006000UL); /* NOP 4 */
188 COPY(0x00006000UL); /* NOP 4 */
189 COPY(0x00006000UL); /* NOP 4 */
190
191#undef COPY
192
193 if (err)
194 goto segv_and_exit;
195
196 flush_icache_range((unsigned long) &frame->retcode,
197 (unsigned long) &frame->retcode + RETCODE_SIZE);
198
199 retcode = (unsigned long __user *) &frame->retcode;
200
201 /* Change user context to branch to signal handler */
202 regs->sp = (unsigned long) frame - 8;
203 regs->b3 = (unsigned long) retcode;
204 regs->pc = (unsigned long) ka->sa.sa_handler;
205
206 /* Give the signal number to the handler */
207 regs->a4 = signr;
208
209 /*
210 * For realtime signals we must also set the second and third
211 * arguments for the signal handler.
212 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
213 */
214 regs->b4 = (unsigned long)&frame->info;
215 regs->a6 = (unsigned long)&frame->uc;
216
217 return 0;
218
219segv_and_exit:
220 force_sigsegv(signr, current);
221 return -EFAULT;
222}
223
224static inline void
225handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
226{
227 switch (regs->a4) {
228 case -ERESTARTNOHAND:
229 if (!has_handler)
230 goto do_restart;
231 regs->a4 = -EINTR;
232 break;
233
234 case -ERESTARTSYS:
235 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
236 regs->a4 = -EINTR;
237 break;
238 }
239 /* fallthrough */
240 case -ERESTARTNOINTR:
241do_restart:
242 regs->a4 = regs->orig_a4;
243 regs->pc -= 4;
244 break;
245 }
246}
247
248/*
249 * handle the actual delivery of a signal to userspace
250 */
251static int handle_signal(int sig,
252 siginfo_t *info, struct k_sigaction *ka,
253 sigset_t *oldset, struct pt_regs *regs,
254 int syscall)
255{
256 int ret;
257
258 /* Are we from a system call? */
259 if (syscall) {
260 /* If so, check system call restarting.. */
261 switch (regs->a4) {
262 case -ERESTART_RESTARTBLOCK:
263 case -ERESTARTNOHAND:
264 regs->a4 = -EINTR;
265 break;
266
267 case -ERESTARTSYS:
268 if (!(ka->sa.sa_flags & SA_RESTART)) {
269 regs->a4 = -EINTR;
270 break;
271 }
272
273 /* fallthrough */
274 case -ERESTARTNOINTR:
275 regs->a4 = regs->orig_a4;
276 regs->pc -= 4;
277 }
278 }
279
280 /* Set up the stack frame */
281 ret = setup_rt_frame(sig, ka, info, oldset, regs);
282 if (ret == 0) {
283 spin_lock_irq(&current->sighand->siglock);
284 sigorsets(&current->blocked, &current->blocked,
285 &ka->sa.sa_mask);
286 if (!(ka->sa.sa_flags & SA_NODEFER))
287 sigaddset(&current->blocked, sig);
288 recalc_sigpending();
289 spin_unlock_irq(&current->sighand->siglock);
290 }
291
292 return ret;
293}
294
295/*
296 * handle a potential signal
297 */
298static void do_signal(struct pt_regs *regs, int syscall)
299{
300 struct k_sigaction ka;
301 siginfo_t info;
302 sigset_t *oldset;
303 int signr;
304
305 /* we want the common case to go fast, which is why we may in certain
306 * cases get here from kernel mode */
307 if (!user_mode(regs))
308 return;
309
310 if (test_thread_flag(TIF_RESTORE_SIGMASK))
311 oldset = &current->saved_sigmask;
312 else
313 oldset = &current->blocked;
314
315 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
316 if (signr > 0) {
317 if (handle_signal(signr, &info, &ka, oldset,
318 regs, syscall) == 0) {
319 /* a signal was successfully delivered; the saved
320 * sigmask will have been stored in the signal frame,
321 * and will be restored by sigreturn, so we can simply
322 * clear the TIF_RESTORE_SIGMASK flag */
323 if (test_thread_flag(TIF_RESTORE_SIGMASK))
324 clear_thread_flag(TIF_RESTORE_SIGMASK);
325
326 tracehook_signal_handler(signr, &info, &ka, regs, 0);
327 }
328
329 return;
330 }
331
332 /* did we come from a system call? */
333 if (syscall) {
334 /* restart the system call - no handlers present */
335 switch (regs->a4) {
336 case -ERESTARTNOHAND:
337 case -ERESTARTSYS:
338 case -ERESTARTNOINTR:
339 regs->a4 = regs->orig_a4;
340 regs->pc -= 4;
341 break;
342
343 case -ERESTART_RESTARTBLOCK:
344 regs->a4 = regs->orig_a4;
345 regs->b0 = __NR_restart_syscall;
346 regs->pc -= 4;
347 break;
348 }
349 }
350
351 /* if there's no signal to deliver, we just put the saved sigmask
352 * back */
353 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
354 clear_thread_flag(TIF_RESTORE_SIGMASK);
355 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
356 }
357}
358
359/*
360 * notification of userspace execution resumption
361 * - triggered by current->work.notify_resume
362 */
363asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags,
364 int syscall)
365{
366 /* deal with pending signal delivery */
367 if (thread_info_flags & ((1 << TIF_SIGPENDING) |
368 (1 << TIF_RESTORE_SIGMASK)))
369 do_signal(regs, syscall);
370
371 if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) {
372 clear_thread_flag(TIF_NOTIFY_RESUME);
373 tracehook_notify_resume(regs);
374 if (current->replacement_session_keyring)
375 key_replace_session_keyring();
376 }
377}
diff --git a/arch/c6x/kernel/soc.c b/arch/c6x/kernel/soc.c
new file mode 100644
index 00000000000..dd45bc39af0
--- /dev/null
+++ b/arch/c6x/kernel/soc.c
@@ -0,0 +1,91 @@
1/*
2 * Miscellaneous SoC-specific hooks.
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 * Author: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/ctype.h>
13#include <linux/etherdevice.h>
14#include <asm/system.h>
15#include <asm/setup.h>
16#include <asm/soc.h>
17
18struct soc_ops soc_ops;
19
20int soc_get_exception(void)
21{
22 if (!soc_ops.get_exception)
23 return -1;
24 return soc_ops.get_exception();
25}
26
27void soc_assert_event(unsigned int evt)
28{
29 if (soc_ops.assert_event)
30 soc_ops.assert_event(evt);
31}
32
33static u8 cmdline_mac[6];
34
35static int __init get_mac_addr_from_cmdline(char *str)
36{
37 int count, i, val;
38
39 for (count = 0; count < 6 && *str; count++, str += 3) {
40 if (!isxdigit(str[0]) || !isxdigit(str[1]))
41 return 0;
42 if (str[2] != ((count < 5) ? ':' : '\0'))
43 return 0;
44
45 for (i = 0, val = 0; i < 2; i++) {
46 val = val << 4;
47 val |= isdigit(str[i]) ?
48 str[i] - '0' : toupper(str[i]) - 'A' + 10;
49 }
50 cmdline_mac[count] = val;
51 }
52 return 1;
53}
54__setup("emac_addr=", get_mac_addr_from_cmdline);
55
56/*
57 * Setup the MAC address for SoC ethernet devices.
58 *
59 * Before calling this function, the ethernet driver will have
60 * initialized the addr with local-mac-address from the device
61 * tree (if found). Allow command line to override, but not
62 * the fused address.
63 */
64int soc_mac_addr(unsigned int index, u8 *addr)
65{
66 int i, have_dt_mac = 0, have_cmdline_mac = 0, have_fuse_mac = 0;
67
68 for (i = 0; i < 6; i++) {
69 if (cmdline_mac[i])
70 have_cmdline_mac = 1;
71 if (c6x_fuse_mac[i])
72 have_fuse_mac = 1;
73 if (addr[i])
74 have_dt_mac = 1;
75 }
76
77 /* cmdline overrides all */
78 if (have_cmdline_mac)
79 memcpy(addr, cmdline_mac, 6);
80 else if (!have_dt_mac) {
81 if (have_fuse_mac)
82 memcpy(addr, c6x_fuse_mac, 6);
83 else
84 random_ether_addr(addr);
85 }
86
87 /* adjust for specific EMAC device */
88 addr[5] += index * c6x_num_cores;
89 return 1;
90}
91EXPORT_SYMBOL_GPL(soc_mac_addr);
diff --git a/arch/c6x/kernel/switch_to.S b/arch/c6x/kernel/switch_to.S
new file mode 100644
index 00000000000..09177ed0fa5
--- /dev/null
+++ b/arch/c6x/kernel/switch_to.S
@@ -0,0 +1,74 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter (msalter@redhat.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/linkage.h>
11#include <asm/asm-offsets.h>
12
13#define SP B15
14
15 /*
16 * void __switch_to(struct thread_info *prev,
17 * struct thread_info *next,
18 * struct task_struct *tsk) ;
19 */
20ENTRY(__switch_to)
21 LDDW .D2T2 *+B4(THREAD_B15_14),B7:B6
22 || MV .L2X A4,B5 ; prev
23 || MV .L1X B4,A5 ; next
24 || MVC .S2 RILC,B1
25
26 STW .D2T2 B3,*+B5(THREAD_PC)
27 || STDW .D1T1 A13:A12,*+A4(THREAD_A13_12)
28 || MVC .S2 ILC,B0
29
30 LDW .D2T2 *+B4(THREAD_PC),B3
31 || LDDW .D1T1 *+A5(THREAD_A13_12),A13:A12
32
33 STDW .D1T1 A11:A10,*+A4(THREAD_A11_10)
34 || STDW .D2T2 B1:B0,*+B5(THREAD_RICL_ICL)
35#ifndef __DSBT__
36 || MVKL .S2 current_ksp,B1
37#endif
38
39 STDW .D2T2 B15:B14,*+B5(THREAD_B15_14)
40 || STDW .D1T1 A15:A14,*+A4(THREAD_A15_14)
41#ifndef __DSBT__
42 || MVKH .S2 current_ksp,B1
43#endif
44
45 ;; Switch to next SP
46 MV .S2 B7,SP
47#ifdef __DSBT__
48 || STW .D2T2 B7,*+B14(current_ksp)
49#else
50 || STW .D2T2 B7,*B1
51 || MV .L2 B6,B14
52#endif
53 || LDDW .D1T1 *+A5(THREAD_RICL_ICL),A1:A0
54
55 STDW .D2T2 B11:B10,*+B5(THREAD_B11_10)
56 || LDDW .D1T1 *+A5(THREAD_A15_14),A15:A14
57
58 STDW .D2T2 B13:B12,*+B5(THREAD_B13_12)
59 || LDDW .D1T1 *+A5(THREAD_A11_10),A11:A10
60
61 B .S2 B3 ; return in next E1
62 || LDDW .D2T2 *+B4(THREAD_B13_12),B13:B12
63
64 LDDW .D2T2 *+B4(THREAD_B11_10),B11:B10
65 NOP
66
67 MV .L2X A0,B0
68 || MV .S1 A6,A4
69
70 MVC .S2 B0,ILC
71 || MV .L2X A1,B1
72
73 MVC .S2 B1,RILC
74ENDPROC(__switch_to)
diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c
new file mode 100644
index 00000000000..3e9bdfbee8a
--- /dev/null
+++ b/arch/c6x/kernel/sys_c6x.c
@@ -0,0 +1,74 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/syscalls.h>
13#include <linux/uaccess.h>
14
15#include <asm/syscalls.h>
16
17#ifdef CONFIG_ACCESS_CHECK
18int _access_ok(unsigned long addr, unsigned long size)
19{
20 if (!size)
21 return 1;
22
23 if (!addr || addr > (0xffffffffUL - (size - 1)))
24 goto _bad_access;
25
26 if (segment_eq(get_fs(), KERNEL_DS))
27 return 1;
28
29 if (memory_start <= addr && (addr + size - 1) < memory_end)
30 return 1;
31
32_bad_access:
33 pr_debug("Bad access attempt: pid[%d] addr[%08lx] size[0x%lx]\n",
34 current->pid, addr, size);
35 return 0;
36}
37EXPORT_SYMBOL(_access_ok);
38#endif
39
40/* sys_cache_sync -- sync caches over given range */
41asmlinkage int sys_cache_sync(unsigned long s, unsigned long e)
42{
43 L1D_cache_block_writeback_invalidate(s, e);
44 L1P_cache_block_invalidate(s, e);
45
46 return 0;
47}
48
49/* Provide the actual syscall number to call mapping. */
50#undef __SYSCALL
51#define __SYSCALL(nr, call) [nr] = (call),
52
53/*
54 * Use trampolines
55 */
56#define sys_pread64 sys_pread_c6x
57#define sys_pwrite64 sys_pwrite_c6x
58#define sys_truncate64 sys_truncate64_c6x
59#define sys_ftruncate64 sys_ftruncate64_c6x
60#define sys_fadvise64 sys_fadvise64_c6x
61#define sys_fadvise64_64 sys_fadvise64_64_c6x
62#define sys_fallocate sys_fallocate_c6x
63
64/* Use sys_mmap_pgoff directly */
65#define sys_mmap2 sys_mmap_pgoff
66
67/*
68 * Note that we can't include <linux/unistd.h> here since the header
69 * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
70 */
71void *sys_call_table[__NR_syscalls] = {
72 [0 ... __NR_syscalls-1] = sys_ni_syscall,
73#include <asm/unistd.h>
74};
diff --git a/arch/c6x/kernel/time.c b/arch/c6x/kernel/time.c
new file mode 100644
index 00000000000..4c9f136165f
--- /dev/null
+++ b/arch/c6x/kernel/time.c
@@ -0,0 +1,65 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/clocksource.h>
14#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/param.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/interrupt.h>
20#include <linux/timex.h>
21#include <linux/profile.h>
22
23#include <asm/timer64.h>
24
25static u32 sched_clock_multiplier;
26#define SCHED_CLOCK_SHIFT 16
27
28static cycle_t tsc_read(struct clocksource *cs)
29{
30 return get_cycles();
31}
32
33static struct clocksource clocksource_tsc = {
34 .name = "timestamp",
35 .rating = 300,
36 .read = tsc_read,
37 .mask = CLOCKSOURCE_MASK(64),
38 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
39};
40
41/*
42 * scheduler clock - returns current time in nanoseconds.
43 */
44u64 sched_clock(void)
45{
46 u64 tsc = get_cycles();
47
48 return (tsc * sched_clock_multiplier) >> SCHED_CLOCK_SHIFT;
49}
50
51void time_init(void)
52{
53 u64 tmp = (u64)NSEC_PER_SEC << SCHED_CLOCK_SHIFT;
54
55 do_div(tmp, c6x_core_freq);
56 sched_clock_multiplier = tmp;
57
58 clocksource_register_hz(&clocksource_tsc, c6x_core_freq);
59
60 /* write anything into TSCL to enable counting */
61 set_creg(TSCL, 0);
62
63 /* probe for timer64 event timer */
64 timer64_init();
65}
diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c
new file mode 100644
index 00000000000..f50e3edd6da
--- /dev/null
+++ b/arch/c6x/kernel/traps.c
@@ -0,0 +1,423 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/ptrace.h>
13#include <linux/kallsyms.h>
14#include <linux/bug.h>
15
16#include <asm/soc.h>
17#include <asm/traps.h>
18
19int (*c6x_nmi_handler)(struct pt_regs *regs);
20
21void __init trap_init(void)
22{
23 ack_exception(EXCEPT_TYPE_NXF);
24 ack_exception(EXCEPT_TYPE_EXC);
25 ack_exception(EXCEPT_TYPE_IXF);
26 ack_exception(EXCEPT_TYPE_SXF);
27 enable_exception();
28}
29
30void show_regs(struct pt_regs *regs)
31{
32 pr_err("\n");
33 pr_err("PC: %08lx SP: %08lx\n", regs->pc, regs->sp);
34 pr_err("Status: %08lx ORIG_A4: %08lx\n", regs->csr, regs->orig_a4);
35 pr_err("A0: %08lx B0: %08lx\n", regs->a0, regs->b0);
36 pr_err("A1: %08lx B1: %08lx\n", regs->a1, regs->b1);
37 pr_err("A2: %08lx B2: %08lx\n", regs->a2, regs->b2);
38 pr_err("A3: %08lx B3: %08lx\n", regs->a3, regs->b3);
39 pr_err("A4: %08lx B4: %08lx\n", regs->a4, regs->b4);
40 pr_err("A5: %08lx B5: %08lx\n", regs->a5, regs->b5);
41 pr_err("A6: %08lx B6: %08lx\n", regs->a6, regs->b6);
42 pr_err("A7: %08lx B7: %08lx\n", regs->a7, regs->b7);
43 pr_err("A8: %08lx B8: %08lx\n", regs->a8, regs->b8);
44 pr_err("A9: %08lx B9: %08lx\n", regs->a9, regs->b9);
45 pr_err("A10: %08lx B10: %08lx\n", regs->a10, regs->b10);
46 pr_err("A11: %08lx B11: %08lx\n", regs->a11, regs->b11);
47 pr_err("A12: %08lx B12: %08lx\n", regs->a12, regs->b12);
48 pr_err("A13: %08lx B13: %08lx\n", regs->a13, regs->b13);
49 pr_err("A14: %08lx B14: %08lx\n", regs->a14, regs->dp);
50 pr_err("A15: %08lx B15: %08lx\n", regs->a15, regs->sp);
51 pr_err("A16: %08lx B16: %08lx\n", regs->a16, regs->b16);
52 pr_err("A17: %08lx B17: %08lx\n", regs->a17, regs->b17);
53 pr_err("A18: %08lx B18: %08lx\n", regs->a18, regs->b18);
54 pr_err("A19: %08lx B19: %08lx\n", regs->a19, regs->b19);
55 pr_err("A20: %08lx B20: %08lx\n", regs->a20, regs->b20);
56 pr_err("A21: %08lx B21: %08lx\n", regs->a21, regs->b21);
57 pr_err("A22: %08lx B22: %08lx\n", regs->a22, regs->b22);
58 pr_err("A23: %08lx B23: %08lx\n", regs->a23, regs->b23);
59 pr_err("A24: %08lx B24: %08lx\n", regs->a24, regs->b24);
60 pr_err("A25: %08lx B25: %08lx\n", regs->a25, regs->b25);
61 pr_err("A26: %08lx B26: %08lx\n", regs->a26, regs->b26);
62 pr_err("A27: %08lx B27: %08lx\n", regs->a27, regs->b27);
63 pr_err("A28: %08lx B28: %08lx\n", regs->a28, regs->b28);
64 pr_err("A29: %08lx B29: %08lx\n", regs->a29, regs->b29);
65 pr_err("A30: %08lx B30: %08lx\n", regs->a30, regs->b30);
66 pr_err("A31: %08lx B31: %08lx\n", regs->a31, regs->b31);
67}
68
69void dump_stack(void)
70{
71 unsigned long stack;
72
73 show_stack(current, &stack);
74}
75EXPORT_SYMBOL(dump_stack);
76
77
78void die(char *str, struct pt_regs *fp, int nr)
79{
80 console_verbose();
81 pr_err("%s: %08x\n", str, nr);
82 show_regs(fp);
83
84 pr_err("Process %s (pid: %d, stackpage=%08lx)\n",
85 current->comm, current->pid, (PAGE_SIZE +
86 (unsigned long) current));
87
88 dump_stack();
89 while (1)
90 ;
91}
92
93static void die_if_kernel(char *str, struct pt_regs *fp, int nr)
94{
95 if (user_mode(fp))
96 return;
97
98 die(str, fp, nr);
99}
100
101
102/* Internal exceptions */
103static struct exception_info iexcept_table[10] = {
104 { "Oops - instruction fetch", SIGBUS, BUS_ADRERR },
105 { "Oops - fetch packet", SIGBUS, BUS_ADRERR },
106 { "Oops - execute packet", SIGILL, ILL_ILLOPC },
107 { "Oops - undefined instruction", SIGILL, ILL_ILLOPC },
108 { "Oops - resource conflict", SIGILL, ILL_ILLOPC },
109 { "Oops - resource access", SIGILL, ILL_PRVREG },
110 { "Oops - privilege", SIGILL, ILL_PRVOPC },
111 { "Oops - loops buffer", SIGILL, ILL_ILLOPC },
112 { "Oops - software exception", SIGILL, ILL_ILLTRP },
113 { "Oops - unknown exception", SIGILL, ILL_ILLOPC }
114};
115
116/* External exceptions */
117static struct exception_info eexcept_table[128] = {
118 { "Oops - external exception", SIGBUS, BUS_ADRERR },
119 { "Oops - external exception", SIGBUS, BUS_ADRERR },
120 { "Oops - external exception", SIGBUS, BUS_ADRERR },
121 { "Oops - external exception", SIGBUS, BUS_ADRERR },
122 { "Oops - external exception", SIGBUS, BUS_ADRERR },
123 { "Oops - external exception", SIGBUS, BUS_ADRERR },
124 { "Oops - external exception", SIGBUS, BUS_ADRERR },
125 { "Oops - external exception", SIGBUS, BUS_ADRERR },
126 { "Oops - external exception", SIGBUS, BUS_ADRERR },
127 { "Oops - external exception", SIGBUS, BUS_ADRERR },
128 { "Oops - external exception", SIGBUS, BUS_ADRERR },
129 { "Oops - external exception", SIGBUS, BUS_ADRERR },
130 { "Oops - external exception", SIGBUS, BUS_ADRERR },
131 { "Oops - external exception", SIGBUS, BUS_ADRERR },
132 { "Oops - external exception", SIGBUS, BUS_ADRERR },
133 { "Oops - external exception", SIGBUS, BUS_ADRERR },
134 { "Oops - external exception", SIGBUS, BUS_ADRERR },
135 { "Oops - external exception", SIGBUS, BUS_ADRERR },
136 { "Oops - external exception", SIGBUS, BUS_ADRERR },
137 { "Oops - external exception", SIGBUS, BUS_ADRERR },
138 { "Oops - external exception", SIGBUS, BUS_ADRERR },
139 { "Oops - external exception", SIGBUS, BUS_ADRERR },
140 { "Oops - external exception", SIGBUS, BUS_ADRERR },
141 { "Oops - external exception", SIGBUS, BUS_ADRERR },
142 { "Oops - external exception", SIGBUS, BUS_ADRERR },
143 { "Oops - external exception", SIGBUS, BUS_ADRERR },
144 { "Oops - external exception", SIGBUS, BUS_ADRERR },
145 { "Oops - external exception", SIGBUS, BUS_ADRERR },
146 { "Oops - external exception", SIGBUS, BUS_ADRERR },
147 { "Oops - external exception", SIGBUS, BUS_ADRERR },
148 { "Oops - external exception", SIGBUS, BUS_ADRERR },
149 { "Oops - external exception", SIGBUS, BUS_ADRERR },
150
151 { "Oops - external exception", SIGBUS, BUS_ADRERR },
152 { "Oops - external exception", SIGBUS, BUS_ADRERR },
153 { "Oops - external exception", SIGBUS, BUS_ADRERR },
154 { "Oops - external exception", SIGBUS, BUS_ADRERR },
155 { "Oops - external exception", SIGBUS, BUS_ADRERR },
156 { "Oops - external exception", SIGBUS, BUS_ADRERR },
157 { "Oops - external exception", SIGBUS, BUS_ADRERR },
158 { "Oops - external exception", SIGBUS, BUS_ADRERR },
159 { "Oops - external exception", SIGBUS, BUS_ADRERR },
160 { "Oops - external exception", SIGBUS, BUS_ADRERR },
161 { "Oops - external exception", SIGBUS, BUS_ADRERR },
162 { "Oops - external exception", SIGBUS, BUS_ADRERR },
163 { "Oops - external exception", SIGBUS, BUS_ADRERR },
164 { "Oops - external exception", SIGBUS, BUS_ADRERR },
165 { "Oops - external exception", SIGBUS, BUS_ADRERR },
166 { "Oops - external exception", SIGBUS, BUS_ADRERR },
167 { "Oops - external exception", SIGBUS, BUS_ADRERR },
168 { "Oops - external exception", SIGBUS, BUS_ADRERR },
169 { "Oops - external exception", SIGBUS, BUS_ADRERR },
170 { "Oops - external exception", SIGBUS, BUS_ADRERR },
171 { "Oops - external exception", SIGBUS, BUS_ADRERR },
172 { "Oops - external exception", SIGBUS, BUS_ADRERR },
173 { "Oops - external exception", SIGBUS, BUS_ADRERR },
174 { "Oops - external exception", SIGBUS, BUS_ADRERR },
175 { "Oops - external exception", SIGBUS, BUS_ADRERR },
176 { "Oops - external exception", SIGBUS, BUS_ADRERR },
177 { "Oops - external exception", SIGBUS, BUS_ADRERR },
178 { "Oops - external exception", SIGBUS, BUS_ADRERR },
179 { "Oops - external exception", SIGBUS, BUS_ADRERR },
180 { "Oops - external exception", SIGBUS, BUS_ADRERR },
181 { "Oops - external exception", SIGBUS, BUS_ADRERR },
182 { "Oops - external exception", SIGBUS, BUS_ADRERR },
183
184 { "Oops - external exception", SIGBUS, BUS_ADRERR },
185 { "Oops - external exception", SIGBUS, BUS_ADRERR },
186 { "Oops - external exception", SIGBUS, BUS_ADRERR },
187 { "Oops - external exception", SIGBUS, BUS_ADRERR },
188 { "Oops - external exception", SIGBUS, BUS_ADRERR },
189 { "Oops - external exception", SIGBUS, BUS_ADRERR },
190 { "Oops - external exception", SIGBUS, BUS_ADRERR },
191 { "Oops - external exception", SIGBUS, BUS_ADRERR },
192 { "Oops - external exception", SIGBUS, BUS_ADRERR },
193 { "Oops - external exception", SIGBUS, BUS_ADRERR },
194 { "Oops - external exception", SIGBUS, BUS_ADRERR },
195 { "Oops - external exception", SIGBUS, BUS_ADRERR },
196 { "Oops - external exception", SIGBUS, BUS_ADRERR },
197 { "Oops - external exception", SIGBUS, BUS_ADRERR },
198 { "Oops - external exception", SIGBUS, BUS_ADRERR },
199 { "Oops - external exception", SIGBUS, BUS_ADRERR },
200 { "Oops - external exception", SIGBUS, BUS_ADRERR },
201 { "Oops - external exception", SIGBUS, BUS_ADRERR },
202 { "Oops - external exception", SIGBUS, BUS_ADRERR },
203 { "Oops - external exception", SIGBUS, BUS_ADRERR },
204 { "Oops - external exception", SIGBUS, BUS_ADRERR },
205 { "Oops - external exception", SIGBUS, BUS_ADRERR },
206 { "Oops - external exception", SIGBUS, BUS_ADRERR },
207 { "Oops - external exception", SIGBUS, BUS_ADRERR },
208 { "Oops - external exception", SIGBUS, BUS_ADRERR },
209 { "Oops - external exception", SIGBUS, BUS_ADRERR },
210 { "Oops - external exception", SIGBUS, BUS_ADRERR },
211 { "Oops - external exception", SIGBUS, BUS_ADRERR },
212 { "Oops - external exception", SIGBUS, BUS_ADRERR },
213 { "Oops - external exception", SIGBUS, BUS_ADRERR },
214 { "Oops - external exception", SIGBUS, BUS_ADRERR },
215 { "Oops - external exception", SIGBUS, BUS_ADRERR },
216
217 { "Oops - external exception", SIGBUS, BUS_ADRERR },
218 { "Oops - external exception", SIGBUS, BUS_ADRERR },
219 { "Oops - external exception", SIGBUS, BUS_ADRERR },
220 { "Oops - external exception", SIGBUS, BUS_ADRERR },
221 { "Oops - external exception", SIGBUS, BUS_ADRERR },
222 { "Oops - external exception", SIGBUS, BUS_ADRERR },
223 { "Oops - external exception", SIGBUS, BUS_ADRERR },
224 { "Oops - external exception", SIGBUS, BUS_ADRERR },
225 { "Oops - external exception", SIGBUS, BUS_ADRERR },
226 { "Oops - external exception", SIGBUS, BUS_ADRERR },
227 { "Oops - external exception", SIGBUS, BUS_ADRERR },
228 { "Oops - external exception", SIGBUS, BUS_ADRERR },
229 { "Oops - external exception", SIGBUS, BUS_ADRERR },
230 { "Oops - external exception", SIGBUS, BUS_ADRERR },
231 { "Oops - external exception", SIGBUS, BUS_ADRERR },
232 { "Oops - external exception", SIGBUS, BUS_ADRERR },
233 { "Oops - external exception", SIGBUS, BUS_ADRERR },
234 { "Oops - external exception", SIGBUS, BUS_ADRERR },
235 { "Oops - external exception", SIGBUS, BUS_ADRERR },
236 { "Oops - external exception", SIGBUS, BUS_ADRERR },
237 { "Oops - external exception", SIGBUS, BUS_ADRERR },
238 { "Oops - external exception", SIGBUS, BUS_ADRERR },
239 { "Oops - external exception", SIGBUS, BUS_ADRERR },
240 { "Oops - CPU memory protection fault", SIGSEGV, SEGV_ACCERR },
241 { "Oops - CPU memory protection fault in L1P", SIGSEGV, SEGV_ACCERR },
242 { "Oops - DMA memory protection fault in L1P", SIGSEGV, SEGV_ACCERR },
243 { "Oops - CPU memory protection fault in L1D", SIGSEGV, SEGV_ACCERR },
244 { "Oops - DMA memory protection fault in L1D", SIGSEGV, SEGV_ACCERR },
245 { "Oops - CPU memory protection fault in L2", SIGSEGV, SEGV_ACCERR },
246 { "Oops - DMA memory protection fault in L2", SIGSEGV, SEGV_ACCERR },
247 { "Oops - EMC CPU memory protection fault", SIGSEGV, SEGV_ACCERR },
248 { "Oops - EMC bus error", SIGBUS, BUS_ADRERR }
249};
250
251static void do_trap(struct exception_info *except_info, struct pt_regs *regs)
252{
253 unsigned long addr = instruction_pointer(regs);
254 siginfo_t info;
255
256 if (except_info->code != TRAP_BRKPT)
257 pr_err("TRAP: %s PC[0x%lx] signo[%d] code[%d]\n",
258 except_info->kernel_str, regs->pc,
259 except_info->signo, except_info->code);
260
261 die_if_kernel(except_info->kernel_str, regs, addr);
262
263 info.si_signo = except_info->signo;
264 info.si_errno = 0;
265 info.si_code = except_info->code;
266 info.si_addr = (void __user *)addr;
267
268 force_sig_info(except_info->signo, &info, current);
269}
270
271/*
272 * Process an internal exception (non maskable)
273 */
274static int process_iexcept(struct pt_regs *regs)
275{
276 unsigned int iexcept_report = get_iexcept();
277 unsigned int iexcept_num;
278
279 ack_exception(EXCEPT_TYPE_IXF);
280
281 pr_err("IEXCEPT: PC[0x%lx]\n", regs->pc);
282
283 while (iexcept_report) {
284 iexcept_num = __ffs(iexcept_report);
285 iexcept_report &= ~(1 << iexcept_num);
286 set_iexcept(iexcept_report);
287 if (*(unsigned int *)regs->pc == BKPT_OPCODE) {
288 /* This is a breakpoint */
289 struct exception_info bkpt_exception = {
290 "Oops - undefined instruction",
291 SIGTRAP, TRAP_BRKPT
292 };
293 do_trap(&bkpt_exception, regs);
294 iexcept_report &= ~(0xFF);
295 set_iexcept(iexcept_report);
296 continue;
297 }
298
299 do_trap(&iexcept_table[iexcept_num], regs);
300 }
301 return 0;
302}
303
304/*
305 * Process an external exception (maskable)
306 */
307static void process_eexcept(struct pt_regs *regs)
308{
309 int evt;
310
311 pr_err("EEXCEPT: PC[0x%lx]\n", regs->pc);
312
313 while ((evt = soc_get_exception()) >= 0)
314 do_trap(&eexcept_table[evt], regs);
315
316 ack_exception(EXCEPT_TYPE_EXC);
317}
318
319/*
320 * Main exception processing
321 */
322asmlinkage int process_exception(struct pt_regs *regs)
323{
324 unsigned int type;
325 unsigned int type_num;
326 unsigned int ie_num = 9; /* default is unknown exception */
327
328 while ((type = get_except_type()) != 0) {
329 type_num = fls(type) - 1;
330
331 switch (type_num) {
332 case EXCEPT_TYPE_NXF:
333 ack_exception(EXCEPT_TYPE_NXF);
334 if (c6x_nmi_handler)
335 (c6x_nmi_handler)(regs);
336 else
337 pr_alert("NMI interrupt!\n");
338 break;
339
340 case EXCEPT_TYPE_IXF:
341 if (process_iexcept(regs))
342 return 1;
343 break;
344
345 case EXCEPT_TYPE_EXC:
346 process_eexcept(regs);
347 break;
348
349 case EXCEPT_TYPE_SXF:
350 ie_num = 8;
351 default:
352 ack_exception(type_num);
353 do_trap(&iexcept_table[ie_num], regs);
354 break;
355 }
356 }
357 return 0;
358}
359
360static int kstack_depth_to_print = 48;
361
362static void show_trace(unsigned long *stack, unsigned long *endstack)
363{
364 unsigned long addr;
365 int i;
366
367 pr_debug("Call trace:");
368 i = 0;
369 while (stack + 1 <= endstack) {
370 addr = *stack++;
371 /*
372 * If the address is either in the text segment of the
373 * kernel, or in the region which contains vmalloc'ed
374 * memory, it *may* be the address of a calling
375 * routine; if so, print it so that someone tracing
376 * down the cause of the crash will be able to figure
377 * out the call path that was taken.
378 */
379 if (__kernel_text_address(addr)) {
380#ifndef CONFIG_KALLSYMS
381 if (i % 5 == 0)
382 pr_debug("\n ");
383#endif
384 pr_debug(" [<%08lx>]", addr);
385 print_symbol(" %s\n", addr);
386 i++;
387 }
388 }
389 pr_debug("\n");
390}
391
392void show_stack(struct task_struct *task, unsigned long *stack)
393{
394 unsigned long *p, *endstack;
395 int i;
396
397 if (!stack) {
398 if (task && task != current)
399 /* We know this is a kernel stack,
400 so this is the start/end */
401 stack = (unsigned long *)thread_saved_ksp(task);
402 else
403 stack = (unsigned long *)&stack;
404 }
405 endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1)
406 & -THREAD_SIZE);
407
408 pr_debug("Stack from %08lx:", (unsigned long)stack);
409 for (i = 0, p = stack; i < kstack_depth_to_print; i++) {
410 if (p + 1 > endstack)
411 break;
412 if (i % 8 == 0)
413 pr_cont("\n ");
414 pr_cont(" %08lx", *p++);
415 }
416 pr_cont("\n");
417 show_trace(stack, endstack);
418}
419
420int is_valid_bugaddr(unsigned long addr)
421{
422 return __kernel_text_address(addr);
423}
diff --git a/arch/c6x/kernel/vectors.S b/arch/c6x/kernel/vectors.S
new file mode 100644
index 00000000000..c95c66fc71e
--- /dev/null
+++ b/arch/c6x/kernel/vectors.S
@@ -0,0 +1,81 @@
1;
2; Port on Texas Instruments TMS320C6x architecture
3;
4; Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
5; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6;
7; This program is free software; you can redistribute it and/or modify
8; it under the terms of the GNU General Public License version 2 as
9; published by the Free Software Foundation.
10;
11; This section handles all the interrupt vector routines.
12; At RESET the processor sets up the DRAM timing parameters and
13; branches to the label _c_int00 which handles initialization for the C code.
14;
15
16#define ALIGNMENT 5
17
18 .macro IRQVEC name, handler
19 .align ALIGNMENT
20 .hidden \name
21 .global \name
22\name:
23#ifdef CONFIG_C6X_BIG_KERNEL
24 STW .D2T1 A0,*B15--[2]
25 || MVKL .S1 \handler,A0
26 MVKH .S1 \handler,A0
27 B .S2X A0
28 LDW .D2T1 *++B15[2],A0
29 NOP 4
30 NOP
31 NOP
32 .endm
33#else /* CONFIG_C6X_BIG_KERNEL */
34 B .S2 \handler
35 NOP
36 NOP
37 NOP
38 NOP
39 NOP
40 NOP
41 NOP
42 .endm
43#endif /* CONFIG_C6X_BIG_KERNEL */
44
45 .sect ".vectors","ax"
46 .align ALIGNMENT
47 .global RESET
48 .hidden RESET
49RESET:
50#ifdef CONFIG_C6X_BIG_KERNEL
51 MVKL .S1 _c_int00,A0 ; branch to _c_int00
52 MVKH .S1 _c_int00,A0
53 B .S2X A0
54#else
55 B .S2 _c_int00
56 NOP
57 NOP
58#endif
59 NOP
60 NOP
61 NOP
62 NOP
63 NOP
64
65
66 IRQVEC NMI,_nmi_handler ; NMI interrupt
67 IRQVEC AINT,_bad_interrupt ; reserved
68 IRQVEC MSGINT,_bad_interrupt ; reserved
69
70 IRQVEC INT4,_int4_handler
71 IRQVEC INT5,_int5_handler
72 IRQVEC INT6,_int6_handler
73 IRQVEC INT7,_int7_handler
74 IRQVEC INT8,_int8_handler
75 IRQVEC INT9,_int9_handler
76 IRQVEC INT10,_int10_handler
77 IRQVEC INT11,_int11_handler
78 IRQVEC INT12,_int12_handler
79 IRQVEC INT13,_int13_handler
80 IRQVEC INT14,_int14_handler
81 IRQVEC INT15,_int15_handler
diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
new file mode 100644
index 00000000000..1d81c4c129e
--- /dev/null
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -0,0 +1,162 @@
1/*
2 * ld script for the c6x kernel
3 *
4 * Copyright (C) 2010, 2011 Texas Instruments Incorporated
5 * Mark Salter <msalter@redhat.com>
6 */
7#include <asm-generic/vmlinux.lds.h>
8#include <asm/thread_info.h>
9#include <asm/page.h>
10
11ENTRY(_c_int00)
12
13#if defined(CONFIG_CPU_BIG_ENDIAN)
14jiffies = jiffies_64 + 4;
15#else
16jiffies = jiffies_64;
17#endif
18
19#define READONLY_SEGMENT_START \
20 . = PAGE_OFFSET;
21#define READWRITE_SEGMENT_START \
22 . = ALIGN(128); \
23 _data_lma = .;
24
25SECTIONS
26{
27 /*
28 * Start kernel read only segment
29 */
30 READONLY_SEGMENT_START
31
32 .vectors :
33 {
34 _vectors_start = .;
35 *(.vectors)
36 . = ALIGN(0x400);
37 _vectors_end = .;
38 }
39
40 . = ALIGN(0x1000);
41 .cmdline :
42 {
43 *(.cmdline)
44 }
45
46 /*
47 * This section contains data which may be shared with other
48 * cores. It needs to be a fixed offset from PAGE_OFFSET
49 * regardless of kernel configuration.
50 */
51 .virtio_ipc_dev :
52 {
53 *(.virtio_ipc_dev)
54 }
55
56 . = ALIGN(PAGE_SIZE);
57 .init :
58 {
59 _stext = .;
60 _sinittext = .;
61 HEAD_TEXT
62 INIT_TEXT
63 _einittext = .;
64 }
65
66 __init_begin = _stext;
67 INIT_DATA_SECTION(16)
68
69 PERCPU_SECTION(128)
70
71 . = ALIGN(PAGE_SIZE);
72 __init_end = .;
73
74 .text :
75 {
76 _text = .;
77 TEXT_TEXT
78 SCHED_TEXT
79 LOCK_TEXT
80 IRQENTRY_TEXT
81 KPROBES_TEXT
82 *(.fixup)
83 *(.gnu.warning)
84 }
85
86 EXCEPTION_TABLE(16)
87 NOTES
88
89 RO_DATA_SECTION(PAGE_SIZE)
90 .const :
91 {
92 *(.const .const.* .gnu.linkonce.r.*)
93 *(.switch)
94 }
95
96 . = ALIGN (8) ;
97 __fdt_blob : AT(ADDR(__fdt_blob) - LOAD_OFFSET)
98 {
99 _fdt_start = . ; /* place for fdt blob */
100 *(__fdt_blob) ; /* Any link-placed DTB */
101 BYTE(0); /* section always has contents */
102 . = _fdt_start + 0x4000; /* Pad up to 16kbyte */
103 _fdt_end = . ;
104 }
105
106 _etext = .;
107
108 /*
109 * Start kernel read-write segment.
110 */
111 READWRITE_SEGMENT_START
112 _sdata = .;
113
114 .fardata : AT(ADDR(.fardata) - LOAD_OFFSET)
115 {
116 INIT_TASK_DATA(THREAD_SIZE)
117 NOSAVE_DATA
118 PAGE_ALIGNED_DATA(PAGE_SIZE)
119 CACHELINE_ALIGNED_DATA(128)
120 READ_MOSTLY_DATA(128)
121 DATA_DATA
122 CONSTRUCTORS
123 *(.data1)
124 *(.fardata .fardata.*)
125 *(.data.debug_bpt)
126 }
127
128 .neardata ALIGN(8) : AT(ADDR(.neardata) - LOAD_OFFSET)
129 {
130 *(.neardata2 .neardata2.* .gnu.linkonce.s2.*)
131 *(.neardata .neardata.* .gnu.linkonce.s.*)
132 . = ALIGN(8);
133 }
134
135 _edata = .;
136
137 __bss_start = .;
138 SBSS(8)
139 BSS(8)
140 .far :
141 {
142 . = ALIGN(8);
143 *(.dynfar)
144 *(.far .far.* .gnu.linkonce.b.*)
145 . = ALIGN(8);
146 }
147 __bss_stop = .;
148
149 _end = .;
150
151 DWARF_DEBUG
152
153 /DISCARD/ :
154 {
155 EXIT_TEXT
156 EXIT_DATA
157 EXIT_CALL
158 *(.discard)
159 *(.discard.*)
160 *(.interp)
161 }
162}
diff --git a/arch/c6x/lib/Makefile b/arch/c6x/lib/Makefile
new file mode 100644
index 00000000000..ffd3c659091
--- /dev/null
+++ b/arch/c6x/lib/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for arch/c6x/lib/
3#
4
5lib-y := divu.o divi.o pop_rts.o push_rts.o remi.o remu.o strasgi.o llshru.o
6lib-y += llshr.o llshl.o negll.o mpyll.o divremi.o divremu.o
7lib-y += checksum.o csum_64plus.o memcpy_64plus.o strasgi_64plus.o
diff --git a/arch/c6x/lib/checksum.c b/arch/c6x/lib/checksum.c
new file mode 100644
index 00000000000..67cc93b0b93
--- /dev/null
+++ b/arch/c6x/lib/checksum.c
@@ -0,0 +1,36 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version
5 * 2 of the License, or (at your option) any later version.
6 */
7#include <linux/module.h>
8#include <net/checksum.h>
9
10#include <asm/byteorder.h>
11
12/*
13 * copy from fs while checksumming, otherwise like csum_partial
14 */
15__wsum
16csum_partial_copy_from_user(const void __user *src, void *dst, int len,
17 __wsum sum, int *csum_err)
18{
19 int missing;
20
21 missing = __copy_from_user(dst, src, len);
22 if (missing) {
23 memset(dst + len - missing, 0, missing);
24 *csum_err = -EFAULT;
25 } else
26 *csum_err = 0;
27
28 return csum_partial(dst, len, sum);
29}
30EXPORT_SYMBOL(csum_partial_copy_from_user);
31
32/* These are from csum_64plus.S */
33EXPORT_SYMBOL(csum_partial);
34EXPORT_SYMBOL(csum_partial_copy);
35EXPORT_SYMBOL(ip_compute_csum);
36EXPORT_SYMBOL(ip_fast_csum);
diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S
new file mode 100644
index 00000000000..6d258964722
--- /dev/null
+++ b/arch/c6x/lib/csum_64plus.S
@@ -0,0 +1,419 @@
1;
2; linux/arch/c6x/lib/csum_64plus.s
3;
4; Port on Texas Instruments TMS320C6x architecture
5;
6; Copyright (C) 2006, 2009, 2010, 2011 Texas Instruments Incorporated
7; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
8;
9; This program is free software; you can redistribute it and/or modify
10; it under the terms of the GNU General Public License version 2 as
11; published by the Free Software Foundation.
12;
13#include <linux/linkage.h>
14
15;
16;unsigned int csum_partial_copy(const char *src, char * dst,
17; int len, int sum)
18;
19; A4: src
20; B4: dst
21; A6: len
22; B6: sum
23; return csum in A4
24;
25
26 .text
27ENTRY(csum_partial_copy)
28 MVC .S2 ILC,B30
29
30 MV .D1X B6,A31 ; given csum
31 ZERO .D1 A9 ; csum (a side)
32|| ZERO .D2 B9 ; csum (b side)
33|| SHRU .S2X A6,2,B5 ; len / 4
34
35 ;; Check alignment and size
36 AND .S1 3,A4,A1
37|| AND .S2 3,B4,B0
38 OR .L2X B0,A1,B0 ; non aligned condition
39|| MVC .S2 B5,ILC
40|| MVK .D2 1,B2
41|| MV .D1X B5,A1 ; words condition
42 [!A1] B .S1 L8
43 [B0] BNOP .S1 L6,5
44
45 SPLOOP 1
46
47 ;; Main loop for aligned words
48 LDW .D1T1 *A4++,A7
49 NOP 4
50 MV .S2X A7,B7
51|| EXTU .S1 A7,0,16,A16
52 STW .D2T2 B7,*B4++
53|| MPYU .M2 B7,B2,B8
54|| ADD .L1 A16,A9,A9
55 NOP
56 SPKERNEL 8,0
57|| ADD .L2 B8,B9,B9
58
59 ZERO .D1 A1
60|| ADD .L1X A9,B9,A9 ; add csum from a and b sides
61
62L6:
63 [!A1] BNOP .S1 L8,5
64
65 ;; Main loop for non-aligned words
66 SPLOOP 2
67 || MVK .L1 1,A2
68
69 LDNW .D1T1 *A4++,A7
70 NOP 3
71
72 NOP
73 MV .S2X A7,B7
74 || EXTU .S1 A7,0,16,A16
75 || MPYU .M1 A7,A2,A8
76
77 ADD .L1 A16,A9,A9
78 SPKERNEL 6,0
79 || STNW .D2T2 B7,*B4++
80 || ADD .L1 A8,A9,A9
81
82L8: AND .S2X 2,A6,B5
83 CMPGT .L2 B5,0,B0
84 [!B0] BNOP .S1 L82,4
85
86 ;; Manage half-word
87 ZERO .L1 A7
88|| ZERO .D1 A8
89
90#ifdef CONFIG_CPU_BIG_ENDIAN
91
92 LDBU .D1T1 *A4++,A7
93 LDBU .D1T1 *A4++,A8
94 NOP 3
95 SHL .S1 A7,8,A0
96 ADD .S1 A8,A9,A9
97 STB .D2T1 A7,*B4++
98|| ADD .S1 A0,A9,A9
99 STB .D2T1 A8,*B4++
100
101#else
102
103 LDBU .D1T1 *A4++,A7
104 LDBU .D1T1 *A4++,A8
105 NOP 3
106 ADD .S1 A7,A9,A9
107 SHL .S1 A8,8,A0
108
109 STB .D2T1 A7,*B4++
110|| ADD .S1 A0,A9,A9
111 STB .D2T1 A8,*B4++
112
113#endif
114
115 ;; Manage eventually the last byte
116L82: AND .S2X 1,A6,B0
117 [!B0] BNOP .S1 L9,5
118
119|| ZERO .L1 A7
120
121L83: LDBU .D1T1 *A4++,A7
122 NOP 4
123
124 MV .L2X A7,B7
125
126#ifdef CONFIG_CPU_BIG_ENDIAN
127
128 STB .D2T2 B7,*B4++
129|| SHL .S1 A7,8,A7
130 ADD .S1 A7,A9,A9
131
132#else
133
134 STB .D2T2 B7,*B4++
135|| ADD .S1 A7,A9,A9
136
137#endif
138
139 ;; Fold the csum
140L9: SHRU .S2X A9,16,B0
141 [!B0] BNOP .S1 L10,5
142
143L91: SHRU .S2X A9,16,B4
144|| EXTU .S1 A9,16,16,A3
145 ADD .D1X A3,B4,A9
146
147 SHRU .S1 A9,16,A0
148 [A0] BNOP .S1 L91,5
149
150L10: ADD .D1 A31,A9,A9
151 MV .D1 A9,A4
152
153 BNOP .S2 B3,4
154 MVC .S2 B30,ILC
155ENDPROC(csum_partial_copy)
156
157;
158;unsigned short
159;ip_fast_csum(unsigned char *iph, unsigned int ihl)
160;{
161; unsigned int checksum = 0;
162; unsigned short *tosum = (unsigned short *) iph;
163; int len;
164;
165; len = ihl*4;
166;
167; if (len <= 0)
168; return 0;
169;
170; while(len) {
171; len -= 2;
172; checksum += *tosum++;
173; }
174; if (len & 1)
175; checksum += *(unsigned char*) tosum;
176;
177; while(checksum >> 16)
178; checksum = (checksum & 0xffff) + (checksum >> 16);
179;
180; return ~checksum;
181;}
182;
183; A4: iph
184; B4: ihl
185; return checksum in A4
186;
187 .text
188
189ENTRY(ip_fast_csum)
190 ZERO .D1 A5
191 || MVC .S2 ILC,B30
192 SHL .S2 B4,2,B0
193 CMPGT .L2 B0,0,B1
194 [!B1] BNOP .S1 L15,4
195 [!B1] ZERO .D1 A3
196
197 [!B0] B .S1 L12
198 SHRU .S2 B0,1,B0
199 MVC .S2 B0,ILC
200 NOP 3
201
202 SPLOOP 1
203 LDHU .D1T1 *A4++,A3
204 NOP 3
205 NOP
206 SPKERNEL 5,0
207 || ADD .L1 A3,A5,A5
208
209L12: SHRU .S1 A5,16,A0
210 [!A0] BNOP .S1 L14,5
211
212L13: SHRU .S2X A5,16,B4
213 EXTU .S1 A5,16,16,A3
214 ADD .D1X A3,B4,A5
215 SHRU .S1 A5,16,A0
216 [A0] BNOP .S1 L13,5
217
218L14: NOT .D1 A5,A3
219 EXTU .S1 A3,16,16,A3
220
221L15: BNOP .S2 B3,3
222 MVC .S2 B30,ILC
223 MV .D1 A3,A4
224ENDPROC(ip_fast_csum)
225
226;
227;unsigned short
228;do_csum(unsigned char *buff, unsigned int len)
229;{
230; int odd, count;
231; unsigned int result = 0;
232;
233; if (len <= 0)
234; goto out;
235; odd = 1 & (unsigned long) buff;
236; if (odd) {
237;#ifdef __LITTLE_ENDIAN
238; result += (*buff << 8);
239;#else
240; result = *buff;
241;#endif
242; len--;
243; buff++;
244; }
245; count = len >> 1; /* nr of 16-bit words.. */
246; if (count) {
247; if (2 & (unsigned long) buff) {
248; result += *(unsigned short *) buff;
249; count--;
250; len -= 2;
251; buff += 2;
252; }
253; count >>= 1; /* nr of 32-bit words.. */
254; if (count) {
255; unsigned int carry = 0;
256; do {
257; unsigned int w = *(unsigned int *) buff;
258; count--;
259; buff += 4;
260; result += carry;
261; result += w;
262; carry = (w > result);
263; } while (count);
264; result += carry;
265; result = (result & 0xffff) + (result >> 16);
266; }
267; if (len & 2) {
268; result += *(unsigned short *) buff;
269; buff += 2;
270; }
271; }
272; if (len & 1)
273;#ifdef __LITTLE_ENDIAN
274; result += *buff;
275;#else
276; result += (*buff << 8);
277;#endif
278; result = (result & 0xffff) + (result >> 16);
279; /* add up carry.. */
280; result = (result & 0xffff) + (result >> 16);
281; if (odd)
282; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
283;out:
284; return result;
285;}
286;
287; A4: buff
288; B4: len
289; return checksum in A4
290;
291
292ENTRY(do_csum)
293 CMPGT .L2 B4,0,B0
294 [!B0] BNOP .S1 L26,3
295 EXTU .S1 A4,31,31,A0
296
297 MV .L1 A0,A3
298|| MV .S1X B3,A5
299|| MV .L2 B4,B3
300|| ZERO .D1 A1
301
302#ifdef CONFIG_CPU_BIG_ENDIAN
303 [A0] SUB .L2 B3,1,B3
304|| [A0] LDBU .D1T1 *A4++,A1
305#else
306 [!A0] BNOP .S1 L21,5
307|| [A0] LDBU .D1T1 *A4++,A0
308 SUB .L2 B3,1,B3
309|| SHL .S1 A0,8,A1
310L21:
311#endif
312 SHR .S2 B3,1,B0
313 [!B0] BNOP .S1 L24,3
314 MVK .L1 2,A0
315 AND .L1 A4,A0,A0
316
317 [!A0] BNOP .S1 L22,5
318|| [A0] LDHU .D1T1 *A4++,A0
319 SUB .L2 B0,1,B0
320|| SUB .S2 B3,2,B3
321|| ADD .L1 A0,A1,A1
322L22:
323 SHR .S2 B0,1,B0
324|| ZERO .L1 A0
325
326 [!B0] BNOP .S1 L23,5
327|| [B0] MVC .S2 B0,ILC
328
329 SPLOOP 3
330 SPMASK L1
331|| MV .L1 A1,A2
332|| LDW .D1T1 *A4++,A1
333
334 NOP 4
335 ADD .L1 A0,A1,A0
336 ADD .L1 A2,A0,A2
337
338 SPKERNEL 1,2
339|| CMPGTU .L1 A1,A2,A0
340
341 ADD .L1 A0,A2,A6
342 EXTU .S1 A6,16,16,A7
343 SHRU .S2X A6,16,B0
344 NOP 1
345 ADD .L1X A7,B0,A1
346L23:
347 MVK .L2 2,B0
348 AND .L2 B3,B0,B0
349 [B0] LDHU .D1T1 *A4++,A0
350 NOP 4
351 [B0] ADD .L1 A0,A1,A1
352L24:
353 EXTU .S2 B3,31,31,B0
354#ifdef CONFIG_CPU_BIG_ENDIAN
355 [!B0] BNOP .S1 L25,4
356|| [B0] LDBU .D1T1 *A4,A0
357 SHL .S1 A0,8,A0
358 ADD .L1 A0,A1,A1
359L25:
360#else
361 [B0] LDBU .D1T1 *A4,A0
362 NOP 4
363 [B0] ADD .L1 A0,A1,A1
364#endif
365 EXTU .S1 A1,16,16,A0
366 SHRU .S2X A1,16,B0
367 NOP 1
368 ADD .L1X A0,B0,A0
369 SHRU .S1 A0,16,A1
370 ADD .L1 A0,A1,A0
371 EXTU .S1 A0,16,16,A1
372 EXTU .S1 A1,16,24,A2
373
374 EXTU .S1 A1,24,16,A0
375|| MV .L2X A3,B0
376
377 [B0] OR .L1 A0,A2,A1
378L26:
379 NOP 1
380 BNOP .S2X A5,4
381 MV .L1 A1,A4
382ENDPROC(do_csum)
383
384;__wsum csum_partial(const void *buff, int len, __wsum wsum)
385;{
386; unsigned int sum = (__force unsigned int)wsum;
387; unsigned int result = do_csum(buff, len);
388;
389; /* add in old sum, and carry.. */
390; result += sum;
391; if (sum > result)
392; result += 1;
393; return (__force __wsum)result;
394;}
395;
396ENTRY(csum_partial)
397 MV .L1X B3,A9
398|| CALLP .S2 do_csum,B3
399|| MV .S1 A6,A8
400 BNOP .S2X A9,2
401 ADD .L1 A8,A4,A1
402 CMPGTU .L1 A8,A1,A0
403 ADD .L1 A1,A0,A4
404ENDPROC(csum_partial)
405
406;unsigned short
407;ip_compute_csum(unsigned char *buff, unsigned int len)
408;
409; A4: buff
410; B4: len
411; return checksum in A4
412
413ENTRY(ip_compute_csum)
414 MV .L1X B3,A9
415|| CALLP .S2 do_csum,B3
416 BNOP .S2X A9,3
417 NOT .S1 A4,A4
418 CLR .S1 A4,16,31,A4
419ENDPROC(ip_compute_csum)
diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S
new file mode 100644
index 00000000000..4bde924f2a9
--- /dev/null
+++ b/arch/c6x/lib/divi.S
@@ -0,0 +1,53 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38ENTRY(__c6xabi_divi)
39 call .s2 __c6xabi_divu
40|| mv .d2 B3, B5
41|| cmpgt .l1 0, A4, A1
42|| cmpgt .l2 0, B4, B1
43
44 [A1] neg .l1 A4, A4
45|| [B1] neg .l2 B4, B4
46|| xor .s1x A1, B1, A1
47 [A1] addkpc .s2 _divu_ret, B3, 4
48_divu_ret:
49 neg .l1 A4, A4
50|| mv .l2 B3,B5
51|| ret .s2 B5
52 nop 5
53ENDPROC(__c6xabi_divi)
diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S
new file mode 100644
index 00000000000..64bc5aa95ad
--- /dev/null
+++ b/arch/c6x/lib/divremi.S
@@ -0,0 +1,46 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21ENTRY(__c6xabi_divremi)
22 stw .d2t2 B3, *B15--[2]
23|| cmpgt .l1 0, A4, A1
24|| cmpgt .l2 0, B4, B2
25|| mv .s1 A4, A5
26|| call .s2 __c6xabi_divu
27
28 [A1] neg .l1 A4, A4
29|| [B2] neg .l2 B4, B4
30|| xor .s2x B2, A1, B0
31|| mv .d2 B4, B2
32
33 [B0] addkpc .s2 _divu_ret_1, B3, 1
34 [!B0] addkpc .s2 _divu_ret_2, B3, 1
35 nop 2
36_divu_ret_1:
37 neg .l1 A4, A4
38_divu_ret_2:
39 ldw .d2t2 *++B15[2], B3
40
41 mpy32 .m1x A4, B2, A6
42 nop 3
43 ret .s2 B3
44 sub .l1 A5, A6, A5
45 nop 4
46ENDPROC(__c6xabi_divremi)
diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S
new file mode 100644
index 00000000000..caa9f23ee16
--- /dev/null
+++ b/arch/c6x/lib/divremu.S
@@ -0,0 +1,87 @@
1;; Copyright 2011 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21ENTRY(__c6xabi_divremu)
22 ;; We use a series of up to 31 subc instructions. First, we find
23 ;; out how many leading zero bits there are in the divisor. This
24 ;; gives us both a shift count for aligning (shifting) the divisor
25 ;; to the, and the number of times we have to execute subc.
26
27 ;; At the end, we have both the remainder and most of the quotient
28 ;; in A4. The top bit of the quotient is computed first and is
29 ;; placed in A2.
30
31 ;; Return immediately if the dividend is zero. Setting B4 to 1
32 ;; is a trick to allow us to leave the following insns in the jump
33 ;; delay slot without affecting the result.
34 mv .s2x A4, B1
35
36 [b1] lmbd .l2 1, B4, B1
37||[!b1] b .s2 B3 ; RETURN A
38||[!b1] mvk .d2 1, B4
39
40||[!b1] zero .s1 A5
41 mv .l1x B1, A6
42|| shl .s2 B4, B1, B4
43
44 ;; The loop performs a maximum of 28 steps, so we do the
45 ;; first 3 here.
46 cmpltu .l1x A4, B4, A2
47 [!A2] sub .l1x A4, B4, A4
48|| shru .s2 B4, 1, B4
49|| xor .s1 1, A2, A2
50
51 shl .s1 A2, 31, A2
52|| [b1] subc .l1x A4,B4,A4
53|| [b1] add .s2 -1, B1, B1
54 [b1] subc .l1x A4,B4,A4
55|| [b1] add .s2 -1, B1, B1
56
57 ;; RETURN A may happen here (note: must happen before the next branch)
58__divremu0:
59 cmpgt .l2 B1, 7, B0
60|| [b1] subc .l1x A4,B4,A4
61|| [b1] add .s2 -1, B1, B1
62 [b1] subc .l1x A4,B4,A4
63|| [b1] add .s2 -1, B1, B1
64|| [b0] b .s1 __divremu0
65 [b1] subc .l1x A4,B4,A4
66|| [b1] add .s2 -1, B1, B1
67 [b1] subc .l1x A4,B4,A4
68|| [b1] add .s2 -1, B1, B1
69 [b1] subc .l1x A4,B4,A4
70|| [b1] add .s2 -1, B1, B1
71 [b1] subc .l1x A4,B4,A4
72|| [b1] add .s2 -1, B1, B1
73 [b1] subc .l1x A4,B4,A4
74|| [b1] add .s2 -1, B1, B1
75 ;; loop backwards branch happens here
76
77 ret .s2 B3
78|| mvk .s1 32, A1
79 sub .l1 A1, A6, A6
80|| extu .s1 A4, A6, A5
81 shl .s1 A4, A6, A4
82 shru .s1 A4, 1, A4
83|| sub .l1 A6, 1, A6
84 or .l1 A2, A4, A4
85 shru .s1 A4, A6, A4
86 nop
87ENDPROC(__c6xabi_divremu)
diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S
new file mode 100644
index 00000000000..64af3c006dd
--- /dev/null
+++ b/arch/c6x/lib/divu.S
@@ -0,0 +1,98 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38ENTRY(__c6xabi_divu)
39 ;; We use a series of up to 31 subc instructions. First, we find
40 ;; out how many leading zero bits there are in the divisor. This
41 ;; gives us both a shift count for aligning (shifting) the divisor
42 ;; to the, and the number of times we have to execute subc.
43
44 ;; At the end, we have both the remainder and most of the quotient
45 ;; in A4. The top bit of the quotient is computed first and is
46 ;; placed in A2.
47
48 ;; Return immediately if the dividend is zero.
49 mv .s2x A4, B1
50 [B1] lmbd .l2 1, B4, B1
51|| [!B1] b .s2 B3 ; RETURN A
52|| [!B1] mvk .d2 1, B4
53 mv .l1x B1, A6
54|| shl .s2 B4, B1, B4
55
56 ;; The loop performs a maximum of 28 steps, so we do the
57 ;; first 3 here.
58 cmpltu .l1x A4, B4, A2
59 [!A2] sub .l1x A4, B4, A4
60|| shru .s2 B4, 1, B4
61|| xor .s1 1, A2, A2
62
63 shl .s1 A2, 31, A2
64|| [B1] subc .l1x A4,B4,A4
65|| [B1] add .s2 -1, B1, B1
66 [B1] subc .l1x A4,B4,A4
67|| [B1] add .s2 -1, B1, B1
68
69 ;; RETURN A may happen here (note: must happen before the next branch)
70_divu_loop:
71 cmpgt .l2 B1, 7, B0
72|| [B1] subc .l1x A4,B4,A4
73|| [B1] add .s2 -1, B1, B1
74 [B1] subc .l1x A4,B4,A4
75|| [B1] add .s2 -1, B1, B1
76|| [B0] b .s1 _divu_loop
77 [B1] subc .l1x A4,B4,A4
78|| [B1] add .s2 -1, B1, B1
79 [B1] subc .l1x A4,B4,A4
80|| [B1] add .s2 -1, B1, B1
81 [B1] subc .l1x A4,B4,A4
82|| [B1] add .s2 -1, B1, B1
83 [B1] subc .l1x A4,B4,A4
84|| [B1] add .s2 -1, B1, B1
85 [B1] subc .l1x A4,B4,A4
86|| [B1] add .s2 -1, B1, B1
87 ;; loop backwards branch happens here
88
89 ret .s2 B3
90|| mvk .s1 32, A1
91 sub .l1 A1, A6, A6
92 shl .s1 A4, A6, A4
93 shru .s1 A4, 1, A4
94|| sub .l1 A6, 1, A6
95 or .l1 A2, A4, A4
96 shru .s1 A4, A6, A4
97 nop
98ENDPROC(__c6xabi_divu)
diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S
new file mode 100644
index 00000000000..7b105e2d1b7
--- /dev/null
+++ b/arch/c6x/lib/llshl.S
@@ -0,0 +1,37 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshl(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshl)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; just return if zero shift
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shru .s1 A4,A0,A0
30 [!A2] neg .l1 A0,A5
31|| [A2] shl .s1 A5,A1,A5
32 [!A2] shl .s1 A4,A5,A5
33|| [A2] or .d1 A5,A0,A5
34|| [!A2] mvk .l1 0,A4
35 [A2] shl .s1 A4,A1,A4
36 bnop .s2 B3,5
37ENDPROC(__c6xabi_llshl)
diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S
new file mode 100644
index 00000000000..fde1bec7cf5
--- /dev/null
+++ b/arch/c6x/lib/llshr.S
@@ -0,0 +1,38 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshr(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshr)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; return if zero shift count
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shl .s1 A5,A0,A0
30 nop
31 [!A2] neg .l1 A0,A4
32|| [A2] shru .s1 A4,A1,A4
33 [!A2] shr .s1 A5,A4,A4
34|| [A2] or .d1 A4,A0,A4
35 [!A2] shr .s1 A5,0x1f,A5
36 [A2] shr .s1 A5,A1,A5
37 bnop .s2 B3,5
38ENDPROC(__c6xabi_llshr)
diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S
new file mode 100644
index 00000000000..596ae3ff5c0
--- /dev/null
+++ b/arch/c6x/lib/llshru.S
@@ -0,0 +1,38 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; uint64_t __c6xabi_llshru(uint64_t val, uint shift)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_llshru)
24 mv .l1x B4,A1
25 [!A1] b .s2 B3 ; return if zero shift count
26 mvk .s1 32,A0
27 sub .d1 A0,A1,A0
28 cmplt .l1 0,A0,A2
29 [A2] shl .s1 A5,A0,A0
30 nop
31 [!A2] neg .l1 A0,A4
32|| [A2] shru .s1 A4,A1,A4
33 [!A2] shru .s1 A5,A4,A4
34|| [A2] or .d1 A4,A0,A4
35|| [!A2] mvk .l1 0,A5
36 [A2] shru .s1 A5,A1,A5
37 bnop .s2 B3,5
38ENDPROC(__c6xabi_llshru)
diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S
new file mode 100644
index 00000000000..0bbc2cbf931
--- /dev/null
+++ b/arch/c6x/lib/memcpy_64plus.S
@@ -0,0 +1,46 @@
1; Port on Texas Instruments TMS320C6x architecture
2;
3; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
4; Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
5;
6; This program is free software; you can redistribute it and/or modify
7; it under the terms of the GNU General Public License version 2 as
8; published by the Free Software Foundation.
9;
10
11#include <linux/linkage.h>
12
13 .text
14
15ENTRY(memcpy)
16 AND .L1 0x1,A6,A0
17 || AND .S1 0x2,A6,A1
18 || AND .L2X 0x4,A6,B0
19 || MV .D1 A4,A3
20 || MVC .S2 ILC,B2
21
22 [A0] LDB .D2T1 *B4++,A5
23 [A1] LDB .D2T1 *B4++,A7
24 [A1] LDB .D2T1 *B4++,A8
25 [B0] LDNW .D2T1 *B4++,A9
26 || SHRU .S2X A6,0x3,B1
27 [!B1] BNOP .S2 B3,1
28
29 [A0] STB .D1T1 A5,*A3++
30 ||[B1] MVC .S2 B1,ILC
31 [A1] STB .D1T1 A7,*A3++
32 [A1] STB .D1T1 A8,*A3++
33 [B0] STNW .D1T1 A9,*A3++ ; return when len < 8
34
35 SPLOOP 2
36
37 LDNDW .D2T1 *B4++,A9:A8
38 NOP 3
39
40 NOP
41 SPKERNEL 0,0
42 || STNDW .D1T1 A9:A8,*A3++
43
44 BNOP .S2 B3,4
45 MVC .S2 B2,ILC
46ENDPROC(memcpy)
diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S
new file mode 100644
index 00000000000..f1034418b4d
--- /dev/null
+++ b/arch/c6x/lib/mpyll.S
@@ -0,0 +1,49 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y)
21 ;;
22 ;; 64x64 multiply
23 ;; First compute partial results using 32-bit parts of x and y:
24 ;;
25 ;; b63 b32 b31 b0
26 ;; -----------------------------
27 ;; | 1 | 0 |
28 ;; -----------------------------
29 ;;
30 ;; P0 = X0*Y0
31 ;; P1 = X0*Y1 + X1*Y0
32 ;; P2 = X1*Y1
33 ;;
34 ;; result = (P2 << 64) + (P1 << 32) + P0
35 ;;
36 ;; Since the result is also 64-bit, we can skip the P2 term.
37
38 .text
39ENTRY(__c6xabi_mpyll)
40 mpy32u .m1x A4,B4,A1:A0 ; X0*Y0
41 b .s2 B3
42 || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits)
43 || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits)
44 nop
45 nop
46 mv .s1 A0,A4
47 add .l1x A2,B0,A5
48 add .s1 A1,A5,A5
49ENDPROC(__c6xabi_mpyll)
diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S
new file mode 100644
index 00000000000..82f4bcec9af
--- /dev/null
+++ b/arch/c6x/lib/negll.S
@@ -0,0 +1,31 @@
1;; Copyright (C) 2010 Texas Instruments Incorporated
2;; Contributed by Mark Salter <msalter@redhat.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18;; int64_t __c6xabi_negll(int64_t val)
19
20#include <linux/linkage.h>
21
22 .text
23ENTRY(__c6xabi_negll)
24 b .s2 B3
25 mvk .l1 0,A0
26 subu .l1 A0,A4,A3:A2
27 sub .l1 A0,A5,A0
28|| ext .s1 A3,24,24,A5
29 add .l1 A5,A0,A5
30 mv .s1 A2,A4
31ENDPROC(__c6xabi_negll)
diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S
new file mode 100644
index 00000000000..d7d96c70e9e
--- /dev/null
+++ b/arch/c6x/lib/pop_rts.S
@@ -0,0 +1,32 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_pop_rts)
23 lddw .d2t2 *++B15, B3:B2
24 lddw .d2t1 *++B15, A11:A10
25 lddw .d2t2 *++B15, B11:B10
26 lddw .d2t1 *++B15, A13:A12
27 lddw .d2t2 *++B15, B13:B12
28 lddw .d2t1 *++B15, A15:A14
29|| b .s2 B3
30 ldw .d2t2 *++B15[2], B14
31 nop 4
32ENDPROC(__c6xabi_pop_rts)
diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S
new file mode 100644
index 00000000000..f6e3db3b606
--- /dev/null
+++ b/arch/c6x/lib/push_rts.S
@@ -0,0 +1,31 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_push_rts)
23 stw .d2t2 B14, *B15--[2]
24 stdw .d2t1 A15:A14, *B15--
25|| b .s2x A3
26 stdw .d2t2 B13:B12, *B15--
27 stdw .d2t1 A13:A12, *B15--
28 stdw .d2t2 B11:B10, *B15--
29 stdw .d2t1 A11:A10, *B15--
30 stdw .d2t2 B3:B2, *B15--
31ENDPROC(__c6xabi_push_rts)
diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S
new file mode 100644
index 00000000000..6f2ca18c3f9
--- /dev/null
+++ b/arch/c6x/lib/remi.S
@@ -0,0 +1,64 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37 .text
38
39ENTRY(__c6xabi_remi)
40 stw .d2t2 B3, *B15--[2]
41|| cmpgt .l1 0, A4, A1
42|| cmpgt .l2 0, B4, B2
43|| mv .s1 A4, A5
44|| call .s2 __c6xabi_divu
45
46 [A1] neg .l1 A4, A4
47|| [B2] neg .l2 B4, B4
48|| xor .s2x B2, A1, B0
49|| mv .d2 B4, B2
50
51 [B0] addkpc .s2 _divu_ret_1, B3, 1
52 [!B0] addkpc .s2 _divu_ret_2, B3, 1
53 nop 2
54_divu_ret_1:
55 neg .l1 A4, A4
56_divu_ret_2:
57 ldw .d2t2 *++B15[2], B3
58
59 mpy32 .m1x A4, B2, A6
60 nop 3
61 ret .s2 B3
62 sub .l1 A5, A6, A4
63 nop 4
64ENDPROC(__c6xabi_remi)
diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S
new file mode 100644
index 00000000000..3fae719185a
--- /dev/null
+++ b/arch/c6x/lib/remu.S
@@ -0,0 +1,82 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 ;; ABI considerations for the divide functions
21 ;; The following registers are call-used:
22 ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
23 ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
24 ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
25 ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
26 ;;
27 ;; In our implementation, divu and remu are leaf functions,
28 ;; while both divi and remi call into divu.
29 ;; A0 is not clobbered by any of the functions.
30 ;; divu does not clobber B2 either, which is taken advantage of
31 ;; in remi.
32 ;; divi uses B5 to hold the original return address during
33 ;; the call to divu.
34 ;; remi uses B2 and A5 to hold the input values during the
35 ;; call to divu. It stores B3 in on the stack.
36
37
38 .text
39
40ENTRY(__c6xabi_remu)
41 ;; The ABI seems designed to prevent these functions calling each other,
42 ;; so we duplicate most of the divsi3 code here.
43 mv .s2x A4, B1
44 lmbd .l2 1, B4, B1
45|| [!B1] b .s2 B3 ; RETURN A
46|| [!B1] mvk .d2 1, B4
47
48 mv .l1x B1, A7
49|| shl .s2 B4, B1, B4
50
51 cmpltu .l1x A4, B4, A1
52 [!A1] sub .l1x A4, B4, A4
53 shru .s2 B4, 1, B4
54
55_remu_loop:
56 cmpgt .l2 B1, 7, B0
57|| [B1] subc .l1x A4,B4,A4
58|| [B1] add .s2 -1, B1, B1
59 ;; RETURN A may happen here (note: must happen before the next branch)
60 [B1] subc .l1x A4,B4,A4
61|| [B1] add .s2 -1, B1, B1
62|| [B0] b .s1 _remu_loop
63 [B1] subc .l1x A4,B4,A4
64|| [B1] add .s2 -1, B1, B1
65 [B1] subc .l1x A4,B4,A4
66|| [B1] add .s2 -1, B1, B1
67 [B1] subc .l1x A4,B4,A4
68|| [B1] add .s2 -1, B1, B1
69 [B1] subc .l1x A4,B4,A4
70|| [B1] add .s2 -1, B1, B1
71 [B1] subc .l1x A4,B4,A4
72|| [B1] add .s2 -1, B1, B1
73 ;; loop backwards branch happens here
74
75 ret .s2 B3
76 [B1] subc .l1x A4,B4,A4
77|| [B1] add .s2 -1, B1, B1
78 [B1] subc .l1x A4,B4,A4
79
80 extu .s1 A4, A7, A4
81 nop 2
82ENDPROC(__c6xabi_remu)
diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S
new file mode 100644
index 00000000000..de274076553
--- /dev/null
+++ b/arch/c6x/lib/strasgi.S
@@ -0,0 +1,89 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_strasgi)
23 ;; This is essentially memcpy, with alignment known to be at least
24 ;; 4, and the size a multiple of 4 greater than or equal to 28.
25 ldw .d2t1 *B4++, A0
26|| mvk .s2 16, B1
27 ldw .d2t1 *B4++, A1
28|| mvk .s2 20, B2
29|| sub .d1 A6, 24, A6
30 ldw .d2t1 *B4++, A5
31 ldw .d2t1 *B4++, A7
32|| mv .l2x A6, B7
33 ldw .d2t1 *B4++, A8
34 ldw .d2t1 *B4++, A9
35|| mv .s2x A0, B5
36|| cmpltu .l2 B2, B7, B0
37
38_strasgi_loop:
39 stw .d1t2 B5, *A4++
40|| [B0] ldw .d2t1 *B4++, A0
41|| mv .s2x A1, B5
42|| mv .l2 B7, B6
43
44 [B0] sub .d2 B6, 24, B7
45|| [B0] b .s2 _strasgi_loop
46|| cmpltu .l2 B1, B6, B0
47
48 [B0] ldw .d2t1 *B4++, A1
49|| stw .d1t2 B5, *A4++
50|| mv .s2x A5, B5
51|| cmpltu .l2 12, B6, B0
52
53 [B0] ldw .d2t1 *B4++, A5
54|| stw .d1t2 B5, *A4++
55|| mv .s2x A7, B5
56|| cmpltu .l2 8, B6, B0
57
58 [B0] ldw .d2t1 *B4++, A7
59|| stw .d1t2 B5, *A4++
60|| mv .s2x A8, B5
61|| cmpltu .l2 4, B6, B0
62
63 [B0] ldw .d2t1 *B4++, A8
64|| stw .d1t2 B5, *A4++
65|| mv .s2x A9, B5
66|| cmpltu .l2 0, B6, B0
67
68 [B0] ldw .d2t1 *B4++, A9
69|| stw .d1t2 B5, *A4++
70|| mv .s2x A0, B5
71|| cmpltu .l2 B2, B7, B0
72
73 ;; loop back branch happens here
74
75 cmpltu .l2 B1, B6, B0
76|| ret .s2 b3
77
78 [B0] stw .d1t1 A1, *A4++
79|| cmpltu .l2 12, B6, B0
80 [B0] stw .d1t1 A5, *A4++
81|| cmpltu .l2 8, B6, B0
82 [B0] stw .d1t1 A7, *A4++
83|| cmpltu .l2 4, B6, B0
84 [B0] stw .d1t1 A8, *A4++
85|| cmpltu .l2 0, B6, B0
86 [B0] stw .d1t1 A9, *A4++
87
88 ;; return happens here
89ENDPROC(__c6xabi_strasgi)
diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S
new file mode 100644
index 00000000000..c9fd159b5fa
--- /dev/null
+++ b/arch/c6x/lib/strasgi_64plus.S
@@ -0,0 +1,39 @@
1;; Copyright 2010 Free Software Foundation, Inc.
2;; Contributed by Bernd Schmidt <bernds@codesourcery.com>.
3;;
4;; This program is free software; you can redistribute it and/or modify
5;; it under the terms of the GNU General Public License as published by
6;; the Free Software Foundation; either version 2 of the License, or
7;; (at your option) any later version.
8;;
9;; This program is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12;; GNU General Public License for more details.
13;;
14;; You should have received a copy of the GNU General Public License
15;; along with this program; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18#include <linux/linkage.h>
19
20 .text
21
22ENTRY(__c6xabi_strasgi_64plus)
23 shru .s2x a6, 2, b31
24|| mv .s1 a4, a30
25|| mv .d2 b4, b30
26
27 add .s2 -4, b31, b31
28
29 sploopd 1
30|| mvc .s2 b31, ilc
31 ldw .d2t2 *b30++, b31
32 nop 4
33 mv .s1x b31,a31
34 spkernel 6, 0
35|| stw .d1t1 a31, *a30++
36
37 ret .s2 b3
38 nop 5
39ENDPROC(__c6xabi_strasgi_64plus)
diff --git a/arch/c6x/mm/Makefile b/arch/c6x/mm/Makefile
new file mode 100644
index 00000000000..136a97576c6
--- /dev/null
+++ b/arch/c6x/mm/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the linux c6x-specific parts of the memory manager.
3#
4
5obj-y := init.o dma-coherent.o
diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c
new file mode 100644
index 00000000000..4187e518037
--- /dev/null
+++ b/arch/c6x/mm/dma-coherent.c
@@ -0,0 +1,143 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot <aurelien.jacquiot@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * DMA uncached mapping support.
12 *
13 * Using code pulled from ARM
14 * Copyright (C) 2000-2004 Russell King
15 *
16 */
17#include <linux/slab.h>
18#include <linux/bitmap.h>
19#include <linux/bitops.h>
20#include <linux/module.h>
21#include <linux/interrupt.h>
22#include <linux/dma-mapping.h>
23#include <linux/memblock.h>
24
25#include <asm/page.h>
26
27/*
28 * DMA coherent memory management, can be redefined using the memdma=
29 * kernel command line
30 */
31
32/* none by default */
33static phys_addr_t dma_base;
34static u32 dma_size;
35static u32 dma_pages;
36
37static unsigned long *dma_bitmap;
38
39/* bitmap lock */
40static DEFINE_SPINLOCK(dma_lock);
41
42/*
43 * Return a DMA coherent and contiguous memory chunk from the DMA memory
44 */
45static inline u32 __alloc_dma_pages(int order)
46{
47 unsigned long flags;
48 u32 pos;
49
50 spin_lock_irqsave(&dma_lock, flags);
51 pos = bitmap_find_free_region(dma_bitmap, dma_pages, order);
52 spin_unlock_irqrestore(&dma_lock, flags);
53
54 return dma_base + (pos << PAGE_SHIFT);
55}
56
57static void __free_dma_pages(u32 addr, int order)
58{
59 unsigned long flags;
60 u32 pos = (addr - dma_base) >> PAGE_SHIFT;
61
62 if (addr < dma_base || (pos + (1 << order)) >= dma_pages) {
63 printk(KERN_ERR "%s: freeing outside range.\n", __func__);
64 BUG();
65 }
66
67 spin_lock_irqsave(&dma_lock, flags);
68 bitmap_release_region(dma_bitmap, pos, order);
69 spin_unlock_irqrestore(&dma_lock, flags);
70}
71
72/*
73 * Allocate DMA coherent memory space and return both the kernel
74 * virtual and DMA address for that space.
75 */
76void *dma_alloc_coherent(struct device *dev, size_t size,
77 dma_addr_t *handle, gfp_t gfp)
78{
79 u32 paddr;
80 int order;
81
82 if (!dma_size || !size)
83 return NULL;
84
85 order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1);
86
87 paddr = __alloc_dma_pages(order);
88
89 if (handle)
90 *handle = paddr;
91
92 if (!paddr)
93 return NULL;
94
95 return phys_to_virt(paddr);
96}
97EXPORT_SYMBOL(dma_alloc_coherent);
98
99/*
100 * Free DMA coherent memory as defined by the above mapping.
101 */
102void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
103 dma_addr_t dma_handle)
104{
105 int order;
106
107 if (!dma_size || !size)
108 return;
109
110 order = get_count_order(((size - 1) >> PAGE_SHIFT) + 1);
111
112 __free_dma_pages(virt_to_phys(vaddr), order);
113}
114EXPORT_SYMBOL(dma_free_coherent);
115
116/*
117 * Initialise the coherent DMA memory allocator using the given uncached region.
118 */
119void __init coherent_mem_init(phys_addr_t start, u32 size)
120{
121 phys_addr_t bitmap_phys;
122
123 if (!size)
124 return;
125
126 printk(KERN_INFO
127 "Coherent memory (DMA) region start=0x%x size=0x%x\n",
128 start, size);
129
130 dma_base = start;
131 dma_size = size;
132
133 /* allocate bitmap */
134 dma_pages = dma_size >> PAGE_SHIFT;
135 if (dma_size & (PAGE_SIZE - 1))
136 ++dma_pages;
137
138 bitmap_phys = memblock_alloc(BITS_TO_LONGS(dma_pages) * sizeof(long),
139 sizeof(long));
140
141 dma_bitmap = phys_to_virt(bitmap_phys);
142 memset(dma_bitmap, 0, dma_pages * PAGE_SIZE);
143}
diff --git a/arch/c6x/mm/init.c b/arch/c6x/mm/init.c
new file mode 100644
index 00000000000..89395f09648
--- /dev/null
+++ b/arch/c6x/mm/init.c
@@ -0,0 +1,113 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
5 * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/mm.h>
12#include <linux/swap.h>
13#include <linux/module.h>
14#include <linux/bootmem.h>
15#ifdef CONFIG_BLK_DEV_RAM
16#include <linux/blkdev.h>
17#endif
18#include <linux/initrd.h>
19
20#include <asm/sections.h>
21
22/*
23 * ZERO_PAGE is a special page that is used for zero-initialized
24 * data and COW.
25 */
26unsigned long empty_zero_page;
27EXPORT_SYMBOL(empty_zero_page);
28
29/*
30 * paging_init() continues the virtual memory environment setup which
31 * was begun by the code in arch/head.S.
32 * The parameters are pointers to where to stick the starting and ending
33 * addresses of available kernel virtual memory.
34 */
35void __init paging_init(void)
36{
37 struct pglist_data *pgdat = NODE_DATA(0);
38 unsigned long zones_size[MAX_NR_ZONES] = {0, };
39
40 empty_zero_page = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
41 memset((void *)empty_zero_page, 0, PAGE_SIZE);
42
43 /*
44 * Set up user data space
45 */
46 set_fs(KERNEL_DS);
47
48 /*
49 * Define zones
50 */
51 zones_size[ZONE_NORMAL] = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
52 pgdat->node_zones[ZONE_NORMAL].zone_start_pfn =
53 __pa(PAGE_OFFSET) >> PAGE_SHIFT;
54
55 free_area_init(zones_size);
56}
57
58void __init mem_init(void)
59{
60 int codek, datak;
61 unsigned long tmp;
62 unsigned long len = memory_end - memory_start;
63
64 high_memory = (void *)(memory_end & PAGE_MASK);
65
66 /* this will put all memory onto the freelists */
67 totalram_pages = free_all_bootmem();
68
69 codek = (_etext - _stext) >> 10;
70 datak = (_end - _sdata) >> 10;
71
72 tmp = nr_free_pages() << PAGE_SHIFT;
73 printk(KERN_INFO "Memory: %luk/%luk RAM (%dk kernel code, %dk data)\n",
74 tmp >> 10, len >> 10, codek, datak);
75}
76
77#ifdef CONFIG_BLK_DEV_INITRD
78void __init free_initrd_mem(unsigned long start, unsigned long end)
79{
80 int pages = 0;
81 for (; start < end; start += PAGE_SIZE) {
82 ClearPageReserved(virt_to_page(start));
83 init_page_count(virt_to_page(start));
84 free_page(start);
85 totalram_pages++;
86 pages++;
87 }
88 printk(KERN_INFO "Freeing initrd memory: %luk freed\n",
89 (pages * PAGE_SIZE) >> 10);
90}
91#endif
92
93void __init free_initmem(void)
94{
95 unsigned long addr;
96
97 /*
98 * The following code should be cool even if these sections
99 * are not page aligned.
100 */
101 addr = PAGE_ALIGN((unsigned long)(__init_begin));
102
103 /* next to check that the page we free is not a partial page */
104 for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
105 addr += PAGE_SIZE) {
106 ClearPageReserved(virt_to_page(addr));
107 init_page_count(virt_to_page(addr));
108 free_page(addr);
109 totalram_pages++;
110 }
111 printk(KERN_INFO "Freeing unused kernel memory: %dK freed\n",
112 (int) ((addr - PAGE_ALIGN((long) &__init_begin)) >> 10));
113}
diff --git a/arch/c6x/platforms/Kconfig b/arch/c6x/platforms/Kconfig
new file mode 100644
index 00000000000..401ee678fd0
--- /dev/null
+++ b/arch/c6x/platforms/Kconfig
@@ -0,0 +1,16 @@
1
2config SOC_TMS320C6455
3 bool "TMS320C6455"
4 default n
5
6config SOC_TMS320C6457
7 bool "TMS320C6457"
8 default n
9
10config SOC_TMS320C6472
11 bool "TMS320C6472"
12 default n
13
14config SOC_TMS320C6474
15 bool "TMS320C6474"
16 default n
diff --git a/arch/c6x/platforms/Makefile b/arch/c6x/platforms/Makefile
new file mode 100644
index 00000000000..9a95b9bca8d
--- /dev/null
+++ b/arch/c6x/platforms/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for arch/c6x/platforms
3#
4# Copyright 2010, 2011 Texas Instruments Incorporated
5#
6
7obj-y = platform.o cache.o megamod-pic.o pll.o plldata.o timer64.o
8obj-y += dscr.o
9
10# SoC objects
11obj-$(CONFIG_SOC_TMS320C6455) += emif.o
12obj-$(CONFIG_SOC_TMS320C6457) += emif.o
diff --git a/arch/c6x/platforms/cache.c b/arch/c6x/platforms/cache.c
new file mode 100644
index 00000000000..86318a16a25
--- /dev/null
+++ b/arch/c6x/platforms/cache.c
@@ -0,0 +1,445 @@
1/*
2 * Copyright (C) 2011 Texas Instruments Incorporated
3 * Author: Mark Salter <msalter@redhat.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#include <linux/of.h>
10#include <linux/of_address.h>
11#include <linux/io.h>
12
13#include <asm/cache.h>
14#include <asm/soc.h>
15
16/*
17 * Internal Memory Control Registers for caches
18 */
19#define IMCR_CCFG 0x0000
20#define IMCR_L1PCFG 0x0020
21#define IMCR_L1PCC 0x0024
22#define IMCR_L1DCFG 0x0040
23#define IMCR_L1DCC 0x0044
24#define IMCR_L2ALLOC0 0x2000
25#define IMCR_L2ALLOC1 0x2004
26#define IMCR_L2ALLOC2 0x2008
27#define IMCR_L2ALLOC3 0x200c
28#define IMCR_L2WBAR 0x4000
29#define IMCR_L2WWC 0x4004
30#define IMCR_L2WIBAR 0x4010
31#define IMCR_L2WIWC 0x4014
32#define IMCR_L2IBAR 0x4018
33#define IMCR_L2IWC 0x401c
34#define IMCR_L1PIBAR 0x4020
35#define IMCR_L1PIWC 0x4024
36#define IMCR_L1DWIBAR 0x4030
37#define IMCR_L1DWIWC 0x4034
38#define IMCR_L1DWBAR 0x4040
39#define IMCR_L1DWWC 0x4044
40#define IMCR_L1DIBAR 0x4048
41#define IMCR_L1DIWC 0x404c
42#define IMCR_L2WB 0x5000
43#define IMCR_L2WBINV 0x5004
44#define IMCR_L2INV 0x5008
45#define IMCR_L1PINV 0x5028
46#define IMCR_L1DWB 0x5040
47#define IMCR_L1DWBINV 0x5044
48#define IMCR_L1DINV 0x5048
49#define IMCR_MAR_BASE 0x8000
50#define IMCR_MAR96_111 0x8180
51#define IMCR_MAR128_191 0x8200
52#define IMCR_MAR224_239 0x8380
53#define IMCR_L2MPFAR 0xa000
54#define IMCR_L2MPFSR 0xa004
55#define IMCR_L2MPFCR 0xa008
56#define IMCR_L2MPLK0 0xa100
57#define IMCR_L2MPLK1 0xa104
58#define IMCR_L2MPLK2 0xa108
59#define IMCR_L2MPLK3 0xa10c
60#define IMCR_L2MPLKCMD 0xa110
61#define IMCR_L2MPLKSTAT 0xa114
62#define IMCR_L2MPPA_BASE 0xa200
63#define IMCR_L1PMPFAR 0xa400
64#define IMCR_L1PMPFSR 0xa404
65#define IMCR_L1PMPFCR 0xa408
66#define IMCR_L1PMPLK0 0xa500
67#define IMCR_L1PMPLK1 0xa504
68#define IMCR_L1PMPLK2 0xa508
69#define IMCR_L1PMPLK3 0xa50c
70#define IMCR_L1PMPLKCMD 0xa510
71#define IMCR_L1PMPLKSTAT 0xa514
72#define IMCR_L1PMPPA_BASE 0xa600
73#define IMCR_L1DMPFAR 0xac00
74#define IMCR_L1DMPFSR 0xac04
75#define IMCR_L1DMPFCR 0xac08
76#define IMCR_L1DMPLK0 0xad00
77#define IMCR_L1DMPLK1 0xad04
78#define IMCR_L1DMPLK2 0xad08
79#define IMCR_L1DMPLK3 0xad0c
80#define IMCR_L1DMPLKCMD 0xad10
81#define IMCR_L1DMPLKSTAT 0xad14
82#define IMCR_L1DMPPA_BASE 0xae00
83#define IMCR_L2PDWAKE0 0xc040
84#define IMCR_L2PDWAKE1 0xc044
85#define IMCR_L2PDSLEEP0 0xc050
86#define IMCR_L2PDSLEEP1 0xc054
87#define IMCR_L2PDSTAT0 0xc060
88#define IMCR_L2PDSTAT1 0xc064
89
90/*
91 * CCFG register values and bits
92 */
93#define L2MODE_0K_CACHE 0x0
94#define L2MODE_32K_CACHE 0x1
95#define L2MODE_64K_CACHE 0x2
96#define L2MODE_128K_CACHE 0x3
97#define L2MODE_256K_CACHE 0x7
98
99#define L2PRIO_URGENT 0x0
100#define L2PRIO_HIGH 0x1
101#define L2PRIO_MEDIUM 0x2
102#define L2PRIO_LOW 0x3
103
104#define CCFG_ID 0x100 /* Invalidate L1P bit */
105#define CCFG_IP 0x200 /* Invalidate L1D bit */
106
107static void __iomem *cache_base;
108
109/*
110 * L1 & L2 caches generic functions
111 */
112#define imcr_get(reg) soc_readl(cache_base + (reg))
113#define imcr_set(reg, value) \
114do { \
115 soc_writel((value), cache_base + (reg)); \
116 soc_readl(cache_base + (reg)); \
117} while (0)
118
119static void cache_block_operation_wait(unsigned int wc_reg)
120{
121 /* Wait for completion */
122 while (imcr_get(wc_reg))
123 cpu_relax();
124}
125
126static DEFINE_SPINLOCK(cache_lock);
127
128/*
129 * Generic function to perform a block cache operation as
130 * invalidate or writeback/invalidate
131 */
132static void cache_block_operation(unsigned int *start,
133 unsigned int *end,
134 unsigned int bar_reg,
135 unsigned int wc_reg)
136{
137 unsigned long flags;
138 unsigned int wcnt =
139 (L2_CACHE_ALIGN_CNT((unsigned int) end)
140 - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
141 unsigned int wc = 0;
142
143 for (; wcnt; wcnt -= wc, start += wc) {
144loop:
145 spin_lock_irqsave(&cache_lock, flags);
146
147 /*
148 * If another cache operation is occuring
149 */
150 if (unlikely(imcr_get(wc_reg))) {
151 spin_unlock_irqrestore(&cache_lock, flags);
152
153 /* Wait for previous operation completion */
154 cache_block_operation_wait(wc_reg);
155
156 /* Try again */
157 goto loop;
158 }
159
160 imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
161
162 if (wcnt > 0xffff)
163 wc = 0xffff;
164 else
165 wc = wcnt;
166
167 /* Set word count value in the WC register */
168 imcr_set(wc_reg, wc & 0xffff);
169
170 spin_unlock_irqrestore(&cache_lock, flags);
171
172 /* Wait for completion */
173 cache_block_operation_wait(wc_reg);
174 }
175}
176
177static void cache_block_operation_nowait(unsigned int *start,
178 unsigned int *end,
179 unsigned int bar_reg,
180 unsigned int wc_reg)
181{
182 unsigned long flags;
183 unsigned int wcnt =
184 (L2_CACHE_ALIGN_CNT((unsigned int) end)
185 - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
186 unsigned int wc = 0;
187
188 for (; wcnt; wcnt -= wc, start += wc) {
189
190 spin_lock_irqsave(&cache_lock, flags);
191
192 imcr_set(bar_reg, L2_CACHE_ALIGN_LOW((unsigned int) start));
193
194 if (wcnt > 0xffff)
195 wc = 0xffff;
196 else
197 wc = wcnt;
198
199 /* Set word count value in the WC register */
200 imcr_set(wc_reg, wc & 0xffff);
201
202 spin_unlock_irqrestore(&cache_lock, flags);
203
204 /* Don't wait for completion on last cache operation */
205 if (wcnt > 0xffff)
206 cache_block_operation_wait(wc_reg);
207 }
208}
209
210/*
211 * L1 caches management
212 */
213
214/*
215 * Disable L1 caches
216 */
217void L1_cache_off(void)
218{
219 unsigned int dummy;
220
221 imcr_set(IMCR_L1PCFG, 0);
222 dummy = imcr_get(IMCR_L1PCFG);
223
224 imcr_set(IMCR_L1DCFG, 0);
225 dummy = imcr_get(IMCR_L1DCFG);
226}
227
228/*
229 * Enable L1 caches
230 */
231void L1_cache_on(void)
232{
233 unsigned int dummy;
234
235 imcr_set(IMCR_L1PCFG, 7);
236 dummy = imcr_get(IMCR_L1PCFG);
237
238 imcr_set(IMCR_L1DCFG, 7);
239 dummy = imcr_get(IMCR_L1DCFG);
240}
241
242/*
243 * L1P global-invalidate all
244 */
245void L1P_cache_global_invalidate(void)
246{
247 unsigned int set = 1;
248 imcr_set(IMCR_L1PINV, set);
249 while (imcr_get(IMCR_L1PINV) & 1)
250 cpu_relax();
251}
252
253/*
254 * L1D global-invalidate all
255 *
256 * Warning: this operation causes all updated data in L1D to
257 * be discarded rather than written back to the lower levels of
258 * memory
259 */
260void L1D_cache_global_invalidate(void)
261{
262 unsigned int set = 1;
263 imcr_set(IMCR_L1DINV, set);
264 while (imcr_get(IMCR_L1DINV) & 1)
265 cpu_relax();
266}
267
268void L1D_cache_global_writeback(void)
269{
270 unsigned int set = 1;
271 imcr_set(IMCR_L1DWB, set);
272 while (imcr_get(IMCR_L1DWB) & 1)
273 cpu_relax();
274}
275
276void L1D_cache_global_writeback_invalidate(void)
277{
278 unsigned int set = 1;
279 imcr_set(IMCR_L1DWBINV, set);
280 while (imcr_get(IMCR_L1DWBINV) & 1)
281 cpu_relax();
282}
283
284/*
285 * L2 caches management
286 */
287
288/*
289 * Set L2 operation mode
290 */
291void L2_cache_set_mode(unsigned int mode)
292{
293 unsigned int ccfg = imcr_get(IMCR_CCFG);
294
295 /* Clear and set the L2MODE bits in CCFG */
296 ccfg &= ~7;
297 ccfg |= (mode & 7);
298 imcr_set(IMCR_CCFG, ccfg);
299 ccfg = imcr_get(IMCR_CCFG);
300}
301
302/*
303 * L2 global-writeback and global-invalidate all
304 */
305void L2_cache_global_writeback_invalidate(void)
306{
307 imcr_set(IMCR_L2WBINV, 1);
308 while (imcr_get(IMCR_L2WBINV))
309 cpu_relax();
310}
311
312/*
313 * L2 global-writeback all
314 */
315void L2_cache_global_writeback(void)
316{
317 imcr_set(IMCR_L2WB, 1);
318 while (imcr_get(IMCR_L2WB))
319 cpu_relax();
320}
321
322/*
323 * Cacheability controls
324 */
325void enable_caching(unsigned long start, unsigned long end)
326{
327 unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
328 unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
329
330 for (; mar <= mar_e; mar += 4)
331 imcr_set(mar, imcr_get(mar) | 1);
332}
333
334void disable_caching(unsigned long start, unsigned long end)
335{
336 unsigned int mar = IMCR_MAR_BASE + ((start >> 24) << 2);
337 unsigned int mar_e = IMCR_MAR_BASE + ((end >> 24) << 2);
338
339 for (; mar <= mar_e; mar += 4)
340 imcr_set(mar, imcr_get(mar) & ~1);
341}
342
343
344/*
345 * L1 block operations
346 */
347void L1P_cache_block_invalidate(unsigned int start, unsigned int end)
348{
349 cache_block_operation((unsigned int *) start,
350 (unsigned int *) end,
351 IMCR_L1PIBAR, IMCR_L1PIWC);
352}
353
354void L1D_cache_block_invalidate(unsigned int start, unsigned int end)
355{
356 cache_block_operation((unsigned int *) start,
357 (unsigned int *) end,
358 IMCR_L1DIBAR, IMCR_L1DIWC);
359}
360
361void L1D_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
362{
363 cache_block_operation((unsigned int *) start,
364 (unsigned int *) end,
365 IMCR_L1DWIBAR, IMCR_L1DWIWC);
366}
367
368void L1D_cache_block_writeback(unsigned int start, unsigned int end)
369{
370 cache_block_operation((unsigned int *) start,
371 (unsigned int *) end,
372 IMCR_L1DWBAR, IMCR_L1DWWC);
373}
374
375/*
376 * L2 block operations
377 */
378void L2_cache_block_invalidate(unsigned int start, unsigned int end)
379{
380 cache_block_operation((unsigned int *) start,
381 (unsigned int *) end,
382 IMCR_L2IBAR, IMCR_L2IWC);
383}
384
385void L2_cache_block_writeback(unsigned int start, unsigned int end)
386{
387 cache_block_operation((unsigned int *) start,
388 (unsigned int *) end,
389 IMCR_L2WBAR, IMCR_L2WWC);
390}
391
392void L2_cache_block_writeback_invalidate(unsigned int start, unsigned int end)
393{
394 cache_block_operation((unsigned int *) start,
395 (unsigned int *) end,
396 IMCR_L2WIBAR, IMCR_L2WIWC);
397}
398
399void L2_cache_block_invalidate_nowait(unsigned int start, unsigned int end)
400{
401 cache_block_operation_nowait((unsigned int *) start,
402 (unsigned int *) end,
403 IMCR_L2IBAR, IMCR_L2IWC);
404}
405
406void L2_cache_block_writeback_nowait(unsigned int start, unsigned int end)
407{
408 cache_block_operation_nowait((unsigned int *) start,
409 (unsigned int *) end,
410 IMCR_L2WBAR, IMCR_L2WWC);
411}
412
413void L2_cache_block_writeback_invalidate_nowait(unsigned int start,
414 unsigned int end)
415{
416 cache_block_operation_nowait((unsigned int *) start,
417 (unsigned int *) end,
418 IMCR_L2WIBAR, IMCR_L2WIWC);
419}
420
421
422/*
423 * L1 and L2 caches configuration
424 */
425void __init c6x_cache_init(void)
426{
427 struct device_node *node;
428
429 node = of_find_compatible_node(NULL, NULL, "ti,c64x+cache");
430 if (!node)
431 return;
432
433 cache_base = of_iomap(node, 0);
434
435 of_node_put(node);
436
437 if (!cache_base)
438 return;
439
440 /* Set L2 caches on the the whole L2 SRAM memory */
441 L2_cache_set_mode(L2MODE_SIZE);
442
443 /* Enable L1 */
444 L1_cache_on();
445}
diff --git a/arch/c6x/platforms/dscr.c b/arch/c6x/platforms/dscr.c
new file mode 100644
index 00000000000..f848a65ee64
--- /dev/null
+++ b/arch/c6x/platforms/dscr.c
@@ -0,0 +1,598 @@
1/*
2 * Device State Control Registers driver
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 * Author: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12/*
13 * The Device State Control Registers (DSCR) provide SoC level control over
14 * a number of peripherals. Details vary considerably among the various SoC
15 * parts. In general, the DSCR block will provide one or more configuration
16 * registers often protected by a lock register. One or more key values must
17 * be written to a lock register in order to unlock the configuration register.
18 * The configuration register may be used to enable (and disable in some
19 * cases) SoC pin drivers, peripheral clock sources (internal or pin), etc.
20 * In some cases, a configuration register is write once or the individual
21 * bits are write once. That is, you may be able to enable a device, but
22 * will not be able to disable it.
23 *
24 * In addition to device configuration, the DSCR block may provide registers
25 * which are used to reset SoC peripherals, provide device ID information,
26 * provide MAC addresses, and other miscellaneous functions.
27 */
28
29#include <linux/of.h>
30#include <linux/of_address.h>
31#include <linux/of_platform.h>
32#include <linux/module.h>
33#include <linux/io.h>
34#include <linux/delay.h>
35#include <asm/soc.h>
36#include <asm/dscr.h>
37
38#define MAX_DEVSTATE_IDS 32
39#define MAX_DEVCTL_REGS 8
40#define MAX_DEVSTAT_REGS 8
41#define MAX_LOCKED_REGS 4
42#define MAX_SOC_EMACS 2
43
44struct rmii_reset_reg {
45 u32 reg;
46 u32 mask;
47};
48
49/*
50 * Some registerd may be locked. In order to write to these
51 * registers, the key value must first be written to the lockreg.
52 */
53struct locked_reg {
54 u32 reg; /* offset from base */
55 u32 lockreg; /* offset from base */
56 u32 key; /* unlock key */
57};
58
59/*
60 * This describes a contiguous area of like control bits used to enable/disable
61 * SoC devices. Each controllable device is given an ID which is used by the
62 * individual device drivers to control the device state. These IDs start at
63 * zero and are assigned sequentially to the control bitfield ranges described
64 * by this structure.
65 */
66struct devstate_ctl_reg {
67 u32 reg; /* register holding the control bits */
68 u8 start_id; /* start id of this range */
69 u8 num_ids; /* number of devices in this range */
70 u8 enable_only; /* bits are write-once to enable only */
71 u8 enable; /* value used to enable device */
72 u8 disable; /* value used to disable device */
73 u8 shift; /* starting (rightmost) bit in range */
74 u8 nbits; /* number of bits per device */
75};
76
77
78/*
79 * This describes a region of status bits indicating the state of
80 * various devices. This is used internally to wait for status
81 * change completion when enabling/disabling a device. Status is
82 * optional and not all device controls will have a corresponding
83 * status.
84 */
85struct devstate_stat_reg {
86 u32 reg; /* register holding the status bits */
87 u8 start_id; /* start id of this range */
88 u8 num_ids; /* number of devices in this range */
89 u8 enable; /* value indicating enabled state */
90 u8 disable; /* value indicating disabled state */
91 u8 shift; /* starting (rightmost) bit in range */
92 u8 nbits; /* number of bits per device */
93};
94
95struct devstate_info {
96 struct devstate_ctl_reg *ctl;
97 struct devstate_stat_reg *stat;
98};
99
100/* These are callbacks to SOC-specific code. */
101struct dscr_ops {
102 void (*init)(struct device_node *node);
103};
104
105struct dscr_regs {
106 spinlock_t lock;
107 void __iomem *base;
108 u32 kick_reg[2];
109 u32 kick_key[2];
110 struct locked_reg locked[MAX_LOCKED_REGS];
111 struct devstate_info devstate_info[MAX_DEVSTATE_IDS];
112 struct rmii_reset_reg rmii_resets[MAX_SOC_EMACS];
113 struct devstate_ctl_reg devctl[MAX_DEVCTL_REGS];
114 struct devstate_stat_reg devstat[MAX_DEVSTAT_REGS];
115};
116
117static struct dscr_regs dscr;
118
119static struct locked_reg *find_locked_reg(u32 reg)
120{
121 int i;
122
123 for (i = 0; i < MAX_LOCKED_REGS; i++)
124 if (dscr.locked[i].key && reg == dscr.locked[i].reg)
125 return &dscr.locked[i];
126 return NULL;
127}
128
129/*
130 * Write to a register with one lock
131 */
132static void dscr_write_locked1(u32 reg, u32 val,
133 u32 lock, u32 key)
134{
135 void __iomem *reg_addr = dscr.base + reg;
136 void __iomem *lock_addr = dscr.base + lock;
137
138 /*
139 * For some registers, the lock is relocked after a short number
140 * of cycles. We have to put the lock write and register write in
141 * the same fetch packet to meet this timing. The .align ensures
142 * the two stw instructions are in the same fetch packet.
143 */
144 asm volatile ("b .s2 0f\n"
145 "nop 5\n"
146 " .align 5\n"
147 "0:\n"
148 "stw .D1T2 %3,*%2\n"
149 "stw .D1T2 %1,*%0\n"
150 :
151 : "a"(reg_addr), "b"(val), "a"(lock_addr), "b"(key)
152 );
153
154 /* in case the hw doesn't reset the lock */
155 soc_writel(0, lock_addr);
156}
157
158/*
159 * Write to a register protected by two lock registers
160 */
161static void dscr_write_locked2(u32 reg, u32 val,
162 u32 lock0, u32 key0,
163 u32 lock1, u32 key1)
164{
165 soc_writel(key0, dscr.base + lock0);
166 soc_writel(key1, dscr.base + lock1);
167 soc_writel(val, dscr.base + reg);
168 soc_writel(0, dscr.base + lock0);
169 soc_writel(0, dscr.base + lock1);
170}
171
172static void dscr_write(u32 reg, u32 val)
173{
174 struct locked_reg *lock;
175
176 lock = find_locked_reg(reg);
177 if (lock)
178 dscr_write_locked1(reg, val, lock->lockreg, lock->key);
179 else if (dscr.kick_key[0])
180 dscr_write_locked2(reg, val, dscr.kick_reg[0], dscr.kick_key[0],
181 dscr.kick_reg[1], dscr.kick_key[1]);
182 else
183 soc_writel(val, dscr.base + reg);
184}
185
186
187/*
188 * Drivers can use this interface to enable/disable SoC IP blocks.
189 */
190void dscr_set_devstate(int id, enum dscr_devstate_t state)
191{
192 struct devstate_ctl_reg *ctl;
193 struct devstate_stat_reg *stat;
194 struct devstate_info *info;
195 u32 ctl_val, val;
196 int ctl_shift, ctl_mask;
197 unsigned long flags;
198
199 if (!dscr.base)
200 return;
201
202 if (id < 0 || id >= MAX_DEVSTATE_IDS)
203 return;
204
205 info = &dscr.devstate_info[id];
206 ctl = info->ctl;
207 stat = info->stat;
208
209 if (ctl == NULL)
210 return;
211
212 ctl_shift = ctl->shift + ctl->nbits * (id - ctl->start_id);
213 ctl_mask = ((1 << ctl->nbits) - 1) << ctl_shift;
214
215 switch (state) {
216 case DSCR_DEVSTATE_ENABLED:
217 ctl_val = ctl->enable << ctl_shift;
218 break;
219 case DSCR_DEVSTATE_DISABLED:
220 if (ctl->enable_only)
221 return;
222 ctl_val = ctl->disable << ctl_shift;
223 break;
224 default:
225 return;
226 }
227
228 spin_lock_irqsave(&dscr.lock, flags);
229
230 val = soc_readl(dscr.base + ctl->reg);
231 val &= ~ctl_mask;
232 val |= ctl_val;
233
234 dscr_write(ctl->reg, val);
235
236 spin_unlock_irqrestore(&dscr.lock, flags);
237
238 if (!stat)
239 return;
240
241 ctl_shift = stat->shift + stat->nbits * (id - stat->start_id);
242
243 if (state == DSCR_DEVSTATE_ENABLED)
244 ctl_val = stat->enable;
245 else
246 ctl_val = stat->disable;
247
248 do {
249 val = soc_readl(dscr.base + stat->reg);
250 val >>= ctl_shift;
251 val &= ((1 << stat->nbits) - 1);
252 } while (val != ctl_val);
253}
254EXPORT_SYMBOL(dscr_set_devstate);
255
256/*
257 * Drivers can use this to reset RMII module.
258 */
259void dscr_rmii_reset(int id, int assert)
260{
261 struct rmii_reset_reg *r;
262 unsigned long flags;
263 u32 val;
264
265 if (id < 0 || id >= MAX_SOC_EMACS)
266 return;
267
268 r = &dscr.rmii_resets[id];
269 if (r->mask == 0)
270 return;
271
272 spin_lock_irqsave(&dscr.lock, flags);
273
274 val = soc_readl(dscr.base + r->reg);
275 if (assert)
276 dscr_write(r->reg, val | r->mask);
277 else
278 dscr_write(r->reg, val & ~(r->mask));
279
280 spin_unlock_irqrestore(&dscr.lock, flags);
281}
282EXPORT_SYMBOL(dscr_rmii_reset);
283
284static void __init dscr_parse_devstat(struct device_node *node,
285 void __iomem *base)
286{
287 u32 val;
288 int err;
289
290 err = of_property_read_u32_array(node, "ti,dscr-devstat", &val, 1);
291 if (!err)
292 c6x_devstat = soc_readl(base + val);
293 printk(KERN_INFO "DEVSTAT: %08x\n", c6x_devstat);
294}
295
296static void __init dscr_parse_silicon_rev(struct device_node *node,
297 void __iomem *base)
298{
299 u32 vals[3];
300 int err;
301
302 err = of_property_read_u32_array(node, "ti,dscr-silicon-rev", vals, 3);
303 if (!err) {
304 c6x_silicon_rev = soc_readl(base + vals[0]);
305 c6x_silicon_rev >>= vals[1];
306 c6x_silicon_rev &= vals[2];
307 }
308}
309
310/*
311 * Some SoCs will have a pair of fuse registers which hold
312 * an ethernet MAC address. The "ti,dscr-mac-fuse-regs"
313 * property is a mapping from fuse register bytes to MAC
314 * address bytes. The expected format is:
315 *
316 * ti,dscr-mac-fuse-regs = <reg0 b3 b2 b1 b0
317 * reg1 b3 b2 b1 b0>
318 *
319 * reg0 and reg1 are the offsets of the two fuse registers.
320 * b3-b0 positionally represent bytes within the fuse register.
321 * b3 is the most significant byte and b0 is the least.
322 * Allowable values for b3-b0 are:
323 *
324 * 0 = fuse register byte not used in MAC address
325 * 1-6 = index+1 into c6x_fuse_mac[]
326 */
327static void __init dscr_parse_mac_fuse(struct device_node *node,
328 void __iomem *base)
329{
330 u32 vals[10], fuse;
331 int f, i, j, err;
332
333 err = of_property_read_u32_array(node, "ti,dscr-mac-fuse-regs",
334 vals, 10);
335 if (err)
336 return;
337
338 for (f = 0; f < 2; f++) {
339 fuse = soc_readl(base + vals[f * 5]);
340 for (j = (f * 5) + 1, i = 24; i >= 0; i -= 8, j++)
341 if (vals[j] && vals[j] <= 6)
342 c6x_fuse_mac[vals[j] - 1] = fuse >> i;
343 }
344}
345
346static void __init dscr_parse_rmii_resets(struct device_node *node,
347 void __iomem *base)
348{
349 const __be32 *p;
350 int i, size;
351
352 /* look for RMII reset registers */
353 p = of_get_property(node, "ti,dscr-rmii-resets", &size);
354 if (p) {
355 /* parse all the reg/mask pairs we can handle */
356 size /= (sizeof(*p) * 2);
357 if (size > MAX_SOC_EMACS)
358 size = MAX_SOC_EMACS;
359
360 for (i = 0; i < size; i++) {
361 dscr.rmii_resets[i].reg = be32_to_cpup(p++);
362 dscr.rmii_resets[i].mask = be32_to_cpup(p++);
363 }
364 }
365}
366
367
368static void __init dscr_parse_privperm(struct device_node *node,
369 void __iomem *base)
370{
371 u32 vals[2];
372 int err;
373
374 err = of_property_read_u32_array(node, "ti,dscr-privperm", vals, 2);
375 if (err)
376 return;
377 dscr_write(vals[0], vals[1]);
378}
379
380/*
381 * SoCs may have "locked" DSCR registers which can only be written
382 * to only after writing a key value to a lock registers. These
383 * regisers can be described with the "ti,dscr-locked-regs" property.
384 * This property provides a list of register descriptions with each
385 * description consisting of three values.
386 *
387 * ti,dscr-locked-regs = <reg0 lockreg0 key0
388 * ...
389 * regN lockregN keyN>;
390 *
391 * reg is the offset of the locked register
392 * lockreg is the offset of the lock register
393 * key is the unlock key written to lockreg
394 *
395 */
396static void __init dscr_parse_locked_regs(struct device_node *node,
397 void __iomem *base)
398{
399 struct locked_reg *r;
400 const __be32 *p;
401 int i, size;
402
403 p = of_get_property(node, "ti,dscr-locked-regs", &size);
404 if (p) {
405 /* parse all the register descriptions we can handle */
406 size /= (sizeof(*p) * 3);
407 if (size > MAX_LOCKED_REGS)
408 size = MAX_LOCKED_REGS;
409
410 for (i = 0; i < size; i++) {
411 r = &dscr.locked[i];
412
413 r->reg = be32_to_cpup(p++);
414 r->lockreg = be32_to_cpup(p++);
415 r->key = be32_to_cpup(p++);
416 }
417 }
418}
419
420/*
421 * SoCs may have DSCR registers which are only write enabled after
422 * writing specific key values to two registers. The two key registers
423 * and the key values can be parsed from a "ti,dscr-kick-regs"
424 * propety with the following layout:
425 *
426 * ti,dscr-kick-regs = <kickreg0 key0 kickreg1 key1>
427 *
428 * kickreg is the offset of the "kick" register
429 * key is the value which unlocks writing for protected regs
430 */
431static void __init dscr_parse_kick_regs(struct device_node *node,
432 void __iomem *base)
433{
434 u32 vals[4];
435 int err;
436
437 err = of_property_read_u32_array(node, "ti,dscr-kick-regs", vals, 4);
438 if (!err) {
439 dscr.kick_reg[0] = vals[0];
440 dscr.kick_key[0] = vals[1];
441 dscr.kick_reg[1] = vals[2];
442 dscr.kick_key[1] = vals[3];
443 }
444}
445
446
447/*
448 * SoCs may provide controls to enable/disable individual IP blocks. These
449 * controls in the DSCR usually control pin drivers but also may control
450 * clocking and or resets. The device tree is used to describe the bitfields
451 * in registers used to control device state. The number of bits and their
452 * values may vary even within the same register.
453 *
454 * The layout of these bitfields is described by the ti,dscr-devstate-ctl-regs
455 * property. This property is a list where each element describes a contiguous
456 * range of control fields with like properties. Each element of the list
457 * consists of 7 cells with the following values:
458 *
459 * start_id num_ids reg enable disable start_bit nbits
460 *
461 * start_id is device id for the first device control in the range
462 * num_ids is the number of device controls in the range
463 * reg is the offset of the register holding the control bits
464 * enable is the value to enable a device
465 * disable is the value to disable a device (0xffffffff if cannot disable)
466 * start_bit is the bit number of the first bit in the range
467 * nbits is the number of bits per device control
468 */
469static void __init dscr_parse_devstate_ctl_regs(struct device_node *node,
470 void __iomem *base)
471{
472 struct devstate_ctl_reg *r;
473 const __be32 *p;
474 int i, j, size;
475
476 p = of_get_property(node, "ti,dscr-devstate-ctl-regs", &size);
477 if (p) {
478 /* parse all the ranges we can handle */
479 size /= (sizeof(*p) * 7);
480 if (size > MAX_DEVCTL_REGS)
481 size = MAX_DEVCTL_REGS;
482
483 for (i = 0; i < size; i++) {
484 r = &dscr.devctl[i];
485
486 r->start_id = be32_to_cpup(p++);
487 r->num_ids = be32_to_cpup(p++);
488 r->reg = be32_to_cpup(p++);
489 r->enable = be32_to_cpup(p++);
490 r->disable = be32_to_cpup(p++);
491 if (r->disable == 0xffffffff)
492 r->enable_only = 1;
493 r->shift = be32_to_cpup(p++);
494 r->nbits = be32_to_cpup(p++);
495
496 for (j = r->start_id;
497 j < (r->start_id + r->num_ids);
498 j++)
499 dscr.devstate_info[j].ctl = r;
500 }
501 }
502}
503
504/*
505 * SoCs may provide status registers indicating the state (enabled/disabled) of
506 * devices on the SoC. The device tree is used to describe the bitfields in
507 * registers used to provide device status. The number of bits and their
508 * values used to provide status may vary even within the same register.
509 *
510 * The layout of these bitfields is described by the ti,dscr-devstate-stat-regs
511 * property. This property is a list where each element describes a contiguous
512 * range of status fields with like properties. Each element of the list
513 * consists of 7 cells with the following values:
514 *
515 * start_id num_ids reg enable disable start_bit nbits
516 *
517 * start_id is device id for the first device status in the range
518 * num_ids is the number of devices covered by the range
519 * reg is the offset of the register holding the status bits
520 * enable is the value indicating device is enabled
521 * disable is the value indicating device is disabled
522 * start_bit is the bit number of the first bit in the range
523 * nbits is the number of bits per device status
524 */
525static void __init dscr_parse_devstate_stat_regs(struct device_node *node,
526 void __iomem *base)
527{
528 struct devstate_stat_reg *r;
529 const __be32 *p;
530 int i, j, size;
531
532 p = of_get_property(node, "ti,dscr-devstate-stat-regs", &size);
533 if (p) {
534 /* parse all the ranges we can handle */
535 size /= (sizeof(*p) * 7);
536 if (size > MAX_DEVSTAT_REGS)
537 size = MAX_DEVSTAT_REGS;
538
539 for (i = 0; i < size; i++) {
540 r = &dscr.devstat[i];
541
542 r->start_id = be32_to_cpup(p++);
543 r->num_ids = be32_to_cpup(p++);
544 r->reg = be32_to_cpup(p++);
545 r->enable = be32_to_cpup(p++);
546 r->disable = be32_to_cpup(p++);
547 r->shift = be32_to_cpup(p++);
548 r->nbits = be32_to_cpup(p++);
549
550 for (j = r->start_id;
551 j < (r->start_id + r->num_ids);
552 j++)
553 dscr.devstate_info[j].stat = r;
554 }
555 }
556}
557
558static struct of_device_id dscr_ids[] __initdata = {
559 { .compatible = "ti,c64x+dscr" },
560 {}
561};
562
563/*
564 * Probe for DSCR area.
565 *
566 * This has to be done early on in case timer or interrupt controller
567 * needs something. e.g. On C6455 SoC, timer must be enabled through
568 * DSCR before it is functional.
569 */
570void __init dscr_probe(void)
571{
572 struct device_node *node;
573 void __iomem *base;
574
575 spin_lock_init(&dscr.lock);
576
577 node = of_find_matching_node(NULL, dscr_ids);
578 if (!node)
579 return;
580
581 base = of_iomap(node, 0);
582 if (!base) {
583 of_node_put(node);
584 return;
585 }
586
587 dscr.base = base;
588
589 dscr_parse_devstat(node, base);
590 dscr_parse_silicon_rev(node, base);
591 dscr_parse_mac_fuse(node, base);
592 dscr_parse_rmii_resets(node, base);
593 dscr_parse_locked_regs(node, base);
594 dscr_parse_kick_regs(node, base);
595 dscr_parse_devstate_ctl_regs(node, base);
596 dscr_parse_devstate_stat_regs(node, base);
597 dscr_parse_privperm(node, base);
598}
diff --git a/arch/c6x/platforms/emif.c b/arch/c6x/platforms/emif.c
new file mode 100644
index 00000000000..8b564dec241
--- /dev/null
+++ b/arch/c6x/platforms/emif.c
@@ -0,0 +1,87 @@
1/*
2 * External Memory Interface
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 * Author: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/of.h>
12#include <linux/of_address.h>
13#include <linux/io.h>
14#include <asm/soc.h>
15#include <asm/dscr.h>
16
17#define NUM_EMIFA_CHIP_ENABLES 4
18
19struct emifa_regs {
20 u32 midr;
21 u32 stat;
22 u32 reserved1[6];
23 u32 bprio;
24 u32 reserved2[23];
25 u32 cecfg[NUM_EMIFA_CHIP_ENABLES];
26 u32 reserved3[4];
27 u32 awcc;
28 u32 reserved4[7];
29 u32 intraw;
30 u32 intmsk;
31 u32 intmskset;
32 u32 intmskclr;
33};
34
35static struct of_device_id emifa_match[] __initdata = {
36 { .compatible = "ti,c64x+emifa" },
37 {}
38};
39
40/*
41 * Parse device tree for existence of an EMIF (External Memory Interface)
42 * and initialize it if found.
43 */
44static int __init c6x_emifa_init(void)
45{
46 struct emifa_regs __iomem *regs;
47 struct device_node *node;
48 const __be32 *p;
49 u32 val;
50 int i, len, err;
51
52 node = of_find_matching_node(NULL, emifa_match);
53 if (!node)
54 return 0;
55
56 regs = of_iomap(node, 0);
57 if (!regs)
58 return 0;
59
60 /* look for a dscr-based enable for emifa pin buffers */
61 err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1);
62 if (!err)
63 dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED);
64
65 /* set up the chip enables */
66 p = of_get_property(node, "ti,emifa-ce-config", &len);
67 if (p) {
68 len /= sizeof(u32);
69 if (len > NUM_EMIFA_CHIP_ENABLES)
70 len = NUM_EMIFA_CHIP_ENABLES;
71 for (i = 0; i <= len; i++)
72 soc_writel(be32_to_cpup(&p[i]), &regs->cecfg[i]);
73 }
74
75 err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1);
76 if (!err)
77 soc_writel(val, &regs->bprio);
78
79 err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1);
80 if (!err)
81 soc_writel(val, &regs->awcc);
82
83 iounmap(regs);
84 of_node_put(node);
85 return 0;
86}
87pure_initcall(c6x_emifa_init);
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
new file mode 100644
index 00000000000..7c37a947fb1
--- /dev/null
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -0,0 +1,349 @@
1/*
2 * Support for C64x+ Megamodule Interrupt Controller
3 *
4 * Copyright (C) 2010, 2011 Texas Instruments Incorporated
5 * Contributed by: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/interrupt.h>
13#include <linux/io.h>
14#include <linux/of.h>
15#include <linux/of_irq.h>
16#include <linux/of_address.h>
17#include <linux/slab.h>
18#include <asm/soc.h>
19#include <asm/megamod-pic.h>
20
21#define NR_COMBINERS 4
22#define NR_MUX_OUTPUTS 12
23
24#define IRQ_UNMAPPED 0xffff
25
26/*
27 * Megamodule Interrupt Controller register layout
28 */
29struct megamod_regs {
30 u32 evtflag[8];
31 u32 evtset[8];
32 u32 evtclr[8];
33 u32 reserved0[8];
34 u32 evtmask[8];
35 u32 mevtflag[8];
36 u32 expmask[8];
37 u32 mexpflag[8];
38 u32 intmux_unused;
39 u32 intmux[7];
40 u32 reserved1[8];
41 u32 aegmux[2];
42 u32 reserved2[14];
43 u32 intxstat;
44 u32 intxclr;
45 u32 intdmask;
46 u32 reserved3[13];
47 u32 evtasrt;
48};
49
50struct megamod_pic {
51 struct irq_host *irqhost;
52 struct megamod_regs __iomem *regs;
53 raw_spinlock_t lock;
54
55 /* hw mux mapping */
56 unsigned int output_to_irq[NR_MUX_OUTPUTS];
57};
58
59static struct megamod_pic *mm_pic;
60
61struct megamod_cascade_data {
62 struct megamod_pic *pic;
63 int index;
64};
65
66static struct megamod_cascade_data cascade_data[NR_COMBINERS];
67
68static void mask_megamod(struct irq_data *data)
69{
70 struct megamod_pic *pic = irq_data_get_irq_chip_data(data);
71 irq_hw_number_t src = irqd_to_hwirq(data);
72 u32 __iomem *evtmask = &pic->regs->evtmask[src / 32];
73
74 raw_spin_lock(&pic->lock);
75 soc_writel(soc_readl(evtmask) | (1 << (src & 31)), evtmask);
76 raw_spin_unlock(&pic->lock);
77}
78
79static void unmask_megamod(struct irq_data *data)
80{
81 struct megamod_pic *pic = irq_data_get_irq_chip_data(data);
82 irq_hw_number_t src = irqd_to_hwirq(data);
83 u32 __iomem *evtmask = &pic->regs->evtmask[src / 32];
84
85 raw_spin_lock(&pic->lock);
86 soc_writel(soc_readl(evtmask) & ~(1 << (src & 31)), evtmask);
87 raw_spin_unlock(&pic->lock);
88}
89
90static struct irq_chip megamod_chip = {
91 .name = "megamod",
92 .irq_mask = mask_megamod,
93 .irq_unmask = unmask_megamod,
94};
95
96static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc)
97{
98 struct megamod_cascade_data *cascade;
99 struct megamod_pic *pic;
100 u32 events;
101 int n, idx;
102
103 cascade = irq_desc_get_handler_data(desc);
104
105 pic = cascade->pic;
106 idx = cascade->index;
107
108 while ((events = soc_readl(&pic->regs->mevtflag[idx])) != 0) {
109 n = __ffs(events);
110
111 irq = irq_linear_revmap(pic->irqhost, idx * 32 + n);
112
113 soc_writel(1 << n, &pic->regs->evtclr[idx]);
114
115 generic_handle_irq(irq);
116 }
117}
118
119static int megamod_map(struct irq_host *h, unsigned int virq,
120 irq_hw_number_t hw)
121{
122 struct megamod_pic *pic = h->host_data;
123 int i;
124
125 /* We shouldn't see a hwirq which is muxed to core controller */
126 for (i = 0; i < NR_MUX_OUTPUTS; i++)
127 if (pic->output_to_irq[i] == hw)
128 return -1;
129
130 irq_set_chip_data(virq, pic);
131 irq_set_chip_and_handler(virq, &megamod_chip, handle_level_irq);
132
133 /* Set default irq type */
134 irq_set_irq_type(virq, IRQ_TYPE_NONE);
135
136 return 0;
137}
138
139static int megamod_xlate(struct irq_host *h, struct device_node *ct,
140 const u32 *intspec, unsigned int intsize,
141 irq_hw_number_t *out_hwirq, unsigned int *out_type)
142
143{
144 /* megamod intspecs must have 1 cell */
145 BUG_ON(intsize != 1);
146 *out_hwirq = intspec[0];
147 *out_type = IRQ_TYPE_NONE;
148 return 0;
149}
150
151static struct irq_host_ops megamod_host_ops = {
152 .map = megamod_map,
153 .xlate = megamod_xlate,
154};
155
156static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
157{
158 int index, offset;
159 u32 val;
160
161 if (src < 0 || src >= (NR_COMBINERS * 32)) {
162 pic->output_to_irq[output] = IRQ_UNMAPPED;
163 return;
164 }
165
166 /* four mappings per mux register */
167 index = output / 4;
168 offset = (output & 3) * 8;
169
170 val = soc_readl(&pic->regs->intmux[index]);
171 val &= ~(0xff << offset);
172 val |= src << offset;
173 soc_writel(val, &pic->regs->intmux[index]);
174}
175
176/*
177 * Parse the MUX mapping, if one exists.
178 *
179 * The MUX map is an array of up to 12 cells; one for each usable core priority
180 * interrupt. The value of a given cell is the megamodule interrupt source
181 * which is to me MUXed to the output corresponding to the cell position
182 * withing the array. The first cell in the array corresponds to priority
183 * 4 and the last (12th) cell corresponds to priority 15. The allowed
184 * values are 4 - ((NR_COMBINERS * 32) - 1). Note that the combined interrupt
185 * sources (0 - 3) are not allowed to be mapped through this property. They
186 * are handled through the "interrupts" property. This allows us to use a
187 * value of zero as a "do not map" placeholder.
188 */
189static void __init parse_priority_map(struct megamod_pic *pic,
190 int *mapping, int size)
191{
192 struct device_node *np = pic->irqhost->of_node;
193 const __be32 *map;
194 int i, maplen;
195 u32 val;
196
197 map = of_get_property(np, "ti,c64x+megamod-pic-mux", &maplen);
198 if (map) {
199 maplen /= 4;
200 if (maplen > size)
201 maplen = size;
202
203 for (i = 0; i < maplen; i++) {
204 val = be32_to_cpup(map);
205 if (val && val >= 4)
206 mapping[i] = val;
207 ++map;
208 }
209 }
210}
211
212static struct megamod_pic * __init init_megamod_pic(struct device_node *np)
213{
214 struct megamod_pic *pic;
215 int i, irq;
216 int mapping[NR_MUX_OUTPUTS];
217
218 pr_info("Initializing C64x+ Megamodule PIC\n");
219
220 pic = kzalloc(sizeof(struct megamod_pic), GFP_KERNEL);
221 if (!pic) {
222 pr_err("%s: Could not alloc PIC structure.\n", np->full_name);
223 return NULL;
224 }
225
226 pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
227 NR_COMBINERS * 32, &megamod_host_ops,
228 IRQ_UNMAPPED);
229 if (!pic->irqhost) {
230 pr_err("%s: Could not alloc host.\n", np->full_name);
231 goto error_free;
232 }
233
234 pic->irqhost->host_data = pic;
235
236 raw_spin_lock_init(&pic->lock);
237
238 pic->regs = of_iomap(np, 0);
239 if (!pic->regs) {
240 pr_err("%s: Could not map registers.\n", np->full_name);
241 goto error_free;
242 }
243
244 /* Initialize MUX map */
245 for (i = 0; i < ARRAY_SIZE(mapping); i++)
246 mapping[i] = IRQ_UNMAPPED;
247
248 parse_priority_map(pic, mapping, ARRAY_SIZE(mapping));
249
250 /*
251 * We can have up to 12 interrupts cascading to the core controller.
252 * These cascades can be from the combined interrupt sources or for
253 * individual interrupt sources. The "interrupts" property only
254 * deals with the cascaded combined interrupts. The individual
255 * interrupts muxed to the core controller use the core controller
256 * as their interrupt parent.
257 */
258 for (i = 0; i < NR_COMBINERS; i++) {
259
260 irq = irq_of_parse_and_map(np, i);
261 if (irq == NO_IRQ)
262 continue;
263
264 /*
265 * We count on the core priority interrupts (4 - 15) being
266 * direct mapped. Check that device tree provided something
267 * in that range.
268 */
269 if (irq < 4 || irq >= NR_PRIORITY_IRQS) {
270 pr_err("%s: combiner-%d virq %d out of range!\n",
271 np->full_name, i, irq);
272 continue;
273 }
274
275 /* record the mapping */
276 mapping[irq - 4] = i;
277
278 pr_debug("%s: combiner-%d cascading to virq %d\n",
279 np->full_name, i, irq);
280
281 cascade_data[i].pic = pic;
282 cascade_data[i].index = i;
283
284 /* mask and clear all events in combiner */
285 soc_writel(~0, &pic->regs->evtmask[i]);
286 soc_writel(~0, &pic->regs->evtclr[i]);
287
288 irq_set_handler_data(irq, &cascade_data[i]);
289 irq_set_chained_handler(irq, megamod_irq_cascade);
290 }
291
292 /* Finally, set up the MUX registers */
293 for (i = 0; i < NR_MUX_OUTPUTS; i++) {
294 if (mapping[i] != IRQ_UNMAPPED) {
295 pr_debug("%s: setting mux %d to priority %d\n",
296 np->full_name, mapping[i], i + 4);
297 set_megamod_mux(pic, mapping[i], i);
298 }
299 }
300
301 return pic;
302
303error_free:
304 kfree(pic);
305
306 return NULL;
307}
308
309/*
310 * Return next active event after ACK'ing it.
311 * Return -1 if no events active.
312 */
313static int get_exception(void)
314{
315 int i, bit;
316 u32 mask;
317
318 for (i = 0; i < NR_COMBINERS; i++) {
319 mask = soc_readl(&mm_pic->regs->mexpflag[i]);
320 if (mask) {
321 bit = __ffs(mask);
322 soc_writel(1 << bit, &mm_pic->regs->evtclr[i]);
323 return (i * 32) + bit;
324 }
325 }
326 return -1;
327}
328
329static void assert_event(unsigned int val)
330{
331 soc_writel(val, &mm_pic->regs->evtasrt);
332}
333
334void __init megamod_pic_init(void)
335{
336 struct device_node *np;
337
338 np = of_find_compatible_node(NULL, NULL, "ti,c64x+megamod-pic");
339 if (!np)
340 return;
341
342 mm_pic = init_megamod_pic(np);
343 of_node_put(np);
344
345 soc_ops.get_exception = get_exception;
346 soc_ops.assert_event = assert_event;
347
348 return;
349}
diff --git a/arch/c6x/platforms/platform.c b/arch/c6x/platforms/platform.c
new file mode 100644
index 00000000000..26c1a355d60
--- /dev/null
+++ b/arch/c6x/platforms/platform.c
@@ -0,0 +1,17 @@
1/*
2 * Copyright 2011 Texas Instruments Incorporated
3 *
4 * This file is licensed under the terms of the GNU General Public License
5 * version 2. This program is licensed "as is" without any warranty of any
6 * kind, whether express or implied.
7 */
8
9#include <linux/init.h>
10#include <linux/of_platform.h>
11
12static int __init c6x_device_probe(void)
13{
14 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
15 return 0;
16}
17core_initcall(c6x_device_probe);
diff --git a/arch/c6x/platforms/pll.c b/arch/c6x/platforms/pll.c
new file mode 100644
index 00000000000..3aa898f7ce4
--- /dev/null
+++ b/arch/c6x/platforms/pll.c
@@ -0,0 +1,444 @@
1/*
2 * Clock and PLL control for C64x+ devices
3 *
4 * Copyright (C) 2010, 2011 Texas Instruments.
5 * Contributed by: Mark Salter <msalter@redhat.com>
6 *
7 * Copied heavily from arm/mach-davinci/clock.c, so:
8 *
9 * Copyright (C) 2006-2007 Texas Instruments.
10 * Copyright (C) 2008-2009 Deep Root Systems, LLC
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/clkdev.h>
20#include <linux/clk.h>
21#include <linux/io.h>
22#include <linux/err.h>
23
24#include <asm/clock.h>
25#include <asm/soc.h>
26
27static LIST_HEAD(clocks);
28static DEFINE_MUTEX(clocks_mutex);
29static DEFINE_SPINLOCK(clockfw_lock);
30
31static void __clk_enable(struct clk *clk)
32{
33 if (clk->parent)
34 __clk_enable(clk->parent);
35 clk->usecount++;
36}
37
38static void __clk_disable(struct clk *clk)
39{
40 if (WARN_ON(clk->usecount == 0))
41 return;
42 --clk->usecount;
43
44 if (clk->parent)
45 __clk_disable(clk->parent);
46}
47
48int clk_enable(struct clk *clk)
49{
50 unsigned long flags;
51
52 if (clk == NULL || IS_ERR(clk))
53 return -EINVAL;
54
55 spin_lock_irqsave(&clockfw_lock, flags);
56 __clk_enable(clk);
57 spin_unlock_irqrestore(&clockfw_lock, flags);
58
59 return 0;
60}
61EXPORT_SYMBOL(clk_enable);
62
63void clk_disable(struct clk *clk)
64{
65 unsigned long flags;
66
67 if (clk == NULL || IS_ERR(clk))
68 return;
69
70 spin_lock_irqsave(&clockfw_lock, flags);
71 __clk_disable(clk);
72 spin_unlock_irqrestore(&clockfw_lock, flags);
73}
74EXPORT_SYMBOL(clk_disable);
75
76unsigned long clk_get_rate(struct clk *clk)
77{
78 if (clk == NULL || IS_ERR(clk))
79 return -EINVAL;
80
81 return clk->rate;
82}
83EXPORT_SYMBOL(clk_get_rate);
84
85long clk_round_rate(struct clk *clk, unsigned long rate)
86{
87 if (clk == NULL || IS_ERR(clk))
88 return -EINVAL;
89
90 if (clk->round_rate)
91 return clk->round_rate(clk, rate);
92
93 return clk->rate;
94}
95EXPORT_SYMBOL(clk_round_rate);
96
97/* Propagate rate to children */
98static void propagate_rate(struct clk *root)
99{
100 struct clk *clk;
101
102 list_for_each_entry(clk, &root->children, childnode) {
103 if (clk->recalc)
104 clk->rate = clk->recalc(clk);
105 propagate_rate(clk);
106 }
107}
108
109int clk_set_rate(struct clk *clk, unsigned long rate)
110{
111 unsigned long flags;
112 int ret = -EINVAL;
113
114 if (clk == NULL || IS_ERR(clk))
115 return ret;
116
117 if (clk->set_rate)
118 ret = clk->set_rate(clk, rate);
119
120 spin_lock_irqsave(&clockfw_lock, flags);
121 if (ret == 0) {
122 if (clk->recalc)
123 clk->rate = clk->recalc(clk);
124 propagate_rate(clk);
125 }
126 spin_unlock_irqrestore(&clockfw_lock, flags);
127
128 return ret;
129}
130EXPORT_SYMBOL(clk_set_rate);
131
132int clk_set_parent(struct clk *clk, struct clk *parent)
133{
134 unsigned long flags;
135
136 if (clk == NULL || IS_ERR(clk))
137 return -EINVAL;
138
139 /* Cannot change parent on enabled clock */
140 if (WARN_ON(clk->usecount))
141 return -EINVAL;
142
143 mutex_lock(&clocks_mutex);
144 clk->parent = parent;
145 list_del_init(&clk->childnode);
146 list_add(&clk->childnode, &clk->parent->children);
147 mutex_unlock(&clocks_mutex);
148
149 spin_lock_irqsave(&clockfw_lock, flags);
150 if (clk->recalc)
151 clk->rate = clk->recalc(clk);
152 propagate_rate(clk);
153 spin_unlock_irqrestore(&clockfw_lock, flags);
154
155 return 0;
156}
157EXPORT_SYMBOL(clk_set_parent);
158
159int clk_register(struct clk *clk)
160{
161 if (clk == NULL || IS_ERR(clk))
162 return -EINVAL;
163
164 if (WARN(clk->parent && !clk->parent->rate,
165 "CLK: %s parent %s has no rate!\n",
166 clk->name, clk->parent->name))
167 return -EINVAL;
168
169 mutex_lock(&clocks_mutex);
170 list_add_tail(&clk->node, &clocks);
171 if (clk->parent)
172 list_add_tail(&clk->childnode, &clk->parent->children);
173 mutex_unlock(&clocks_mutex);
174
175 /* If rate is already set, use it */
176 if (clk->rate)
177 return 0;
178
179 /* Else, see if there is a way to calculate it */
180 if (clk->recalc)
181 clk->rate = clk->recalc(clk);
182
183 /* Otherwise, default to parent rate */
184 else if (clk->parent)
185 clk->rate = clk->parent->rate;
186
187 return 0;
188}
189EXPORT_SYMBOL(clk_register);
190
191void clk_unregister(struct clk *clk)
192{
193 if (clk == NULL || IS_ERR(clk))
194 return;
195
196 mutex_lock(&clocks_mutex);
197 list_del(&clk->node);
198 list_del(&clk->childnode);
199 mutex_unlock(&clocks_mutex);
200}
201EXPORT_SYMBOL(clk_unregister);
202
203
204static u32 pll_read(struct pll_data *pll, int reg)
205{
206 return soc_readl(pll->base + reg);
207}
208
209static unsigned long clk_sysclk_recalc(struct clk *clk)
210{
211 u32 v, plldiv = 0;
212 struct pll_data *pll;
213 unsigned long rate = clk->rate;
214
215 if (WARN_ON(!clk->parent))
216 return rate;
217
218 rate = clk->parent->rate;
219
220 /* the parent must be a PLL */
221 if (WARN_ON(!clk->parent->pll_data))
222 return rate;
223
224 pll = clk->parent->pll_data;
225
226 /* If pre-PLL, source clock is before the multiplier and divider(s) */
227 if (clk->flags & PRE_PLL)
228 rate = pll->input_rate;
229
230 if (!clk->div) {
231 pr_debug("%s: (no divider) rate = %lu KHz\n",
232 clk->name, rate / 1000);
233 return rate;
234 }
235
236 if (clk->flags & FIXED_DIV_PLL) {
237 rate /= clk->div;
238 pr_debug("%s: (fixed divide by %d) rate = %lu KHz\n",
239 clk->name, clk->div, rate / 1000);
240 return rate;
241 }
242
243 v = pll_read(pll, clk->div);
244 if (v & PLLDIV_EN)
245 plldiv = (v & PLLDIV_RATIO_MASK) + 1;
246
247 if (plldiv == 0)
248 plldiv = 1;
249
250 rate /= plldiv;
251
252 pr_debug("%s: (divide by %d) rate = %lu KHz\n",
253 clk->name, plldiv, rate / 1000);
254
255 return rate;
256}
257
258static unsigned long clk_leafclk_recalc(struct clk *clk)
259{
260 if (WARN_ON(!clk->parent))
261 return clk->rate;
262
263 pr_debug("%s: (parent %s) rate = %lu KHz\n",
264 clk->name, clk->parent->name, clk->parent->rate / 1000);
265
266 return clk->parent->rate;
267}
268
269static unsigned long clk_pllclk_recalc(struct clk *clk)
270{
271 u32 ctrl, mult = 0, prediv = 0, postdiv = 0;
272 u8 bypass;
273 struct pll_data *pll = clk->pll_data;
274 unsigned long rate = clk->rate;
275
276 if (clk->flags & FIXED_RATE_PLL)
277 return rate;
278
279 ctrl = pll_read(pll, PLLCTL);
280 rate = pll->input_rate = clk->parent->rate;
281
282 if (ctrl & PLLCTL_PLLEN)
283 bypass = 0;
284 else
285 bypass = 1;
286
287 if (pll->flags & PLL_HAS_MUL) {
288 mult = pll_read(pll, PLLM);
289 mult = (mult & PLLM_PLLM_MASK) + 1;
290 }
291 if (pll->flags & PLL_HAS_PRE) {
292 prediv = pll_read(pll, PLLPRE);
293 if (prediv & PLLDIV_EN)
294 prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
295 else
296 prediv = 0;
297 }
298 if (pll->flags & PLL_HAS_POST) {
299 postdiv = pll_read(pll, PLLPOST);
300 if (postdiv & PLLDIV_EN)
301 postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
302 else
303 postdiv = 1;
304 }
305
306 if (!bypass) {
307 if (prediv)
308 rate /= prediv;
309 if (mult)
310 rate *= mult;
311 if (postdiv)
312 rate /= postdiv;
313
314 pr_debug("PLL%d: input = %luMHz, pre[%d] mul[%d] post[%d] "
315 "--> %luMHz output.\n",
316 pll->num, clk->parent->rate / 1000000,
317 prediv, mult, postdiv, rate / 1000000);
318 } else
319 pr_debug("PLL%d: input = %luMHz, bypass mode.\n",
320 pll->num, clk->parent->rate / 1000000);
321
322 return rate;
323}
324
325
326static void __init __init_clk(struct clk *clk)
327{
328 INIT_LIST_HEAD(&clk->node);
329 INIT_LIST_HEAD(&clk->children);
330 INIT_LIST_HEAD(&clk->childnode);
331
332 if (!clk->recalc) {
333
334 /* Check if clock is a PLL */
335 if (clk->pll_data)
336 clk->recalc = clk_pllclk_recalc;
337
338 /* Else, if it is a PLL-derived clock */
339 else if (clk->flags & CLK_PLL)
340 clk->recalc = clk_sysclk_recalc;
341
342 /* Otherwise, it is a leaf clock (PSC clock) */
343 else if (clk->parent)
344 clk->recalc = clk_leafclk_recalc;
345 }
346}
347
348void __init c6x_clks_init(struct clk_lookup *clocks)
349{
350 struct clk_lookup *c;
351 struct clk *clk;
352 size_t num_clocks = 0;
353
354 for (c = clocks; c->clk; c++) {
355 clk = c->clk;
356
357 __init_clk(clk);
358 clk_register(clk);
359 num_clocks++;
360
361 /* Turn on clocks that Linux doesn't otherwise manage */
362 if (clk->flags & ALWAYS_ENABLED)
363 clk_enable(clk);
364 }
365
366 clkdev_add_table(clocks, num_clocks);
367}
368
369#ifdef CONFIG_DEBUG_FS
370
371#include <linux/debugfs.h>
372#include <linux/seq_file.h>
373
374#define CLKNAME_MAX 10 /* longest clock name */
375#define NEST_DELTA 2
376#define NEST_MAX 4
377
378static void
379dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
380{
381 char *state;
382 char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
383 struct clk *clk;
384 unsigned i;
385
386 if (parent->flags & CLK_PLL)
387 state = "pll";
388 else
389 state = "";
390
391 /* <nest spaces> name <pad to end> */
392 memset(buf, ' ', sizeof(buf) - 1);
393 buf[sizeof(buf) - 1] = 0;
394 i = strlen(parent->name);
395 memcpy(buf + nest, parent->name,
396 min(i, (unsigned)(sizeof(buf) - 1 - nest)));
397
398 seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
399 buf, parent->usecount, state, clk_get_rate(parent));
400 /* REVISIT show device associations too */
401
402 /* cost is now small, but not linear... */
403 list_for_each_entry(clk, &parent->children, childnode) {
404 dump_clock(s, nest + NEST_DELTA, clk);
405 }
406}
407
408static int c6x_ck_show(struct seq_file *m, void *v)
409{
410 struct clk *clk;
411
412 /*
413 * Show clock tree; We trust nonzero usecounts equate to PSC enables...
414 */
415 mutex_lock(&clocks_mutex);
416 list_for_each_entry(clk, &clocks, node)
417 if (!clk->parent)
418 dump_clock(m, 0, clk);
419 mutex_unlock(&clocks_mutex);
420
421 return 0;
422}
423
424static int c6x_ck_open(struct inode *inode, struct file *file)
425{
426 return single_open(file, c6x_ck_show, NULL);
427}
428
429static const struct file_operations c6x_ck_operations = {
430 .open = c6x_ck_open,
431 .read = seq_read,
432 .llseek = seq_lseek,
433 .release = single_release,
434};
435
436static int __init c6x_clk_debugfs_init(void)
437{
438 debugfs_create_file("c6x_clocks", S_IFREG | S_IRUGO, NULL, NULL,
439 &c6x_ck_operations);
440
441 return 0;
442}
443device_initcall(c6x_clk_debugfs_init);
444#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/c6x/platforms/plldata.c b/arch/c6x/platforms/plldata.c
new file mode 100644
index 00000000000..2cfd6f42968
--- /dev/null
+++ b/arch/c6x/platforms/plldata.c
@@ -0,0 +1,404 @@
1/*
2 * Port on Texas Instruments TMS320C6x architecture
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated
5 * Author: Mark Salter <msalter@redhat.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/ioport.h>
16#include <linux/clkdev.h>
17#include <linux/of.h>
18#include <linux/of_address.h>
19
20#include <asm/clock.h>
21#include <asm/setup.h>
22#include <asm/irq.h>
23
24/*
25 * Common SoC clock support.
26 */
27
28/* Default input for PLL1 */
29struct clk clkin1 = {
30 .name = "clkin1",
31 .node = LIST_HEAD_INIT(clkin1.node),
32 .children = LIST_HEAD_INIT(clkin1.children),
33 .childnode = LIST_HEAD_INIT(clkin1.childnode),
34};
35
36struct pll_data c6x_soc_pll1 = {
37 .num = 1,
38 .sysclks = {
39 {
40 .name = "pll1",
41 .parent = &clkin1,
42 .pll_data = &c6x_soc_pll1,
43 .flags = CLK_PLL,
44 },
45 {
46 .name = "pll1_sysclk1",
47 .parent = &c6x_soc_pll1.sysclks[0],
48 .flags = CLK_PLL,
49 },
50 {
51 .name = "pll1_sysclk2",
52 .parent = &c6x_soc_pll1.sysclks[0],
53 .flags = CLK_PLL,
54 },
55 {
56 .name = "pll1_sysclk3",
57 .parent = &c6x_soc_pll1.sysclks[0],
58 .flags = CLK_PLL,
59 },
60 {
61 .name = "pll1_sysclk4",
62 .parent = &c6x_soc_pll1.sysclks[0],
63 .flags = CLK_PLL,
64 },
65 {
66 .name = "pll1_sysclk5",
67 .parent = &c6x_soc_pll1.sysclks[0],
68 .flags = CLK_PLL,
69 },
70 {
71 .name = "pll1_sysclk6",
72 .parent = &c6x_soc_pll1.sysclks[0],
73 .flags = CLK_PLL,
74 },
75 {
76 .name = "pll1_sysclk7",
77 .parent = &c6x_soc_pll1.sysclks[0],
78 .flags = CLK_PLL,
79 },
80 {
81 .name = "pll1_sysclk8",
82 .parent = &c6x_soc_pll1.sysclks[0],
83 .flags = CLK_PLL,
84 },
85 {
86 .name = "pll1_sysclk9",
87 .parent = &c6x_soc_pll1.sysclks[0],
88 .flags = CLK_PLL,
89 },
90 {
91 .name = "pll1_sysclk10",
92 .parent = &c6x_soc_pll1.sysclks[0],
93 .flags = CLK_PLL,
94 },
95 {
96 .name = "pll1_sysclk11",
97 .parent = &c6x_soc_pll1.sysclks[0],
98 .flags = CLK_PLL,
99 },
100 {
101 .name = "pll1_sysclk12",
102 .parent = &c6x_soc_pll1.sysclks[0],
103 .flags = CLK_PLL,
104 },
105 {
106 .name = "pll1_sysclk13",
107 .parent = &c6x_soc_pll1.sysclks[0],
108 .flags = CLK_PLL,
109 },
110 {
111 .name = "pll1_sysclk14",
112 .parent = &c6x_soc_pll1.sysclks[0],
113 .flags = CLK_PLL,
114 },
115 {
116 .name = "pll1_sysclk15",
117 .parent = &c6x_soc_pll1.sysclks[0],
118 .flags = CLK_PLL,
119 },
120 {
121 .name = "pll1_sysclk16",
122 .parent = &c6x_soc_pll1.sysclks[0],
123 .flags = CLK_PLL,
124 },
125 },
126};
127
128/* CPU core clock */
129struct clk c6x_core_clk = {
130 .name = "core",
131};
132
133/* miscellaneous IO clocks */
134struct clk c6x_i2c_clk = {
135 .name = "i2c",
136};
137
138struct clk c6x_watchdog_clk = {
139 .name = "watchdog",
140};
141
142struct clk c6x_mcbsp1_clk = {
143 .name = "mcbsp1",
144};
145
146struct clk c6x_mcbsp2_clk = {
147 .name = "mcbsp2",
148};
149
150struct clk c6x_mdio_clk = {
151 .name = "mdio",
152};
153
154
155#ifdef CONFIG_SOC_TMS320C6455
156static struct clk_lookup c6455_clks[] = {
157 CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
158 CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
159 CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
160 CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
161 CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
162 CLK(NULL, "core", &c6x_core_clk),
163 CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
164 CLK("watchdog", NULL, &c6x_watchdog_clk),
165 CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
166 CLK("", NULL, NULL)
167};
168
169
170static void __init c6455_setup_clocks(struct device_node *node)
171{
172 struct pll_data *pll = &c6x_soc_pll1;
173 struct clk *sysclks = pll->sysclks;
174
175 pll->flags = PLL_HAS_PRE | PLL_HAS_MUL;
176
177 sysclks[2].flags |= FIXED_DIV_PLL;
178 sysclks[2].div = 3;
179 sysclks[3].flags |= FIXED_DIV_PLL;
180 sysclks[3].div = 6;
181 sysclks[4].div = PLLDIV4;
182 sysclks[5].div = PLLDIV5;
183
184 c6x_core_clk.parent = &sysclks[0];
185 c6x_i2c_clk.parent = &sysclks[3];
186 c6x_watchdog_clk.parent = &sysclks[3];
187 c6x_mdio_clk.parent = &sysclks[3];
188
189 c6x_clks_init(c6455_clks);
190}
191#endif /* CONFIG_SOC_TMS320C6455 */
192
193#ifdef CONFIG_SOC_TMS320C6457
194static struct clk_lookup c6457_clks[] = {
195 CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
196 CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
197 CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
198 CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
199 CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
200 CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
201 CLK(NULL, "core", &c6x_core_clk),
202 CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
203 CLK("watchdog", NULL, &c6x_watchdog_clk),
204 CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
205 CLK("", NULL, NULL)
206};
207
208static void __init c6457_setup_clocks(struct device_node *node)
209{
210 struct pll_data *pll = &c6x_soc_pll1;
211 struct clk *sysclks = pll->sysclks;
212
213 pll->flags = PLL_HAS_MUL | PLL_HAS_POST;
214
215 sysclks[1].flags |= FIXED_DIV_PLL;
216 sysclks[1].div = 1;
217 sysclks[2].flags |= FIXED_DIV_PLL;
218 sysclks[2].div = 3;
219 sysclks[3].flags |= FIXED_DIV_PLL;
220 sysclks[3].div = 6;
221 sysclks[4].div = PLLDIV4;
222 sysclks[5].div = PLLDIV5;
223
224 c6x_core_clk.parent = &sysclks[1];
225 c6x_i2c_clk.parent = &sysclks[3];
226 c6x_watchdog_clk.parent = &sysclks[5];
227 c6x_mdio_clk.parent = &sysclks[5];
228
229 c6x_clks_init(c6457_clks);
230}
231#endif /* CONFIG_SOC_TMS320C6455 */
232
233#ifdef CONFIG_SOC_TMS320C6472
234static struct clk_lookup c6472_clks[] = {
235 CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
236 CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
237 CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
238 CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
239 CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
240 CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
241 CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
242 CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
243 CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
244 CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
245 CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
246 CLK(NULL, "core", &c6x_core_clk),
247 CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
248 CLK("watchdog", NULL, &c6x_watchdog_clk),
249 CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
250 CLK("", NULL, NULL)
251};
252
253/* assumptions used for delay loop calculations */
254#define MIN_CLKIN1_KHz 15625
255#define MAX_CORE_KHz 700000
256#define MIN_PLLOUT_KHz MIN_CLKIN1_KHz
257
258static void __init c6472_setup_clocks(struct device_node *node)
259{
260 struct pll_data *pll = &c6x_soc_pll1;
261 struct clk *sysclks = pll->sysclks;
262 int i;
263
264 pll->flags = PLL_HAS_MUL;
265
266 for (i = 1; i <= 6; i++) {
267 sysclks[i].flags |= FIXED_DIV_PLL;
268 sysclks[i].div = 1;
269 }
270
271 sysclks[7].flags |= FIXED_DIV_PLL;
272 sysclks[7].div = 3;
273 sysclks[8].flags |= FIXED_DIV_PLL;
274 sysclks[8].div = 6;
275 sysclks[9].flags |= FIXED_DIV_PLL;
276 sysclks[9].div = 2;
277 sysclks[10].div = PLLDIV10;
278
279 c6x_core_clk.parent = &sysclks[get_coreid() + 1];
280 c6x_i2c_clk.parent = &sysclks[8];
281 c6x_watchdog_clk.parent = &sysclks[8];
282 c6x_mdio_clk.parent = &sysclks[5];
283
284 c6x_clks_init(c6472_clks);
285}
286#endif /* CONFIG_SOC_TMS320C6472 */
287
288
289#ifdef CONFIG_SOC_TMS320C6474
290static struct clk_lookup c6474_clks[] = {
291 CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
292 CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
293 CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
294 CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
295 CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
296 CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]),
297 CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]),
298 CLK(NULL, "core", &c6x_core_clk),
299 CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
300 CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk),
301 CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk),
302 CLK("watchdog", NULL, &c6x_watchdog_clk),
303 CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
304 CLK("", NULL, NULL)
305};
306
307static void __init c6474_setup_clocks(struct device_node *node)
308{
309 struct pll_data *pll = &c6x_soc_pll1;
310 struct clk *sysclks = pll->sysclks;
311
312 pll->flags = PLL_HAS_MUL;
313
314 sysclks[7].flags |= FIXED_DIV_PLL;
315 sysclks[7].div = 1;
316 sysclks[9].flags |= FIXED_DIV_PLL;
317 sysclks[9].div = 3;
318 sysclks[10].flags |= FIXED_DIV_PLL;
319 sysclks[10].div = 6;
320
321 sysclks[11].div = PLLDIV11;
322
323 sysclks[12].flags |= FIXED_DIV_PLL;
324 sysclks[12].div = 2;
325
326 sysclks[13].div = PLLDIV13;
327
328 c6x_core_clk.parent = &sysclks[7];
329 c6x_i2c_clk.parent = &sysclks[10];
330 c6x_watchdog_clk.parent = &sysclks[10];
331 c6x_mcbsp1_clk.parent = &sysclks[10];
332 c6x_mcbsp2_clk.parent = &sysclks[10];
333
334 c6x_clks_init(c6474_clks);
335}
336#endif /* CONFIG_SOC_TMS320C6474 */
337
338static struct of_device_id c6x_clkc_match[] __initdata = {
339#ifdef CONFIG_SOC_TMS320C6455
340 { .compatible = "ti,c6455-pll", .data = c6455_setup_clocks },
341#endif
342#ifdef CONFIG_SOC_TMS320C6457
343 { .compatible = "ti,c6457-pll", .data = c6457_setup_clocks },
344#endif
345#ifdef CONFIG_SOC_TMS320C6472
346 { .compatible = "ti,c6472-pll", .data = c6472_setup_clocks },
347#endif
348#ifdef CONFIG_SOC_TMS320C6474
349 { .compatible = "ti,c6474-pll", .data = c6474_setup_clocks },
350#endif
351 { .compatible = "ti,c64x+pll" },
352 {}
353};
354
355void __init c64x_setup_clocks(void)
356{
357 void (*__setup_clocks)(struct device_node *np);
358 struct pll_data *pll = &c6x_soc_pll1;
359 struct device_node *node;
360 const struct of_device_id *id;
361 int err;
362 u32 val;
363
364 node = of_find_matching_node(NULL, c6x_clkc_match);
365 if (!node)
366 return;
367
368 pll->base = of_iomap(node, 0);
369 if (!pll->base)
370 goto out;
371
372 err = of_property_read_u32(node, "clock-frequency", &val);
373 if (err || val == 0) {
374 pr_err("%s: no clock-frequency found! Using %dMHz\n",
375 node->full_name, (int)val / 1000000);
376 val = 25000000;
377 }
378 clkin1.rate = val;
379
380 err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val);
381 if (err)
382 val = 5000;
383 pll->bypass_delay = val;
384
385 err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val);
386 if (err)
387 val = 30000;
388 pll->reset_delay = val;
389
390 err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val);
391 if (err)
392 val = 30000;
393 pll->lock_delay = val;
394
395 /* id->data is a pointer to SoC-specific setup */
396 id = of_match_node(c6x_clkc_match, node);
397 if (id && id->data) {
398 __setup_clocks = id->data;
399 __setup_clocks(node);
400 }
401
402out:
403 of_node_put(node);
404}
diff --git a/arch/c6x/platforms/timer64.c b/arch/c6x/platforms/timer64.c
new file mode 100644
index 00000000000..03c03c24919
--- /dev/null
+++ b/arch/c6x/platforms/timer64.c
@@ -0,0 +1,244 @@
1/*
2 * Copyright (C) 2010, 2011 Texas Instruments Incorporated
3 * Contributed by: Mark Salter (msalter@redhat.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/clockchips.h>
11#include <linux/interrupt.h>
12#include <linux/io.h>
13#include <linux/of.h>
14#include <linux/of_irq.h>
15#include <linux/of_address.h>
16#include <asm/soc.h>
17#include <asm/dscr.h>
18#include <asm/timer64.h>
19
20struct timer_regs {
21 u32 reserved0;
22 u32 emumgt;
23 u32 reserved1;
24 u32 reserved2;
25 u32 cntlo;
26 u32 cnthi;
27 u32 prdlo;
28 u32 prdhi;
29 u32 tcr;
30 u32 tgcr;
31 u32 wdtcr;
32};
33
34static struct timer_regs __iomem *timer;
35
36#define TCR_TSTATLO 0x001
37#define TCR_INVOUTPLO 0x002
38#define TCR_INVINPLO 0x004
39#define TCR_CPLO 0x008
40#define TCR_ENAMODELO_ONCE 0x040
41#define TCR_ENAMODELO_CONT 0x080
42#define TCR_ENAMODELO_MASK 0x0c0
43#define TCR_PWIDLO_MASK 0x030
44#define TCR_CLKSRCLO 0x100
45#define TCR_TIENLO 0x200
46#define TCR_TSTATHI (0x001 << 16)
47#define TCR_INVOUTPHI (0x002 << 16)
48#define TCR_CPHI (0x008 << 16)
49#define TCR_PWIDHI_MASK (0x030 << 16)
50#define TCR_ENAMODEHI_ONCE (0x040 << 16)
51#define TCR_ENAMODEHI_CONT (0x080 << 16)
52#define TCR_ENAMODEHI_MASK (0x0c0 << 16)
53
54#define TGCR_TIMLORS 0x001
55#define TGCR_TIMHIRS 0x002
56#define TGCR_TIMMODE_UD32 0x004
57#define TGCR_TIMMODE_WDT64 0x008
58#define TGCR_TIMMODE_CD32 0x00c
59#define TGCR_TIMMODE_MASK 0x00c
60#define TGCR_PSCHI_MASK (0x00f << 8)
61#define TGCR_TDDRHI_MASK (0x00f << 12)
62
63/*
64 * Timer clocks are divided down from the CPU clock
65 * The divisor is in the EMUMGTCLKSPD register
66 */
67#define TIMER_DIVISOR \
68 ((soc_readl(&timer->emumgt) & (0xf << 16)) >> 16)
69
70#define TIMER64_RATE (c6x_core_freq / TIMER_DIVISOR)
71
72#define TIMER64_MODE_DISABLED 0
73#define TIMER64_MODE_ONE_SHOT TCR_ENAMODELO_ONCE
74#define TIMER64_MODE_PERIODIC TCR_ENAMODELO_CONT
75
76static int timer64_mode;
77static int timer64_devstate_id = -1;
78
79static void timer64_config(unsigned long period)
80{
81 u32 tcr = soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK;
82
83 soc_writel(tcr, &timer->tcr);
84 soc_writel(period - 1, &timer->prdlo);
85 soc_writel(0, &timer->cntlo);
86 tcr |= timer64_mode;
87 soc_writel(tcr, &timer->tcr);
88}
89
90static void timer64_enable(void)
91{
92 u32 val;
93
94 if (timer64_devstate_id >= 0)
95 dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED);
96
97 /* disable timer, reset count */
98 soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr);
99 soc_writel(0, &timer->prdlo);
100
101 /* use internal clock and 1 cycle pulse width */
102 val = soc_readl(&timer->tcr);
103 soc_writel(val & ~(TCR_CLKSRCLO | TCR_PWIDLO_MASK), &timer->tcr);
104
105 /* dual 32-bit unchained mode */
106 val = soc_readl(&timer->tgcr) & ~TGCR_TIMMODE_MASK;
107 soc_writel(val, &timer->tgcr);
108 soc_writel(val | (TGCR_TIMLORS | TGCR_TIMMODE_UD32), &timer->tgcr);
109}
110
111static void timer64_disable(void)
112{
113 /* disable timer, reset count */
114 soc_writel(soc_readl(&timer->tcr) & ~TCR_ENAMODELO_MASK, &timer->tcr);
115 soc_writel(0, &timer->prdlo);
116
117 if (timer64_devstate_id >= 0)
118 dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_DISABLED);
119}
120
121static int next_event(unsigned long delta,
122 struct clock_event_device *evt)
123{
124 timer64_config(delta);
125 return 0;
126}
127
128static void set_clock_mode(enum clock_event_mode mode,
129 struct clock_event_device *evt)
130{
131 switch (mode) {
132 case CLOCK_EVT_MODE_PERIODIC:
133 timer64_enable();
134 timer64_mode = TIMER64_MODE_PERIODIC;
135 timer64_config(TIMER64_RATE / HZ);
136 break;
137 case CLOCK_EVT_MODE_ONESHOT:
138 timer64_enable();
139 timer64_mode = TIMER64_MODE_ONE_SHOT;
140 break;
141 case CLOCK_EVT_MODE_UNUSED:
142 case CLOCK_EVT_MODE_SHUTDOWN:
143 timer64_mode = TIMER64_MODE_DISABLED;
144 timer64_disable();
145 break;
146 case CLOCK_EVT_MODE_RESUME:
147 break;
148 }
149}
150
151static struct clock_event_device t64_clockevent_device = {
152 .name = "TIMER64_EVT32_TIMER",
153 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
154 .rating = 200,
155 .set_mode = set_clock_mode,
156 .set_next_event = next_event,
157};
158
159static irqreturn_t timer_interrupt(int irq, void *dev_id)
160{
161 struct clock_event_device *cd = &t64_clockevent_device;
162
163 cd->event_handler(cd);
164
165 return IRQ_HANDLED;
166}
167
168static struct irqaction timer_iact = {
169 .name = "timer",
170 .flags = IRQF_TIMER,
171 .handler = timer_interrupt,
172 .dev_id = &t64_clockevent_device,
173};
174
175void __init timer64_init(void)
176{
177 struct clock_event_device *cd = &t64_clockevent_device;
178 struct device_node *np, *first = NULL;
179 u32 val;
180 int err, found = 0;
181
182 for_each_compatible_node(np, NULL, "ti,c64x+timer64") {
183 err = of_property_read_u32(np, "ti,core-mask", &val);
184 if (!err) {
185 if (val & (1 << get_coreid())) {
186 found = 1;
187 break;
188 }
189 } else if (!first)
190 first = np;
191 }
192 if (!found) {
193 /* try first one with no core-mask */
194 if (first)
195 np = of_node_get(first);
196 else {
197 pr_debug("Cannot find ti,c64x+timer64 timer.\n");
198 return;
199 }
200 }
201
202 timer = of_iomap(np, 0);
203 if (!timer) {
204 pr_debug("%s: Cannot map timer registers.\n", np->full_name);
205 goto out;
206 }
207 pr_debug("%s: Timer registers=%p.\n", np->full_name, timer);
208
209 cd->irq = irq_of_parse_and_map(np, 0);
210 if (cd->irq == NO_IRQ) {
211 pr_debug("%s: Cannot find interrupt.\n", np->full_name);
212 iounmap(timer);
213 goto out;
214 }
215
216 /* If there is a device state control, save the ID. */
217 err = of_property_read_u32(np, "ti,dscr-dev-enable", &val);
218 if (!err) {
219 timer64_devstate_id = val;
220
221 /*
222 * It is necessary to enable the timer block here because
223 * the TIMER_DIVISOR macro needs to read a timer register
224 * to get the divisor.
225 */
226 dscr_set_devstate(timer64_devstate_id, DSCR_DEVSTATE_ENABLED);
227 }
228
229 pr_debug("%s: Timer irq=%d.\n", np->full_name, cd->irq);
230
231 clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5);
232
233 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
234 cd->min_delta_ns = clockevent_delta2ns(250, cd);
235
236 cd->cpumask = cpumask_of(smp_processor_id());
237
238 clockevents_register_device(cd);
239 setup_irq(cd->irq, &timer_iact);
240
241out:
242 of_node_put(np);
243 return;
244}
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 408b055c585..b3abfb08aa5 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -19,10 +19,6 @@ config GENERIC_CMOS_UPDATE
19config ARCH_USES_GETTIMEOFFSET 19config ARCH_USES_GETTIMEOFFSET
20 def_bool n 20 def_bool n
21 21
22config GENERIC_IOMAP
23 bool
24 default y
25
26config ARCH_HAS_ILOG2_U32 22config ARCH_HAS_ILOG2_U32
27 bool 23 bool
28 default n 24 default n
@@ -52,6 +48,7 @@ config CRIS
52 select HAVE_IDE 48 select HAVE_IDE
53 select HAVE_GENERIC_HARDIRQS 49 select HAVE_GENERIC_HARDIRQS
54 select GENERIC_IRQ_SHOW 50 select GENERIC_IRQ_SHOW
51 select GENERIC_IOMAP
55 52
56config HZ 53config HZ
57 int 54 int
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index a2bde374462..b34438e026b 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -404,8 +404,7 @@ static int __init init_axis_flash(void)
404 */ 404 */
405 int blockstat; 405 int blockstat;
406 do { 406 do {
407 blockstat = main_mtd->block_isbad(main_mtd, 407 blockstat = mtd_block_isbad(main_mtd, ptable_sector);
408 ptable_sector);
409 if (blockstat < 0) 408 if (blockstat < 0)
410 ptable_sector = 0; /* read error */ 409 ptable_sector = 0; /* read error */
411 else if (blockstat) 410 else if (blockstat)
@@ -413,8 +412,8 @@ static int __init init_axis_flash(void)
413 } while (blockstat && ptable_sector); 412 } while (blockstat && ptable_sector);
414#endif 413#endif
415 if (ptable_sector) { 414 if (ptable_sector) {
416 main_mtd->read(main_mtd, ptable_sector, PAGESIZE, 415 mtd_read(main_mtd, ptable_sector, PAGESIZE, &len,
417 &len, page); 416 page);
418 ptable_head = &((struct partitiontable *) page)->head; 417 ptable_head = &((struct partitiontable *) page)->head;
419 } 418 }
420 419
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index c5e69abb488..bbbf7927f23 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -317,6 +317,7 @@ config PCI
317 bool "Use PCI" 317 bool "Use PCI"
318 depends on MB93090_MB00 318 depends on MB93090_MB00
319 default y 319 default y
320 select GENERIC_PCI_IOMAP
320 help 321 help
321 Some FR-V systems (such as the MB93090-MB00 VDK) have PCI 322 Some FR-V systems (such as the MB93090-MB00 VDK) have PCI
322 onboard. If you have one of these boards and you wish to use the PCI 323 onboard. If you have one of these boards and you wish to use the PCI
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index ca7475e73b5..8cb50a2fbcb 100644
--- a/arch/frv/include/asm/io.h
+++ b/arch/frv/include/asm/io.h
@@ -21,6 +21,7 @@
21#include <asm/virtconvert.h> 21#include <asm/virtconvert.h>
22#include <asm/string.h> 22#include <asm/string.h>
23#include <asm/mb-regs.h> 23#include <asm/mb-regs.h>
24#include <asm-generic/pci_iomap.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25 26
26/* 27/*
@@ -370,7 +371,6 @@ static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long
370 371
371/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 372/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
372struct pci_dev; 373struct pci_dev;
373extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
374static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) 374static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
375{ 375{
376} 376}
diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
index b73b542f8f4..21f1df1b378 100644
--- a/arch/frv/mb93090-mb00/Makefile
+++ b/arch/frv/mb93090-mb00/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5ifeq "$(CONFIG_PCI)" "y" 5ifeq "$(CONFIG_PCI)" "y"
6obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o 6obj-y := pci-frv.o pci-irq.o pci-vdk.o
7 7
8ifeq "$(CONFIG_MMU)" "y" 8ifeq "$(CONFIG_MMU)" "y"
9obj-y += pci-dma.o 9obj-y += pci-dma.o
diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c
deleted file mode 100644
index 35f6df28351..00000000000
--- a/arch/frv/mb93090-mb00/pci-iomap.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/* pci-iomap.c: description
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/pci.h>
12#include <linux/module.h>
13
14void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
15{
16 resource_size_t start = pci_resource_start(dev, bar);
17 resource_size_t len = pci_resource_len(dev, bar);
18 unsigned long flags = pci_resource_flags(dev, bar);
19
20 if (!len || !start)
21 return NULL;
22
23 if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
24 return (void __iomem *) start;
25
26 return NULL;
27}
28
29EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 02513c2dd5e..9059e390588 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -26,6 +26,7 @@ config HEXAGON
26 select HAVE_ARCH_KGDB 26 select HAVE_ARCH_KGDB
27 select HAVE_ARCH_TRACEHOOK 27 select HAVE_ARCH_TRACEHOOK
28 select NO_IOPORT 28 select NO_IOPORT
29 select GENERIC_IOMAP
29 # mostly generic routines, with some accelerated ones 30 # mostly generic routines, with some accelerated ones
30 ---help--- 31 ---help---
31 Qualcomm Hexagon is a processor architecture designed for high 32 Qualcomm Hexagon is a processor architecture designed for high
@@ -73,9 +74,6 @@ config GENERIC_CSUM
73config GENERIC_IRQ_PROBE 74config GENERIC_IRQ_PROBE
74 def_bool y 75 def_bool y
75 76
76config GENERIC_IOMAP
77 def_bool y
78
79#config ZONE_DMA 77#config ZONE_DMA
80# bool 78# bool
81# default y 79# default y
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 3b7a7c48378..bd7266903bf 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -32,6 +32,7 @@ config IA64
32 select GENERIC_IRQ_SHOW 32 select GENERIC_IRQ_SHOW
33 select ARCH_WANT_OPTIONAL_GPIOLIB 33 select ARCH_WANT_OPTIONAL_GPIOLIB
34 select ARCH_HAVE_NMI_SAFE_CMPXCHG 34 select ARCH_HAVE_NMI_SAFE_CMPXCHG
35 select GENERIC_IOMAP
35 default y 36 default y
36 help 37 help
37 The Itanium Processor Family is Intel's 64-bit successor to 38 The Itanium Processor Family is Intel's 64-bit successor to
@@ -105,10 +106,6 @@ config EFI
105 bool 106 bool
106 default y 107 default y
107 108
108config GENERIC_IOMAP
109 bool
110 default y
111
112config ARCH_CLOCKSOURCE_DATA 109config ARCH_CLOCKSOURCE_DATA
113 def_bool y 110 def_bool y
114 111
diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h
index 105c93b00b1..b6a809fa299 100644
--- a/arch/ia64/include/asm/iommu.h
+++ b/arch/ia64/include/asm/iommu.h
@@ -11,10 +11,12 @@ extern void no_iommu_init(void);
11extern int force_iommu, no_iommu; 11extern int force_iommu, no_iommu;
12extern int iommu_pass_through; 12extern int iommu_pass_through;
13extern int iommu_detected; 13extern int iommu_detected;
14extern int iommu_group_mf;
14#else 15#else
15#define iommu_pass_through (0) 16#define iommu_pass_through (0)
16#define no_iommu (1) 17#define no_iommu (1)
17#define iommu_detected (0) 18#define iommu_detected (0)
19#define iommu_group_mf (0)
18#endif 20#endif
19extern void iommu_dma_init(void); 21extern void iommu_dma_init(void);
20extern void machvec_init(const char *name); 22extern void machvec_init(const char *name);
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h
index 1d2427d116e..fbb519828aa 100644
--- a/arch/ia64/include/asm/xen/interface.h
+++ b/arch/ia64/include/asm/xen/interface.h
@@ -71,7 +71,7 @@
71__DEFINE_GUEST_HANDLE(uchar, unsigned char); 71__DEFINE_GUEST_HANDLE(uchar, unsigned char);
72__DEFINE_GUEST_HANDLE(uint, unsigned int); 72__DEFINE_GUEST_HANDLE(uint, unsigned int);
73__DEFINE_GUEST_HANDLE(ulong, unsigned long); 73__DEFINE_GUEST_HANDLE(ulong, unsigned long);
74__DEFINE_GUEST_HANDLE(u64, unsigned long); 74
75DEFINE_GUEST_HANDLE(char); 75DEFINE_GUEST_HANDLE(char);
76DEFINE_GUEST_HANDLE(int); 76DEFINE_GUEST_HANDLE(int);
77DEFINE_GUEST_HANDLE(long); 77DEFINE_GUEST_HANDLE(long);
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index c16162c7086..eb117572005 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -33,6 +33,7 @@ int force_iommu __read_mostly;
33#endif 33#endif
34 34
35int iommu_pass_through; 35int iommu_pass_through;
36int iommu_group_mf;
36 37
37/* Dummy device used for NULL arguments (normally ISA). Better would 38/* Dummy device used for NULL arguments (normally ISA). Better would
38 be probably a smaller DMA mask, but this is bug-to-bug compatible 39 be probably a smaller DMA mask, but this is bug-to-bug compatible
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 43f4c92816e..40505200249 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -774,13 +774,13 @@ struct kvm *kvm_arch_alloc_vm(void)
774 return kvm; 774 return kvm;
775} 775}
776 776
777struct kvm_io_range { 777struct kvm_ia64_io_range {
778 unsigned long start; 778 unsigned long start;
779 unsigned long size; 779 unsigned long size;
780 unsigned long type; 780 unsigned long type;
781}; 781};
782 782
783static const struct kvm_io_range io_ranges[] = { 783static const struct kvm_ia64_io_range io_ranges[] = {
784 {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER}, 784 {VGA_IO_START, VGA_IO_SIZE, GPFN_FRAME_BUFFER},
785 {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO}, 785 {MMIO_START, MMIO_SIZE, GPFN_LOW_MMIO},
786 {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO}, 786 {LEGACY_IO_START, LEGACY_IO_SIZE, GPFN_LEGACY_IO},
@@ -1366,14 +1366,12 @@ static void kvm_release_vm_pages(struct kvm *kvm)
1366{ 1366{
1367 struct kvm_memslots *slots; 1367 struct kvm_memslots *slots;
1368 struct kvm_memory_slot *memslot; 1368 struct kvm_memory_slot *memslot;
1369 int i, j; 1369 int j;
1370 unsigned long base_gfn; 1370 unsigned long base_gfn;
1371 1371
1372 slots = kvm_memslots(kvm); 1372 slots = kvm_memslots(kvm);
1373 for (i = 0; i < slots->nmemslots; i++) { 1373 kvm_for_each_memslot(memslot, slots) {
1374 memslot = &slots->memslots[i];
1375 base_gfn = memslot->base_gfn; 1374 base_gfn = memslot->base_gfn;
1376
1377 for (j = 0; j < memslot->npages; j++) { 1375 for (j = 0; j < memslot->npages; j++) {
1378 if (memslot->rmap[j]) 1376 if (memslot->rmap[j])
1379 put_page((struct page *)memslot->rmap[j]); 1377 put_page((struct page *)memslot->rmap[j]);
@@ -1820,7 +1818,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
1820 if (log->slot >= KVM_MEMORY_SLOTS) 1818 if (log->slot >= KVM_MEMORY_SLOTS)
1821 goto out; 1819 goto out;
1822 1820
1823 memslot = &kvm->memslots->memslots[log->slot]; 1821 memslot = id_to_memslot(kvm->memslots, log->slot);
1824 r = -ENOENT; 1822 r = -ENOENT;
1825 if (!memslot->dirty_bitmap) 1823 if (!memslot->dirty_bitmap)
1826 goto out; 1824 goto out;
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 81fdaa72c54..99c363617f2 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -37,9 +37,6 @@ config GENERIC_CALIBRATE_DELAY
37 bool 37 bool
38 default y 38 default y
39 39
40config GENERIC_IOMAP
41 def_bool MMU
42
43config GENERIC_CSUM 40config GENERIC_CSUM
44 bool 41 bool
45 42
@@ -81,6 +78,7 @@ source "kernel/Kconfig.freezer"
81config MMU 78config MMU
82 bool "MMU-based Paged Memory Management Support" 79 bool "MMU-based Paged Memory Management Support"
83 default y 80 default y
81 select GENERIC_IOMAP
84 help 82 help
85 Select if you want MMU-based virtualised addressing space 83 Select if you want MMU-based virtualised addressing space
86 support by paged memory management. If unsure, say 'Y'. 84 support by paged memory management. If unsure, say 'Y'.
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index e446bab2427..f0eead74fff 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -17,6 +17,7 @@ config MICROBLAZE
17 select HAVE_GENERIC_HARDIRQS 17 select HAVE_GENERIC_HARDIRQS
18 select GENERIC_IRQ_PROBE 18 select GENERIC_IRQ_PROBE
19 select GENERIC_IRQ_SHOW 19 select GENERIC_IRQ_SHOW
20 select GENERIC_PCI_IOMAP
20 21
21config SWAP 22config SWAP
22 def_bool n 23 def_bool n
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index cc54187f3d3..a175132e449 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -9,7 +9,14 @@
9#ifndef _ASM_MICROBLAZE_IRQ_H 9#ifndef _ASM_MICROBLAZE_IRQ_H
10#define _ASM_MICROBLAZE_IRQ_H 10#define _ASM_MICROBLAZE_IRQ_H
11 11
12#define NR_IRQS 32 12
13/*
14 * Linux IRQ# is currently offset by one to map to the hardware
15 * irq number. So hardware IRQ0 maps to Linux irq 1.
16 */
17#define NO_IRQ_OFFSET 1
18#define IRQ_OFFSET NO_IRQ_OFFSET
19#define NR_IRQS (32 + IRQ_OFFSET)
13#include <asm-generic/irq.h> 20#include <asm-generic/irq.h>
14 21
15/* This type is the placeholder for a hardware interrupt number. It has to 22/* This type is the placeholder for a hardware interrupt number. It has to
@@ -20,8 +27,6 @@ typedef unsigned long irq_hw_number_t;
20 27
21extern unsigned int nr_irq; 28extern unsigned int nr_irq;
22 29
23#define NO_IRQ (-1)
24
25struct pt_regs; 30struct pt_regs;
26extern void do_IRQ(struct pt_regs *regs); 31extern void do_IRQ(struct pt_regs *regs);
27 32
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index ed9d0f6e2cd..a25e6b5e2ad 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -174,15 +174,8 @@ extern int page_is_ram(unsigned long pfn);
174 174
175#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) 175#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
176 176
177 177# define __pa(x) __virt_to_phys((unsigned long)(x))
178# ifndef CONFIG_MMU 178# define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
179# define __pa(vaddr) ((unsigned long) (vaddr))
180# define __va(paddr) ((void *) (paddr))
181# else /* CONFIG_MMU */
182# define __pa(x) __virt_to_phys((unsigned long)(x))
183# define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
184# endif /* CONFIG_MMU */
185
186 179
187/* Convert between virtual and physical address for MMU. */ 180/* Convert between virtual and physical address for MMU. */
188/* Handle MicroBlaze processor with virtual memory. */ 181/* Handle MicroBlaze processor with virtual memory. */
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
index 904e5ef6a11..6c72ed7eba9 100644
--- a/arch/microblaze/include/asm/setup.h
+++ b/arch/microblaze/include/asm/setup.h
@@ -26,12 +26,6 @@ int setup_early_printk(char *opt);
26void remap_early_printk(void); 26void remap_early_printk(void);
27void disable_early_printk(void); 27void disable_early_printk(void);
28 28
29#if defined(CONFIG_EARLY_PRINTK)
30#define eprintk early_printk
31#else
32#define eprintk printk
33#endif
34
35void heartbeat(void); 29void heartbeat(void);
36void setup_heartbeat(void); 30void setup_heartbeat(void);
37 31
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 7d7092b917a..d20ffbc86be 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -391,8 +391,11 @@
391#define __NR_clock_adjtime 373 391#define __NR_clock_adjtime 373
392#define __NR_syncfs 374 392#define __NR_syncfs 374
393#define __NR_setns 375 393#define __NR_setns 375
394#define __NR_sendmmsg 376
395#define __NR_process_vm_readv 377
396#define __NR_process_vm_writev 378
394 397
395#define __NR_syscalls 376 398#define __NR_syscalls 379
396 399
397#ifdef __KERNEL__ 400#ifdef __KERNEL__
398#ifndef __ASSEMBLY__ 401#ifndef __ASSEMBLY__
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index d26d92d4775..8356e47631c 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -50,9 +50,9 @@ static void early_printk_uartlite_write(struct console *unused,
50 const char *s, unsigned n) 50 const char *s, unsigned n)
51{ 51{
52 while (*s && n-- > 0) { 52 while (*s && n-- > 0) {
53 early_printk_uartlite_putc(*s);
54 if (*s == '\n') 53 if (*s == '\n')
55 early_printk_uartlite_putc('\r'); 54 early_printk_uartlite_putc('\r');
55 early_printk_uartlite_putc(*s);
56 s++; 56 s++;
57 } 57 }
58} 58}
@@ -94,9 +94,9 @@ static void early_printk_uart16550_write(struct console *unused,
94 const char *s, unsigned n) 94 const char *s, unsigned n)
95{ 95{
96 while (*s && n-- > 0) { 96 while (*s && n-- > 0) {
97 early_printk_uart16550_putc(*s);
98 if (*s == '\n') 97 if (*s == '\n')
99 early_printk_uart16550_putc('\r'); 98 early_printk_uart16550_putc('\r');
99 early_printk_uart16550_putc(*s);
100 s++; 100 s++;
101 } 101 }
102} 102}
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index ca15bc5c744..66e34a3bfe1 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -468,7 +468,7 @@ C_ENTRY(sys_fork_wrapper):
468 addi r5, r0, SIGCHLD /* Arg 0: flags */ 468 addi r5, r0, SIGCHLD /* Arg 0: flags */
469 lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */ 469 lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
470 addik r7, r1, 0 /* Arg 2: parent context */ 470 addik r7, r1, 0 /* Arg 2: parent context */
471 add r8. r0, r0 /* Arg 3: (unused) */ 471 add r8, r0, r0 /* Arg 3: (unused) */
472 add r9, r0, r0; /* Arg 4: (unused) */ 472 add r9, r0, r0; /* Arg 4: (unused) */
473 brid do_fork /* Do real work (tail-call) */ 473 brid do_fork /* Do real work (tail-call) */
474 add r10, r0, r0; /* Arg 5: (unused) */ 474 add r10, r0, r0; /* Arg 5: (unused) */
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index eb41441c7fd..44b177e2ab1 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -42,8 +42,9 @@ unsigned int nr_irq;
42 42
43static void intc_enable_or_unmask(struct irq_data *d) 43static void intc_enable_or_unmask(struct irq_data *d)
44{ 44{
45 unsigned long mask = 1 << d->irq; 45 unsigned long mask = 1 << d->hwirq;
46 pr_debug("enable_or_unmask: %d\n", d->irq); 46
47 pr_debug("enable_or_unmask: %ld\n", d->hwirq);
47 out_be32(INTC_BASE + SIE, mask); 48 out_be32(INTC_BASE + SIE, mask);
48 49
49 /* ack level irqs because they can't be acked during 50 /* ack level irqs because they can't be acked during
@@ -56,20 +57,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
56 57
57static void intc_disable_or_mask(struct irq_data *d) 58static void intc_disable_or_mask(struct irq_data *d)
58{ 59{
59 pr_debug("disable: %d\n", d->irq); 60 pr_debug("disable: %ld\n", d->hwirq);
60 out_be32(INTC_BASE + CIE, 1 << d->irq); 61 out_be32(INTC_BASE + CIE, 1 << d->hwirq);
61} 62}
62 63
63static void intc_ack(struct irq_data *d) 64static void intc_ack(struct irq_data *d)
64{ 65{
65 pr_debug("ack: %d\n", d->irq); 66 pr_debug("ack: %ld\n", d->hwirq);
66 out_be32(INTC_BASE + IAR, 1 << d->irq); 67 out_be32(INTC_BASE + IAR, 1 << d->hwirq);
67} 68}
68 69
69static void intc_mask_ack(struct irq_data *d) 70static void intc_mask_ack(struct irq_data *d)
70{ 71{
71 unsigned long mask = 1 << d->irq; 72 unsigned long mask = 1 << d->hwirq;
72 pr_debug("disable_and_ack: %d\n", d->irq); 73
74 pr_debug("disable_and_ack: %ld\n", d->hwirq);
73 out_be32(INTC_BASE + CIE, mask); 75 out_be32(INTC_BASE + CIE, mask);
74 out_be32(INTC_BASE + IAR, mask); 76 out_be32(INTC_BASE + IAR, mask);
75} 77}
@@ -91,7 +93,7 @@ unsigned int get_irq(struct pt_regs *regs)
91 * order to handle multiple interrupt controllers. It currently 93 * order to handle multiple interrupt controllers. It currently
92 * is hardcoded to check for interrupts only on the first INTC. 94 * is hardcoded to check for interrupts only on the first INTC.
93 */ 95 */
94 irq = in_be32(INTC_BASE + IVR); 96 irq = in_be32(INTC_BASE + IVR) + NO_IRQ_OFFSET;
95 pr_debug("get_irq: %d\n", irq); 97 pr_debug("get_irq: %d\n", irq);
96 98
97 return irq; 99 return irq;
@@ -99,7 +101,7 @@ unsigned int get_irq(struct pt_regs *regs)
99 101
100void __init init_IRQ(void) 102void __init init_IRQ(void)
101{ 103{
102 u32 i, j, intr_type; 104 u32 i, intr_mask;
103 struct device_node *intc = NULL; 105 struct device_node *intc = NULL;
104#ifdef CONFIG_SELFMOD_INTC 106#ifdef CONFIG_SELFMOD_INTC
105 unsigned int intc_baseaddr = 0; 107 unsigned int intc_baseaddr = 0;
@@ -113,35 +115,24 @@ void __init init_IRQ(void)
113 0 115 0
114 }; 116 };
115#endif 117#endif
116 const char * const intc_list[] = { 118 intc = of_find_compatible_node(NULL, NULL, "xlnx,xps-intc-1.00.a");
117 "xlnx,xps-intc-1.00.a",
118 NULL
119 };
120
121 for (j = 0; intc_list[j] != NULL; j++) {
122 intc = of_find_compatible_node(NULL, NULL, intc_list[j]);
123 if (intc)
124 break;
125 }
126 BUG_ON(!intc); 119 BUG_ON(!intc);
127 120
128 intc_baseaddr = be32_to_cpup(of_get_property(intc, 121 intc_baseaddr = be32_to_cpup(of_get_property(intc, "reg", NULL));
129 "reg", NULL));
130 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 122 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
131 nr_irq = be32_to_cpup(of_get_property(intc, 123 nr_irq = be32_to_cpup(of_get_property(intc,
132 "xlnx,num-intr-inputs", NULL)); 124 "xlnx,num-intr-inputs", NULL));
133 125
134 intr_type = 126 intr_mask =
135 be32_to_cpup(of_get_property(intc, 127 be32_to_cpup(of_get_property(intc, "xlnx,kind-of-intr", NULL));
136 "xlnx,kind-of-intr", NULL)); 128 if (intr_mask > (u32)((1ULL << nr_irq) - 1))
137 if (intr_type > (u32)((1ULL << nr_irq) - 1))
138 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 129 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
139 130
140#ifdef CONFIG_SELFMOD_INTC 131#ifdef CONFIG_SELFMOD_INTC
141 selfmod_function((int *) arr_func, intc_baseaddr); 132 selfmod_function((int *) arr_func, intc_baseaddr);
142#endif 133#endif
143 printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n", 134 printk(KERN_INFO "XPS intc #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
144 intc_list[j], intc_baseaddr, nr_irq, intr_type); 135 intc_baseaddr, nr_irq, intr_mask);
145 136
146 /* 137 /*
147 * Disable all external interrupts until they are 138 * Disable all external interrupts until they are
@@ -155,8 +146,8 @@ void __init init_IRQ(void)
155 /* Turn on the Master Enable. */ 146 /* Turn on the Master Enable. */
156 out_be32(intc_baseaddr + MER, MER_HIE | MER_ME); 147 out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
157 148
158 for (i = 0; i < nr_irq; ++i) { 149 for (i = IRQ_OFFSET; i < (nr_irq + IRQ_OFFSET); ++i) {
159 if (intr_type & (0x00000001 << i)) { 150 if (intr_mask & (0x00000001 << (i - IRQ_OFFSET))) {
160 irq_set_chip_and_handler_name(i, &intc_dev, 151 irq_set_chip_and_handler_name(i, &intc_dev,
161 handle_edge_irq, "edge"); 152 handle_edge_irq, "edge");
162 irq_clear_status_flags(i, IRQ_LEVEL); 153 irq_clear_status_flags(i, IRQ_LEVEL);
@@ -165,5 +156,6 @@ void __init init_IRQ(void)
165 handle_level_irq, "level"); 156 handle_level_irq, "level");
166 irq_set_status_flags(i, IRQ_LEVEL); 157 irq_set_status_flags(i, IRQ_LEVEL);
167 } 158 }
159 irq_get_irq_data(i)->hwirq = i - IRQ_OFFSET;
168 } 160 }
169} 161}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index e5d63a89b9b..bbebcae72c0 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -33,11 +33,12 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
33 irq_enter(); 33 irq_enter();
34 irq = get_irq(regs); 34 irq = get_irq(regs);
35next_irq: 35next_irq:
36 BUG_ON(irq == -1U); 36 BUG_ON(!irq);
37 generic_handle_irq(irq); 37 /* Substract 1 because of get_irq */
38 generic_handle_irq(irq + IRQ_OFFSET - NO_IRQ_OFFSET);
38 39
39 irq = get_irq(regs); 40 irq = get_irq(regs);
40 if (irq != -1U) { 41 if (irq) {
41 pr_debug("next irq: %d\n", irq); 42 pr_debug("next irq: %d\n", irq);
42 ++concurrent_irq; 43 ++concurrent_irq;
43 goto next_irq; 44 goto next_irq;
@@ -52,13 +53,13 @@ next_irq:
52 intc without any cascades or any connection that's why mapping is 1:1 */ 53 intc without any cascades or any connection that's why mapping is 1:1 */
53unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) 54unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
54{ 55{
55 return hwirq; 56 return hwirq + IRQ_OFFSET;
56} 57}
57EXPORT_SYMBOL_GPL(irq_create_mapping); 58EXPORT_SYMBOL_GPL(irq_create_mapping);
58 59
59unsigned int irq_create_of_mapping(struct device_node *controller, 60unsigned int irq_create_of_mapping(struct device_node *controller,
60 const u32 *intspec, unsigned int intsize) 61 const u32 *intspec, unsigned int intsize)
61{ 62{
62 return intspec[0]; 63 return intspec[0] + IRQ_OFFSET;
63} 64}
64EXPORT_SYMBOL_GPL(irq_create_of_mapping); 65EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
index 142426f631b..f39257a5abc 100644
--- a/arch/microblaze/kernel/module.c
+++ b/arch/microblaze/kernel/module.c
@@ -100,7 +100,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
100 break; 100 break;
101 101
102 case R_MICROBLAZE_64_NONE: 102 case R_MICROBLAZE_64_NONE:
103 pr_debug("R_MICROBLAZE_NONE\n"); 103 pr_debug("R_MICROBLAZE_64_NONE\n");
104 break; 104 break;
105 105
106 case R_MICROBLAZE_NONE: 106 case R_MICROBLAZE_NONE:
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 0e654a12d37..604cd9dd133 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -145,32 +145,32 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
145 setup_early_printk(NULL); 145 setup_early_printk(NULL);
146#endif 146#endif
147 147
148 eprintk("Ramdisk addr 0x%08x, ", ram); 148 printk("Ramdisk addr 0x%08x, ", ram);
149 if (fdt) 149 if (fdt)
150 eprintk("FDT at 0x%08x\n", fdt); 150 printk("FDT at 0x%08x\n", fdt);
151 else 151 else
152 eprintk("Compiled-in FDT at 0x%08x\n", 152 printk("Compiled-in FDT at 0x%08x\n",
153 (unsigned int)_fdt_start); 153 (unsigned int)_fdt_start);
154 154
155#ifdef CONFIG_MTD_UCLINUX 155#ifdef CONFIG_MTD_UCLINUX
156 eprintk("Found romfs @ 0x%08x (0x%08x)\n", 156 printk("Found romfs @ 0x%08x (0x%08x)\n",
157 romfs_base, romfs_size); 157 romfs_base, romfs_size);
158 eprintk("#### klimit %p ####\n", old_klimit); 158 printk("#### klimit %p ####\n", old_klimit);
159 BUG_ON(romfs_size < 0); /* What else can we do? */ 159 BUG_ON(romfs_size < 0); /* What else can we do? */
160 160
161 eprintk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", 161 printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
162 romfs_size, romfs_base, (unsigned)&_ebss); 162 romfs_size, romfs_base, (unsigned)&_ebss);
163 163
164 eprintk("New klimit: 0x%08x\n", (unsigned)klimit); 164 printk("New klimit: 0x%08x\n", (unsigned)klimit);
165#endif 165#endif
166 166
167#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 167#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
168 if (msr) 168 if (msr)
169 eprintk("!!!Your kernel has setup MSR instruction but " 169 printk("!!!Your kernel has setup MSR instruction but "
170 "CPU don't have it %x\n", msr); 170 "CPU don't have it %x\n", msr);
171#else 171#else
172 if (!msr) 172 if (!msr)
173 eprintk("!!!Your kernel not setup MSR instruction but " 173 printk("!!!Your kernel not setup MSR instruction but "
174 "CPU have it %x\n", msr); 174 "CPU have it %x\n", msr);
175#endif 175#endif
176 176
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 8789daa2a34..6a2b294ef6d 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -380,3 +380,6 @@ ENTRY(sys_call_table)
380 .long sys_clock_adjtime 380 .long sys_clock_adjtime
381 .long sys_syncfs 381 .long sys_syncfs
382 .long sys_setns /* 375 */ 382 .long sys_setns /* 375 */
383 .long sys_sendmmsg
384 .long sys_process_vm_readv
385 .long sys_process_vm_writev
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index af74b1113aa..3cb0bf64013 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -243,7 +243,7 @@ static int timer_initialized;
243 243
244void __init time_init(void) 244void __init time_init(void)
245{ 245{
246 u32 irq, i = 0; 246 u32 irq;
247 u32 timer_num = 1; 247 u32 timer_num = 1;
248 struct device_node *timer = NULL; 248 struct device_node *timer = NULL;
249 const void *prop; 249 const void *prop;
@@ -258,33 +258,24 @@ void __init time_init(void)
258 0 258 0
259 }; 259 };
260#endif 260#endif
261 const char * const timer_list[] = { 261 timer = of_find_compatible_node(NULL, NULL, "xlnx,xps-timer-1.00.a");
262 "xlnx,xps-timer-1.00.a",
263 NULL
264 };
265
266 for (i = 0; timer_list[i] != NULL; i++) {
267 timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
268 if (timer)
269 break;
270 }
271 BUG_ON(!timer); 262 BUG_ON(!timer);
272 263
273 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); 264 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
274 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 265 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
275 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); 266 irq = irq_of_parse_and_map(timer, 0);
276 timer_num = be32_to_cpup(of_get_property(timer, 267 timer_num = be32_to_cpup(of_get_property(timer,
277 "xlnx,one-timer-only", NULL)); 268 "xlnx,one-timer-only", NULL));
278 if (timer_num) { 269 if (timer_num) {
279 eprintk(KERN_EMERG "Please enable two timers in HW\n"); 270 printk(KERN_EMERG "Please enable two timers in HW\n");
280 BUG(); 271 BUG();
281 } 272 }
282 273
283#ifdef CONFIG_SELFMOD_TIMER 274#ifdef CONFIG_SELFMOD_TIMER
284 selfmod_function((int *) arr_func, timer_baseaddr); 275 selfmod_function((int *) arr_func, timer_baseaddr);
285#endif 276#endif
286 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", 277 printk(KERN_INFO "XPS timer #0 at 0x%08x, irq=%d\n",
287 timer_list[i], timer_baseaddr, irq); 278 timer_baseaddr, irq);
288 279
289 /* If there is clock-frequency property than use it */ 280 /* If there is clock-frequency property than use it */
290 prop = of_get_property(timer, "clock-frequency", NULL); 281 prop = of_get_property(timer, "clock-frequency", NULL);
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index c13067b243c..844960e8ae1 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -20,6 +20,7 @@ lib-y += uaccess_old.o
20 20
21lib-y += ashldi3.o 21lib-y += ashldi3.o
22lib-y += ashrdi3.o 22lib-y += ashrdi3.o
23lib-y += cmpdi2.o
23lib-y += divsi3.o 24lib-y += divsi3.o
24lib-y += lshrdi3.o 25lib-y += lshrdi3.o
25lib-y += modsi3.o 26lib-y += modsi3.o
diff --git a/arch/microblaze/lib/cmpdi2.c b/arch/microblaze/lib/cmpdi2.c
new file mode 100644
index 00000000000..a708400ea7b
--- /dev/null
+++ b/arch/microblaze/lib/cmpdi2.c
@@ -0,0 +1,26 @@
1#include <linux/module.h>
2
3#include "libgcc.h"
4
5word_type __cmpdi2(long long a, long long b)
6{
7 const DWunion au = {
8 .ll = a
9 };
10 const DWunion bu = {
11 .ll = b
12 };
13
14 if (au.s.high < bu.s.high)
15 return 0;
16 else if (au.s.high > bu.s.high)
17 return 2;
18
19 if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
20 return 0;
21 else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
22 return 2;
23
24 return 1;
25}
26EXPORT_SYMBOL(__cmpdi2);
diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c
index 57acda852f5..b07abbac031 100644
--- a/arch/microblaze/pci/iomap.c
+++ b/arch/microblaze/pci/iomap.c
@@ -10,25 +10,6 @@
10#include <asm/io.h> 10#include <asm/io.h>
11#include <asm/pci-bridge.h> 11#include <asm/pci-bridge.h>
12 12
13void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
14{
15 resource_size_t start = pci_resource_start(dev, bar);
16 resource_size_t len = pci_resource_len(dev, bar);
17 unsigned long flags = pci_resource_flags(dev, bar);
18
19 if (!len)
20 return NULL;
21 if (max && len > max)
22 len = max;
23 if (flags & IORESOURCE_IO)
24 return ioport_map(start, len);
25 if (flags & IORESOURCE_MEM)
26 return ioremap(start, len);
27 /* What? */
28 return NULL;
29}
30EXPORT_SYMBOL(pci_iomap);
31
32void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 13void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
33{ 14{
34 if (isa_vaddr_is_ioport(addr)) 15 if (isa_vaddr_is_ioport(addr))
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index db841c7b9d5..0d71b2ed810 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -242,7 +242,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
242 line, pin); 242 line, pin);
243 243
244 virq = irq_create_mapping(NULL, line); 244 virq = irq_create_mapping(NULL, line);
245 if (virq != NO_IRQ) 245 if (virq)
246 irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); 246 irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
247 } else { 247 } else {
248 pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", 248 pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
@@ -253,7 +253,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
253 virq = irq_create_of_mapping(oirq.controller, oirq.specifier, 253 virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
254 oirq.size); 254 oirq.size);
255 } 255 }
256 if (virq == NO_IRQ) { 256 if (!virq) {
257 pr_debug(" Failed to map !\n"); 257 pr_debug(" Failed to map !\n");
258 return -1; 258 return -1;
259 } 259 }
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a7636d3ddc6..29d92187ff3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -16,6 +16,7 @@ config MIPS
16 select HAVE_FUNCTION_GRAPH_TRACER 16 select HAVE_FUNCTION_GRAPH_TRACER
17 select HAVE_KPROBES 17 select HAVE_KPROBES
18 select HAVE_KRETPROBES 18 select HAVE_KRETPROBES
19 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
19 select RTC_LIB if !MACH_LOONGSON 20 select RTC_LIB if !MACH_LOONGSON
20 select GENERIC_ATOMIC64 if !64BIT 21 select GENERIC_ATOMIC64 if !64BIT
21 select HAVE_DMA_ATTRS 22 select HAVE_DMA_ATTRS
@@ -2316,6 +2317,7 @@ config PCI
2316 bool "Support for PCI controller" 2317 bool "Support for PCI controller"
2317 depends on HW_HAS_PCI 2318 depends on HW_HAS_PCI
2318 select PCI_DOMAINS 2319 select PCI_DOMAINS
2320 select GENERIC_PCI_IOMAP
2319 help 2321 help
2320 Find out whether you have a PCI motherboard. PCI is the name of a 2322 Find out whether you have a PCI motherboard. PCI is the name of a
2321 bus system, i.e. the way the CPU talks to the other stuff inside 2323 bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 40b223b603b..c22385400fc 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -834,10 +834,13 @@ static struct mtd_partition mtd_partitions[] = {
834 } 834 }
835}; 835};
836 836
837static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
838
837static struct physmap_flash_data flash_data = { 839static struct physmap_flash_data flash_data = {
838 .width = 2, 840 .width = 2,
839 .nr_parts = ARRAY_SIZE(mtd_partitions), 841 .nr_parts = ARRAY_SIZE(mtd_partitions),
840 .parts = mtd_partitions, 842 .parts = mtd_partitions,
843 .part_probe_types = bcm63xx_part_types,
841}; 844};
842 845
843static struct resource mtd_resources[] = { 846static struct resource mtd_resources[] = {
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
index ed72e6a26b7..1e6b587f62c 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
@@ -16,7 +16,6 @@
16#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ 16#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
17#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ 17#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
18#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ 18#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
19#define CRC_LEN 4 /* Length of CRC in bytes */
20#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */ 19#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
21 20
22#define NUM_PIRELLI 2 21#define NUM_PIRELLI 2
@@ -77,19 +76,19 @@ struct bcm_tag {
77 /* 192-195: Version flash layout */ 76 /* 192-195: Version flash layout */
78 char flash_layout_ver[FLASHLAYOUTVER_LEN]; 77 char flash_layout_ver[FLASHLAYOUTVER_LEN];
79 /* 196-199: kernel+rootfs CRC32 */ 78 /* 196-199: kernel+rootfs CRC32 */
80 char fskernel_crc[CRC_LEN]; 79 __u32 fskernel_crc;
81 /* 200-215: Unused except on Alice Gate where is is information */ 80 /* 200-215: Unused except on Alice Gate where is is information */
82 char information2[TAGINFO2_LEN]; 81 char information2[TAGINFO2_LEN];
83 /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */ 82 /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
84 char image_crc[CRC_LEN]; 83 __u32 image_crc;
85 /* 220-223: CRC32 of rootfs partition */ 84 /* 220-223: CRC32 of rootfs partition */
86 char rootfs_crc[CRC_LEN]; 85 __u32 rootfs_crc;
87 /* 224-227: CRC32 of kernel partition */ 86 /* 224-227: CRC32 of kernel partition */
88 char kernel_crc[CRC_LEN]; 87 __u32 kernel_crc;
89 /* 228-235: Unused at present */ 88 /* 228-235: Unused at present */
90 char reserved1[8]; 89 char reserved1[8];
91 /* 236-239: CRC32 of header excluding last 20 bytes */ 90 /* 236-239: CRC32 of header excluding last 20 bytes */
92 char header_crc[CRC_LEN]; 91 __u32 header_crc;
93 /* 240-255: Unused at present */ 92 /* 240-255: Unused at present */
94 char reserved2[16]; 93 char reserved2[16];
95}; 94};
diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c
index 2ab899c4b4c..2635b1a9633 100644
--- a/arch/mips/lib/iomap-pci.c
+++ b/arch/mips/lib/iomap-pci.c
@@ -40,32 +40,6 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
40 return (void __iomem *) (ctrl->io_map_base + port); 40 return (void __iomem *) (ctrl->io_map_base + port);
41} 41}
42 42
43/*
44 * Create a virtual mapping cookie for a PCI BAR (memory or IO)
45 */
46void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
47{
48 resource_size_t start = pci_resource_start(dev, bar);
49 resource_size_t len = pci_resource_len(dev, bar);
50 unsigned long flags = pci_resource_flags(dev, bar);
51
52 if (!len || !start)
53 return NULL;
54 if (maxlen && len > maxlen)
55 len = maxlen;
56 if (flags & IORESOURCE_IO)
57 return ioport_map_pci(dev, start, len);
58 if (flags & IORESOURCE_MEM) {
59 if (flags & IORESOURCE_CACHEABLE)
60 return ioremap(start, len);
61 return ioremap_nocache(start, len);
62 }
63 /* What? */
64 return NULL;
65}
66
67EXPORT_SYMBOL(pci_iomap);
68
69void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 43void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
70{ 44{
71 iounmap(addr); 45 iounmap(addr);
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 438db84a1f7..8f1c40d5817 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -252,6 +252,7 @@ config PCI
252 bool "Use PCI" 252 bool "Use PCI"
253 depends on MN10300_UNIT_ASB2305 253 depends on MN10300_UNIT_ASB2305
254 default y 254 default y
255 select GENERIC_PCI_IOMAP
255 help 256 help
256 Some systems (such as the ASB2305) have PCI onboard. If you have one 257 Some systems (such as the ASB2305) have PCI onboard. If you have one
257 of these boards and you wish to use the PCI facilities, say Y here. 258 of these boards and you wish to use the PCI facilities, say Y here.
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index 787255da744..139df8c53de 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -229,7 +229,6 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
229 229
230/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 230/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
231struct pci_dev; 231struct pci_dev;
232extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
233static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) 232static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
234{ 233{
235} 234}
@@ -251,15 +250,15 @@ static inline void *phys_to_virt(unsigned long address)
251/* 250/*
252 * Change "struct page" to physical address. 251 * Change "struct page" to physical address.
253 */ 252 */
254static inline void *__ioremap(unsigned long offset, unsigned long size, 253static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,
255 unsigned long flags) 254 unsigned long flags)
256{ 255{
257 return (void *) offset; 256 return (void __iomem *) offset;
258} 257}
259 258
260static inline void *ioremap(unsigned long offset, unsigned long size) 259static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
261{ 260{
262 return (void *) offset; 261 return (void __iomem *) offset;
263} 262}
264 263
265/* 264/*
@@ -267,14 +266,14 @@ static inline void *ioremap(unsigned long offset, unsigned long size)
267 * area. it's useful if some control registers are in such an area and write 266 * area. it's useful if some control registers are in such an area and write
268 * combining or read caching is not desirable: 267 * combining or read caching is not desirable:
269 */ 268 */
270static inline void *ioremap_nocache(unsigned long offset, unsigned long size) 269static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size)
271{ 270{
272 return (void *) (offset | 0x20000000); 271 return (void __iomem *) (offset | 0x20000000);
273} 272}
274 273
275#define ioremap_wc ioremap_nocache 274#define ioremap_wc ioremap_nocache
276 275
277static inline void iounmap(void *addr) 276static inline void iounmap(void __iomem *addr)
278{ 277{
279} 278}
280 279
diff --git a/arch/mn10300/unit-asb2305/Makefile b/arch/mn10300/unit-asb2305/Makefile
index 0551022225b..cbc5abaa939 100644
--- a/arch/mn10300/unit-asb2305/Makefile
+++ b/arch/mn10300/unit-asb2305/Makefile
@@ -5,4 +5,4 @@
5############################################################################### 5###############################################################################
6obj-y := unit-init.o leds.o 6obj-y := unit-init.o leds.o
7 7
8obj-$(CONFIG_PCI) += pci.o pci-asb2305.o pci-irq.o pci-iomap.o 8obj-$(CONFIG_PCI) += pci.o pci-asb2305.o pci-irq.o
diff --git a/arch/mn10300/unit-asb2305/pci-iomap.c b/arch/mn10300/unit-asb2305/pci-iomap.c
deleted file mode 100644
index c1a8d8f941f..00000000000
--- a/arch/mn10300/unit-asb2305/pci-iomap.c
+++ /dev/null
@@ -1,31 +0,0 @@
1/* ASB2305 PCI I/O mapping handler
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#include <linux/pci.h>
12#include <linux/module.h>
13
14/*
15 * Create a virtual mapping cookie for a PCI BAR (memory or IO)
16 */
17void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
18{
19 resource_size_t start = pci_resource_start(dev, bar);
20 resource_size_t len = pci_resource_len(dev, bar);
21 unsigned long flags = pci_resource_flags(dev, bar);
22
23 if (!len || !start)
24 return NULL;
25
26 if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
27 return (void __iomem *) start;
28
29 return NULL;
30}
31EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index e518a5a4cf4..081a54f1a93 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -38,9 +38,6 @@ config RWSEM_XCHGADD_ALGORITHM
38config GENERIC_HWEIGHT 38config GENERIC_HWEIGHT
39 def_bool y 39 def_bool y
40 40
41config GENERIC_IOMAP
42 def_bool y
43
44config NO_IOPORT 41config NO_IOPORT
45 def_bool y 42 def_bool y
46 43
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index fdfd8be29e9..242a1b7ac75 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -14,6 +14,7 @@ config PARISC
14 select GENERIC_ATOMIC64 if !64BIT 14 select GENERIC_ATOMIC64 if !64BIT
15 select HAVE_GENERIC_HARDIRQS 15 select HAVE_GENERIC_HARDIRQS
16 select GENERIC_IRQ_PROBE 16 select GENERIC_IRQ_PROBE
17 select GENERIC_PCI_IOMAP
17 select IRQ_PER_CPU 18 select IRQ_PER_CPU
18 select ARCH_HAVE_NMI_SAFE_CMPXCHG 19 select ARCH_HAVE_NMI_SAFE_CMPXCHG
19 20
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 8f470c93b16..fb8e10a4fb3 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -436,28 +436,6 @@ void ioport_unmap(void __iomem *addr)
436 } 436 }
437} 437}
438 438
439/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
440void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
441{
442 resource_size_t start = pci_resource_start(dev, bar);
443 resource_size_t len = pci_resource_len(dev, bar);
444 unsigned long flags = pci_resource_flags(dev, bar);
445
446 if (!len || !start)
447 return NULL;
448 if (maxlen && len > maxlen)
449 len = maxlen;
450 if (flags & IORESOURCE_IO)
451 return ioport_map(start, len);
452 if (flags & IORESOURCE_MEM) {
453 if (flags & IORESOURCE_CACHEABLE)
454 return ioremap(start, len);
455 return ioremap_nocache(start, len);
456 }
457 /* What? */
458 return NULL;
459}
460
461void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 439void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
462{ 440{
463 if (!INDIRECT_ADDR(addr)) { 441 if (!INDIRECT_ADDR(addr)) {
@@ -483,5 +461,4 @@ EXPORT_SYMBOL(iowrite16_rep);
483EXPORT_SYMBOL(iowrite32_rep); 461EXPORT_SYMBOL(iowrite32_rep);
484EXPORT_SYMBOL(ioport_map); 462EXPORT_SYMBOL(ioport_map);
485EXPORT_SYMBOL(ioport_unmap); 463EXPORT_SYMBOL(ioport_unmap);
486EXPORT_SYMBOL(pci_iomap);
487EXPORT_SYMBOL(pci_iounmap); 464EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 692ac7588e2..1919634a9b3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -718,6 +718,7 @@ config PCI
718 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx 718 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
719 default PCI_QSPAN if !4xx && !CPM2 && 8xx 719 default PCI_QSPAN if !4xx && !CPM2 && 8xx
720 select ARCH_SUPPORTS_MSI 720 select ARCH_SUPPORTS_MSI
721 select GENERIC_PCI_IOMAP
721 help 722 help
722 Find out whether your system includes a PCI bus. PCI is the name of 723 Find out whether your system includes a PCI bus. PCI is the name of
723 a bus system, i.e. the way the CPU talks to the other stuff inside 724 a bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 0ad432bc81d..f7727d91ac6 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -170,8 +170,8 @@ struct kvm_sregs {
170 } ppc64; 170 } ppc64;
171 struct { 171 struct {
172 __u32 sr[16]; 172 __u32 sr[16];
173 __u64 ibat[8]; 173 __u64 ibat[8];
174 __u64 dbat[8]; 174 __u64 dbat[8];
175 } ppc32; 175 } ppc32;
176 } s; 176 } s;
177 struct { 177 struct {
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index 26279180739..97a3715ac8b 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -119,24 +119,6 @@ EXPORT_SYMBOL(ioport_map);
119EXPORT_SYMBOL(ioport_unmap); 119EXPORT_SYMBOL(ioport_unmap);
120 120
121#ifdef CONFIG_PCI 121#ifdef CONFIG_PCI
122void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
123{
124 resource_size_t start = pci_resource_start(dev, bar);
125 resource_size_t len = pci_resource_len(dev, bar);
126 unsigned long flags = pci_resource_flags(dev, bar);
127
128 if (!len)
129 return NULL;
130 if (max && len > max)
131 len = max;
132 if (flags & IORESOURCE_IO)
133 return ioport_map(start, len);
134 if (flags & IORESOURCE_MEM)
135 return ioremap(start, len);
136 /* What? */
137 return NULL;
138}
139
140void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 122void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
141{ 123{
142 if (isa_vaddr_is_ioport(addr)) 124 if (isa_vaddr_is_ioport(addr))
@@ -146,6 +128,5 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
146 iounmap(addr); 128 iounmap(addr);
147} 129}
148 130
149EXPORT_SYMBOL(pci_iomap);
150EXPORT_SYMBOL(pci_iounmap); 131EXPORT_SYMBOL(pci_iounmap);
151#endif /* CONFIG_PCI */ 132#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index c7b5afeecaf..3fea3689527 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -441,6 +441,9 @@ static void __init fixup_port_irq(int index,
441 return; 441 return;
442 442
443 port->irq = virq; 443 port->irq = virq;
444
445 if (of_device_is_compatible(np, "fsl,ns16550"))
446 port->handle_irq = fsl8250_handle_irq;
444} 447}
445 448
446static void __init fixup_port_pio(int index, 449static void __init fixup_port_pio(int index,
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index a459479995c..e41ac6f7dcf 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -498,7 +498,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
498 498
499 /* If nothing is dirty, don't bother messing with page tables. */ 499 /* If nothing is dirty, don't bother messing with page tables. */
500 if (is_dirty) { 500 if (is_dirty) {
501 memslot = &kvm->memslots->memslots[log->slot]; 501 memslot = id_to_memslot(kvm->memslots, log->slot);
502 502
503 ga = memslot->base_gfn << PAGE_SHIFT; 503 ga = memslot->base_gfn << PAGE_SHIFT;
504 ga_end = ga + (memslot->npages << PAGE_SHIFT); 504 ga_end = ga + (memslot->npages << PAGE_SHIFT);
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 286f13d601c..a795a13f4a7 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -86,7 +86,7 @@ static inline int lpcr_rmls(unsigned long rma_size)
86 * to allocate contiguous physical memory for the real memory 86 * to allocate contiguous physical memory for the real memory
87 * areas for guests. 87 * areas for guests.
88 */ 88 */
89void kvm_rma_init(void) 89void __init kvm_rma_init(void)
90{ 90{
91 unsigned long i; 91 unsigned long i;
92 unsigned long j, npages; 92 unsigned long j, npages;
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 31e1adeaa92..0cfb46d54b8 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -175,9 +175,6 @@ config PPC_INDIRECT_MMIO
175config PPC_IO_WORKAROUNDS 175config PPC_IO_WORKAROUNDS
176 bool 176 bool
177 177
178config GENERIC_IOMAP
179 bool
180
181source "drivers/cpufreq/Kconfig" 178source "drivers/cpufreq/Kconfig"
182 179
183menu "CPU Frequency drivers" 180menu "CPU Frequency drivers"
diff --git a/arch/s390/Kbuild b/arch/s390/Kbuild
index ae4b01060ed..9858476fa0f 100644
--- a/arch/s390/Kbuild
+++ b/arch/s390/Kbuild
@@ -1,6 +1,7 @@
1obj-y += kernel/ 1obj-y += kernel/
2obj-y += mm/ 2obj-y += mm/
3obj-y += crypto/ 3obj-$(CONFIG_KVM) += kvm/
4obj-y += appldata/ 4obj-$(CONFIG_CRYPTO_HW) += crypto/
5obj-y += hypfs/ 5obj-$(CONFIG_S390_HYPFS_FS) += hypfs/
6obj-y += kvm/ 6obj-$(CONFIG_APPLDATA_BASE) += appldata/
7obj-$(CONFIG_MATHEMU) += math-emu/
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 28d183c4275..d1727584230 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -193,18 +193,13 @@ config HOTPLUG_CPU
193 Say N if you want to disable CPU hotplug. 193 Say N if you want to disable CPU hotplug.
194 194
195config SCHED_MC 195config SCHED_MC
196 def_bool y 196 def_bool n
197 prompt "Multi-core scheduler support"
198 depends on SMP
199 help
200 Multi-core scheduler support improves the CPU scheduler's decision
201 making when dealing with multi-core CPU chips at a cost of slightly
202 increased overhead in some places.
203 197
204config SCHED_BOOK 198config SCHED_BOOK
205 def_bool y 199 def_bool y
206 prompt "Book scheduler support" 200 prompt "Book scheduler support"
207 depends on SMP && SCHED_MC 201 depends on SMP
202 select SCHED_MC
208 help 203 help
209 Book scheduler support improves the CPU scheduler's decision making 204 Book scheduler support improves the CPU scheduler's decision making
210 when dealing with machines that have several books. 205 when dealing with machines that have several books.
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 27a0b5df5ea..e9f35334169 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -99,7 +99,6 @@ core-y += arch/s390/
99 99
100libs-y += arch/s390/lib/ 100libs-y += arch/s390/lib/
101drivers-y += drivers/s390/ 101drivers-y += drivers/s390/
102drivers-$(CONFIG_MATHEMU) += arch/s390/math-emu/
103 102
104# must be linked after kernel 103# must be linked after kernel
105drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ 104drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 635d677d328..f2737a005af 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -23,4 +23,4 @@ $(obj)/compressed/vmlinux: FORCE
23 23
24install: $(CONFIGURE) $(obj)/image 24install: $(CONFIGURE) $(obj)/image
25 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \ 25 sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/image \
26 System.map Kerntypes "$(INSTALL_PATH)" 26 System.map "$(INSTALL_PATH)"
diff --git a/arch/s390/include/asm/kdebug.h b/arch/s390/include/asm/kdebug.h
index 40db27cd6e6..5c1abd47612 100644
--- a/arch/s390/include/asm/kdebug.h
+++ b/arch/s390/include/asm/kdebug.h
@@ -22,6 +22,6 @@ enum die_val {
22 DIE_NMI_IPI, 22 DIE_NMI_IPI,
23}; 23};
24 24
25extern void die(const char *, struct pt_regs *, long); 25extern void die(struct pt_regs *, const char *);
26 26
27#endif 27#endif
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 9e13c7d56cc..707f2306725 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -97,47 +97,52 @@ struct _lowcore {
97 __u32 gpregs_save_area[16]; /* 0x0180 */ 97 __u32 gpregs_save_area[16]; /* 0x0180 */
98 __u32 cregs_save_area[16]; /* 0x01c0 */ 98 __u32 cregs_save_area[16]; /* 0x01c0 */
99 99
100 /* Save areas. */
101 __u32 save_area_sync[8]; /* 0x0200 */
102 __u32 save_area_async[8]; /* 0x0220 */
103 __u32 save_area_restart[1]; /* 0x0240 */
104 __u8 pad_0x0244[0x0248-0x0244]; /* 0x0244 */
105
100 /* Return psws. */ 106 /* Return psws. */
101 __u32 save_area[16]; /* 0x0200 */ 107 psw_t return_psw; /* 0x0248 */
102 psw_t return_psw; /* 0x0240 */ 108 psw_t return_mcck_psw; /* 0x0250 */
103 psw_t return_mcck_psw; /* 0x0248 */
104 109
105 /* CPU time accounting values */ 110 /* CPU time accounting values */
106 __u64 sync_enter_timer; /* 0x0250 */ 111 __u64 sync_enter_timer; /* 0x0258 */
107 __u64 async_enter_timer; /* 0x0258 */ 112 __u64 async_enter_timer; /* 0x0260 */
108 __u64 mcck_enter_timer; /* 0x0260 */ 113 __u64 mcck_enter_timer; /* 0x0268 */
109 __u64 exit_timer; /* 0x0268 */ 114 __u64 exit_timer; /* 0x0270 */
110 __u64 user_timer; /* 0x0270 */ 115 __u64 user_timer; /* 0x0278 */
111 __u64 system_timer; /* 0x0278 */ 116 __u64 system_timer; /* 0x0280 */
112 __u64 steal_timer; /* 0x0280 */ 117 __u64 steal_timer; /* 0x0288 */
113 __u64 last_update_timer; /* 0x0288 */ 118 __u64 last_update_timer; /* 0x0290 */
114 __u64 last_update_clock; /* 0x0290 */ 119 __u64 last_update_clock; /* 0x0298 */
115 120
116 /* Current process. */ 121 /* Current process. */
117 __u32 current_task; /* 0x0298 */ 122 __u32 current_task; /* 0x02a0 */
118 __u32 thread_info; /* 0x029c */ 123 __u32 thread_info; /* 0x02a4 */
119 __u32 kernel_stack; /* 0x02a0 */ 124 __u32 kernel_stack; /* 0x02a8 */
120 125
121 /* Interrupt and panic stack. */ 126 /* Interrupt and panic stack. */
122 __u32 async_stack; /* 0x02a4 */ 127 __u32 async_stack; /* 0x02ac */
123 __u32 panic_stack; /* 0x02a8 */ 128 __u32 panic_stack; /* 0x02b0 */
124 129
125 /* Address space pointer. */ 130 /* Address space pointer. */
126 __u32 kernel_asce; /* 0x02ac */ 131 __u32 kernel_asce; /* 0x02b4 */
127 __u32 user_asce; /* 0x02b0 */ 132 __u32 user_asce; /* 0x02b8 */
128 __u32 current_pid; /* 0x02b4 */ 133 __u32 current_pid; /* 0x02bc */
129 134
130 /* SMP info area */ 135 /* SMP info area */
131 __u32 cpu_nr; /* 0x02b8 */ 136 __u32 cpu_nr; /* 0x02c0 */
132 __u32 softirq_pending; /* 0x02bc */ 137 __u32 softirq_pending; /* 0x02c4 */
133 __u32 percpu_offset; /* 0x02c0 */ 138 __u32 percpu_offset; /* 0x02c8 */
134 __u32 ext_call_fast; /* 0x02c4 */ 139 __u32 ext_call_fast; /* 0x02cc */
135 __u64 int_clock; /* 0x02c8 */ 140 __u64 int_clock; /* 0x02d0 */
136 __u64 mcck_clock; /* 0x02d0 */ 141 __u64 mcck_clock; /* 0x02d8 */
137 __u64 clock_comparator; /* 0x02d8 */ 142 __u64 clock_comparator; /* 0x02e0 */
138 __u32 machine_flags; /* 0x02e0 */ 143 __u32 machine_flags; /* 0x02e8 */
139 __u32 ftrace_func; /* 0x02e4 */ 144 __u32 ftrace_func; /* 0x02ec */
140 __u8 pad_0x02e8[0x0300-0x02e8]; /* 0x02e8 */ 145 __u8 pad_0x02f8[0x0300-0x02f0]; /* 0x02f0 */
141 146
142 /* Interrupt response block */ 147 /* Interrupt response block */
143 __u8 irb[64]; /* 0x0300 */ 148 __u8 irb[64]; /* 0x0300 */
@@ -229,57 +234,62 @@ struct _lowcore {
229 psw_t mcck_new_psw; /* 0x01e0 */ 234 psw_t mcck_new_psw; /* 0x01e0 */
230 psw_t io_new_psw; /* 0x01f0 */ 235 psw_t io_new_psw; /* 0x01f0 */
231 236
232 /* Entry/exit save area & return psws. */ 237 /* Save areas. */
233 __u64 save_area[16]; /* 0x0200 */ 238 __u64 save_area_sync[8]; /* 0x0200 */
234 psw_t return_psw; /* 0x0280 */ 239 __u64 save_area_async[8]; /* 0x0240 */
235 psw_t return_mcck_psw; /* 0x0290 */ 240 __u64 save_area_restart[1]; /* 0x0280 */
241 __u8 pad_0x0288[0x0290-0x0288]; /* 0x0288 */
242
243 /* Return psws. */
244 psw_t return_psw; /* 0x0290 */
245 psw_t return_mcck_psw; /* 0x02a0 */
236 246
237 /* CPU accounting and timing values. */ 247 /* CPU accounting and timing values. */
238 __u64 sync_enter_timer; /* 0x02a0 */ 248 __u64 sync_enter_timer; /* 0x02b0 */
239 __u64 async_enter_timer; /* 0x02a8 */ 249 __u64 async_enter_timer; /* 0x02b8 */
240 __u64 mcck_enter_timer; /* 0x02b0 */ 250 __u64 mcck_enter_timer; /* 0x02c0 */
241 __u64 exit_timer; /* 0x02b8 */ 251 __u64 exit_timer; /* 0x02c8 */
242 __u64 user_timer; /* 0x02c0 */ 252 __u64 user_timer; /* 0x02d0 */
243 __u64 system_timer; /* 0x02c8 */ 253 __u64 system_timer; /* 0x02d8 */
244 __u64 steal_timer; /* 0x02d0 */ 254 __u64 steal_timer; /* 0x02e0 */
245 __u64 last_update_timer; /* 0x02d8 */ 255 __u64 last_update_timer; /* 0x02e8 */
246 __u64 last_update_clock; /* 0x02e0 */ 256 __u64 last_update_clock; /* 0x02f0 */
247 257
248 /* Current process. */ 258 /* Current process. */
249 __u64 current_task; /* 0x02e8 */ 259 __u64 current_task; /* 0x02f8 */
250 __u64 thread_info; /* 0x02f0 */ 260 __u64 thread_info; /* 0x0300 */
251 __u64 kernel_stack; /* 0x02f8 */ 261 __u64 kernel_stack; /* 0x0308 */
252 262
253 /* Interrupt and panic stack. */ 263 /* Interrupt and panic stack. */
254 __u64 async_stack; /* 0x0300 */ 264 __u64 async_stack; /* 0x0310 */
255 __u64 panic_stack; /* 0x0308 */ 265 __u64 panic_stack; /* 0x0318 */
256 266
257 /* Address space pointer. */ 267 /* Address space pointer. */
258 __u64 kernel_asce; /* 0x0310 */ 268 __u64 kernel_asce; /* 0x0320 */
259 __u64 user_asce; /* 0x0318 */ 269 __u64 user_asce; /* 0x0328 */
260 __u64 current_pid; /* 0x0320 */ 270 __u64 current_pid; /* 0x0330 */
261 271
262 /* SMP info area */ 272 /* SMP info area */
263 __u32 cpu_nr; /* 0x0328 */ 273 __u32 cpu_nr; /* 0x0338 */
264 __u32 softirq_pending; /* 0x032c */ 274 __u32 softirq_pending; /* 0x033c */
265 __u64 percpu_offset; /* 0x0330 */ 275 __u64 percpu_offset; /* 0x0340 */
266 __u64 ext_call_fast; /* 0x0338 */ 276 __u64 ext_call_fast; /* 0x0348 */
267 __u64 int_clock; /* 0x0340 */ 277 __u64 int_clock; /* 0x0350 */
268 __u64 mcck_clock; /* 0x0348 */ 278 __u64 mcck_clock; /* 0x0358 */
269 __u64 clock_comparator; /* 0x0350 */ 279 __u64 clock_comparator; /* 0x0360 */
270 __u64 vdso_per_cpu_data; /* 0x0358 */ 280 __u64 vdso_per_cpu_data; /* 0x0368 */
271 __u64 machine_flags; /* 0x0360 */ 281 __u64 machine_flags; /* 0x0370 */
272 __u64 ftrace_func; /* 0x0368 */ 282 __u64 ftrace_func; /* 0x0378 */
273 __u64 gmap; /* 0x0370 */ 283 __u64 gmap; /* 0x0380 */
274 __u64 cmf_hpp; /* 0x0378 */ 284 __u8 pad_0x0388[0x0400-0x0388]; /* 0x0388 */
275 285
276 /* Interrupt response block. */ 286 /* Interrupt response block. */
277 __u8 irb[64]; /* 0x0380 */ 287 __u8 irb[64]; /* 0x0400 */
278 288
279 /* Per cpu primary space access list */ 289 /* Per cpu primary space access list */
280 __u32 paste[16]; /* 0x03c0 */ 290 __u32 paste[16]; /* 0x0440 */
281 291
282 __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */ 292 __u8 pad_0x0480[0x0e00-0x0480]; /* 0x0480 */
283 293
284 /* 294 /*
285 * 0xe00 contains the address of the IPL Parameter Information 295 * 0xe00 contains the address of the IPL Parameter Information
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 5325c89a584..0fbd1899c7b 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -19,7 +19,7 @@
19#define ARCH_NEEDS_WEAK_PER_CPU 19#define ARCH_NEEDS_WEAK_PER_CPU
20#endif 20#endif
21 21
22#define arch_irqsafe_cpu_to_op(pcp, val, op) \ 22#define arch_this_cpu_to_op(pcp, val, op) \
23do { \ 23do { \
24 typedef typeof(pcp) pcp_op_T__; \ 24 typedef typeof(pcp) pcp_op_T__; \
25 pcp_op_T__ old__, new__, prev__; \ 25 pcp_op_T__ old__, new__, prev__; \
@@ -41,27 +41,27 @@ do { \
41 preempt_enable(); \ 41 preempt_enable(); \
42} while (0) 42} while (0)
43 43
44#define irqsafe_cpu_add_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +) 44#define this_cpu_add_1(pcp, val) arch_this_cpu_to_op(pcp, val, +)
45#define irqsafe_cpu_add_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +) 45#define this_cpu_add_2(pcp, val) arch_this_cpu_to_op(pcp, val, +)
46#define irqsafe_cpu_add_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +) 46#define this_cpu_add_4(pcp, val) arch_this_cpu_to_op(pcp, val, +)
47#define irqsafe_cpu_add_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +) 47#define this_cpu_add_8(pcp, val) arch_this_cpu_to_op(pcp, val, +)
48 48
49#define irqsafe_cpu_and_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &) 49#define this_cpu_and_1(pcp, val) arch_this_cpu_to_op(pcp, val, &)
50#define irqsafe_cpu_and_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &) 50#define this_cpu_and_2(pcp, val) arch_this_cpu_to_op(pcp, val, &)
51#define irqsafe_cpu_and_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &) 51#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, &)
52#define irqsafe_cpu_and_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &) 52#define this_cpu_and_8(pcp, val) arch_this_cpu_to_op(pcp, val, &)
53 53
54#define irqsafe_cpu_or_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |) 54#define this_cpu_or_1(pcp, val) arch_this_cpu_to_op(pcp, val, |)
55#define irqsafe_cpu_or_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |) 55#define this_cpu_or_2(pcp, val) arch_this_cpu_to_op(pcp, val, |)
56#define irqsafe_cpu_or_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |) 56#define this_cpu_or_4(pcp, val) arch_this_cpu_to_op(pcp, val, |)
57#define irqsafe_cpu_or_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |) 57#define this_cpu_or_8(pcp, val) arch_this_cpu_to_op(pcp, val, |)
58 58
59#define irqsafe_cpu_xor_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^) 59#define this_cpu_xor_1(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
60#define irqsafe_cpu_xor_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^) 60#define this_cpu_xor_2(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
61#define irqsafe_cpu_xor_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^) 61#define this_cpu_xor_4(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
62#define irqsafe_cpu_xor_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^) 62#define this_cpu_xor_8(pcp, val) arch_this_cpu_to_op(pcp, val, ^)
63 63
64#define arch_irqsafe_cpu_cmpxchg(pcp, oval, nval) \ 64#define arch_this_cpu_cmpxchg(pcp, oval, nval) \
65({ \ 65({ \
66 typedef typeof(pcp) pcp_op_T__; \ 66 typedef typeof(pcp) pcp_op_T__; \
67 pcp_op_T__ ret__; \ 67 pcp_op_T__ ret__; \
@@ -79,10 +79,10 @@ do { \
79 ret__; \ 79 ret__; \
80}) 80})
81 81
82#define irqsafe_cpu_cmpxchg_1(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval) 82#define this_cpu_cmpxchg_1(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
83#define irqsafe_cpu_cmpxchg_2(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval) 83#define this_cpu_cmpxchg_2(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
84#define irqsafe_cpu_cmpxchg_4(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval) 84#define this_cpu_cmpxchg_4(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
85#define irqsafe_cpu_cmpxchg_8(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval) 85#define this_cpu_cmpxchg_8(pcp, oval, nval) arch_this_cpu_cmpxchg(pcp, oval, nval)
86 86
87#include <asm-generic/percpu.h> 87#include <asm-generic/percpu.h>
88 88
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 4f289ff0b7f..011358c1b18 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -128,28 +128,11 @@ static inline int is_zero_pfn(unsigned long pfn)
128 * effect, this also makes sure that 64 bit module code cannot be used 128 * effect, this also makes sure that 64 bit module code cannot be used
129 * as system call address. 129 * as system call address.
130 */ 130 */
131
132extern unsigned long VMALLOC_START; 131extern unsigned long VMALLOC_START;
132extern unsigned long VMALLOC_END;
133extern struct page *vmemmap;
133 134
134#ifndef __s390x__ 135#define VMEM_MAX_PHYS ((unsigned long) vmemmap)
135#define VMALLOC_SIZE (96UL << 20)
136#define VMALLOC_END 0x7e000000UL
137#define VMEM_MAP_END 0x80000000UL
138#else /* __s390x__ */
139#define VMALLOC_SIZE (128UL << 30)
140#define VMALLOC_END 0x3e000000000UL
141#define VMEM_MAP_END 0x40000000000UL
142#endif /* __s390x__ */
143
144/*
145 * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1
146 * mapping. This needs to be calculated at compile time since the size of the
147 * VMEM_MAP is static but the size of struct page can change.
148 */
149#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page))
150#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES)
151#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1))
152#define vmemmap ((struct page *) VMALLOC_END)
153 136
154/* 137/*
155 * A 31 bit pagetable entry of S390 has following format: 138 * A 31 bit pagetable entry of S390 has following format:
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 5f33d37d032..27272f6a14c 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -80,8 +80,6 @@ struct thread_struct {
80 unsigned int acrs[NUM_ACRS]; 80 unsigned int acrs[NUM_ACRS];
81 unsigned long ksp; /* kernel stack pointer */ 81 unsigned long ksp; /* kernel stack pointer */
82 mm_segment_t mm_segment; 82 mm_segment_t mm_segment;
83 unsigned long prot_addr; /* address of protection-excep. */
84 unsigned int trap_no;
85 unsigned long gmap_addr; /* address of last gmap fault. */ 83 unsigned long gmap_addr; /* address of last gmap fault. */
86 struct per_regs per_user; /* User specified PER registers */ 84 struct per_regs per_user; /* User specified PER registers */
87 struct per_event per_event; /* Cause of the last PER trap */ 85 struct per_event per_event; /* Cause of the last PER trap */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index a65846340d5..56da355678f 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -324,7 +324,8 @@ struct pt_regs
324 psw_t psw; 324 psw_t psw;
325 unsigned long gprs[NUM_GPRS]; 325 unsigned long gprs[NUM_GPRS];
326 unsigned long orig_gpr2; 326 unsigned long orig_gpr2;
327 unsigned int svc_code; 327 unsigned int int_code;
328 unsigned long int_parm_long;
328}; 329};
329 330
330/* 331/*
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index e63d13dd3bf..d75c8e78f7e 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -352,7 +352,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
352 * @no_output_qs: number of output queues 352 * @no_output_qs: number of output queues
353 * @input_handler: handler to be called for input queues 353 * @input_handler: handler to be called for input queues
354 * @output_handler: handler to be called for output queues 354 * @output_handler: handler to be called for output queues
355 * @queue_start_poll: polling handlers (one per input queue or NULL) 355 * @queue_start_poll_array: polling handlers (one per input queue or NULL)
356 * @int_parm: interruption parameter 356 * @int_parm: interruption parameter
357 * @input_sbal_addr_array: address of no_input_qs * 128 pointers 357 * @input_sbal_addr_array: address of no_input_qs * 128 pointers
358 * @output_sbal_addr_array: address of no_output_qs * 128 pointers 358 * @output_sbal_addr_array: address of no_output_qs * 128 pointers
@@ -372,7 +372,8 @@ struct qdio_initialize {
372 unsigned int no_output_qs; 372 unsigned int no_output_qs;
373 qdio_handler_t *input_handler; 373 qdio_handler_t *input_handler;
374 qdio_handler_t *output_handler; 374 qdio_handler_t *output_handler;
375 void (**queue_start_poll) (struct ccw_device *, int, unsigned long); 375 void (**queue_start_poll_array) (struct ccw_device *, int,
376 unsigned long);
376 int scan_threshold; 377 int scan_threshold;
377 unsigned long int_parm; 378 unsigned long int_parm;
378 void **input_sbal_addr_array; 379 void **input_sbal_addr_array;
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index e3bffd4e2d6..7040b8567cd 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -56,6 +56,7 @@ enum {
56 ec_schedule = 0, 56 ec_schedule = 0,
57 ec_call_function, 57 ec_call_function,
58 ec_call_function_single, 58 ec_call_function_single,
59 ec_stop_cpu,
59}; 60};
60 61
61/* 62/*
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index ab47a69fdf0..c32e9123b40 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -23,7 +23,6 @@ extern void __cpu_die (unsigned int cpu);
23extern int __cpu_up (unsigned int cpu); 23extern int __cpu_up (unsigned int cpu);
24 24
25extern struct mutex smp_cpu_state_mutex; 25extern struct mutex smp_cpu_state_mutex;
26extern int smp_cpu_polarization[];
27 26
28extern void arch_send_call_function_single_ipi(int cpu); 27extern void arch_send_call_function_single_ipi(int cpu);
29extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 28extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
diff --git a/arch/s390/include/asm/sparsemem.h b/arch/s390/include/asm/sparsemem.h
index 545d219e6a2..0fb34027d3f 100644
--- a/arch/s390/include/asm/sparsemem.h
+++ b/arch/s390/include/asm/sparsemem.h
@@ -4,8 +4,8 @@
4#ifdef CONFIG_64BIT 4#ifdef CONFIG_64BIT
5 5
6#define SECTION_SIZE_BITS 28 6#define SECTION_SIZE_BITS 28
7#define MAX_PHYSADDR_BITS 42 7#define MAX_PHYSADDR_BITS 46
8#define MAX_PHYSMEM_BITS 42 8#define MAX_PHYSMEM_BITS 46
9 9
10#else 10#else
11 11
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h
index b239ff53b18..fb214dd9b7e 100644
--- a/arch/s390/include/asm/syscall.h
+++ b/arch/s390/include/asm/syscall.h
@@ -27,7 +27,7 @@ static inline long syscall_get_nr(struct task_struct *task,
27 struct pt_regs *regs) 27 struct pt_regs *regs)
28{ 28{
29 return test_tsk_thread_flag(task, TIF_SYSCALL) ? 29 return test_tsk_thread_flag(task, TIF_SYSCALL) ?
30 (regs->svc_code & 0xffff) : -1; 30 (regs->int_code & 0xffff) : -1;
31} 31}
32 32
33static inline void syscall_rollback(struct task_struct *task, 33static inline void syscall_rollback(struct task_struct *task,
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index ef573c1d71a..d73cc6b6000 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -20,8 +20,6 @@
20 20
21struct task_struct; 21struct task_struct;
22 22
23extern int sysctl_userprocess_debug;
24
25extern struct task_struct *__switch_to(void *, void *); 23extern struct task_struct *__switch_to(void *, void *);
26extern void update_per_regs(struct task_struct *task); 24extern void update_per_regs(struct task_struct *task);
27 25
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index 005d77d8ae2..0837de80c35 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -4,6 +4,10 @@
4#include <linux/cpumask.h> 4#include <linux/cpumask.h>
5#include <asm/sysinfo.h> 5#include <asm/sysinfo.h>
6 6
7struct cpu;
8
9#ifdef CONFIG_SCHED_BOOK
10
7extern unsigned char cpu_core_id[NR_CPUS]; 11extern unsigned char cpu_core_id[NR_CPUS];
8extern cpumask_t cpu_core_map[NR_CPUS]; 12extern cpumask_t cpu_core_map[NR_CPUS];
9 13
@@ -16,8 +20,6 @@ static inline const struct cpumask *cpu_coregroup_mask(int cpu)
16#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 20#define topology_core_cpumask(cpu) (&cpu_core_map[cpu])
17#define mc_capable() (1) 21#define mc_capable() (1)
18 22
19#ifdef CONFIG_SCHED_BOOK
20
21extern unsigned char cpu_book_id[NR_CPUS]; 23extern unsigned char cpu_book_id[NR_CPUS];
22extern cpumask_t cpu_book_map[NR_CPUS]; 24extern cpumask_t cpu_book_map[NR_CPUS];
23 25
@@ -29,19 +31,45 @@ static inline const struct cpumask *cpu_book_mask(int cpu)
29#define topology_book_id(cpu) (cpu_book_id[cpu]) 31#define topology_book_id(cpu) (cpu_book_id[cpu])
30#define topology_book_cpumask(cpu) (&cpu_book_map[cpu]) 32#define topology_book_cpumask(cpu) (&cpu_book_map[cpu])
31 33
32#endif /* CONFIG_SCHED_BOOK */ 34int topology_cpu_init(struct cpu *);
33
34int topology_set_cpu_management(int fc); 35int topology_set_cpu_management(int fc);
35void topology_schedule_update(void); 36void topology_schedule_update(void);
36void store_topology(struct sysinfo_15_1_x *info); 37void store_topology(struct sysinfo_15_1_x *info);
38void topology_expect_change(void);
39
40#else /* CONFIG_SCHED_BOOK */
41
42static inline void topology_schedule_update(void) { }
43static inline int topology_cpu_init(struct cpu *cpu) { return 0; }
44static inline void topology_expect_change(void) { }
37 45
38#define POLARIZATION_UNKNWN (-1) 46#endif /* CONFIG_SCHED_BOOK */
47
48#define POLARIZATION_UNKNOWN (-1)
39#define POLARIZATION_HRZ (0) 49#define POLARIZATION_HRZ (0)
40#define POLARIZATION_VL (1) 50#define POLARIZATION_VL (1)
41#define POLARIZATION_VM (2) 51#define POLARIZATION_VM (2)
42#define POLARIZATION_VH (3) 52#define POLARIZATION_VH (3)
43 53
44#ifdef CONFIG_SMP 54extern int cpu_polarization[];
55
56static inline void cpu_set_polarization(int cpu, int val)
57{
58#ifdef CONFIG_SCHED_BOOK
59 cpu_polarization[cpu] = val;
60#endif
61}
62
63static inline int cpu_read_polarization(int cpu)
64{
65#ifdef CONFIG_SCHED_BOOK
66 return cpu_polarization[cpu];
67#else
68 return POLARIZATION_HRZ;
69#endif
70}
71
72#ifdef CONFIG_SCHED_BOOK
45void s390_init_cpu_topology(void); 73void s390_init_cpu_topology(void);
46#else 74#else
47static inline void s390_init_cpu_topology(void) 75static inline void s390_init_cpu_topology(void)
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 58de4c91c33..8a8008fe7b8 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -398,6 +398,7 @@
398#define __ARCH_WANT_SYS_SIGNAL 398#define __ARCH_WANT_SYS_SIGNAL
399#define __ARCH_WANT_SYS_UTIME 399#define __ARCH_WANT_SYS_UTIME
400#define __ARCH_WANT_SYS_SOCKETCALL 400#define __ARCH_WANT_SYS_SOCKETCALL
401#define __ARCH_WANT_SYS_IPC
401#define __ARCH_WANT_SYS_FADVISE64 402#define __ARCH_WANT_SYS_FADVISE64
402#define __ARCH_WANT_SYS_GETPGRP 403#define __ARCH_WANT_SYS_GETPGRP
403#define __ARCH_WANT_SYS_LLSEEK 404#define __ARCH_WANT_SYS_LLSEEK
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index dd4f0764091..7d9ec924e7e 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -32,7 +32,8 @@ extra-y += head.o init_task.o vmlinux.lds
32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o) 32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
33 33
34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
35obj-$(CONFIG_SMP) += smp.o topology.o 35obj-$(CONFIG_SMP) += smp.o
36obj-$(CONFIG_SCHED_BOOK) += topology.o
36obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \ 37obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \
37 switch_cpu.o) 38 switch_cpu.o)
38obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o 39obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 751318765e2..6e6a72e66d6 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -45,7 +45,8 @@ int main(void)
45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw)); 45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); 46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); 47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
48 DEFINE(__PT_SVC_CODE, offsetof(struct pt_regs, svc_code)); 48 DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
49 DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
49 DEFINE(__PT_SIZE, sizeof(struct pt_regs)); 50 DEFINE(__PT_SIZE, sizeof(struct pt_regs));
50 BLANK(); 51 BLANK();
51 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain)); 52 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
@@ -108,7 +109,9 @@ int main(void)
108 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw)); 109 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
109 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw)); 110 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
110 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw)); 111 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
111 DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area)); 112 DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
113 DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
114 DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
112 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw)); 115 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
113 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw)); 116 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
114 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer)); 117 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
@@ -150,7 +153,6 @@ int main(void)
150 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 153 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
151 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 154 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
152 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); 155 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
153 DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp));
154 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); 156 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
155#endif /* CONFIG_32BIT */ 157#endif /* CONFIG_32BIT */
156 return 0; 158 return 0;
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index f8828d38fa6..3aa4d00aaf5 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -33,7 +33,7 @@ s390_base_mcck_handler_fn:
33 .previous 33 .previous
34 34
35ENTRY(s390_base_ext_handler) 35ENTRY(s390_base_ext_handler)
36 stmg %r0,%r15,__LC_SAVE_AREA 36 stmg %r0,%r15,__LC_SAVE_AREA_ASYNC
37 basr %r13,0 37 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD 380: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn 39 larl %r1,s390_base_ext_handler_fn
@@ -41,7 +41,7 @@ ENTRY(s390_base_ext_handler)
41 ltgr %r1,%r1 41 ltgr %r1,%r1
42 jz 1f 42 jz 1f
43 basr %r14,%r1 43 basr %r14,%r1
441: lmg %r0,%r15,__LC_SAVE_AREA 441: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW 46 lpswe __LC_EXT_OLD_PSW
47 47
@@ -53,7 +53,7 @@ s390_base_ext_handler_fn:
53 .previous 53 .previous
54 54
55ENTRY(s390_base_pgm_handler) 55ENTRY(s390_base_pgm_handler)
56 stmg %r0,%r15,__LC_SAVE_AREA 56 stmg %r0,%r15,__LC_SAVE_AREA_SYNC
57 basr %r13,0 57 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD 580: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn 59 larl %r1,s390_base_pgm_handler_fn
@@ -61,7 +61,7 @@ ENTRY(s390_base_pgm_handler)
61 ltgr %r1,%r1 61 ltgr %r1,%r1
62 jz 1f 62 jz 1f
63 basr %r14,%r1 63 basr %r14,%r1
64 lmg %r0,%r15,__LC_SAVE_AREA 64 lmg %r0,%r15,__LC_SAVE_AREA_SYNC
65 lpswe __LC_PGM_OLD_PSW 65 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13) 661: lpswe disabled_wait_psw-0b(%r13)
67 67
@@ -142,7 +142,7 @@ s390_base_mcck_handler_fn:
142 .previous 142 .previous
143 143
144ENTRY(s390_base_ext_handler) 144ENTRY(s390_base_ext_handler)
145 stm %r0,%r15,__LC_SAVE_AREA 145 stm %r0,%r15,__LC_SAVE_AREA_ASYNC
146 basr %r13,0 146 basr %r13,0
1470: ahi %r15,-STACK_FRAME_OVERHEAD 1470: ahi %r15,-STACK_FRAME_OVERHEAD
148 l %r1,2f-0b(%r13) 148 l %r1,2f-0b(%r13)
@@ -150,7 +150,7 @@ ENTRY(s390_base_ext_handler)
150 ltr %r1,%r1 150 ltr %r1,%r1
151 jz 1f 151 jz 1f
152 basr %r14,%r1 152 basr %r14,%r1
1531: lm %r0,%r15,__LC_SAVE_AREA 1531: lm %r0,%r15,__LC_SAVE_AREA_ASYNC
154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
155 lpsw __LC_EXT_OLD_PSW 155 lpsw __LC_EXT_OLD_PSW
156 156
@@ -164,7 +164,7 @@ s390_base_ext_handler_fn:
164 .previous 164 .previous
165 165
166ENTRY(s390_base_pgm_handler) 166ENTRY(s390_base_pgm_handler)
167 stm %r0,%r15,__LC_SAVE_AREA 167 stm %r0,%r15,__LC_SAVE_AREA_SYNC
168 basr %r13,0 168 basr %r13,0
1690: ahi %r15,-STACK_FRAME_OVERHEAD 1690: ahi %r15,-STACK_FRAME_OVERHEAD
170 l %r1,2f-0b(%r13) 170 l %r1,2f-0b(%r13)
@@ -172,7 +172,7 @@ ENTRY(s390_base_pgm_handler)
172 ltr %r1,%r1 172 ltr %r1,%r1
173 jz 1f 173 jz 1f
174 basr %r14,%r1 174 basr %r14,%r1
175 lm %r0,%r15,__LC_SAVE_AREA 175 lm %r0,%r15,__LC_SAVE_AREA_SYNC
176 lpsw __LC_PGM_OLD_PSW 176 lpsw __LC_PGM_OLD_PSW
177 177
1781: lpsw disabled_wait_psw-0b(%r13) 1781: lpsw disabled_wait_psw-0b(%r13)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 84a98289844..ab64bdbab2a 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -278,9 +278,6 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
278{ 278{
279 if (call >> 16) /* hack for backward compatibility */ 279 if (call >> 16) /* hack for backward compatibility */
280 return -EINVAL; 280 return -EINVAL;
281
282 call &= 0xffff;
283
284 switch (call) { 281 switch (call) {
285 case SEMTIMEDOP: 282 case SEMTIMEDOP:
286 return compat_sys_semtimedop(first, compat_ptr(ptr), 283 return compat_sys_semtimedop(first, compat_ptr(ptr),
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 4f68c81d3ff..6fe78c2f95d 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -501,8 +501,12 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
501 501
502 /* We forgot to include these in the sigcontext. 502 /* We forgot to include these in the sigcontext.
503 To avoid breaking binary compatibility, they are passed as args. */ 503 To avoid breaking binary compatibility, they are passed as args. */
504 regs->gprs[4] = current->thread.trap_no; 504 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
505 regs->gprs[5] = current->thread.prot_addr; 505 sig == SIGTRAP || sig == SIGFPE) {
506 /* set extra registers only for synchronous signals */
507 regs->gprs[4] = regs->int_code & 127;
508 regs->gprs[5] = regs->int_parm_long;
509 }
506 510
507 /* Place signal number on stack to allow backtrace from handler. */ 511 /* Place signal number on stack to allow backtrace from handler. */
508 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) 512 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
@@ -544,9 +548,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
544 /* Set up to return from userspace. If provided, use a stub 548 /* Set up to return from userspace. If provided, use a stub
545 already in userspace. */ 549 already in userspace. */
546 if (ka->sa.sa_flags & SA_RESTORER) { 550 if (ka->sa.sa_flags & SA_RESTORER) {
547 regs->gprs[14] = (__u64) ka->sa.sa_restorer; 551 regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
548 } else { 552 } else {
549 regs->gprs[14] = (__u64) frame->retcode; 553 regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE;
550 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 554 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
551 (u16 __force __user *)(frame->retcode)); 555 (u16 __force __user *)(frame->retcode));
552 } 556 }
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 45df6d456aa..e2f847599c8 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1578,10 +1578,15 @@ void show_code(struct pt_regs *regs)
1578 ptr += sprintf(ptr, "%s Code:", mode); 1578 ptr += sprintf(ptr, "%s Code:", mode);
1579 hops = 0; 1579 hops = 0;
1580 while (start < end && hops < 8) { 1580 while (start < end && hops < 8) {
1581 *ptr++ = (start == 32) ? '>' : ' '; 1581 opsize = insn_length(code[start]);
1582 if (start + opsize == 32)
1583 *ptr++ = '#';
1584 else if (start == 32)
1585 *ptr++ = '>';
1586 else
1587 *ptr++ = ' ';
1582 addr = regs->psw.addr + start - 32; 1588 addr = regs->psw.addr + start - 32;
1583 ptr += sprintf(ptr, ONELONG, addr); 1589 ptr += sprintf(ptr, ONELONG, addr);
1584 opsize = insn_length(code[start]);
1585 if (start + opsize >= end) 1590 if (start + opsize >= end)
1586 break; 1591 break;
1587 for (i = 0; i < opsize; i++) 1592 for (i = 0; i < opsize; i++)
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c9ffe002519..52098d6dfaa 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -434,18 +434,22 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
434 } 434 }
435} 435}
436 436
437static void __init setup_boot_command_line(void) 437static inline int has_ebcdic_char(const char *str)
438{ 438{
439 int i; 439 int i;
440 440
441 /* convert arch command line to ascii */ 441 for (i = 0; str[i]; i++)
442 for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++) 442 if (str[i] & 0x80)
443 if (COMMAND_LINE[i] & 0x80) 443 return 1;
444 break; 444 return 0;
445 if (i < ARCH_COMMAND_LINE_SIZE) 445}
446 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
447 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
448 446
447static void __init setup_boot_command_line(void)
448{
449 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
450 /* convert arch command line to ascii if necessary */
451 if (has_ebcdic_char(COMMAND_LINE))
452 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
449 /* copy arch command line */ 453 /* copy arch command line */
450 strlcpy(boot_command_line, strstrip(COMMAND_LINE), 454 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451 ARCH_COMMAND_LINE_SIZE); 455 ARCH_COMMAND_LINE_SIZE);
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b13157057e0..3705700ed37 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 4
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 8
25 */ 25__PT_R3 = __PT_GPRS + 12
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 16
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 20
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 24
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 28
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 30__PT_R8 = __PT_GPRS + 32
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 31__PT_R9 = __PT_GPRS + 36
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 32__PT_R10 = __PT_GPRS + 40
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 33__PT_R11 = __PT_GPRS + 44
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 34__PT_R12 = __PT_GPRS + 48
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 35__PT_R13 = __PT_GPRS + 524
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 36__PT_R14 = __PT_GPRS + 56
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 37__PT_R15 = __PT_GPRS + 60
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 39_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
50 _TIF_MCCK_PENDING | _TIF_PER_TRAP ) 40 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
@@ -58,133 +48,91 @@ STACK_SIZE = 1 << STACK_SHIFT
58 48
59#define BASED(name) name-system_call(%r13) 49#define BASED(name) name-system_call(%r13)
60 50
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON 51 .macro TRACE_IRQS_ON
52#ifdef CONFIG_TRACE_IRQFLAGS
63 basr %r2,%r0 53 basr %r2,%r0
64 l %r1,BASED(.Ltrace_irq_on_caller) 54 l %r1,BASED(.Lhardirqs_on)
65 basr %r14,%r1 55 basr %r14,%r1 # call trace_hardirqs_on_caller
56#endif
66 .endm 57 .endm
67 58
68 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
69 basr %r2,%r0 61 basr %r2,%r0
70 l %r1,BASED(.Ltrace_irq_off_caller) 62 l %r1,BASED(.Lhardirqs_off)
71 basr %r14,%r1 63 basr %r14,%r1 # call trace_hardirqs_off_caller
72 .endm
73#else
74#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF
76#endif 64#endif
65 .endm
77 66
78#ifdef CONFIG_LOCKDEP
79 .macro LOCKDEP_SYS_EXIT 67 .macro LOCKDEP_SYS_EXIT
80 tm SP_PSW+1(%r15),0x01 # returning to user ? 68#ifdef CONFIG_LOCKDEP
81 jz 0f 69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
82 l %r1,BASED(.Llockdep_sys_exit) 71 l %r1,BASED(.Llockdep_sys_exit)
83 basr %r14,%r1 72 basr %r14,%r1 # call lockdep_sys_exit
840:
85 .endm
86#else
87#define LOCKDEP_SYS_EXIT
88#endif 73#endif
89
90/*
91 * Register usage in interrupt handlers:
92 * R9 - pointer to current task structure
93 * R13 - pointer to literal pool
94 * R14 - return register for function calls
95 * R15 - kernel stack pointer
96 */
97
98 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
99 lm %r10,%r11,\lc_from
100 sl %r10,\lc_to
101 sl %r11,\lc_to+4
102 bc 3,BASED(0f)
103 sl %r10,BASED(.Lc_1)
1040: al %r10,\lc_sum
105 al %r11,\lc_sum+4
106 bc 12,BASED(1f)
107 al %r10,BASED(.Lc_1)
1081: stm %r10,%r11,\lc_sum
109 .endm
110
111 .macro SAVE_ALL_SVC psworg,savearea
112 stm %r12,%r15,\savearea
113 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
114 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
115 s %r15,BASED(.Lc_spsize) # make room for registers & psw
116 .endm
117
118 .macro SAVE_ALL_BASE savearea
119 stm %r12,%r15,\savearea
120 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
121 .endm 74 .endm
122 75
123 .macro SAVE_ALL_PGM psworg,savearea 76 .macro CHECK_STACK stacksize,savearea
124 tm \psworg+1,0x01 # test problem state bit
125#ifdef CONFIG_CHECK_STACK 77#ifdef CONFIG_CHECK_STACK
126 bnz BASED(1f) 78 tml %r15,\stacksize - CONFIG_STACK_GUARD
127 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 79 la %r14,\savearea
128 bnz BASED(2f) 80 jz stack_overflow
129 la %r12,\psworg
130 b BASED(stack_overflow)
131#else
132 bz BASED(2f)
133#endif 81#endif
1341: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
1352: s %r15,BASED(.Lc_spsize) # make room for registers & psw
136 .endm 82 .endm
137 83
138 .macro SAVE_ALL_ASYNC psworg,savearea 84 .macro SWITCH_ASYNC savearea,stack,shift
139 stm %r12,%r15,\savearea 85 tmh %r8,0x0001 # interrupting from user ?
140 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 86 jnz 1f
141 la %r12,\psworg 87 lr %r14,%r9
142 tm \psworg+1,0x01 # test problem state bit 88 sl %r14,BASED(.Lcritical_start)
143 bnz BASED(1f) # from user -> load async stack 89 cl %r14,BASED(.Lcritical_length)
144 clc \psworg+4(4),BASED(.Lcritical_end) 90 jhe 0f
145 bhe BASED(0f) 91 la %r11,\savearea # inside critical section, do cleanup
146 clc \psworg+4(4),BASED(.Lcritical_start) 92 bras %r14,cleanup_critical
147 bl BASED(0f) 93 tmh %r8,0x0001 # retest problem state after cleanup
148 l %r14,BASED(.Lcleanup_critical) 94 jnz 1f
149 basr %r14,%r14 950: l %r14,\stack # are we already on the target stack?
150 tm 1(%r12),0x01 # retest problem state after cleanup
151 bnz BASED(1f)
1520: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
153 slr %r14,%r15 96 slr %r14,%r15
154 sra %r14,STACK_SHIFT 97 sra %r14,\shift
155#ifdef CONFIG_CHECK_STACK 98 jnz 1f
156 bnz BASED(1f) 99 CHECK_STACK 1<<\shift,\savearea
157 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 j 2f
158 bnz BASED(2f) 1011: l %r15,\stack # load target stack
159 b BASED(stack_overflow) 1022: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
160#else 103 la %r11,STACK_FRAME_OVERHEAD(%r15)
161 bz BASED(2f)
162#endif
1631: l %r15,__LC_ASYNC_STACK
1642: s %r15,BASED(.Lc_spsize) # make room for registers & psw
165 .endm 104 .endm
166 105
167 .macro CREATE_STACK_FRAME savearea 106 .macro ADD64 high,low,timer
168 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 107 al \high,\timer
169 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 108 al \low,\timer+4
170 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 109 brc 12,.+8
171 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 110 ahi \high,1
172 .endm 111 .endm
173 112
174 .macro RESTORE_ALL psworg,sync 113 .macro SUB64 high,low,timer
175 mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore 114 sl \high,\timer
176 .if !\sync 115 sl \low,\timer+4
177 ni \psworg+1,0xfd # clear wait state bit 116 brc 3,.+8
178 .endif 117 ahi \high,-1
179 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 118 .endm
180 stpt __LC_EXIT_TIMER 119
181 lpsw \psworg # back to caller 120 .macro UPDATE_VTIME high,low,enter_timer
121 lm \high,\low,__LC_EXIT_TIMER
122 SUB64 \high,\low,\enter_timer
123 ADD64 \high,\low,__LC_USER_TIMER
124 stm \high,\low,__LC_USER_TIMER
125 lm \high,\low,__LC_LAST_UPDATE_TIMER
126 SUB64 \high,\low,__LC_EXIT_TIMER
127 ADD64 \high,\low,__LC_SYSTEM_TIMER
128 stm \high,\low,__LC_SYSTEM_TIMER
129 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
182 .endm 130 .endm
183 131
184 .macro REENABLE_IRQS 132 .macro REENABLE_IRQS
185 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 133 st %r8,__LC_RETURN_PSW
186 ni __SF_EMPTY(%r15),0xbf 134 ni __LC_RETURN_PSW,0xbf
187 ssm __SF_EMPTY(%r15) 135 ssm __LC_RETURN_PSW
188 .endm 136 .endm
189 137
190 .section .kprobes.text, "ax" 138 .section .kprobes.text, "ax"
@@ -197,14 +145,13 @@ STACK_SIZE = 1 << STACK_SHIFT
197 * gpr2 = prev 145 * gpr2 = prev
198 */ 146 */
199ENTRY(__switch_to) 147ENTRY(__switch_to)
200 basr %r1,0 148 l %r4,__THREAD_info(%r2) # get thread_info of prev
2010: l %r4,__THREAD_info(%r2) # get thread_info of prev
202 l %r5,__THREAD_info(%r3) # get thread_info of next 149 l %r5,__THREAD_info(%r3) # get thread_info of next
203 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? 150 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
204 bz 1f-0b(%r1) 151 jz 0f
205 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev 152 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
206 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next 153 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
2071: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1540: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
208 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev 155 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
209 l %r15,__THREAD_ksp(%r3) # load kernel stack of next 156 l %r15,__THREAD_ksp(%r3) # load kernel stack of next
210 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 157 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
@@ -224,48 +171,55 @@ __critical_start:
224 171
225ENTRY(system_call) 172ENTRY(system_call)
226 stpt __LC_SYNC_ENTER_TIMER 173 stpt __LC_SYNC_ENTER_TIMER
227sysc_saveall: 174sysc_stm:
228 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 175 stm %r8,%r15,__LC_SAVE_AREA_SYNC
229 CREATE_STACK_FRAME __LC_SAVE_AREA 176 l %r12,__LC_THREAD_INFO
230 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 177 l %r13,__LC_SVC_NEW_PSW+4
231 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 178sysc_per:
232 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 179 l %r15,__LC_KERNEL_STACK
233 oi __TI_flags+3(%r12),_TIF_SYSCALL 180 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
181 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
234sysc_vtime: 182sysc_vtime:
235 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 183 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
236sysc_stime: 184 stm %r0,%r7,__PT_R0(%r11)
237 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 185 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
238sysc_update: 186 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
239 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 187 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
240sysc_do_svc: 188sysc_do_svc:
241 xr %r7,%r7 189 oi __TI_flags+3(%r12),_TIF_SYSCALL
242 icm %r7,3,SP_SVC_CODE+2(%r15)# load svc number and test for svc 0 190 lh %r8,__PT_INT_CODE+2(%r11)
243 bnz BASED(sysc_nr_ok) # svc number > 0 191 sla %r8,2 # shift and test for svc0
192 jnz sysc_nr_ok
244 # svc 0: system call number in %r1 193 # svc 0: system call number in %r1
245 cl %r1,BASED(.Lnr_syscalls) 194 cl %r1,BASED(.Lnr_syscalls)
246 bnl BASED(sysc_nr_ok) 195 jnl sysc_nr_ok
247 sth %r1,SP_SVC_CODE+2(%r15) 196 sth %r1,__PT_INT_CODE+2(%r11)
248 lr %r7,%r1 # copy svc number to %r7 197 lr %r8,%r1
198 sla %r8,2
249sysc_nr_ok: 199sysc_nr_ok:
250 sll %r7,2 # svc number *4 200 l %r10,BASED(.Lsys_call_table) # 31 bit system call table
251 l %r10,BASED(.Lsysc_table) 201 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
202 st %r2,__PT_ORIG_GPR2(%r11)
203 st %r7,STACK_FRAME_OVERHEAD(%r15)
204 l %r9,0(%r8,%r10) # get system call addr.
252 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 205 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
253 mvc SP_ARGS(4,%r15),SP_R7(%r15) 206 jnz sysc_tracesys
254 l %r8,0(%r7,%r10) # get system call addr. 207 basr %r14,%r9 # call sys_xxxx
255 bnz BASED(sysc_tracesys) 208 st %r2,__PT_R2(%r11) # store return value
256 basr %r14,%r8 # call sys_xxxx
257 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
258 209
259sysc_return: 210sysc_return:
260 LOCKDEP_SYS_EXIT 211 LOCKDEP_SYS_EXIT
261sysc_tif: 212sysc_tif:
262 tm SP_PSW+1(%r15),0x01 # returning to user ? 213 tm __PT_PSW+1(%r11),0x01 # returning to user ?
263 bno BASED(sysc_restore) 214 jno sysc_restore
264 tm __TI_flags+3(%r12),_TIF_WORK_SVC 215 tm __TI_flags+3(%r12),_TIF_WORK_SVC
265 bnz BASED(sysc_work) # there is work to do (signals etc.) 216 jnz sysc_work # check for work
266 ni __TI_flags+3(%r12),255-_TIF_SYSCALL 217 ni __TI_flags+3(%r12),255-_TIF_SYSCALL
267sysc_restore: 218sysc_restore:
268 RESTORE_ALL __LC_RETURN_PSW,1 219 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
220 stpt __LC_EXIT_TIMER
221 lm %r0,%r15,__PT_R0(%r11)
222 lpsw __LC_RETURN_PSW
269sysc_done: 223sysc_done:
270 224
271# 225#
@@ -273,16 +227,16 @@ sysc_done:
273# 227#
274sysc_work: 228sysc_work:
275 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 229 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
276 bo BASED(sysc_mcck_pending) 230 jo sysc_mcck_pending
277 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 231 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
278 bo BASED(sysc_reschedule) 232 jo sysc_reschedule
279 tm __TI_flags+3(%r12),_TIF_SIGPENDING 233 tm __TI_flags+3(%r12),_TIF_SIGPENDING
280 bo BASED(sysc_sigpending) 234 jo sysc_sigpending
281 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 235 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
282 bo BASED(sysc_notify_resume) 236 jo sysc_notify_resume
283 tm __TI_flags+3(%r12),_TIF_PER_TRAP 237 tm __TI_flags+3(%r12),_TIF_PER_TRAP
284 bo BASED(sysc_singlestep) 238 jo sysc_singlestep
285 b BASED(sysc_return) # beware of critical section cleanup 239 j sysc_return # beware of critical section cleanup
286 240
287# 241#
288# _TIF_NEED_RESCHED is set, call schedule 242# _TIF_NEED_RESCHED is set, call schedule
@@ -290,13 +244,13 @@ sysc_work:
290sysc_reschedule: 244sysc_reschedule:
291 l %r1,BASED(.Lschedule) 245 l %r1,BASED(.Lschedule)
292 la %r14,BASED(sysc_return) 246 la %r14,BASED(sysc_return)
293 br %r1 # call scheduler 247 br %r1 # call schedule
294 248
295# 249#
296# _TIF_MCCK_PENDING is set, call handler 250# _TIF_MCCK_PENDING is set, call handler
297# 251#
298sysc_mcck_pending: 252sysc_mcck_pending:
299 l %r1,BASED(.Ls390_handle_mcck) 253 l %r1,BASED(.Lhandle_mcck)
300 la %r14,BASED(sysc_return) 254 la %r14,BASED(sysc_return)
301 br %r1 # TIF bit will be cleared by handler 255 br %r1 # TIF bit will be cleared by handler
302 256
@@ -305,23 +259,24 @@ sysc_mcck_pending:
305# 259#
306sysc_sigpending: 260sysc_sigpending:
307 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 261 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
308 la %r2,SP_PTREGS(%r15) # load pt_regs 262 lr %r2,%r11 # pass pointer to pt_regs
309 l %r1,BASED(.Ldo_signal) 263 l %r1,BASED(.Ldo_signal)
310 basr %r14,%r1 # call do_signal 264 basr %r14,%r1 # call do_signal
311 tm __TI_flags+3(%r12),_TIF_SYSCALL 265 tm __TI_flags+3(%r12),_TIF_SYSCALL
312 bno BASED(sysc_return) 266 jno sysc_return
313 lm %r2,%r6,SP_R2(%r15) # load svc arguments 267 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
314 xr %r7,%r7 # svc 0 returns -ENOSYS 268 xr %r8,%r8 # svc 0 returns -ENOSYS
315 clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2) 269 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
316 bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 270 jnl sysc_nr_ok # invalid svc number -> do svc 0
317 icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number 271 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number
318 b BASED(sysc_nr_ok) # restart svc 272 sla %r8,2
273 j sysc_nr_ok # restart svc
319 274
320# 275#
321# _TIF_NOTIFY_RESUME is set, call do_notify_resume 276# _TIF_NOTIFY_RESUME is set, call do_notify_resume
322# 277#
323sysc_notify_resume: 278sysc_notify_resume:
324 la %r2,SP_PTREGS(%r15) # load pt_regs 279 lr %r2,%r11 # pass pointer to pt_regs
325 l %r1,BASED(.Ldo_notify_resume) 280 l %r1,BASED(.Ldo_notify_resume)
326 la %r14,BASED(sysc_return) 281 la %r14,BASED(sysc_return)
327 br %r1 # call do_notify_resume 282 br %r1 # call do_notify_resume
@@ -331,56 +286,57 @@ sysc_notify_resume:
331# 286#
332sysc_singlestep: 287sysc_singlestep:
333 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 288 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
334 la %r2,SP_PTREGS(%r15) # address of register-save area 289 lr %r2,%r11 # pass pointer to pt_regs
335 l %r1,BASED(.Lhandle_per) # load adr. of per handler 290 l %r1,BASED(.Ldo_per_trap)
336 la %r14,BASED(sysc_return) # load adr. of system return 291 la %r14,BASED(sysc_return)
337 br %r1 # branch to do_per_trap 292 br %r1 # call do_per_trap
338 293
339# 294#
340# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 295# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
341# and after the system call 296# and after the system call
342# 297#
343sysc_tracesys: 298sysc_tracesys:
344 l %r1,BASED(.Ltrace_entry) 299 l %r1,BASED(.Ltrace_enter)
345 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lr %r2,%r11 # pass pointer to pt_regs
346 la %r3,0 301 la %r3,0
347 xr %r0,%r0 302 xr %r0,%r0
348 icm %r0,3,SP_SVC_CODE(%r15) 303 icm %r0,3,__PT_INT_CODE+2(%r11)
349 st %r0,SP_R2(%r15) 304 st %r0,__PT_R2(%r11)
350 basr %r14,%r1 305 basr %r14,%r1 # call do_syscall_trace_enter
351 cl %r2,BASED(.Lnr_syscalls) 306 cl %r2,BASED(.Lnr_syscalls)
352 bnl BASED(sysc_tracenogo) 307 jnl sysc_tracenogo
353 lr %r7,%r2 308 lr %r8,%r2
354 sll %r7,2 # svc number *4 309 sll %r8,2
355 l %r8,0(%r7,%r10) 310 l %r9,0(%r8,%r10)
356sysc_tracego: 311sysc_tracego:
357 lm %r3,%r6,SP_R3(%r15) 312 lm %r3,%r7,__PT_R3(%r11)
358 mvc SP_ARGS(4,%r15),SP_R7(%r15) 313 st %r7,STACK_FRAME_OVERHEAD(%r15)
359 l %r2,SP_ORIG_R2(%r15) 314 l %r2,__PT_ORIG_GPR2(%r11)
360 basr %r14,%r8 # call sys_xxx 315 basr %r14,%r9 # call sys_xxx
361 st %r2,SP_R2(%r15) # store return value 316 st %r2,__PT_R2(%r11) # store return value
362sysc_tracenogo: 317sysc_tracenogo:
363 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 318 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
364 bz BASED(sysc_return) 319 jz sysc_return
365 l %r1,BASED(.Ltrace_exit) 320 l %r1,BASED(.Ltrace_exit)
366 la %r2,SP_PTREGS(%r15) # load pt_regs 321 lr %r2,%r11 # pass pointer to pt_regs
367 la %r14,BASED(sysc_return) 322 la %r14,BASED(sysc_return)
368 br %r1 323 br %r1 # call do_syscall_trace_exit
369 324
370# 325#
371# a new process exits the kernel with ret_from_fork 326# a new process exits the kernel with ret_from_fork
372# 327#
373ENTRY(ret_from_fork) 328ENTRY(ret_from_fork)
329 la %r11,STACK_FRAME_OVERHEAD(%r15)
330 l %r12,__LC_THREAD_INFO
374 l %r13,__LC_SVC_NEW_PSW+4 331 l %r13,__LC_SVC_NEW_PSW+4
375 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 332 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
376 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 333 jo 0f
377 bo BASED(0f) 334 st %r15,__PT_R15(%r11) # store stack pointer for new kthread
378 st %r15,SP_R15(%r15) # store stack pointer for new kthread 3350: l %r1,BASED(.Lschedule_tail)
3790: l %r1,BASED(.Lschedtail) 336 basr %r14,%r1 # call schedule_tail
380 basr %r14,%r1
381 TRACE_IRQS_ON 337 TRACE_IRQS_ON
382 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 338 ssm __LC_SVC_NEW_PSW # reenable interrupts
383 b BASED(sysc_tracenogo) 339 j sysc_tracenogo
384 340
385# 341#
386# kernel_execve function needs to deal with pt_regs that is not 342# kernel_execve function needs to deal with pt_regs that is not
@@ -390,153 +346,98 @@ ENTRY(kernel_execve)
390 stm %r12,%r15,48(%r15) 346 stm %r12,%r15,48(%r15)
391 lr %r14,%r15 347 lr %r14,%r15
392 l %r13,__LC_SVC_NEW_PSW+4 348 l %r13,__LC_SVC_NEW_PSW+4
393 s %r15,BASED(.Lc_spsize) 349 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
394 st %r14,__SF_BACKCHAIN(%r15) 350 st %r14,__SF_BACKCHAIN(%r15)
395 la %r12,SP_PTREGS(%r15) 351 la %r12,STACK_FRAME_OVERHEAD(%r15)
396 xc 0(__PT_SIZE,%r12),0(%r12) 352 xc 0(__PT_SIZE,%r12),0(%r12)
397 l %r1,BASED(.Ldo_execve) 353 l %r1,BASED(.Ldo_execve)
398 lr %r5,%r12 354 lr %r5,%r12
399 basr %r14,%r1 355 basr %r14,%r1 # call do_execve
400 ltr %r2,%r2 356 ltr %r2,%r2
401 be BASED(0f) 357 je 0f
402 a %r15,BASED(.Lc_spsize) 358 ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
403 lm %r12,%r15,48(%r15) 359 lm %r12,%r15,48(%r15)
404 br %r14 360 br %r14
405 # execve succeeded. 361 # execve succeeded.
4060: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3620: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
407 l %r15,__LC_KERNEL_STACK # load ksp 363 l %r15,__LC_KERNEL_STACK # load ksp
408 s %r15,BASED(.Lc_spsize) # make room for registers & psw 364 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
409 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 365 la %r11,STACK_FRAME_OVERHEAD(%r15)
366 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
410 l %r12,__LC_THREAD_INFO 367 l %r12,__LC_THREAD_INFO
411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 368 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
412 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 369 ssm __LC_SVC_NEW_PSW # reenable interrupts
413 l %r1,BASED(.Lexecve_tail) 370 l %r1,BASED(.Lexecve_tail)
414 basr %r14,%r1 371 basr %r14,%r1 # call execve_tail
415 b BASED(sysc_return) 372 j sysc_return
416 373
417/* 374/*
418 * Program check handler routine 375 * Program check handler routine
419 */ 376 */
420 377
421ENTRY(pgm_check_handler) 378ENTRY(pgm_check_handler)
422/*
423 * First we need to check for a special case:
424 * Single stepping an instruction that disables the PER event mask will
425 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
426 * For a single stepped SVC the program check handler gets control after
427 * the SVC new PSW has been loaded. But we want to execute the SVC first and
428 * then handle the PER event. Therefore we update the SVC old PSW to point
429 * to the pgm_check_handler and branch to the SVC handler after we checked
430 * if we have to load the kernel stack register.
431 * For every other possible cause for PER event without the PER mask set
432 * we just ignore the PER event (FIXME: is there anything we have to do
433 * for LPSW?).
434 */
435 stpt __LC_SYNC_ENTER_TIMER 379 stpt __LC_SYNC_ENTER_TIMER
436 SAVE_ALL_BASE __LC_SAVE_AREA 380 stm %r8,%r15,__LC_SAVE_AREA_SYNC
437 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 381 l %r12,__LC_THREAD_INFO
438 bnz BASED(pgm_per) # got per exception -> special case 382 l %r13,__LC_SVC_NEW_PSW+4
439 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 383 lm %r8,%r9,__LC_PGM_OLD_PSW
440 CREATE_STACK_FRAME __LC_SAVE_AREA 384 tmh %r8,0x0001 # test problem state bit
441 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW 385 jnz 1f # -> fault in user space
442 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 386 tmh %r8,0x4000 # PER bit set in old PSW ?
443 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 387 jnz 0f # -> enabled, can't be a double fault
444 bz BASED(pgm_no_vtime) 388 tm __LC_PGM_ILC+3,0x80 # check for per exception
445 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 389 jnz pgm_svcper # -> single stepped svc
446 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 3900: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
447 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 391 j 2f
448pgm_no_vtime: 3921: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
449 l %r3,__LC_PGM_ILC # load program interruption code 393 l %r15,__LC_KERNEL_STACK
450 l %r4,__LC_TRANS_EXC_CODE 3942: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
451 REENABLE_IRQS 395 la %r11,STACK_FRAME_OVERHEAD(%r15)
452 la %r8,0x7f 396 stm %r0,%r7,__PT_R0(%r11)
453 nr %r8,%r3 397 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
454 sll %r8,2 398 stm %r8,%r9,__PT_PSW(%r11)
455 l %r1,BASED(.Ljump_table) 399 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
456 l %r1,0(%r8,%r1) # load address of handler routine 400 mvc __PT_INT_PARM_LONG(4,%r11),__LC_TRANS_EXC_CODE
457 la %r2,SP_PTREGS(%r15) # address of register-save area 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
458 basr %r14,%r1 # branch to interrupt-handler 402 jz 0f
459pgm_exit:
460 b BASED(sysc_return)
461
462#
463# handle per exception
464#
465pgm_per:
466 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
467 bnz BASED(pgm_per_std) # ok, normal per event from user space
468# ok its one of the special cases, now we need to find out which one
469 clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
470 be BASED(pgm_svcper)
471# no interesting special case, ignore PER event
472 lm %r12,%r15,__LC_SAVE_AREA
473 lpsw 0x28
474
475#
476# Normal per exception
477#
478pgm_per_std:
479 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
480 CREATE_STACK_FRAME __LC_SAVE_AREA
481 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
482 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
483 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
484 bz BASED(pgm_no_vtime2)
485 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
486 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
487 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
488pgm_no_vtime2:
489 l %r1,__TI_task(%r12) 403 l %r1,__TI_task(%r12)
490 tm SP_PSW+1(%r15),0x01 # kernel per event ? 404 tmh %r8,0x0001 # kernel per event ?
491 bz BASED(kernel_per) 405 jz pgm_kprobe
492 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 406 oi __TI_flags+3(%r12),_TIF_PER_TRAP
493 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS 407 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
408 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
494 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 409 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
495 oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4100: REENABLE_IRQS
496 l %r3,__LC_PGM_ILC # load program interruption code 411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
497 l %r4,__LC_TRANS_EXC_CODE
498 REENABLE_IRQS
499 la %r8,0x7f
500 nr %r8,%r3 # clear per-event-bit and ilc
501 be BASED(pgm_exit2) # only per or per+check ?
502 sll %r8,2
503 l %r1,BASED(.Ljump_table) 412 l %r1,BASED(.Ljump_table)
504 l %r1,0(%r8,%r1) # load address of handler routine 413 la %r10,0x7f
505 la %r2,SP_PTREGS(%r15) # address of register-save area 414 n %r10,__PT_INT_CODE(%r11)
415 je sysc_return
416 sll %r10,2
417 l %r1,0(%r10,%r1) # load address of handler routine
418 lr %r2,%r11 # pass pointer to pt_regs
506 basr %r14,%r1 # branch to interrupt-handler 419 basr %r14,%r1 # branch to interrupt-handler
507pgm_exit2: 420 j sysc_return
508 b BASED(sysc_return)
509 421
510# 422#
511# it was a single stepped SVC that is causing all the trouble 423# PER event in supervisor state, must be kprobes
512# 424#
513pgm_svcper: 425pgm_kprobe:
514 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 426 REENABLE_IRQS
515 CREATE_STACK_FRAME __LC_SAVE_AREA 427 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
516 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 428 l %r1,BASED(.Ldo_per_trap)
517 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 429 lr %r2,%r11 # pass pointer to pt_regs
518 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 430 basr %r14,%r1 # call do_per_trap
519 oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) 431 j sysc_return
520 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
521 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
522 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
523 l %r8,__TI_task(%r12)
524 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
525 mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
526 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
527 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
528 lm %r2,%r6,SP_R2(%r15) # load svc arguments
529 b BASED(sysc_do_svc)
530 432
531# 433#
532# per was called from kernel, must be kprobes 434# single stepped system call
533# 435#
534kernel_per: 436pgm_svcper:
535 REENABLE_IRQS 437 oi __TI_flags+3(%r12),_TIF_PER_TRAP
536 la %r2,SP_PTREGS(%r15) # address of register-save area 438 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
537 l %r1,BASED(.Lhandle_per) # load adr. of per handler 439 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per)
538 basr %r14,%r1 # branch to do_single_step 440 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs
539 b BASED(pgm_exit)
540 441
541/* 442/*
542 * IO interrupt handler routine 443 * IO interrupt handler routine
@@ -545,28 +446,35 @@ kernel_per:
545ENTRY(io_int_handler) 446ENTRY(io_int_handler)
546 stck __LC_INT_CLOCK 447 stck __LC_INT_CLOCK
547 stpt __LC_ASYNC_ENTER_TIMER 448 stpt __LC_ASYNC_ENTER_TIMER
548 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 449 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
549 CREATE_STACK_FRAME __LC_SAVE_AREA+16 450 l %r12,__LC_THREAD_INFO
550 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 451 l %r13,__LC_SVC_NEW_PSW+4
551 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 452 lm %r8,%r9,__LC_IO_OLD_PSW
552 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 453 tmh %r8,0x0001 # interrupting from user ?
553 bz BASED(io_no_vtime) 454 jz io_skip
554 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 455 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
555 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 456io_skip:
556 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 457 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
557io_no_vtime: 458 stm %r0,%r7,__PT_R0(%r11)
459 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
460 stm %r8,%r9,__PT_PSW(%r11)
558 TRACE_IRQS_OFF 461 TRACE_IRQS_OFF
559 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 462 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
560 la %r2,SP_PTREGS(%r15) # address of register-save area 463 l %r1,BASED(.Ldo_IRQ)
561 basr %r14,%r1 # branch to standard irq handler 464 lr %r2,%r11 # pass pointer to pt_regs
465 basr %r14,%r1 # call do_IRQ
562io_return: 466io_return:
563 LOCKDEP_SYS_EXIT 467 LOCKDEP_SYS_EXIT
564 TRACE_IRQS_ON 468 TRACE_IRQS_ON
565io_tif: 469io_tif:
566 tm __TI_flags+3(%r12),_TIF_WORK_INT 470 tm __TI_flags+3(%r12),_TIF_WORK_INT
567 bnz BASED(io_work) # there is work to do (signals etc.) 471 jnz io_work # there is work to do (signals etc.)
568io_restore: 472io_restore:
569 RESTORE_ALL __LC_RETURN_PSW,0 473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
474 ni __LC_RETURN_PSW+1,0xfd # clean wait state bit
475 stpt __LC_EXIT_TIMER
476 lm %r0,%r15,__PT_R0(%r11)
477 lpsw __LC_RETURN_PSW
570io_done: 478io_done:
571 479
572# 480#
@@ -577,28 +485,29 @@ io_done:
577# Before any work can be done, a switch to the kernel stack is required. 485# Before any work can be done, a switch to the kernel stack is required.
578# 486#
579io_work: 487io_work:
580 tm SP_PSW+1(%r15),0x01 # returning to user ? 488 tm __PT_PSW+1(%r11),0x01 # returning to user ?
581 bo BASED(io_work_user) # yes -> do resched & signal 489 jo io_work_user # yes -> do resched & signal
582#ifdef CONFIG_PREEMPT 490#ifdef CONFIG_PREEMPT
583 # check for preemptive scheduling 491 # check for preemptive scheduling
584 icm %r0,15,__TI_precount(%r12) 492 icm %r0,15,__TI_precount(%r12)
585 bnz BASED(io_restore) # preemption disabled 493 jnz io_restore # preemption disabled
586 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 494 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
587 bno BASED(io_restore) 495 jno io_restore
588 # switch to kernel stack 496 # switch to kernel stack
589 l %r1,SP_R15(%r15) 497 l %r1,__PT_R15(%r11)
590 s %r1,BASED(.Lc_spsize) 498 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
591 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 499 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
592 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 500 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
501 la %r11,STACK_FRAME_OVERHEAD(%r1)
593 lr %r15,%r1 502 lr %r15,%r1
594 # TRACE_IRQS_ON already done at io_return, call 503 # TRACE_IRQS_ON already done at io_return, call
595 # TRACE_IRQS_OFF to keep things symmetrical 504 # TRACE_IRQS_OFF to keep things symmetrical
596 TRACE_IRQS_OFF 505 TRACE_IRQS_OFF
597 l %r1,BASED(.Lpreempt_schedule_irq) 506 l %r1,BASED(.Lpreempt_irq)
598 basr %r14,%r1 # call preempt_schedule_irq 507 basr %r14,%r1 # call preempt_schedule_irq
599 b BASED(io_return) 508 j io_return
600#else 509#else
601 b BASED(io_restore) 510 j io_restore
602#endif 511#endif
603 512
604# 513#
@@ -606,9 +515,10 @@ io_work:
606# 515#
607io_work_user: 516io_work_user:
608 l %r1,__LC_KERNEL_STACK 517 l %r1,__LC_KERNEL_STACK
609 s %r1,BASED(.Lc_spsize) 518 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
610 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 519 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
611 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 520 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
521 la %r11,STACK_FRAME_OVERHEAD(%r1)
612 lr %r15,%r1 522 lr %r15,%r1
613 523
614# 524#
@@ -618,24 +528,24 @@ io_work_user:
618# 528#
619io_work_tif: 529io_work_tif:
620 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 530 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
621 bo BASED(io_mcck_pending) 531 jo io_mcck_pending
622 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 532 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
623 bo BASED(io_reschedule) 533 jo io_reschedule
624 tm __TI_flags+3(%r12),_TIF_SIGPENDING 534 tm __TI_flags+3(%r12),_TIF_SIGPENDING
625 bo BASED(io_sigpending) 535 jo io_sigpending
626 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 536 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
627 bo BASED(io_notify_resume) 537 jo io_notify_resume
628 b BASED(io_return) # beware of critical section cleanup 538 j io_return # beware of critical section cleanup
629 539
630# 540#
631# _TIF_MCCK_PENDING is set, call handler 541# _TIF_MCCK_PENDING is set, call handler
632# 542#
633io_mcck_pending: 543io_mcck_pending:
634 # TRACE_IRQS_ON already done at io_return 544 # TRACE_IRQS_ON already done at io_return
635 l %r1,BASED(.Ls390_handle_mcck) 545 l %r1,BASED(.Lhandle_mcck)
636 basr %r14,%r1 # TIF bit will be cleared by handler 546 basr %r14,%r1 # TIF bit will be cleared by handler
637 TRACE_IRQS_OFF 547 TRACE_IRQS_OFF
638 b BASED(io_return) 548 j io_return
639 549
640# 550#
641# _TIF_NEED_RESCHED is set, call schedule 551# _TIF_NEED_RESCHED is set, call schedule
@@ -643,37 +553,37 @@ io_mcck_pending:
643io_reschedule: 553io_reschedule:
644 # TRACE_IRQS_ON already done at io_return 554 # TRACE_IRQS_ON already done at io_return
645 l %r1,BASED(.Lschedule) 555 l %r1,BASED(.Lschedule)
646 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 556 ssm __LC_SVC_NEW_PSW # reenable interrupts
647 basr %r14,%r1 # call scheduler 557 basr %r14,%r1 # call scheduler
648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 558 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF 559 TRACE_IRQS_OFF
650 b BASED(io_return) 560 j io_return
651 561
652# 562#
653# _TIF_SIGPENDING is set, call do_signal 563# _TIF_SIGPENDING is set, call do_signal
654# 564#
655io_sigpending: 565io_sigpending:
656 # TRACE_IRQS_ON already done at io_return 566 # TRACE_IRQS_ON already done at io_return
657 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
658 la %r2,SP_PTREGS(%r15) # load pt_regs
659 l %r1,BASED(.Ldo_signal) 567 l %r1,BASED(.Ldo_signal)
568 ssm __LC_SVC_NEW_PSW # reenable interrupts
569 lr %r2,%r11 # pass pointer to pt_regs
660 basr %r14,%r1 # call do_signal 570 basr %r14,%r1 # call do_signal
661 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 571 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
662 TRACE_IRQS_OFF 572 TRACE_IRQS_OFF
663 b BASED(io_return) 573 j io_return
664 574
665# 575#
666# _TIF_SIGPENDING is set, call do_signal 576# _TIF_SIGPENDING is set, call do_signal
667# 577#
668io_notify_resume: 578io_notify_resume:
669 # TRACE_IRQS_ON already done at io_return 579 # TRACE_IRQS_ON already done at io_return
670 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
671 la %r2,SP_PTREGS(%r15) # load pt_regs
672 l %r1,BASED(.Ldo_notify_resume) 580 l %r1,BASED(.Ldo_notify_resume)
673 basr %r14,%r1 # call do_signal 581 ssm __LC_SVC_NEW_PSW # reenable interrupts
674 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 582 lr %r2,%r11 # pass pointer to pt_regs
583 basr %r14,%r1 # call do_notify_resume
584 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
675 TRACE_IRQS_OFF 585 TRACE_IRQS_OFF
676 b BASED(io_return) 586 j io_return
677 587
678/* 588/*
679 * External interrupt handler routine 589 * External interrupt handler routine
@@ -682,23 +592,25 @@ io_notify_resume:
682ENTRY(ext_int_handler) 592ENTRY(ext_int_handler)
683 stck __LC_INT_CLOCK 593 stck __LC_INT_CLOCK
684 stpt __LC_ASYNC_ENTER_TIMER 594 stpt __LC_ASYNC_ENTER_TIMER
685 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 595 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
686 CREATE_STACK_FRAME __LC_SAVE_AREA+16 596 l %r12,__LC_THREAD_INFO
687 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 597 l %r13,__LC_SVC_NEW_PSW+4
688 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 598 lm %r8,%r9,__LC_EXT_OLD_PSW
689 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 599 tmh %r8,0x0001 # interrupting from user ?
690 bz BASED(ext_no_vtime) 600 jz ext_skip
691 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 601 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
692 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 602ext_skip:
693 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 603 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
694ext_no_vtime: 604 stm %r0,%r7,__PT_R0(%r11)
605 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
606 stm %r8,%r9,__PT_PSW(%r11)
695 TRACE_IRQS_OFF 607 TRACE_IRQS_OFF
696 la %r2,SP_PTREGS(%r15) # address of register-save area 608 lr %r2,%r11 # pass pointer to pt_regs
697 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 609 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
698 l %r4,__LC_EXT_PARAMS # get external parameters 610 l %r4,__LC_EXT_PARAMS # get external parameters
699 l %r1,BASED(.Ldo_extint) 611 l %r1,BASED(.Ldo_extint)
700 basr %r14,%r1 612 basr %r14,%r1 # call do_extint
701 b BASED(io_return) 613 j io_return
702 614
703__critical_end: 615__critical_end:
704 616
@@ -710,82 +622,74 @@ ENTRY(mcck_int_handler)
710 stck __LC_MCCK_CLOCK 622 stck __LC_MCCK_CLOCK
711 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 623 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
712 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 624 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
713 SAVE_ALL_BASE __LC_SAVE_AREA+32 625 l %r12,__LC_THREAD_INFO
714 la %r12,__LC_MCK_OLD_PSW 626 l %r13,__LC_SVC_NEW_PSW+4
627 lm %r8,%r9,__LC_MCK_OLD_PSW
715 tm __LC_MCCK_CODE,0x80 # system damage? 628 tm __LC_MCCK_CODE,0x80 # system damage?
716 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 629 jo mcck_panic # yes -> rest of mcck code invalid
717 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA 630 la %r14,__LC_CPU_TIMER_SAVE_AREA
631 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
718 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 632 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
719 bo BASED(1f) 633 jo 3f
720 la %r14,__LC_SYNC_ENTER_TIMER 634 la %r14,__LC_SYNC_ENTER_TIMER
721 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 635 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
722 bl BASED(0f) 636 jl 0f
723 la %r14,__LC_ASYNC_ENTER_TIMER 637 la %r14,__LC_ASYNC_ENTER_TIMER
7240: clc 0(8,%r14),__LC_EXIT_TIMER 6380: clc 0(8,%r14),__LC_EXIT_TIMER
725 bl BASED(0f) 639 jl 1f
726 la %r14,__LC_EXIT_TIMER 640 la %r14,__LC_EXIT_TIMER
7270: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6411: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
728 bl BASED(0f) 642 jl 2f
729 la %r14,__LC_LAST_UPDATE_TIMER 643 la %r14,__LC_LAST_UPDATE_TIMER
7300: spt 0(%r14) 6442: spt 0(%r14)
731 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 645 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7321: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6463: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
733 bno BASED(mcck_int_main) # no -> skip cleanup critical 647 jno mcck_panic # no -> skip cleanup critical
734 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 648 tm %r8,0x0001 # interrupting from user ?
735 bnz BASED(mcck_int_main) # from user -> load async stack 649 jz mcck_skip
736 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) 650 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
737 bhe BASED(mcck_int_main) 651mcck_skip:
738 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) 652 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
739 bl BASED(mcck_int_main) 653 mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
740 l %r14,BASED(.Lcleanup_critical) 654 stm %r8,%r9,__PT_PSW(%r11)
741 basr %r14,%r14 655 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
742mcck_int_main: 656 l %r1,BASED(.Ldo_machine_check)
743 l %r14,__LC_PANIC_STACK # are we already on the panic stack? 657 lr %r2,%r11 # pass pointer to pt_regs
744 slr %r14,%r15 658 basr %r14,%r1 # call s390_do_machine_check
745 sra %r14,PAGE_SHIFT 659 tm __PT_PSW+1(%r11),0x01 # returning to user ?
746 be BASED(0f) 660 jno mcck_return
747 l %r15,__LC_PANIC_STACK # load panic stack
7480: s %r15,BASED(.Lc_spsize) # make room for registers & psw
749 CREATE_STACK_FRAME __LC_SAVE_AREA+32
750 mvc SP_PSW(8,%r15),0(%r12)
751 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
752 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
753 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
754 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
755 bz BASED(mcck_no_vtime)
756 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
757 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
758 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
759mcck_no_vtime:
760 la %r2,SP_PTREGS(%r15) # load pt_regs
761 l %r1,BASED(.Ls390_mcck)
762 basr %r14,%r1 # call machine check handler
763 tm SP_PSW+1(%r15),0x01 # returning to user ?
764 bno BASED(mcck_return)
765 l %r1,__LC_KERNEL_STACK # switch to kernel stack 661 l %r1,__LC_KERNEL_STACK # switch to kernel stack
766 s %r1,BASED(.Lc_spsize) 662 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
767 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 663 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
768 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 664 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
665 la %r11,STACK_FRAME_OVERHEAD(%r15)
769 lr %r15,%r1 666 lr %r15,%r1
770 stosm __SF_EMPTY(%r15),0x04 # turn dat on 667 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
771 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 668 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
772 bno BASED(mcck_return) 669 jno mcck_return
773 TRACE_IRQS_OFF 670 TRACE_IRQS_OFF
774 l %r1,BASED(.Ls390_handle_mcck) 671 l %r1,BASED(.Lhandle_mcck)
775 basr %r14,%r1 # call machine check handler 672 basr %r14,%r1 # call s390_handle_mcck
776 TRACE_IRQS_ON 673 TRACE_IRQS_ON
777mcck_return: 674mcck_return:
778 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW 675 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
779 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 676 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
780 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 677 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
781 bno BASED(0f) 678 jno 0f
782 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 679 lm %r0,%r15,__PT_R0(%r11)
783 stpt __LC_EXIT_TIMER 680 stpt __LC_EXIT_TIMER
784 lpsw __LC_RETURN_MCCK_PSW # back to caller 681 lpsw __LC_RETURN_MCCK_PSW
7850: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 6820: lm %r0,%r15,__PT_R0(%r11)
786 lpsw __LC_RETURN_MCCK_PSW # back to caller 683 lpsw __LC_RETURN_MCCK_PSW
787 684
788 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 685mcck_panic:
686 l %r14,__LC_PANIC_STACK
687 slr %r14,%r15
688 sra %r14,PAGE_SHIFT
689 jz 0f
690 l %r15,__LC_PANIC_STACK
6910: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
692 j mcck_skip
789 693
790/* 694/*
791 * Restart interruption handler, kick starter for additional CPUs 695 * Restart interruption handler, kick starter for additional CPUs
@@ -799,18 +703,18 @@ restart_base:
799 stck __LC_LAST_UPDATE_CLOCK 703 stck __LC_LAST_UPDATE_CLOCK
800 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 704 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
801 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 705 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
802 l %r15,__LC_SAVE_AREA+60 # load ksp 706 l %r15,__LC_GPREGS_SAVE_AREA+60 # load ksp
803 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs 707 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
804 lam %a0,%a15,__LC_AREGS_SAVE_AREA 708 lam %a0,%a15,__LC_AREGS_SAVE_AREA
805 lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone 709 lm %r6,%r15,__SF_GPRS(%r15)# load registers from clone
806 l %r1,__LC_THREAD_INFO 710 l %r1,__LC_THREAD_INFO
807 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 711 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
808 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 712 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
809 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 713 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
810 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 714 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
811 basr %r14,0 715 basr %r14,0
812 l %r14,restart_addr-.(%r14) 716 l %r14,restart_addr-.(%r14)
813 basr %r14,%r14 # branch to start_secondary 717 basr %r14,%r14 # call start_secondary
814restart_addr: 718restart_addr:
815 .long start_secondary 719 .long start_secondary
816 .align 8 720 .align 8
@@ -835,19 +739,19 @@ restart_go:
835# PSW restart interrupt handler 739# PSW restart interrupt handler
836# 740#
837ENTRY(psw_restart_int_handler) 741ENTRY(psw_restart_int_handler)
838 st %r15,__LC_SAVE_AREA+48(%r0) # save r15 742 st %r15,__LC_SAVE_AREA_RESTART
839 basr %r15,0 743 basr %r15,0
8400: l %r15,.Lrestart_stack-0b(%r15) # load restart stack 7440: l %r15,.Lrestart_stack-0b(%r15) # load restart stack
841 l %r15,0(%r15) 745 l %r15,0(%r15)
842 ahi %r15,-SP_SIZE # make room for pt_regs 746 ahi %r15,-__PT_SIZE # create pt_regs on stack
843 stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 747 stm %r0,%r14,__PT_R0(%r15)
844 mvc SP_R15(4,%r15),__LC_SAVE_AREA+48(%r0)# store saved %r15 to stack 748 mvc __PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
845 mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw 749 mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
846 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 750 ahi %r15,-STACK_FRAME_OVERHEAD
751 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
847 basr %r14,0 752 basr %r14,0
8481: l %r14,.Ldo_restart-1b(%r14) 7531: l %r14,.Ldo_restart-1b(%r14)
849 basr %r14,%r14 754 basr %r14,%r14
850
851 basr %r14,0 # load disabled wait PSW if 755 basr %r14,0 # load disabled wait PSW if
8522: lpsw restart_psw_crash-2b(%r14) # do_restart returns 7562: lpsw restart_psw_crash-2b(%r14) # do_restart returns
853 .align 4 757 .align 4
@@ -869,215 +773,174 @@ restart_psw_crash:
869 */ 773 */
870stack_overflow: 774stack_overflow:
871 l %r15,__LC_PANIC_STACK # change to panic stack 775 l %r15,__LC_PANIC_STACK # change to panic stack
872 sl %r15,BASED(.Lc_spsize) 776 ahi %r15,-__PT_SIZE # create pt_regs
873 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 777 stm %r0,%r7,__PT_R0(%r15)
874 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 778 stm %r8,%r9,__PT_PSW(%r15)
875 la %r1,__LC_SAVE_AREA 779 mvc __PT_R8(32,%r11),0(%r14)
876 ch %r12,BASED(.L0x020) # old psw addr == __LC_SVC_OLD_PSW ? 780 lr %r15,%r11
877 be BASED(0f) 781 ahi %r15,-STACK_FRAME_OVERHEAD
878 ch %r12,BASED(.L0x028) # old psw addr == __LC_PGM_OLD_PSW ? 782 l %r1,BASED(1f)
879 be BASED(0f) 783 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
880 la %r1,__LC_SAVE_AREA+16 784 lr %r2,%r11 # pass pointer to pt_regs
8810: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack 785 br %r1 # branch to kernel_stack_overflow
882 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
883 l %r1,BASED(1f) # branch to kernel_stack_overflow
884 la %r2,SP_PTREGS(%r15) # load pt_regs
885 br %r1
8861: .long kernel_stack_overflow 7861: .long kernel_stack_overflow
887#endif 787#endif
888 788
889cleanup_table_system_call: 789cleanup_table:
890 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 790 .long system_call + 0x80000000
891cleanup_table_sysc_tif: 791 .long sysc_do_svc + 0x80000000
892 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 792 .long sysc_tif + 0x80000000
893cleanup_table_sysc_restore: 793 .long sysc_restore + 0x80000000
894 .long sysc_restore + 0x80000000, sysc_done + 0x80000000 794 .long sysc_done + 0x80000000
895cleanup_table_io_tif: 795 .long io_tif + 0x80000000
896 .long io_tif + 0x80000000, io_restore + 0x80000000 796 .long io_restore + 0x80000000
897cleanup_table_io_restore: 797 .long io_done + 0x80000000
898 .long io_restore + 0x80000000, io_done + 0x80000000
899 798
900cleanup_critical: 799cleanup_critical:
901 clc 4(4,%r12),BASED(cleanup_table_system_call) 800 cl %r9,BASED(cleanup_table) # system_call
902 bl BASED(0f) 801 jl 0f
903 clc 4(4,%r12),BASED(cleanup_table_system_call+4) 802 cl %r9,BASED(cleanup_table+4) # sysc_do_svc
904 bl BASED(cleanup_system_call) 803 jl cleanup_system_call
9050: 804 cl %r9,BASED(cleanup_table+8) # sysc_tif
906 clc 4(4,%r12),BASED(cleanup_table_sysc_tif) 805 jl 0f
907 bl BASED(0f) 806 cl %r9,BASED(cleanup_table+12) # sysc_restore
908 clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) 807 jl cleanup_sysc_tif
909 bl BASED(cleanup_sysc_tif) 808 cl %r9,BASED(cleanup_table+16) # sysc_done
9100: 809 jl cleanup_sysc_restore
911 clc 4(4,%r12),BASED(cleanup_table_sysc_restore) 810 cl %r9,BASED(cleanup_table+20) # io_tif
912 bl BASED(0f) 811 jl 0f
913 clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) 812 cl %r9,BASED(cleanup_table+24) # io_restore
914 bl BASED(cleanup_sysc_restore) 813 jl cleanup_io_tif
9150: 814 cl %r9,BASED(cleanup_table+28) # io_done
916 clc 4(4,%r12),BASED(cleanup_table_io_tif) 815 jl cleanup_io_restore
917 bl BASED(0f) 8160: br %r14
918 clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
919 bl BASED(cleanup_io_tif)
9200:
921 clc 4(4,%r12),BASED(cleanup_table_io_restore)
922 bl BASED(0f)
923 clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
924 bl BASED(cleanup_io_restore)
9250:
926 br %r14
927 817
928cleanup_system_call: 818cleanup_system_call:
929 mvc __LC_RETURN_PSW(8),0(%r12) 819 # check if stpt has been executed
930 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) 820 cl %r9,BASED(cleanup_system_call_insn)
931 bh BASED(0f) 821 jh 0f
932 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
933 c %r12,BASED(.Lmck_old_psw)
934 be BASED(0f)
935 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 822 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9360: c %r12,BASED(.Lmck_old_psw) 823 chi %r11,__LC_SAVE_AREA_ASYNC
937 la %r12,__LC_SAVE_AREA+32 824 je 0f
938 be BASED(0f) 825 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
939 la %r12,__LC_SAVE_AREA+16 8260: # check if stm has been executed
9400: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) 827 cl %r9,BASED(cleanup_system_call_insn+4)
941 bhe BASED(cleanup_vtime) 828 jh 0f
942 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) 829 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
943 bh BASED(0f) 8300: # set up saved registers r12, and r13
944 mvc __LC_SAVE_AREA(16),0(%r12) 831 st %r12,16(%r11) # r12 thread-info pointer
9450: st %r13,4(%r12) 832 st %r13,20(%r11) # r13 literal-pool pointer
946 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 833 # check if the user time calculation has been done
947 s %r15,BASED(.Lc_spsize) # make room for registers & psw 834 cl %r9,BASED(cleanup_system_call_insn+8)
948 st %r15,12(%r12) 835 jh 0f
949 CREATE_STACK_FRAME __LC_SAVE_AREA 836 l %r10,__LC_EXIT_TIMER
950 mvc 0(4,%r12),__LC_THREAD_INFO 837 l %r15,__LC_EXIT_TIMER+4
951 l %r12,__LC_THREAD_INFO 838 SUB64 %r10,%r15,__LC_SYNC_ENTER_TIMER
952 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 839 ADD64 %r10,%r15,__LC_USER_TIMER
953 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 840 st %r10,__LC_USER_TIMER
954 oi __TI_flags+3(%r12),_TIF_SYSCALL 841 st %r15,__LC_USER_TIMER+4
955cleanup_vtime: 8420: # check if the system time calculation has been done
956 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 843 cl %r9,BASED(cleanup_system_call_insn+12)
957 bhe BASED(cleanup_stime) 844 jh 0f
958 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 845 l %r10,__LC_LAST_UPDATE_TIMER
959cleanup_stime: 846 l %r15,__LC_LAST_UPDATE_TIMER+4
960 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 847 SUB64 %r10,%r15,__LC_EXIT_TIMER
961 bh BASED(cleanup_update) 848 ADD64 %r10,%r15,__LC_SYSTEM_TIMER
962 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 849 st %r10,__LC_SYSTEM_TIMER
963cleanup_update: 850 st %r15,__LC_SYSTEM_TIMER+4
8510: # update accounting time stamp
964 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 852 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
965 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 853 # set up saved register 11
966 la %r12,__LC_RETURN_PSW 854 l %r15,__LC_KERNEL_STACK
855 ahi %r15,-__PT_SIZE
856 st %r15,12(%r11) # r11 pt_regs pointer
857 # fill pt_regs
858 mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
859 stm %r0,%r7,__PT_R0(%r15)
860 mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
861 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
862 # setup saved register 15
863 ahi %r15,-STACK_FRAME_OVERHEAD
864 st %r15,28(%r11) # r15 stack pointer
865 # set new psw address and exit
866 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000
967 br %r14 867 br %r14
968cleanup_system_call_insn: 868cleanup_system_call_insn:
969 .long sysc_saveall + 0x80000000
970 .long system_call + 0x80000000 869 .long system_call + 0x80000000
971 .long sysc_vtime + 0x80000000 870 .long sysc_stm + 0x80000000
972 .long sysc_stime + 0x80000000 871 .long sysc_vtime + 0x80000000 + 36
973 .long sysc_update + 0x80000000 872 .long sysc_vtime + 0x80000000 + 76
974 873
975cleanup_sysc_tif: 874cleanup_sysc_tif:
976 mvc __LC_RETURN_PSW(4),0(%r12) 875 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000
977 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
978 la %r12,__LC_RETURN_PSW
979 br %r14 876 br %r14
980 877
981cleanup_sysc_restore: 878cleanup_sysc_restore:
982 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) 879 cl %r9,BASED(cleanup_sysc_restore_insn)
983 be BASED(2f) 880 jhe 0f
984 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 881 l %r9,12(%r11) # get saved pointer to pt_regs
985 c %r12,BASED(.Lmck_old_psw) 882 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
986 be BASED(0f) 883 mvc 0(32,%r11),__PT_R8(%r9)
987 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 884 lm %r0,%r7,__PT_R0(%r9)
9880: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) 8850: lm %r8,%r9,__LC_RETURN_PSW
989 be BASED(2f)
990 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
991 c %r12,BASED(.Lmck_old_psw)
992 la %r12,__LC_SAVE_AREA+32
993 be BASED(1f)
994 la %r12,__LC_SAVE_AREA+16
9951: mvc 0(16,%r12),SP_R12(%r15)
996 lm %r0,%r11,SP_R0(%r15)
997 l %r15,SP_R15(%r15)
9982: la %r12,__LC_RETURN_PSW
999 br %r14 886 br %r14
1000cleanup_sysc_restore_insn: 887cleanup_sysc_restore_insn:
1001 .long sysc_done - 4 + 0x80000000 888 .long sysc_done - 4 + 0x80000000
1002 .long sysc_done - 8 + 0x80000000
1003 889
1004cleanup_io_tif: 890cleanup_io_tif:
1005 mvc __LC_RETURN_PSW(4),0(%r12) 891 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000
1006 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
1007 la %r12,__LC_RETURN_PSW
1008 br %r14 892 br %r14
1009 893
1010cleanup_io_restore: 894cleanup_io_restore:
1011 clc 4(4,%r12),BASED(cleanup_io_restore_insn) 895 cl %r9,BASED(cleanup_io_restore_insn)
1012 be BASED(1f) 896 jhe 0f
1013 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 897 l %r9,12(%r11) # get saved r11 pointer to pt_regs
1014 clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) 898 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
1015 be BASED(1f) 899 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
1016 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 900 mvc 0(32,%r11),__PT_R8(%r9)
1017 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) 901 lm %r0,%r7,__PT_R0(%r9)
1018 lm %r0,%r11,SP_R0(%r15) 9020: lm %r8,%r9,__LC_RETURN_PSW
1019 l %r15,SP_R15(%r15)
10201: la %r12,__LC_RETURN_PSW
1021 br %r14 903 br %r14
1022cleanup_io_restore_insn: 904cleanup_io_restore_insn:
1023 .long io_done - 4 + 0x80000000 905 .long io_done - 4 + 0x80000000
1024 .long io_done - 8 + 0x80000000
1025 906
1026/* 907/*
1027 * Integer constants 908 * Integer constants
1028 */ 909 */
1029 .align 4 910 .align 4
1030.Lc_spsize: .long SP_SIZE 911.Lnr_syscalls: .long NR_syscalls
1031.Lc_overhead: .long STACK_FRAME_OVERHEAD
1032.Lnr_syscalls: .long NR_syscalls
1033.L0x018: .short 0x018
1034.L0x020: .short 0x020
1035.L0x028: .short 0x028
1036.L0x030: .short 0x030
1037.L0x038: .short 0x038
1038.Lc_1: .long 1
1039 912
1040/* 913/*
1041 * Symbol constants 914 * Symbol constants
1042 */ 915 */
1043.Ls390_mcck: .long s390_do_machine_check 916.Ldo_machine_check: .long s390_do_machine_check
1044.Ls390_handle_mcck: 917.Lhandle_mcck: .long s390_handle_mcck
1045 .long s390_handle_mcck 918.Ldo_IRQ: .long do_IRQ
1046.Lmck_old_psw: .long __LC_MCK_OLD_PSW 919.Ldo_extint: .long do_extint
1047.Ldo_IRQ: .long do_IRQ 920.Ldo_signal: .long do_signal
1048.Ldo_extint: .long do_extint 921.Ldo_notify_resume: .long do_notify_resume
1049.Ldo_signal: .long do_signal 922.Ldo_per_trap: .long do_per_trap
1050.Ldo_notify_resume: 923.Ldo_execve: .long do_execve
1051 .long do_notify_resume 924.Lexecve_tail: .long execve_tail
1052.Lhandle_per: .long do_per_trap 925.Ljump_table: .long pgm_check_table
1053.Ldo_execve: .long do_execve 926.Lschedule: .long schedule
1054.Lexecve_tail: .long execve_tail
1055.Ljump_table: .long pgm_check_table
1056.Lschedule: .long schedule
1057#ifdef CONFIG_PREEMPT 927#ifdef CONFIG_PREEMPT
1058.Lpreempt_schedule_irq: 928.Lpreempt_irq: .long preempt_schedule_irq
1059 .long preempt_schedule_irq
1060#endif 929#endif
1061.Ltrace_entry: .long do_syscall_trace_enter 930.Ltrace_enter: .long do_syscall_trace_enter
1062.Ltrace_exit: .long do_syscall_trace_exit 931.Ltrace_exit: .long do_syscall_trace_exit
1063.Lschedtail: .long schedule_tail 932.Lschedule_tail: .long schedule_tail
1064.Lsysc_table: .long sys_call_table 933.Lsys_call_table: .long sys_call_table
934.Lsysc_per: .long sysc_per + 0x80000000
1065#ifdef CONFIG_TRACE_IRQFLAGS 935#ifdef CONFIG_TRACE_IRQFLAGS
1066.Ltrace_irq_on_caller: 936.Lhardirqs_on: .long trace_hardirqs_on_caller
1067 .long trace_hardirqs_on_caller 937.Lhardirqs_off: .long trace_hardirqs_off_caller
1068.Ltrace_irq_off_caller:
1069 .long trace_hardirqs_off_caller
1070#endif 938#endif
1071#ifdef CONFIG_LOCKDEP 939#ifdef CONFIG_LOCKDEP
1072.Llockdep_sys_exit: 940.Llockdep_sys_exit: .long lockdep_sys_exit
1073 .long lockdep_sys_exit
1074#endif 941#endif
1075.Lcritical_start: 942.Lcritical_start: .long __critical_start + 0x80000000
1076 .long __critical_start + 0x80000000 943.Lcritical_length: .long __critical_end - __critical_start
1077.Lcritical_end:
1078 .long __critical_end + 0x80000000
1079.Lcleanup_critical:
1080 .long cleanup_critical
1081 944
1082 .section .rodata, "a" 945 .section .rodata, "a"
1083#define SYSCALL(esa,esame,emu) .long esa 946#define SYSCALL(esa,esame,emu) .long esa
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index ef8fb1d6e8d..bf538aaf407 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -6,15 +6,15 @@
6#include <asm/ptrace.h> 6#include <asm/ptrace.h>
7 7
8 8
9extern void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 9extern void (*pgm_check_table[128])(struct pt_regs *);
10extern void *restart_stack; 10extern void *restart_stack;
11 11
12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); 12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs); 13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
14 14
15void do_protection_exception(struct pt_regs *, long, unsigned long); 15void do_protection_exception(struct pt_regs *regs);
16void do_dat_exception(struct pt_regs *, long, unsigned long); 16void do_dat_exception(struct pt_regs *regs);
17void do_asce_exception(struct pt_regs *, long, unsigned long); 17void do_asce_exception(struct pt_regs *regs);
18 18
19void do_per_trap(struct pt_regs *regs); 19void do_per_trap(struct pt_regs *regs);
20void syscall_trace(struct pt_regs *regs, int entryexit); 20void syscall_trace(struct pt_regs *regs, int entryexit);
@@ -28,7 +28,7 @@ void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
28void do_restart(void); 28void do_restart(void);
29int __cpuinit start_secondary(void *cpuvoid); 29int __cpuinit start_secondary(void *cpuvoid);
30void __init startup_init(void); 30void __init startup_init(void);
31void die(const char * str, struct pt_regs * regs, long err); 31void die(struct pt_regs *regs, const char *str);
32 32
33void __init time_init(void); 33void __init time_init(void);
34 34
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 83a93747e2f..412a7b8783d 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 8
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 16
25 */ 25__PT_R3 = __PT_GPRS + 24
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 32
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 40
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 48
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 56
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 30__PT_R8 = __PT_GPRS + 64
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 31__PT_R9 = __PT_GPRS + 72
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 32__PT_R10 = __PT_GPRS + 80
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 33__PT_R11 = __PT_GPRS + 88
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 34__PT_R12 = __PT_GPRS + 96
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 35__PT_R13 = __PT_GPRS + 104
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 36__PT_R14 = __PT_GPRS + 112
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 37__PT_R15 = __PT_GPRS + 120
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 39STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
50STACK_SIZE = 1 << STACK_SHIFT 40STACK_SIZE = 1 << STACK_SHIFT
@@ -59,154 +49,103 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 49
60#define BASED(name) name-system_call(%r13) 50#define BASED(name) name-system_call(%r13)
61 51
62 .macro SPP newpp
63#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
64 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
65 jz .+8
66 .insn s,0xb2800000,\newpp
67#endif
68 .endm
69
70 .macro HANDLE_SIE_INTERCEPT
71#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
72 tm __TI_flags+6(%r12),_TIF_SIE>>8
73 jz 0f
74 SPP __LC_CMF_HPP # set host id
75 clc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
76 jl 0f
77 clc SP_PSW+8(8,%r15),BASED(.Lsie_done)
78 jhe 0f
79 mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
800:
81#endif
82 .endm
83
84#ifdef CONFIG_TRACE_IRQFLAGS
85 .macro TRACE_IRQS_ON 52 .macro TRACE_IRQS_ON
53#ifdef CONFIG_TRACE_IRQFLAGS
86 basr %r2,%r0 54 basr %r2,%r0
87 brasl %r14,trace_hardirqs_on_caller 55 brasl %r14,trace_hardirqs_on_caller
56#endif
88 .endm 57 .endm
89 58
90 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
91 basr %r2,%r0 61 basr %r2,%r0
92 brasl %r14,trace_hardirqs_off_caller 62 brasl %r14,trace_hardirqs_off_caller
93 .endm
94#else
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF
97#endif 63#endif
64 .endm
98 65
99#ifdef CONFIG_LOCKDEP
100 .macro LOCKDEP_SYS_EXIT 66 .macro LOCKDEP_SYS_EXIT
101 tm SP_PSW+1(%r15),0x01 # returning to user ? 67#ifdef CONFIG_LOCKDEP
102 jz 0f 68 tm __PT_PSW+1(%r11),0x01 # returning to user ?
69 jz .+10
103 brasl %r14,lockdep_sys_exit 70 brasl %r14,lockdep_sys_exit
1040:
105 .endm
106#else
107#define LOCKDEP_SYS_EXIT
108#endif 71#endif
109
110 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
111 lg %r10,\lc_from
112 slg %r10,\lc_to
113 alg %r10,\lc_sum
114 stg %r10,\lc_sum
115 .endm 72 .endm
116 73
117/* 74 .macro SPP newpp
118 * Register usage in interrupt handlers: 75#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
119 * R9 - pointer to current task structure 76 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
120 * R13 - pointer to literal pool 77 jz .+8
121 * R14 - return register for function calls 78 .insn s,0xb2800000,\newpp
122 * R15 - kernel stack pointer 79#endif
123 */ 80 .endm
124 81
125 .macro SAVE_ALL_SVC psworg,savearea 82 .macro HANDLE_SIE_INTERCEPT scratch
126 stmg %r11,%r15,\savearea 83#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
127 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 84 tm __TI_flags+6(%r12),_TIF_SIE>>8
128 aghi %r15,-SP_SIZE # make room for registers & psw 85 jz .+42
129 lg %r11,__LC_LAST_BREAK 86 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
87 jz .+8
88 .insn s,0xb2800000,BASED(.Lhost_id) # set host id
89 lgr \scratch,%r9
90 slg \scratch,BASED(.Lsie_loop)
91 clg \scratch,BASED(.Lsie_length)
92 jhe .+10
93 lg %r9,BASED(.Lsie_loop)
94#endif
130 .endm 95 .endm
131 96
132 .macro SAVE_ALL_PGM psworg,savearea 97 .macro CHECK_STACK stacksize,savearea
133 stmg %r11,%r15,\savearea
134 tm \psworg+1,0x01 # test problem state bit
135#ifdef CONFIG_CHECK_STACK 98#ifdef CONFIG_CHECK_STACK
136 jnz 1f 99 tml %r15,\stacksize - CONFIG_STACK_GUARD
137 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 lghi %r14,\savearea
138 jnz 2f 101 jz stack_overflow
139 la %r12,\psworg
140 j stack_overflow
141#else
142 jz 2f
143#endif 102#endif
1441: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
1452: aghi %r15,-SP_SIZE # make room for registers & psw
146 larl %r13,system_call
147 lg %r11,__LC_LAST_BREAK
148 .endm 103 .endm
149 104
150 .macro SAVE_ALL_ASYNC psworg,savearea 105 .macro SWITCH_ASYNC savearea,stack,shift
151 stmg %r11,%r15,\savearea 106 tmhh %r8,0x0001 # interrupting from user ?
152 larl %r13,system_call 107 jnz 1f
153 lg %r11,__LC_LAST_BREAK 108 lgr %r14,%r9
154 la %r12,\psworg 109 slg %r14,BASED(.Lcritical_start)
155 tm \psworg+1,0x01 # test problem state bit 110 clg %r14,BASED(.Lcritical_length)
156 jnz 1f # from user -> load kernel stack
157 clc \psworg+8(8),BASED(.Lcritical_end)
158 jhe 0f 111 jhe 0f
159 clc \psworg+8(8),BASED(.Lcritical_start) 112 lghi %r11,\savearea # inside critical section, do cleanup
160 jl 0f
161 brasl %r14,cleanup_critical 113 brasl %r14,cleanup_critical
162 tm 1(%r12),0x01 # retest problem state after cleanup 114 tmhh %r8,0x0001 # retest problem state after cleanup
163 jnz 1f 115 jnz 1f
1640: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? 1160: lg %r14,\stack # are we already on the target stack?
165 slgr %r14,%r15 117 slgr %r14,%r15
166 srag %r14,%r14,STACK_SHIFT 118 srag %r14,%r14,\shift
167#ifdef CONFIG_CHECK_STACK
168 jnz 1f 119 jnz 1f
169 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 120 CHECK_STACK 1<<\shift,\savearea
170 jnz 2f 121 j 2f
171 j stack_overflow 1221: lg %r15,\stack # load target stack
172#else 1232: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
173 jz 2f 124 la %r11,STACK_FRAME_OVERHEAD(%r15)
174#endif
1751: lg %r15,__LC_ASYNC_STACK # load async stack
1762: aghi %r15,-SP_SIZE # make room for registers & psw
177 .endm
178
179 .macro CREATE_STACK_FRAME savearea
180 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
181 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
182 mvc SP_R11(40,%r15),\savearea # move %r11-%r15 to stack
183 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack
184 .endm 125 .endm
185 126
186 .macro RESTORE_ALL psworg,sync 127 .macro UPDATE_VTIME scratch,enter_timer
187 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore 128 lg \scratch,__LC_EXIT_TIMER
188 .if !\sync 129 slg \scratch,\enter_timer
189 ni \psworg+1,0xfd # clear wait state bit 130 alg \scratch,__LC_USER_TIMER
190 .endif 131 stg \scratch,__LC_USER_TIMER
191 lg %r14,__LC_VDSO_PER_CPU 132 lg \scratch,__LC_LAST_UPDATE_TIMER
192 lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user 133 slg \scratch,__LC_EXIT_TIMER
193 stpt __LC_EXIT_TIMER 134 alg \scratch,__LC_SYSTEM_TIMER
194 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 135 stg \scratch,__LC_SYSTEM_TIMER
195 lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user 136 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
196 lpswe \psworg # back to caller
197 .endm 137 .endm
198 138
199 .macro LAST_BREAK 139 .macro LAST_BREAK scratch
200 srag %r10,%r11,23 140 srag \scratch,%r10,23
201 jz 0f 141 jz .+10
202 stg %r11,__TI_last_break(%r12) 142 stg %r10,__TI_last_break(%r12)
2030:
204 .endm 143 .endm
205 144
206 .macro REENABLE_IRQS 145 .macro REENABLE_IRQS
207 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 146 stg %r8,__LC_RETURN_PSW
208 ni __SF_EMPTY(%r15),0xbf 147 ni __LC_RETURN_PSW,0xbf
209 ssm __SF_EMPTY(%r15) 148 ssm __LC_RETURN_PSW
210 .endm 149 .endm
211 150
212 .section .kprobes.text, "ax" 151 .section .kprobes.text, "ax"
@@ -245,55 +184,66 @@ __critical_start:
245 184
246ENTRY(system_call) 185ENTRY(system_call)
247 stpt __LC_SYNC_ENTER_TIMER 186 stpt __LC_SYNC_ENTER_TIMER
248sysc_saveall: 187sysc_stmg:
249 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 188 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
250 CREATE_STACK_FRAME __LC_SAVE_AREA 189 lg %r10,__LC_LAST_BREAK
251 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 190 lg %r12,__LC_THREAD_INFO
252 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 191 larl %r13,system_call
253 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 192sysc_per:
254 oi __TI_flags+7(%r12),_TIF_SYSCALL 193 lg %r15,__LC_KERNEL_STACK
194 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
195 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
255sysc_vtime: 196sysc_vtime:
256 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 197 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
257sysc_stime: 198 LAST_BREAK %r13
258 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 199 stmg %r0,%r7,__PT_R0(%r11)
259sysc_update: 200 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
260 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 201 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
261 LAST_BREAK 202 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
262sysc_do_svc: 203sysc_do_svc:
263 llgh %r7,SP_SVC_CODE+2(%r15) 204 oi __TI_flags+7(%r12),_TIF_SYSCALL
264 slag %r7,%r7,2 # shift and test for svc 0 205 llgh %r8,__PT_INT_CODE+2(%r11)
206 slag %r8,%r8,2 # shift and test for svc 0
265 jnz sysc_nr_ok 207 jnz sysc_nr_ok
266 # svc 0: system call number in %r1 208 # svc 0: system call number in %r1
267 llgfr %r1,%r1 # clear high word in r1 209 llgfr %r1,%r1 # clear high word in r1
268 cghi %r1,NR_syscalls 210 cghi %r1,NR_syscalls
269 jnl sysc_nr_ok 211 jnl sysc_nr_ok
270 sth %r1,SP_SVC_CODE+2(%r15) 212 sth %r1,__PT_INT_CODE+2(%r11)
271 slag %r7,%r1,2 # shift and test for svc 0 213 slag %r8,%r1,2
272sysc_nr_ok: 214sysc_nr_ok:
273 larl %r10,sys_call_table 215 larl %r10,sys_call_table # 64 bit system call table
274#ifdef CONFIG_COMPAT 216#ifdef CONFIG_COMPAT
275 tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? 217 tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
276 jno sysc_noemu 218 jno sysc_noemu
277 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # 31 bit system call table
278sysc_noemu: 220sysc_noemu:
279#endif 221#endif
222 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
223 stg %r2,__PT_ORIG_GPR2(%r11)
224 stg %r7,STACK_FRAME_OVERHEAD(%r15)
225 lgf %r9,0(%r8,%r10) # get system call add.
280 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 226 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
281 mvc SP_ARGS(8,%r15),SP_R7(%r15)
282 lgf %r8,0(%r7,%r10) # load address of system call routine
283 jnz sysc_tracesys 227 jnz sysc_tracesys
284 basr %r14,%r8 # call sys_xxxx 228 basr %r14,%r9 # call sys_xxxx
285 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 229 stg %r2,__PT_R2(%r11) # store return value
286 230
287sysc_return: 231sysc_return:
288 LOCKDEP_SYS_EXIT 232 LOCKDEP_SYS_EXIT
289sysc_tif: 233sysc_tif:
290 tm SP_PSW+1(%r15),0x01 # returning to user ? 234 tm __PT_PSW+1(%r11),0x01 # returning to user ?
291 jno sysc_restore 235 jno sysc_restore
292 tm __TI_flags+7(%r12),_TIF_WORK_SVC 236 tm __TI_flags+7(%r12),_TIF_WORK_SVC
293 jnz sysc_work # there is work to do (signals etc.) 237 jnz sysc_work # check for work
294 ni __TI_flags+7(%r12),255-_TIF_SYSCALL 238 ni __TI_flags+7(%r12),255-_TIF_SYSCALL
295sysc_restore: 239sysc_restore:
296 RESTORE_ALL __LC_RETURN_PSW,1 240 lg %r14,__LC_VDSO_PER_CPU
241 lmg %r0,%r10,__PT_R0(%r11)
242 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
243 stpt __LC_EXIT_TIMER
244 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
245 lmg %r11,%r15,__PT_R11(%r11)
246 lpswe __LC_RETURN_PSW
297sysc_done: 247sysc_done:
298 248
299# 249#
@@ -317,7 +267,7 @@ sysc_work:
317# 267#
318sysc_reschedule: 268sysc_reschedule:
319 larl %r14,sysc_return 269 larl %r14,sysc_return
320 jg schedule # return point is sysc_return 270 jg schedule
321 271
322# 272#
323# _TIF_MCCK_PENDING is set, call handler 273# _TIF_MCCK_PENDING is set, call handler
@@ -331,33 +281,33 @@ sysc_mcck_pending:
331# 281#
332sysc_sigpending: 282sysc_sigpending:
333 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 283 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
334 la %r2,SP_PTREGS(%r15) # load pt_regs 284 lgr %r2,%r11 # pass pointer to pt_regs
335 brasl %r14,do_signal # call do_signal 285 brasl %r14,do_signal
336 tm __TI_flags+7(%r12),_TIF_SYSCALL 286 tm __TI_flags+7(%r12),_TIF_SYSCALL
337 jno sysc_return 287 jno sysc_return
338 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 288 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
339 lghi %r7,0 # svc 0 returns -ENOSYS 289 lghi %r8,0 # svc 0 returns -ENOSYS
340 lh %r1,SP_SVC_CODE+2(%r15) # load new svc number 290 lh %r1,__PT_INT_CODE+2(%r11) # load new svc number
341 cghi %r1,NR_syscalls 291 cghi %r1,NR_syscalls
342 jnl sysc_nr_ok # invalid svc number -> do svc 0 292 jnl sysc_nr_ok # invalid svc number -> do svc 0
343 slag %r7,%r1,2 293 slag %r8,%r1,2
344 j sysc_nr_ok # restart svc 294 j sysc_nr_ok # restart svc
345 295
346# 296#
347# _TIF_NOTIFY_RESUME is set, call do_notify_resume 297# _TIF_NOTIFY_RESUME is set, call do_notify_resume
348# 298#
349sysc_notify_resume: 299sysc_notify_resume:
350 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lgr %r2,%r11 # pass pointer to pt_regs
351 larl %r14,sysc_return 301 larl %r14,sysc_return
352 jg do_notify_resume # call do_notify_resume 302 jg do_notify_resume
353 303
354# 304#
355# _TIF_PER_TRAP is set, call do_per_trap 305# _TIF_PER_TRAP is set, call do_per_trap
356# 306#
357sysc_singlestep: 307sysc_singlestep:
358 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 308 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
359 la %r2,SP_PTREGS(%r15) # address of register-save area 309 lgr %r2,%r11 # pass pointer to pt_regs
360 larl %r14,sysc_return # load adr. of system return 310 larl %r14,sysc_return
361 jg do_per_trap 311 jg do_per_trap
362 312
363# 313#
@@ -365,41 +315,41 @@ sysc_singlestep:
365# and after the system call 315# and after the system call
366# 316#
367sysc_tracesys: 317sysc_tracesys:
368 la %r2,SP_PTREGS(%r15) # load pt_regs 318 lgr %r2,%r11 # pass pointer to pt_regs
369 la %r3,0 319 la %r3,0
370 llgh %r0,SP_SVC_CODE+2(%r15) 320 llgh %r0,__PT_INT_CODE+2(%r11)
371 stg %r0,SP_R2(%r15) 321 stg %r0,__PT_R2(%r11)
372 brasl %r14,do_syscall_trace_enter 322 brasl %r14,do_syscall_trace_enter
373 lghi %r0,NR_syscalls 323 lghi %r0,NR_syscalls
374 clgr %r0,%r2 324 clgr %r0,%r2
375 jnh sysc_tracenogo 325 jnh sysc_tracenogo
376 sllg %r7,%r2,2 # svc number *4 326 sllg %r8,%r2,2
377 lgf %r8,0(%r7,%r10) 327 lgf %r9,0(%r8,%r10)
378sysc_tracego: 328sysc_tracego:
379 lmg %r3,%r6,SP_R3(%r15) 329 lmg %r3,%r7,__PT_R3(%r11)
380 mvc SP_ARGS(8,%r15),SP_R7(%r15) 330 stg %r7,STACK_FRAME_OVERHEAD(%r15)
381 lg %r2,SP_ORIG_R2(%r15) 331 lg %r2,__PT_ORIG_GPR2(%r11)
382 basr %r14,%r8 # call sys_xxx 332 basr %r14,%r9 # call sys_xxx
383 stg %r2,SP_R2(%r15) # store return value 333 stg %r2,__PT_R2(%r11) # store return value
384sysc_tracenogo: 334sysc_tracenogo:
385 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 335 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
386 jz sysc_return 336 jz sysc_return
387 la %r2,SP_PTREGS(%r15) # load pt_regs 337 lgr %r2,%r11 # pass pointer to pt_regs
388 larl %r14,sysc_return # return point is sysc_return 338 larl %r14,sysc_return
389 jg do_syscall_trace_exit 339 jg do_syscall_trace_exit
390 340
391# 341#
392# a new process exits the kernel with ret_from_fork 342# a new process exits the kernel with ret_from_fork
393# 343#
394ENTRY(ret_from_fork) 344ENTRY(ret_from_fork)
395 lg %r13,__LC_SVC_NEW_PSW+8 345 la %r11,STACK_FRAME_OVERHEAD(%r15)
396 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 346 lg %r12,__LC_THREAD_INFO
397 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 347 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
398 jo 0f 348 jo 0f
399 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 349 stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
4000: brasl %r14,schedule_tail 3500: brasl %r14,schedule_tail
401 TRACE_IRQS_ON 351 TRACE_IRQS_ON
402 stosm 24(%r15),0x03 # reenable interrupts 352 ssm __LC_SVC_NEW_PSW # reenable interrupts
403 j sysc_tracenogo 353 j sysc_tracenogo
404 354
405# 355#
@@ -409,26 +359,26 @@ ENTRY(ret_from_fork)
409ENTRY(kernel_execve) 359ENTRY(kernel_execve)
410 stmg %r12,%r15,96(%r15) 360 stmg %r12,%r15,96(%r15)
411 lgr %r14,%r15 361 lgr %r14,%r15
412 aghi %r15,-SP_SIZE 362 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
413 stg %r14,__SF_BACKCHAIN(%r15) 363 stg %r14,__SF_BACKCHAIN(%r15)
414 la %r12,SP_PTREGS(%r15) 364 la %r12,STACK_FRAME_OVERHEAD(%r15)
415 xc 0(__PT_SIZE,%r12),0(%r12) 365 xc 0(__PT_SIZE,%r12),0(%r12)
416 lgr %r5,%r12 366 lgr %r5,%r12
417 brasl %r14,do_execve 367 brasl %r14,do_execve
418 ltgfr %r2,%r2 368 ltgfr %r2,%r2
419 je 0f 369 je 0f
420 aghi %r15,SP_SIZE 370 aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
421 lmg %r12,%r15,96(%r15) 371 lmg %r12,%r15,96(%r15)
422 br %r14 372 br %r14
423 # execve succeeded. 373 # execve succeeded.
4240: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3740: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
425 lg %r15,__LC_KERNEL_STACK # load ksp 375 lg %r15,__LC_KERNEL_STACK # load ksp
426 aghi %r15,-SP_SIZE # make room for registers & psw 376 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427 lg %r13,__LC_SVC_NEW_PSW+8 377 la %r11,STACK_FRAME_OVERHEAD(%r15)
428 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 378 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
429 lg %r12,__LC_THREAD_INFO 379 lg %r12,__LC_THREAD_INFO
430 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 380 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 381 ssm __LC_SVC_NEW_PSW # reenable interrupts
432 brasl %r14,execve_tail 382 brasl %r14,execve_tail
433 j sysc_return 383 j sysc_return
434 384
@@ -437,127 +387,72 @@ ENTRY(kernel_execve)
437 */ 387 */
438 388
439ENTRY(pgm_check_handler) 389ENTRY(pgm_check_handler)
440/*
441 * First we need to check for a special case:
442 * Single stepping an instruction that disables the PER event mask will
443 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
444 * For a single stepped SVC the program check handler gets control after
445 * the SVC new PSW has been loaded. But we want to execute the SVC first and
446 * then handle the PER event. Therefore we update the SVC old PSW to point
447 * to the pgm_check_handler and branch to the SVC handler after we checked
448 * if we have to load the kernel stack register.
449 * For every other possible cause for PER event without the PER mask set
450 * we just ignore the PER event (FIXME: is there anything we have to do
451 * for LPSW?).
452 */
453 stpt __LC_SYNC_ENTER_TIMER 390 stpt __LC_SYNC_ENTER_TIMER
454 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 391 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
455 jnz pgm_per # got per exception -> special case 392 lg %r10,__LC_LAST_BREAK
456 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 393 lg %r12,__LC_THREAD_INFO
457 CREATE_STACK_FRAME __LC_SAVE_AREA 394 larl %r13,system_call
458 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 395 lmg %r8,%r9,__LC_PGM_OLD_PSW
459 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 396 HANDLE_SIE_INTERCEPT %r14
460 HANDLE_SIE_INTERCEPT 397 tmhh %r8,0x0001 # test problem state bit
461 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 398 jnz 1f # -> fault in user space
462 jz pgm_no_vtime 399 tmhh %r8,0x4000 # PER bit set in old PSW ?
463 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 400 jnz 0f # -> enabled, can't be a double fault
464 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
465 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 402 jnz pgm_svcper # -> single stepped svc
466 LAST_BREAK 4030: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
467pgm_no_vtime: 404 j 2f
468 stg %r11,SP_ARGS(%r15) 4051: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
469 lgf %r3,__LC_PGM_ILC # load program interruption code 406 LAST_BREAK %r14
470 lg %r4,__LC_TRANS_EXC_CODE 407 lg %r15,__LC_KERNEL_STACK
471 REENABLE_IRQS 4082: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
472 lghi %r8,0x7f 409 la %r11,STACK_FRAME_OVERHEAD(%r15)
473 ngr %r8,%r3 410 stmg %r0,%r7,__PT_R0(%r11)
474 sll %r8,3 411 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
475 larl %r1,pgm_check_table 412 stmg %r8,%r9,__PT_PSW(%r11)
476 lg %r1,0(%r8,%r1) # load address of handler routine 413 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
477 la %r2,SP_PTREGS(%r15) # address of register-save area 414 mvc __PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
478 basr %r14,%r1 # branch to interrupt-handler 415 stg %r10,__PT_ARGS(%r11)
479pgm_exit: 416 tm __LC_PGM_ILC+3,0x80 # check for per exception
480 j sysc_return 417 jz 0f
481
482#
483# handle per exception
484#
485pgm_per:
486 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
487 jnz pgm_per_std # ok, normal per event from user space
488# ok its one of the special cases, now we need to find out which one
489 clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
490 je pgm_svcper
491# no interesting special case, ignore PER event
492 lpswe __LC_PGM_OLD_PSW
493
494#
495# Normal per exception
496#
497pgm_per_std:
498 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
499 CREATE_STACK_FRAME __LC_SAVE_AREA
500 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
501 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
502 HANDLE_SIE_INTERCEPT
503 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
504 jz pgm_no_vtime2
505 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
506 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
507 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
508 LAST_BREAK
509pgm_no_vtime2:
510 lg %r1,__TI_task(%r12) 418 lg %r1,__TI_task(%r12)
511 tm SP_PSW+1(%r15),0x01 # kernel per event ? 419 tmhh %r8,0x0001 # kernel per event ?
512 jz kernel_per 420 jz pgm_kprobe
513 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 421 oi __TI_flags+7(%r12),_TIF_PER_TRAP
514 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 422 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
423 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
515 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 424 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
516 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4250: REENABLE_IRQS
517 lgf %r3,__LC_PGM_ILC # load program interruption code 426 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
518 lg %r4,__LC_TRANS_EXC_CODE
519 REENABLE_IRQS
520 lghi %r8,0x7f
521 ngr %r8,%r3 # clear per-event-bit and ilc
522 je pgm_exit2
523 sll %r8,3
524 larl %r1,pgm_check_table 427 larl %r1,pgm_check_table
525 lg %r1,0(%r8,%r1) # load address of handler routine 428 llgh %r10,__PT_INT_CODE+2(%r11)
526 la %r2,SP_PTREGS(%r15) # address of register-save area 429 nill %r10,0x007f
430 sll %r10,3
431 je sysc_return
432 lg %r1,0(%r10,%r1) # load address of handler routine
433 lgr %r2,%r11 # pass pointer to pt_regs
527 basr %r14,%r1 # branch to interrupt-handler 434 basr %r14,%r1 # branch to interrupt-handler
528pgm_exit2:
529 j sysc_return 435 j sysc_return
530 436
531# 437#
532# it was a single stepped SVC that is causing all the trouble 438# PER event in supervisor state, must be kprobes
533# 439#
534pgm_svcper: 440pgm_kprobe:
535 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 441 REENABLE_IRQS
536 CREATE_STACK_FRAME __LC_SAVE_AREA 442 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
537 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 443 lgr %r2,%r11 # pass pointer to pt_regs
538 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 444 brasl %r14,do_per_trap
539 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 445 j sysc_return
540 oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
541 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
542 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
543 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
544 LAST_BREAK
545 lg %r8,__TI_task(%r12)
546 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
547 mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
548 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
549 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
550 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
551 j sysc_do_svc
552 446
553# 447#
554# per was called from kernel, must be kprobes 448# single stepped system call
555# 449#
556kernel_per: 450pgm_svcper:
557 REENABLE_IRQS 451 oi __TI_flags+7(%r12),_TIF_PER_TRAP
558 la %r2,SP_PTREGS(%r15) # address of register-save area 452 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
559 brasl %r14,do_per_trap 453 larl %r14,sysc_per
560 j pgm_exit 454 stg %r14,__LC_RETURN_PSW+8
455 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs
561 456
562/* 457/*
563 * IO interrupt handler routine 458 * IO interrupt handler routine
@@ -565,21 +460,25 @@ kernel_per:
565ENTRY(io_int_handler) 460ENTRY(io_int_handler)
566 stck __LC_INT_CLOCK 461 stck __LC_INT_CLOCK
567 stpt __LC_ASYNC_ENTER_TIMER 462 stpt __LC_ASYNC_ENTER_TIMER
568 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 463 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
569 CREATE_STACK_FRAME __LC_SAVE_AREA+40 464 lg %r10,__LC_LAST_BREAK
570 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 465 lg %r12,__LC_THREAD_INFO
571 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 466 larl %r13,system_call
572 HANDLE_SIE_INTERCEPT 467 lmg %r8,%r9,__LC_IO_OLD_PSW
573 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 468 HANDLE_SIE_INTERCEPT %r14
574 jz io_no_vtime 469 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
575 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 470 tmhh %r8,0x0001 # interrupting from user?
576 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 471 jz io_skip
577 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 472 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
578 LAST_BREAK 473 LAST_BREAK %r14
579io_no_vtime: 474io_skip:
475 stmg %r0,%r7,__PT_R0(%r11)
476 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
477 stmg %r8,%r9,__PT_PSW(%r11)
580 TRACE_IRQS_OFF 478 TRACE_IRQS_OFF
581 la %r2,SP_PTREGS(%r15) # address of register-save area 479 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
582 brasl %r14,do_IRQ # call standard irq handler 480 lgr %r2,%r11 # pass pointer to pt_regs
481 brasl %r14,do_IRQ
583io_return: 482io_return:
584 LOCKDEP_SYS_EXIT 483 LOCKDEP_SYS_EXIT
585 TRACE_IRQS_ON 484 TRACE_IRQS_ON
@@ -587,7 +486,14 @@ io_tif:
587 tm __TI_flags+7(%r12),_TIF_WORK_INT 486 tm __TI_flags+7(%r12),_TIF_WORK_INT
588 jnz io_work # there is work to do (signals etc.) 487 jnz io_work # there is work to do (signals etc.)
589io_restore: 488io_restore:
590 RESTORE_ALL __LC_RETURN_PSW,0 489 lg %r14,__LC_VDSO_PER_CPU
490 lmg %r0,%r10,__PT_R0(%r11)
491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
492 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
493 stpt __LC_EXIT_TIMER
494 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
495 lmg %r11,%r15,__PT_R11(%r11)
496 lpswe __LC_RETURN_PSW
591io_done: 497io_done:
592 498
593# 499#
@@ -600,7 +506,7 @@ io_done:
600# Before any work can be done, a switch to the kernel stack is required. 506# Before any work can be done, a switch to the kernel stack is required.
601# 507#
602io_work: 508io_work:
603 tm SP_PSW+1(%r15),0x01 # returning to user ? 509 tm __PT_PSW+1(%r11),0x01 # returning to user ?
604 jo io_work_user # yes -> do resched & signal 510 jo io_work_user # yes -> do resched & signal
605#ifdef CONFIG_PREEMPT 511#ifdef CONFIG_PREEMPT
606 # check for preemptive scheduling 512 # check for preemptive scheduling
@@ -609,10 +515,11 @@ io_work:
609 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 515 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
610 jno io_restore 516 jno io_restore
611 # switch to kernel stack 517 # switch to kernel stack
612 lg %r1,SP_R15(%r15) 518 lg %r1,__PT_R15(%r11)
613 aghi %r1,-SP_SIZE 519 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
614 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 520 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
615 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 521 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
522 la %r11,STACK_FRAME_OVERHEAD(%r1)
616 lgr %r15,%r1 523 lgr %r15,%r1
617 # TRACE_IRQS_ON already done at io_return, call 524 # TRACE_IRQS_ON already done at io_return, call
618 # TRACE_IRQS_OFF to keep things symmetrical 525 # TRACE_IRQS_OFF to keep things symmetrical
@@ -628,9 +535,10 @@ io_work:
628# 535#
629io_work_user: 536io_work_user:
630 lg %r1,__LC_KERNEL_STACK 537 lg %r1,__LC_KERNEL_STACK
631 aghi %r1,-SP_SIZE 538 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
632 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 539 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
633 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 540 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
541 la %r11,STACK_FRAME_OVERHEAD(%r1)
634 lgr %r15,%r1 542 lgr %r15,%r1
635 543
636# 544#
@@ -663,9 +571,9 @@ io_mcck_pending:
663# 571#
664io_reschedule: 572io_reschedule:
665 # TRACE_IRQS_ON already done at io_return 573 # TRACE_IRQS_ON already done at io_return
666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 574 ssm __LC_SVC_NEW_PSW # reenable interrupts
667 brasl %r14,schedule # call scheduler 575 brasl %r14,schedule # call scheduler
668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 576 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF 577 TRACE_IRQS_OFF
670 j io_return 578 j io_return
671 579
@@ -674,10 +582,10 @@ io_reschedule:
674# 582#
675io_sigpending: 583io_sigpending:
676 # TRACE_IRQS_ON already done at io_return 584 # TRACE_IRQS_ON already done at io_return
677 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 585 ssm __LC_SVC_NEW_PSW # reenable interrupts
678 la %r2,SP_PTREGS(%r15) # load pt_regs 586 lgr %r2,%r11 # pass pointer to pt_regs
679 brasl %r14,do_signal # call do_signal 587 brasl %r14,do_signal
680 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 588 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
681 TRACE_IRQS_OFF 589 TRACE_IRQS_OFF
682 j io_return 590 j io_return
683 591
@@ -686,10 +594,10 @@ io_sigpending:
686# 594#
687io_notify_resume: 595io_notify_resume:
688 # TRACE_IRQS_ON already done at io_return 596 # TRACE_IRQS_ON already done at io_return
689 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 597 ssm __LC_SVC_NEW_PSW # reenable interrupts
690 la %r2,SP_PTREGS(%r15) # load pt_regs 598 lgr %r2,%r11 # pass pointer to pt_regs
691 brasl %r14,do_notify_resume # call do_notify_resume 599 brasl %r14,do_notify_resume
692 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 600 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
693 TRACE_IRQS_OFF 601 TRACE_IRQS_OFF
694 j io_return 602 j io_return
695 603
@@ -699,21 +607,24 @@ io_notify_resume:
699ENTRY(ext_int_handler) 607ENTRY(ext_int_handler)
700 stck __LC_INT_CLOCK 608 stck __LC_INT_CLOCK
701 stpt __LC_ASYNC_ENTER_TIMER 609 stpt __LC_ASYNC_ENTER_TIMER
702 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 610 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
703 CREATE_STACK_FRAME __LC_SAVE_AREA+40 611 lg %r10,__LC_LAST_BREAK
704 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 612 lg %r12,__LC_THREAD_INFO
705 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 613 larl %r13,system_call
706 HANDLE_SIE_INTERCEPT 614 lmg %r8,%r9,__LC_EXT_OLD_PSW
707 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 615 HANDLE_SIE_INTERCEPT %r14
708 jz ext_no_vtime 616 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
709 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 617 tmhh %r8,0x0001 # interrupting from user ?
710 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 618 jz ext_skip
711 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 619 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
712 LAST_BREAK 620 LAST_BREAK %r14
713ext_no_vtime: 621ext_skip:
622 stmg %r0,%r7,__PT_R0(%r11)
623 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
624 stmg %r8,%r9,__PT_PSW(%r11)
714 TRACE_IRQS_OFF 625 TRACE_IRQS_OFF
715 lghi %r1,4096 626 lghi %r1,4096
716 la %r2,SP_PTREGS(%r15) # address of register-save area 627 lgr %r2,%r11 # pass pointer to pt_regs
717 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 628 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
718 llgf %r4,__LC_EXT_PARAMS # get external parameter 629 llgf %r4,__LC_EXT_PARAMS # get external parameter
719 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 630 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
@@ -730,81 +641,77 @@ ENTRY(mcck_int_handler)
730 la %r1,4095 # revalidate r1 641 la %r1,4095 # revalidate r1
731 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 642 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
732 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 643 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
733 stmg %r11,%r15,__LC_SAVE_AREA+80 644 lg %r10,__LC_LAST_BREAK
645 lg %r12,__LC_THREAD_INFO
734 larl %r13,system_call 646 larl %r13,system_call
735 lg %r11,__LC_LAST_BREAK 647 lmg %r8,%r9,__LC_MCK_OLD_PSW
736 la %r12,__LC_MCK_OLD_PSW 648 HANDLE_SIE_INTERCEPT %r14
737 tm __LC_MCCK_CODE,0x80 # system damage? 649 tm __LC_MCCK_CODE,0x80 # system damage?
738 jo mcck_int_main # yes -> rest of mcck code invalid 650 jo mcck_panic # yes -> rest of mcck code invalid
739 la %r14,4095 651 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
740 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) 652 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
741 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 653 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
742 jo 1f 654 jo 3f
743 la %r14,__LC_SYNC_ENTER_TIMER 655 la %r14,__LC_SYNC_ENTER_TIMER
744 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 656 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
745 jl 0f 657 jl 0f
746 la %r14,__LC_ASYNC_ENTER_TIMER 658 la %r14,__LC_ASYNC_ENTER_TIMER
7470: clc 0(8,%r14),__LC_EXIT_TIMER 6590: clc 0(8,%r14),__LC_EXIT_TIMER
748 jl 0f 660 jl 1f
749 la %r14,__LC_EXIT_TIMER 661 la %r14,__LC_EXIT_TIMER
7500: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6621: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
751 jl 0f 663 jl 2f
752 la %r14,__LC_LAST_UPDATE_TIMER 664 la %r14,__LC_LAST_UPDATE_TIMER
7530: spt 0(%r14) 6652: spt 0(%r14)
754 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 666 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7551: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6673: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
756 jno mcck_int_main # no -> skip cleanup critical 668 jno mcck_panic # no -> skip cleanup critical
757 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 669 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
758 jnz mcck_int_main # from user -> load kernel stack 670 tm %r8,0x0001 # interrupting from user ?
759 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) 671 jz mcck_skip
760 jhe mcck_int_main 672 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
761 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) 673 LAST_BREAK %r14
762 jl mcck_int_main 674mcck_skip:
763 brasl %r14,cleanup_critical 675 lghi %r14,__LC_GPREGS_SAVE_AREA
764mcck_int_main: 676 mvc __PT_R0(128,%r11),0(%r14)
765 lg %r14,__LC_PANIC_STACK # are we already on the panic stack? 677 stmg %r8,%r9,__PT_PSW(%r11)
766 slgr %r14,%r15 678 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
767 srag %r14,%r14,PAGE_SHIFT 679 lgr %r2,%r11 # pass pointer to pt_regs
768 jz 0f
769 lg %r15,__LC_PANIC_STACK # load panic stack
7700: aghi %r15,-SP_SIZE # make room for registers & psw
771 CREATE_STACK_FRAME __LC_SAVE_AREA+80
772 mvc SP_PSW(16,%r15),0(%r12)
773 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
774 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
775 jno mcck_no_vtime # no -> no timer update
776 HANDLE_SIE_INTERCEPT
777 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
778 jz mcck_no_vtime
779 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
780 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
781 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
782 LAST_BREAK
783mcck_no_vtime:
784 la %r2,SP_PTREGS(%r15) # load pt_regs
785 brasl %r14,s390_do_machine_check 680 brasl %r14,s390_do_machine_check
786 tm SP_PSW+1(%r15),0x01 # returning to user ? 681 tm __PT_PSW+1(%r11),0x01 # returning to user ?
787 jno mcck_return 682 jno mcck_return
788 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 683 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
789 aghi %r1,-SP_SIZE 684 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
790 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 685 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
791 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 686 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
687 la %r11,STACK_FRAME_OVERHEAD(%r1)
792 lgr %r15,%r1 688 lgr %r15,%r1
793 stosm __SF_EMPTY(%r15),0x04 # turn dat on 689 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
794 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 690 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
795 jno mcck_return 691 jno mcck_return
796 TRACE_IRQS_OFF 692 TRACE_IRQS_OFF
797 brasl %r14,s390_handle_mcck 693 brasl %r14,s390_handle_mcck
798 TRACE_IRQS_ON 694 TRACE_IRQS_ON
799mcck_return: 695mcck_return:
800 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 696 lg %r14,__LC_VDSO_PER_CPU
697 lmg %r0,%r10,__PT_R0(%r11)
698 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
801 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 699 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
802 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
803 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 700 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
804 jno 0f 701 jno 0f
805 stpt __LC_EXIT_TIMER 702 stpt __LC_EXIT_TIMER
8060: lpswe __LC_RETURN_MCCK_PSW # back to caller 703 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
807mcck_done: 7040: lmg %r11,%r15,__PT_R11(%r11)
705 lpswe __LC_RETURN_MCCK_PSW
706
707mcck_panic:
708 lg %r14,__LC_PANIC_STACK
709 slgr %r14,%r15
710 srag %r14,%r14,PAGE_SHIFT
711 jz 0f
712 lg %r15,__LC_PANIC_STACK
7130: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
714 j mcck_skip
808 715
809/* 716/*
810 * Restart interruption handler, kick starter for additional CPUs 717 * Restart interruption handler, kick starter for additional CPUs
@@ -818,17 +725,18 @@ restart_base:
818 stck __LC_LAST_UPDATE_CLOCK 725 stck __LC_LAST_UPDATE_CLOCK
819 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 726 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
820 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 727 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
821 lg %r15,__LC_SAVE_AREA+120 # load ksp 728 lghi %r10,__LC_GPREGS_SAVE_AREA
729 lg %r15,120(%r10) # load ksp
822 lghi %r10,__LC_CREGS_SAVE_AREA 730 lghi %r10,__LC_CREGS_SAVE_AREA
823 lctlg %c0,%c15,0(%r10) # get new ctl regs 731 lctlg %c0,%c15,0(%r10) # get new ctl regs
824 lghi %r10,__LC_AREGS_SAVE_AREA 732 lghi %r10,__LC_AREGS_SAVE_AREA
825 lam %a0,%a15,0(%r10) 733 lam %a0,%a15,0(%r10)
826 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 734 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
827 lg %r1,__LC_THREAD_INFO 735 lg %r1,__LC_THREAD_INFO
828 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 736 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
829 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 737 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
830 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 738 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
831 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 739 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
832 brasl %r14,start_secondary 740 brasl %r14,start_secondary
833 .align 8 741 .align 8
834restart_vtime: 742restart_vtime:
@@ -852,16 +760,16 @@ restart_go:
852# PSW restart interrupt handler 760# PSW restart interrupt handler
853# 761#
854ENTRY(psw_restart_int_handler) 762ENTRY(psw_restart_int_handler)
855 stg %r15,__LC_SAVE_AREA+120(%r0) # save r15 763 stg %r15,__LC_SAVE_AREA_RESTART
856 larl %r15,restart_stack # load restart stack 764 larl %r15,restart_stack # load restart stack
857 lg %r15,0(%r15) 765 lg %r15,0(%r15)
858 aghi %r15,-SP_SIZE # make room for pt_regs 766 aghi %r15,-__PT_SIZE # create pt_regs on stack
859 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 767 stmg %r0,%r14,__PT_R0(%r15)
860 mvc SP_R15(8,%r15),__LC_SAVE_AREA+120(%r0)# store saved %r15 to stack 768 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
861 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw 769 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
862 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 770 aghi %r15,-STACK_FRAME_OVERHEAD
771 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
863 brasl %r14,do_restart 772 brasl %r14,do_restart
864
865 larl %r14,restart_psw_crash # load disabled wait PSW if 773 larl %r14,restart_psw_crash # load disabled wait PSW if
866 lpswe 0(%r14) # do_restart returns 774 lpswe 0(%r14) # do_restart returns
867 .align 8 775 .align 8
@@ -877,172 +785,153 @@ restart_psw_crash:
877 * Setup a pt_regs so that show_trace can provide a good call trace. 785 * Setup a pt_regs so that show_trace can provide a good call trace.
878 */ 786 */
879stack_overflow: 787stack_overflow:
880 lg %r15,__LC_PANIC_STACK # change to panic stack 788 lg %r11,__LC_PANIC_STACK # change to panic stack
881 aghi %r15,-SP_SIZE 789 aghi %r11,-__PT_SIZE # create pt_regs
882 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 790 stmg %r0,%r7,__PT_R0(%r11)
883 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack 791 stmg %r8,%r9,__PT_PSW(%r11)
884 la %r1,__LC_SAVE_AREA 792 mvc __PT_R8(64,%r11),0(%r14)
885 chi %r12,__LC_SVC_OLD_PSW 793 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
886 je 0f 794 lgr %r15,%r11
887 chi %r12,__LC_PGM_OLD_PSW 795 aghi %r15,-STACK_FRAME_OVERHEAD
888 je 0f 796 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
889 la %r1,__LC_SAVE_AREA+40 797 lgr %r2,%r11 # pass pointer to pt_regs
8900: mvc SP_R11(40,%r15),0(%r1) # move %r11-%r15 to stack
891 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
892 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
893 la %r2,SP_PTREGS(%r15) # load pt_regs
894 jg kernel_stack_overflow 798 jg kernel_stack_overflow
895#endif 799#endif
896 800
897cleanup_table_system_call: 801 .align 8
898 .quad system_call, sysc_do_svc 802cleanup_table:
899cleanup_table_sysc_tif: 803 .quad system_call
900 .quad sysc_tif, sysc_restore 804 .quad sysc_do_svc
901cleanup_table_sysc_restore: 805 .quad sysc_tif
902 .quad sysc_restore, sysc_done 806 .quad sysc_restore
903cleanup_table_io_tif: 807 .quad sysc_done
904 .quad io_tif, io_restore 808 .quad io_tif
905cleanup_table_io_restore: 809 .quad io_restore
906 .quad io_restore, io_done 810 .quad io_done
907 811
908cleanup_critical: 812cleanup_critical:
909 clc 8(8,%r12),BASED(cleanup_table_system_call) 813 clg %r9,BASED(cleanup_table) # system_call
910 jl 0f 814 jl 0f
911 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 815 clg %r9,BASED(cleanup_table+8) # sysc_do_svc
912 jl cleanup_system_call 816 jl cleanup_system_call
9130: 817 clg %r9,BASED(cleanup_table+16) # sysc_tif
914 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
915 jl 0f 818 jl 0f
916 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) 819 clg %r9,BASED(cleanup_table+24) # sysc_restore
917 jl cleanup_sysc_tif 820 jl cleanup_sysc_tif
9180: 821 clg %r9,BASED(cleanup_table+32) # sysc_done
919 clc 8(8,%r12),BASED(cleanup_table_sysc_restore)
920 jl 0f
921 clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8)
922 jl cleanup_sysc_restore 822 jl cleanup_sysc_restore
9230: 823 clg %r9,BASED(cleanup_table+40) # io_tif
924 clc 8(8,%r12),BASED(cleanup_table_io_tif)
925 jl 0f 824 jl 0f
926 clc 8(8,%r12),BASED(cleanup_table_io_tif+8) 825 clg %r9,BASED(cleanup_table+48) # io_restore
927 jl cleanup_io_tif 826 jl cleanup_io_tif
9280: 827 clg %r9,BASED(cleanup_table+56) # io_done
929 clc 8(8,%r12),BASED(cleanup_table_io_restore)
930 jl 0f
931 clc 8(8,%r12),BASED(cleanup_table_io_restore+8)
932 jl cleanup_io_restore 828 jl cleanup_io_restore
9330: 8290: br %r14
934 br %r14 830
935 831
936cleanup_system_call: 832cleanup_system_call:
937 mvc __LC_RETURN_PSW(16),0(%r12) 833 # check if stpt has been executed
938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 834 clg %r9,BASED(cleanup_system_call_insn)
939 jh 0f 835 jh 0f
940 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
941 cghi %r12,__LC_MCK_OLD_PSW
942 je 0f
943 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 836 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9440: cghi %r12,__LC_MCK_OLD_PSW 837 cghi %r11,__LC_SAVE_AREA_ASYNC
945 la %r12,__LC_SAVE_AREA+80
946 je 0f 838 je 0f
947 la %r12,__LC_SAVE_AREA+40 839 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
9480: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) 8400: # check if stmg has been executed
949 jhe cleanup_vtime 841 clg %r9,BASED(cleanup_system_call_insn+8)
950 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
951 jh 0f 842 jh 0f
952 mvc __LC_SAVE_AREA(40),0(%r12) 843 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
9530: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 8440: # check if base register setup + TIF bit load has been done
954 aghi %r15,-SP_SIZE # make room for registers & psw 845 clg %r9,BASED(cleanup_system_call_insn+16)
955 stg %r15,32(%r12) 846 jhe 0f
956 stg %r11,0(%r12) 847 # set up saved registers r10 and r12
957 CREATE_STACK_FRAME __LC_SAVE_AREA 848 stg %r10,16(%r11) # r10 last break
958 mvc 8(8,%r12),__LC_THREAD_INFO 849 stg %r12,32(%r11) # r12 thread-info pointer
959 lg %r12,__LC_THREAD_INFO 8500: # check if the user time update has been done
960 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 851 clg %r9,BASED(cleanup_system_call_insn+24)
961 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 852 jh 0f
962 oi __TI_flags+7(%r12),_TIF_SYSCALL 853 lg %r15,__LC_EXIT_TIMER
963cleanup_vtime: 854 slg %r15,__LC_SYNC_ENTER_TIMER
964 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 855 alg %r15,__LC_USER_TIMER
965 jhe cleanup_stime 856 stg %r15,__LC_USER_TIMER
966 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 8570: # check if the system time update has been done
967cleanup_stime: 858 clg %r9,BASED(cleanup_system_call_insn+32)
968 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 859 jh 0f
969 jh cleanup_update 860 lg %r15,__LC_LAST_UPDATE_TIMER
970 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 861 slg %r15,__LC_EXIT_TIMER
971cleanup_update: 862 alg %r15,__LC_SYSTEM_TIMER
863 stg %r15,__LC_SYSTEM_TIMER
8640: # update accounting time stamp
972 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 865 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
973 srag %r12,%r11,23 866 # do LAST_BREAK
974 lg %r12,__LC_THREAD_INFO 867 lg %r9,16(%r11)
868 srag %r9,%r9,23
975 jz 0f 869 jz 0f
976 stg %r11,__TI_last_break(%r12) 870 mvc __TI_last_break(8,%r12),16(%r11)
9770: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 8710: # set up saved register r11
978 la %r12,__LC_RETURN_PSW 872 lg %r15,__LC_KERNEL_STACK
873 aghi %r15,-__PT_SIZE
874 stg %r15,24(%r11) # r11 pt_regs pointer
875 # fill pt_regs
876 mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
877 stmg %r0,%r7,__PT_R0(%r15)
878 mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
879 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
880 # setup saved register r15
881 aghi %r15,-STACK_FRAME_OVERHEAD
882 stg %r15,56(%r11) # r15 stack pointer
883 # set new psw address and exit
884 larl %r9,sysc_do_svc
979 br %r14 885 br %r14
980cleanup_system_call_insn: 886cleanup_system_call_insn:
981 .quad sysc_saveall
982 .quad system_call 887 .quad system_call
983 .quad sysc_vtime 888 .quad sysc_stmg
984 .quad sysc_stime 889 .quad sysc_per
985 .quad sysc_update 890 .quad sysc_vtime+18
891 .quad sysc_vtime+42
986 892
987cleanup_sysc_tif: 893cleanup_sysc_tif:
988 mvc __LC_RETURN_PSW(8),0(%r12) 894 larl %r9,sysc_tif
989 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
990 la %r12,__LC_RETURN_PSW
991 br %r14 895 br %r14
992 896
993cleanup_sysc_restore: 897cleanup_sysc_restore:
994 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) 898 clg %r9,BASED(cleanup_sysc_restore_insn)
995 je 2f
996 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
997 jhe 0f
998 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
999 cghi %r12,__LC_MCK_OLD_PSW
1000 je 0f 899 je 0f
1001 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 900 lg %r9,24(%r11) # get saved pointer to pt_regs
10020: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 901 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1003 cghi %r12,__LC_MCK_OLD_PSW 902 mvc 0(64,%r11),__PT_R8(%r9)
1004 la %r12,__LC_SAVE_AREA+80 903 lmg %r0,%r7,__PT_R0(%r9)
1005 je 1f 9040: lmg %r8,%r9,__LC_RETURN_PSW
1006 la %r12,__LC_SAVE_AREA+40
10071: mvc 0(40,%r12),SP_R11(%r15)
1008 lmg %r0,%r10,SP_R0(%r15)
1009 lg %r15,SP_R15(%r15)
10102: la %r12,__LC_RETURN_PSW
1011 br %r14 905 br %r14
1012cleanup_sysc_restore_insn: 906cleanup_sysc_restore_insn:
1013 .quad sysc_done - 4 907 .quad sysc_done - 4
1014 .quad sysc_done - 16
1015 908
1016cleanup_io_tif: 909cleanup_io_tif:
1017 mvc __LC_RETURN_PSW(8),0(%r12) 910 larl %r9,io_tif
1018 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
1019 la %r12,__LC_RETURN_PSW
1020 br %r14 911 br %r14
1021 912
1022cleanup_io_restore: 913cleanup_io_restore:
1023 clc 8(8,%r12),BASED(cleanup_io_restore_insn) 914 clg %r9,BASED(cleanup_io_restore_insn)
1024 je 1f 915 je 0f
1025 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) 916 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1026 jhe 0f 917 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1027 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 918 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
10280: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 919 mvc 0(64,%r11),__PT_R8(%r9)
1029 mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) 920 lmg %r0,%r7,__PT_R0(%r9)
1030 lmg %r0,%r10,SP_R0(%r15) 9210: lmg %r8,%r9,__LC_RETURN_PSW
1031 lg %r15,SP_R15(%r15)
10321: la %r12,__LC_RETURN_PSW
1033 br %r14 922 br %r14
1034cleanup_io_restore_insn: 923cleanup_io_restore_insn:
1035 .quad io_done - 4 924 .quad io_done - 4
1036 .quad io_done - 16
1037 925
1038/* 926/*
1039 * Integer constants 927 * Integer constants
1040 */ 928 */
1041 .align 4 929 .align 8
1042.Lcritical_start: 930.Lcritical_start:
1043 .quad __critical_start 931 .quad __critical_start
1044.Lcritical_end: 932.Lcritical_length:
1045 .quad __critical_end 933 .quad __critical_end - __critical_start
934
1046 935
1047#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 936#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1048/* 937/*
@@ -1054,6 +943,7 @@ ENTRY(sie64a)
1054 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 943 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
1055 stg %r2,__SF_EMPTY(%r15) # save control block pointer 944 stg %r2,__SF_EMPTY(%r15) # save control block pointer
1056 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 945 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
946 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
1057 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 947 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1058 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 948 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1059 oi __TI_flags+6(%r14),_TIF_SIE>>8 949 oi __TI_flags+6(%r14),_TIF_SIE>>8
@@ -1070,7 +960,7 @@ sie_gmap:
1070 SPP __SF_EMPTY(%r15) # set guest id 960 SPP __SF_EMPTY(%r15) # set guest id
1071 sie 0(%r14) 961 sie 0(%r14)
1072sie_done: 962sie_done:
1073 SPP __LC_CMF_HPP # set host id 963 SPP __SF_EMPTY+16(%r15) # set host id
1074 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 964 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1075sie_exit: 965sie_exit:
1076 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 966 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -1093,8 +983,10 @@ sie_fault:
1093 .align 8 983 .align 8
1094.Lsie_loop: 984.Lsie_loop:
1095 .quad sie_loop 985 .quad sie_loop
1096.Lsie_done: 986.Lsie_length:
1097 .quad sie_done 987 .quad sie_done - sie_loop
988.Lhost_id:
989 .quad 0
1098 990
1099 .section __ex_table,"a" 991 .section __ex_table,"a"
1100 .quad sie_loop,sie_fault 992 .quad sie_loop,sie_fault
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 900068d2bf9..c27a0727f93 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -329,8 +329,8 @@ iplstart:
329# 329#
330# reset files in VM reader 330# reset files in VM reader
331# 331#
332 stidp __LC_SAVE_AREA # store cpuid 332 stidp __LC_SAVE_AREA_SYNC # store cpuid
333 tm __LC_SAVE_AREA,0xff # running VM ? 333 tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
334 bno .Lnoreset 334 bno .Lnoreset
335 la %r2,.Lreset 335 la %r2,.Lreset
336 lhi %r3,26 336 lhi %r3,26
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 3cd0f25ab01..47b168fb29c 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -208,6 +208,7 @@ void machine_kexec_cleanup(struct kimage *image)
208void arch_crash_save_vmcoreinfo(void) 208void arch_crash_save_vmcoreinfo(void)
209{ 209{
210 VMCOREINFO_SYMBOL(lowcore_ptr); 210 VMCOREINFO_SYMBOL(lowcore_ptr);
211 VMCOREINFO_SYMBOL(high_memory);
211 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); 212 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
212} 213}
213 214
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
index 19b4568f4ce..22d502e885e 100644
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -64,70 +64,82 @@ void detect_memory_layout(struct mem_chunk chunk[])
64EXPORT_SYMBOL(detect_memory_layout); 64EXPORT_SYMBOL(detect_memory_layout);
65 65
66/* 66/*
67 * Move memory chunks array from index "from" to index "to"
68 */
69static void mem_chunk_move(struct mem_chunk chunk[], int to, int from)
70{
71 int cnt = MEMORY_CHUNKS - to;
72
73 memmove(&chunk[to], &chunk[from], cnt * sizeof(struct mem_chunk));
74}
75
76/*
77 * Initialize memory chunk
78 */
79static void mem_chunk_init(struct mem_chunk *chunk, unsigned long addr,
80 unsigned long size, int type)
81{
82 chunk->type = type;
83 chunk->addr = addr;
84 chunk->size = size;
85}
86
87/*
67 * Create memory hole with given address, size, and type 88 * Create memory hole with given address, size, and type
68 */ 89 */
69void create_mem_hole(struct mem_chunk chunks[], unsigned long addr, 90void create_mem_hole(struct mem_chunk chunk[], unsigned long addr,
70 unsigned long size, int type) 91 unsigned long size, int type)
71{ 92{
72 unsigned long start, end, new_size; 93 unsigned long lh_start, lh_end, lh_size, ch_start, ch_end, ch_size;
73 int i; 94 int i, ch_type;
74 95
75 for (i = 0; i < MEMORY_CHUNKS; i++) { 96 for (i = 0; i < MEMORY_CHUNKS; i++) {
76 if (chunks[i].size == 0) 97 if (chunk[i].size == 0)
77 continue;
78 if (addr + size < chunks[i].addr)
79 continue;
80 if (addr >= chunks[i].addr + chunks[i].size)
81 continue; 98 continue;
82 start = max(addr, chunks[i].addr); 99
83 end = min(addr + size, chunks[i].addr + chunks[i].size); 100 /* Define chunk properties */
84 new_size = end - start; 101 ch_start = chunk[i].addr;
85 if (new_size == 0) 102 ch_size = chunk[i].size;
86 continue; 103 ch_end = ch_start + ch_size - 1;
87 if (start == chunks[i].addr && 104 ch_type = chunk[i].type;
88 end == chunks[i].addr + chunks[i].size) { 105
89 /* Remove chunk */ 106 /* Is memory chunk hit by memory hole? */
90 chunks[i].type = type; 107 if (addr + size <= ch_start)
91 } else if (start == chunks[i].addr) { 108 continue; /* No: memory hole in front of chunk */
92 /* Make chunk smaller at start */ 109 if (addr > ch_end)
93 if (i >= MEMORY_CHUNKS - 1) 110 continue; /* No: memory hole after chunk */
94 panic("Unable to create memory hole"); 111
95 memmove(&chunks[i + 1], &chunks[i], 112 /* Yes: Define local hole properties */
96 sizeof(struct mem_chunk) * 113 lh_start = max(addr, chunk[i].addr);
97 (MEMORY_CHUNKS - (i + 1))); 114 lh_end = min(addr + size - 1, ch_end);
98 chunks[i + 1].addr = chunks[i].addr + new_size; 115 lh_size = lh_end - lh_start + 1;
99 chunks[i + 1].size = chunks[i].size - new_size; 116
100 chunks[i].size = new_size; 117 if (lh_start == ch_start && lh_end == ch_end) {
101 chunks[i].type = type; 118 /* Hole covers complete memory chunk */
102 i += 1; 119 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
103 } else if (end == chunks[i].addr + chunks[i].size) { 120 } else if (lh_end == ch_end) {
104 /* Make chunk smaller at end */ 121 /* Hole starts in memory chunk and convers chunk end */
105 if (i >= MEMORY_CHUNKS - 1) 122 mem_chunk_move(chunk, i + 1, i);
106 panic("Unable to create memory hole"); 123 mem_chunk_init(&chunk[i], ch_start, ch_size - lh_size,
107 memmove(&chunks[i + 1], &chunks[i], 124 ch_type);
108 sizeof(struct mem_chunk) * 125 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
109 (MEMORY_CHUNKS - (i + 1)));
110 chunks[i + 1].addr = start;
111 chunks[i + 1].size = new_size;
112 chunks[i + 1].type = type;
113 chunks[i].size -= new_size;
114 i += 1; 126 i += 1;
127 } else if (lh_start == ch_start) {
128 /* Hole ends in memory chunk */
129 mem_chunk_move(chunk, i + 1, i);
130 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
131 mem_chunk_init(&chunk[i + 1], lh_end + 1,
132 ch_size - lh_size, ch_type);
133 break;
115 } else { 134 } else {
116 /* Create memory hole */ 135 /* Hole splits memory chunk */
117 if (i >= MEMORY_CHUNKS - 2) 136 mem_chunk_move(chunk, i + 2, i);
118 panic("Unable to create memory hole"); 137 mem_chunk_init(&chunk[i], ch_start,
119 memmove(&chunks[i + 2], &chunks[i], 138 lh_start - ch_start, ch_type);
120 sizeof(struct mem_chunk) * 139 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
121 (MEMORY_CHUNKS - (i + 2))); 140 mem_chunk_init(&chunk[i + 2], lh_end + 1,
122 chunks[i + 1].addr = addr; 141 ch_end - lh_end, ch_type);
123 chunks[i + 1].size = size; 142 break;
124 chunks[i + 1].type = type;
125 chunks[i + 2].addr = addr + size;
126 chunks[i + 2].size =
127 chunks[i].addr + chunks[i].size - (addr + size);
128 chunks[i + 2].type = chunks[i].type;
129 chunks[i].size = addr - chunks[i].addr;
130 i += 2;
131 } 143 }
132 } 144 }
133} 145}
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 732a793ec53..36b32658fb2 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -17,11 +17,11 @@
17# 17#
18ENTRY(store_status) 18ENTRY(store_status)
19 /* Save register one and load save area base */ 19 /* Save register one and load save area base */
20 stg %r1,__LC_SAVE_AREA+120(%r0) 20 stg %r1,__LC_SAVE_AREA_RESTART
21 lghi %r1,SAVE_AREA_BASE 21 lghi %r1,SAVE_AREA_BASE
22 /* General purpose registers */ 22 /* General purpose registers */
23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
24 lg %r2,__LC_SAVE_AREA+120(%r0) 24 lg %r2,__LC_SAVE_AREA_RESTART
25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) 25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
26 /* Control registers */ 26 /* Control registers */
27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f11d1b037c5..354de0763ef 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -95,6 +95,15 @@ struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
95int __initdata memory_end_set; 95int __initdata memory_end_set;
96unsigned long __initdata memory_end; 96unsigned long __initdata memory_end;
97 97
98unsigned long VMALLOC_START;
99EXPORT_SYMBOL(VMALLOC_START);
100
101unsigned long VMALLOC_END;
102EXPORT_SYMBOL(VMALLOC_END);
103
104struct page *vmemmap;
105EXPORT_SYMBOL(vmemmap);
106
98/* An array with a pointer to the lowcore of every CPU. */ 107/* An array with a pointer to the lowcore of every CPU. */
99struct _lowcore *lowcore_ptr[NR_CPUS]; 108struct _lowcore *lowcore_ptr[NR_CPUS];
100EXPORT_SYMBOL(lowcore_ptr); 109EXPORT_SYMBOL(lowcore_ptr);
@@ -278,6 +287,15 @@ static int __init early_parse_mem(char *p)
278} 287}
279early_param("mem", early_parse_mem); 288early_param("mem", early_parse_mem);
280 289
290static int __init parse_vmalloc(char *arg)
291{
292 if (!arg)
293 return -EINVAL;
294 VMALLOC_END = (memparse(arg, &arg) + PAGE_SIZE - 1) & PAGE_MASK;
295 return 0;
296}
297early_param("vmalloc", parse_vmalloc);
298
281unsigned int user_mode = HOME_SPACE_MODE; 299unsigned int user_mode = HOME_SPACE_MODE;
282EXPORT_SYMBOL_GPL(user_mode); 300EXPORT_SYMBOL_GPL(user_mode);
283 301
@@ -383,7 +401,6 @@ setup_lowcore(void)
383 __ctl_set_bit(14, 29); 401 __ctl_set_bit(14, 29);
384 } 402 }
385#else 403#else
386 lc->cmf_hpp = -1ULL;
387 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; 404 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
388#endif 405#endif
389 lc->sync_enter_timer = S390_lowcore.sync_enter_timer; 406 lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
@@ -479,8 +496,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
479 496
480static void __init setup_memory_end(void) 497static void __init setup_memory_end(void)
481{ 498{
482 unsigned long memory_size; 499 unsigned long vmax, vmalloc_size, tmp;
483 unsigned long max_mem;
484 int i; 500 int i;
485 501
486 502
@@ -490,12 +506,9 @@ static void __init setup_memory_end(void)
490 memory_end_set = 1; 506 memory_end_set = 1;
491 } 507 }
492#endif 508#endif
493 memory_size = 0; 509 real_memory_size = 0;
494 memory_end &= PAGE_MASK; 510 memory_end &= PAGE_MASK;
495 511
496 max_mem = memory_end ? min(VMEM_MAX_PHYS, memory_end) : VMEM_MAX_PHYS;
497 memory_end = min(max_mem, memory_end);
498
499 /* 512 /*
500 * Make sure all chunks are MAX_ORDER aligned so we don't need the 513 * Make sure all chunks are MAX_ORDER aligned so we don't need the
501 * extra checks that HOLES_IN_ZONE would require. 514 * extra checks that HOLES_IN_ZONE would require.
@@ -515,23 +528,48 @@ static void __init setup_memory_end(void)
515 chunk->addr = start; 528 chunk->addr = start;
516 chunk->size = end - start; 529 chunk->size = end - start;
517 } 530 }
531 real_memory_size = max(real_memory_size,
532 chunk->addr + chunk->size);
518 } 533 }
519 534
535 /* Choose kernel address space layout: 2, 3, or 4 levels. */
536#ifdef CONFIG_64BIT
537 vmalloc_size = VMALLOC_END ?: 128UL << 30;
538 tmp = (memory_end ?: real_memory_size) / PAGE_SIZE;
539 tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size;
540 if (tmp <= (1UL << 42))
541 vmax = 1UL << 42; /* 3-level kernel page table */
542 else
543 vmax = 1UL << 53; /* 4-level kernel page table */
544#else
545 vmalloc_size = VMALLOC_END ?: 96UL << 20;
546 vmax = 1UL << 31; /* 2-level kernel page table */
547#endif
548 /* vmalloc area is at the end of the kernel address space. */
549 VMALLOC_END = vmax;
550 VMALLOC_START = vmax - vmalloc_size;
551
552 /* Split remaining virtual space between 1:1 mapping & vmemmap array */
553 tmp = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
554 tmp = VMALLOC_START - tmp * sizeof(struct page);
555 tmp &= ~((vmax >> 11) - 1); /* align to page table level */
556 tmp = min(tmp, 1UL << MAX_PHYSMEM_BITS);
557 vmemmap = (struct page *) tmp;
558
559 /* Take care that memory_end is set and <= vmemmap */
560 memory_end = min(memory_end ?: real_memory_size, tmp);
561
562 /* Fixup memory chunk array to fit into 0..memory_end */
520 for (i = 0; i < MEMORY_CHUNKS; i++) { 563 for (i = 0; i < MEMORY_CHUNKS; i++) {
521 struct mem_chunk *chunk = &memory_chunk[i]; 564 struct mem_chunk *chunk = &memory_chunk[i];
522 565
523 real_memory_size = max(real_memory_size, 566 if (chunk->addr >= memory_end) {
524 chunk->addr + chunk->size);
525 if (chunk->addr >= max_mem) {
526 memset(chunk, 0, sizeof(*chunk)); 567 memset(chunk, 0, sizeof(*chunk));
527 continue; 568 continue;
528 } 569 }
529 if (chunk->addr + chunk->size > max_mem) 570 if (chunk->addr + chunk->size > memory_end)
530 chunk->size = max_mem - chunk->addr; 571 chunk->size = memory_end - chunk->addr;
531 memory_size = max(memory_size, chunk->addr + chunk->size);
532 } 572 }
533 if (!memory_end)
534 memory_end = memory_size;
535} 573}
536 574
537void *restart_stack __attribute__((__section__(".data"))); 575void *restart_stack __attribute__((__section__(".data")));
@@ -655,7 +693,6 @@ static int __init verify_crash_base(unsigned long crash_base,
655static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size, 693static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
656 int type) 694 int type)
657{ 695{
658
659 create_mem_hole(memory_chunk, addr, size, type); 696 create_mem_hole(memory_chunk, addr, size, type);
660} 697}
661 698
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 7f6f9f35454..a8ba840294f 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -302,9 +302,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
302 302
303 /* We forgot to include these in the sigcontext. 303 /* We forgot to include these in the sigcontext.
304 To avoid breaking binary compatibility, they are passed as args. */ 304 To avoid breaking binary compatibility, they are passed as args. */
305 regs->gprs[4] = current->thread.trap_no; 305 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
306 regs->gprs[5] = current->thread.prot_addr; 306 sig == SIGTRAP || sig == SIGFPE) {
307 regs->gprs[6] = task_thread_info(current)->last_break; 307 /* set extra registers only for synchronous signals */
308 regs->gprs[4] = regs->int_code & 127;
309 regs->gprs[5] = regs->int_parm_long;
310 regs->gprs[6] = task_thread_info(current)->last_break;
311 }
308 312
309 /* Place signal number on stack to allow backtrace from handler. */ 313 /* Place signal number on stack to allow backtrace from handler. */
310 if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) 314 if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
@@ -434,13 +438,13 @@ void do_signal(struct pt_regs *regs)
434 * call information. 438 * call information.
435 */ 439 */
436 current_thread_info()->system_call = 440 current_thread_info()->system_call =
437 test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; 441 test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;
438 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 442 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
439 443
440 if (signr > 0) { 444 if (signr > 0) {
441 /* Whee! Actually deliver the signal. */ 445 /* Whee! Actually deliver the signal. */
442 if (current_thread_info()->system_call) { 446 if (current_thread_info()->system_call) {
443 regs->svc_code = current_thread_info()->system_call; 447 regs->int_code = current_thread_info()->system_call;
444 /* Check for system call restarting. */ 448 /* Check for system call restarting. */
445 switch (regs->gprs[2]) { 449 switch (regs->gprs[2]) {
446 case -ERESTART_RESTARTBLOCK: 450 case -ERESTART_RESTARTBLOCK:
@@ -457,7 +461,7 @@ void do_signal(struct pt_regs *regs)
457 regs->gprs[2] = regs->orig_gpr2; 461 regs->gprs[2] = regs->orig_gpr2;
458 regs->psw.addr = 462 regs->psw.addr =
459 __rewind_psw(regs->psw, 463 __rewind_psw(regs->psw,
460 regs->svc_code >> 16); 464 regs->int_code >> 16);
461 break; 465 break;
462 } 466 }
463 } 467 }
@@ -488,11 +492,11 @@ void do_signal(struct pt_regs *regs)
488 /* No handlers present - check for system call restart */ 492 /* No handlers present - check for system call restart */
489 clear_thread_flag(TIF_SYSCALL); 493 clear_thread_flag(TIF_SYSCALL);
490 if (current_thread_info()->system_call) { 494 if (current_thread_info()->system_call) {
491 regs->svc_code = current_thread_info()->system_call; 495 regs->int_code = current_thread_info()->system_call;
492 switch (regs->gprs[2]) { 496 switch (regs->gprs[2]) {
493 case -ERESTART_RESTARTBLOCK: 497 case -ERESTART_RESTARTBLOCK:
494 /* Restart with sys_restart_syscall */ 498 /* Restart with sys_restart_syscall */
495 regs->svc_code = __NR_restart_syscall; 499 regs->int_code = __NR_restart_syscall;
496 /* fallthrough */ 500 /* fallthrough */
497 case -ERESTARTNOHAND: 501 case -ERESTARTNOHAND:
498 case -ERESTARTSYS: 502 case -ERESTARTSYS:
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 66cca03c028..2398ce6b15a 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -69,9 +69,7 @@ enum s390_cpu_state {
69}; 69};
70 70
71DEFINE_MUTEX(smp_cpu_state_mutex); 71DEFINE_MUTEX(smp_cpu_state_mutex);
72int smp_cpu_polarization[NR_CPUS];
73static int smp_cpu_state[NR_CPUS]; 72static int smp_cpu_state[NR_CPUS];
74static int cpu_management;
75 73
76static DEFINE_PER_CPU(struct cpu, cpu_devices); 74static DEFINE_PER_CPU(struct cpu, cpu_devices);
77 75
@@ -149,29 +147,59 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
149 sp -= sizeof(struct pt_regs); 147 sp -= sizeof(struct pt_regs);
150 regs = (struct pt_regs *) sp; 148 regs = (struct pt_regs *) sp;
151 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs)); 149 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
152 regs->psw = lc->psw_save_area; 150 regs->psw = current_lc->psw_save_area;
153 sp -= STACK_FRAME_OVERHEAD; 151 sp -= STACK_FRAME_OVERHEAD;
154 sf = (struct stack_frame *) sp; 152 sf = (struct stack_frame *) sp;
155 sf->back_chain = regs->gprs[15]; 153 sf->back_chain = 0;
156 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]); 154 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
157} 155}
158 156
157static void smp_stop_cpu(void)
158{
159 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
160 cpu_relax();
161}
162
159void smp_send_stop(void) 163void smp_send_stop(void)
160{ 164{
161 int cpu, rc; 165 cpumask_t cpumask;
166 int cpu;
167 u64 end;
162 168
163 /* Disable all interrupts/machine checks */ 169 /* Disable all interrupts/machine checks */
164 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT); 170 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
165 trace_hardirqs_off(); 171 trace_hardirqs_off();
166 172
167 /* stop all processors */ 173 cpumask_copy(&cpumask, cpu_online_mask);
168 for_each_online_cpu(cpu) { 174 cpumask_clear_cpu(smp_processor_id(), &cpumask);
169 if (cpu == smp_processor_id()) 175
170 continue; 176 if (oops_in_progress) {
171 do { 177 /*
172 rc = sigp(cpu, sigp_stop); 178 * Give the other cpus the opportunity to complete
173 } while (rc == sigp_busy); 179 * outstanding interrupts before stopping them.
180 */
181 end = get_clock() + (1000000UL << 12);
182 for_each_cpu(cpu, &cpumask) {
183 set_bit(ec_stop_cpu, (unsigned long *)
184 &lowcore_ptr[cpu]->ext_call_fast);
185 while (sigp(cpu, sigp_emergency_signal) == sigp_busy &&
186 get_clock() < end)
187 cpu_relax();
188 }
189 while (get_clock() < end) {
190 for_each_cpu(cpu, &cpumask)
191 if (cpu_stopped(cpu))
192 cpumask_clear_cpu(cpu, &cpumask);
193 if (cpumask_empty(&cpumask))
194 break;
195 cpu_relax();
196 }
197 }
174 198
199 /* stop all processors */
200 for_each_cpu(cpu, &cpumask) {
201 while (sigp(cpu, sigp_stop) == sigp_busy)
202 cpu_relax();
175 while (!cpu_stopped(cpu)) 203 while (!cpu_stopped(cpu))
176 cpu_relax(); 204 cpu_relax();
177 } 205 }
@@ -187,7 +215,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
187{ 215{
188 unsigned long bits; 216 unsigned long bits;
189 217
190 if (ext_int_code == 0x1202) 218 if ((ext_int_code & 0xffff) == 0x1202)
191 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++; 219 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++;
192 else 220 else
193 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++; 221 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++;
@@ -196,6 +224,9 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
196 */ 224 */
197 bits = xchg(&S390_lowcore.ext_call_fast, 0); 225 bits = xchg(&S390_lowcore.ext_call_fast, 0);
198 226
227 if (test_bit(ec_stop_cpu, &bits))
228 smp_stop_cpu();
229
199 if (test_bit(ec_schedule, &bits)) 230 if (test_bit(ec_schedule, &bits))
200 scheduler_ipi(); 231 scheduler_ipi();
201 232
@@ -204,6 +235,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
204 235
205 if (test_bit(ec_call_function_single, &bits)) 236 if (test_bit(ec_call_function_single, &bits))
206 generic_smp_call_function_single_interrupt(); 237 generic_smp_call_function_single_interrupt();
238
207} 239}
208 240
209/* 241/*
@@ -369,7 +401,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
369 if (cpu_known(cpu_id)) 401 if (cpu_known(cpu_id))
370 continue; 402 continue;
371 __cpu_logical_map[logical_cpu] = cpu_id; 403 __cpu_logical_map[logical_cpu] = cpu_id;
372 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 404 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
373 if (!cpu_stopped(logical_cpu)) 405 if (!cpu_stopped(logical_cpu))
374 continue; 406 continue;
375 set_cpu_present(logical_cpu, true); 407 set_cpu_present(logical_cpu, true);
@@ -403,7 +435,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
403 if (cpu_known(cpu_id)) 435 if (cpu_known(cpu_id))
404 continue; 436 continue;
405 __cpu_logical_map[logical_cpu] = cpu_id; 437 __cpu_logical_map[logical_cpu] = cpu_id;
406 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 438 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
407 set_cpu_present(logical_cpu, true); 439 set_cpu_present(logical_cpu, true);
408 if (cpu >= info->configured) 440 if (cpu >= info->configured)
409 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; 441 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
@@ -656,7 +688,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
656 - sizeof(struct stack_frame)); 688 - sizeof(struct stack_frame));
657 memset(sf, 0, sizeof(struct stack_frame)); 689 memset(sf, 0, sizeof(struct stack_frame));
658 sf->gprs[9] = (unsigned long) sf; 690 sf->gprs[9] = (unsigned long) sf;
659 cpu_lowcore->save_area[15] = (unsigned long) sf; 691 cpu_lowcore->gpregs_save_area[15] = (unsigned long) sf;
660 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); 692 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
661 atomic_inc(&init_mm.context.attach_count); 693 atomic_inc(&init_mm.context.attach_count);
662 asm volatile( 694 asm volatile(
@@ -806,7 +838,7 @@ void __init smp_prepare_boot_cpu(void)
806 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 838 S390_lowcore.percpu_offset = __per_cpu_offset[0];
807 current_set[0] = current; 839 current_set[0] = current;
808 smp_cpu_state[0] = CPU_STATE_CONFIGURED; 840 smp_cpu_state[0] = CPU_STATE_CONFIGURED;
809 smp_cpu_polarization[0] = POLARIZATION_UNKNWN; 841 cpu_set_polarization(0, POLARIZATION_UNKNOWN);
810} 842}
811 843
812void __init smp_cpus_done(unsigned int max_cpus) 844void __init smp_cpus_done(unsigned int max_cpus)
@@ -868,7 +900,8 @@ static ssize_t cpu_configure_store(struct device *dev,
868 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); 900 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
869 if (!rc) { 901 if (!rc) {
870 smp_cpu_state[cpu] = CPU_STATE_STANDBY; 902 smp_cpu_state[cpu] = CPU_STATE_STANDBY;
871 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 903 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
904 topology_expect_change();
872 } 905 }
873 } 906 }
874 break; 907 break;
@@ -877,7 +910,8 @@ static ssize_t cpu_configure_store(struct device *dev,
877 rc = sclp_cpu_configure(__cpu_logical_map[cpu]); 910 rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
878 if (!rc) { 911 if (!rc) {
879 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; 912 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
880 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 913 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
914 topology_expect_change();
881 } 915 }
882 } 916 }
883 break; 917 break;
@@ -892,35 +926,6 @@ out:
892static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); 926static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
893#endif /* CONFIG_HOTPLUG_CPU */ 927#endif /* CONFIG_HOTPLUG_CPU */
894 928
895static ssize_t cpu_polarization_show(struct device *dev,
896 struct device_attribute *attr, char *buf)
897{
898 int cpu = dev->id;
899 ssize_t count;
900
901 mutex_lock(&smp_cpu_state_mutex);
902 switch (smp_cpu_polarization[cpu]) {
903 case POLARIZATION_HRZ:
904 count = sprintf(buf, "horizontal\n");
905 break;
906 case POLARIZATION_VL:
907 count = sprintf(buf, "vertical:low\n");
908 break;
909 case POLARIZATION_VM:
910 count = sprintf(buf, "vertical:medium\n");
911 break;
912 case POLARIZATION_VH:
913 count = sprintf(buf, "vertical:high\n");
914 break;
915 default:
916 count = sprintf(buf, "unknown\n");
917 break;
918 }
919 mutex_unlock(&smp_cpu_state_mutex);
920 return count;
921}
922static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
923
924static ssize_t show_cpu_address(struct device *dev, 929static ssize_t show_cpu_address(struct device *dev,
925 struct device_attribute *attr, char *buf) 930 struct device_attribute *attr, char *buf)
926{ 931{
@@ -928,13 +933,11 @@ static ssize_t show_cpu_address(struct device *dev,
928} 933}
929static DEVICE_ATTR(address, 0444, show_cpu_address, NULL); 934static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
930 935
931
932static struct attribute *cpu_common_attrs[] = { 936static struct attribute *cpu_common_attrs[] = {
933#ifdef CONFIG_HOTPLUG_CPU 937#ifdef CONFIG_HOTPLUG_CPU
934 &dev_attr_configure.attr, 938 &dev_attr_configure.attr,
935#endif 939#endif
936 &dev_attr_address.attr, 940 &dev_attr_address.attr,
937 &dev_attr_polarization.attr,
938 NULL, 941 NULL,
939}; 942};
940 943
@@ -1055,11 +1058,20 @@ static int __devinit smp_add_present_cpu(int cpu)
1055 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); 1058 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
1056 if (rc) 1059 if (rc)
1057 goto out_cpu; 1060 goto out_cpu;
1058 if (!cpu_online(cpu)) 1061 if (cpu_online(cpu)) {
1059 goto out; 1062 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
1060 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 1063 if (rc)
1061 if (!rc) 1064 goto out_online;
1062 return 0; 1065 }
1066 rc = topology_cpu_init(c);
1067 if (rc)
1068 goto out_topology;
1069 return 0;
1070
1071out_topology:
1072 if (cpu_online(cpu))
1073 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
1074out_online:
1063 sysfs_remove_group(&s->kobj, &cpu_common_attr_group); 1075 sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
1064out_cpu: 1076out_cpu:
1065#ifdef CONFIG_HOTPLUG_CPU 1077#ifdef CONFIG_HOTPLUG_CPU
@@ -1111,61 +1123,16 @@ static ssize_t __ref rescan_store(struct device *dev,
1111static DEVICE_ATTR(rescan, 0200, NULL, rescan_store); 1123static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
1112#endif /* CONFIG_HOTPLUG_CPU */ 1124#endif /* CONFIG_HOTPLUG_CPU */
1113 1125
1114static ssize_t dispatching_show(struct device *dev, 1126static int __init s390_smp_init(void)
1115 struct device_attribute *attr,
1116 char *buf)
1117{
1118 ssize_t count;
1119
1120 mutex_lock(&smp_cpu_state_mutex);
1121 count = sprintf(buf, "%d\n", cpu_management);
1122 mutex_unlock(&smp_cpu_state_mutex);
1123 return count;
1124}
1125
1126static ssize_t dispatching_store(struct device *dev,
1127 struct device_attribute *attr,
1128 const char *buf,
1129 size_t count)
1130{
1131 int val, rc;
1132 char delim;
1133
1134 if (sscanf(buf, "%d %c", &val, &delim) != 1)
1135 return -EINVAL;
1136 if (val != 0 && val != 1)
1137 return -EINVAL;
1138 rc = 0;
1139 get_online_cpus();
1140 mutex_lock(&smp_cpu_state_mutex);
1141 if (cpu_management == val)
1142 goto out;
1143 rc = topology_set_cpu_management(val);
1144 if (!rc)
1145 cpu_management = val;
1146out:
1147 mutex_unlock(&smp_cpu_state_mutex);
1148 put_online_cpus();
1149 return rc ? rc : count;
1150}
1151static DEVICE_ATTR(dispatching, 0644, dispatching_show,
1152 dispatching_store);
1153
1154static int __init topology_init(void)
1155{ 1127{
1156 int cpu; 1128 int cpu, rc;
1157 int rc;
1158 1129
1159 register_cpu_notifier(&smp_cpu_nb); 1130 register_cpu_notifier(&smp_cpu_nb);
1160
1161#ifdef CONFIG_HOTPLUG_CPU 1131#ifdef CONFIG_HOTPLUG_CPU
1162 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan); 1132 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
1163 if (rc) 1133 if (rc)
1164 return rc; 1134 return rc;
1165#endif 1135#endif
1166 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
1167 if (rc)
1168 return rc;
1169 for_each_present_cpu(cpu) { 1136 for_each_present_cpu(cpu) {
1170 rc = smp_add_present_cpu(cpu); 1137 rc = smp_add_present_cpu(cpu);
1171 if (rc) 1138 if (rc)
@@ -1173,4 +1140,4 @@ static int __init topology_init(void)
1173 } 1140 }
1174 return 0; 1141 return 0;
1175} 1142}
1176subsys_initcall(topology_init); 1143subsys_initcall(s390_smp_init);
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 476081440df..78ea1948ff5 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -60,74 +60,22 @@ out:
60} 60}
61 61
62/* 62/*
63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.
64 *
65 * This is really horribly ugly.
66 */ 64 */
67SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, 65SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
68 unsigned long, third, void __user *, ptr) 66 unsigned long, third, void __user *, ptr)
69{ 67{
70 struct ipc_kludge tmp; 68 if (call >> 16)
71 int ret; 69 return -EINVAL;
72 70 /* The s390 sys_ipc variant has only five parameters instead of six
73 switch (call) { 71 * like the generic variant. The only difference is the handling of
74 case SEMOP: 72 * the SEMTIMEDOP subcall where on s390 the third parameter is used
75 return sys_semtimedop(first, (struct sembuf __user *)ptr, 73 * as a pointer to a struct timespec where the generic variant uses
76 (unsigned)second, NULL); 74 * the fifth parameter.
77 case SEMTIMEDOP: 75 * Therefore we can call the generic variant by simply passing the
78 return sys_semtimedop(first, (struct sembuf __user *)ptr, 76 * third parameter also as fifth parameter.
79 (unsigned)second, 77 */
80 (const struct timespec __user *) third); 78 return sys_ipc(call, first, second, third, ptr, third);
81 case SEMGET:
82 return sys_semget(first, (int)second, third);
83 case SEMCTL: {
84 union semun fourth;
85 if (!ptr)
86 return -EINVAL;
87 if (get_user(fourth.__pad, (void __user * __user *) ptr))
88 return -EFAULT;
89 return sys_semctl(first, (int)second, third, fourth);
90 }
91 case MSGSND:
92 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
93 (size_t)second, third);
94 break;
95 case MSGRCV:
96 if (!ptr)
97 return -EINVAL;
98 if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
99 sizeof (struct ipc_kludge)))
100 return -EFAULT;
101 return sys_msgrcv (first, tmp.msgp,
102 (size_t)second, tmp.msgtyp, third);
103 case MSGGET:
104 return sys_msgget((key_t)first, (int)second);
105 case MSGCTL:
106 return sys_msgctl(first, (int)second,
107 (struct msqid_ds __user *)ptr);
108
109 case SHMAT: {
110 ulong raddr;
111 ret = do_shmat(first, (char __user *)ptr,
112 (int)second, &raddr);
113 if (ret)
114 return ret;
115 return put_user (raddr, (ulong __user *) third);
116 break;
117 }
118 case SHMDT:
119 return sys_shmdt ((char __user *)ptr);
120 case SHMGET:
121 return sys_shmget(first, (size_t)second, third);
122 case SHMCTL:
123 return sys_shmctl(first, (int)second,
124 (struct shmid_ds __user *) ptr);
125 default:
126 return -ENOSYS;
127
128 }
129
130 return -EINVAL;
131} 79}
132 80
133#ifdef CONFIG_64BIT 81#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 6e0e29b29a7..7370a41948c 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * Copyright IBM Corp. 2007 2 * Copyright IBM Corp. 2007,2011
3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
4 */ 4 */
5 5
6#define KMSG_COMPONENT "cpu" 6#define KMSG_COMPONENT "cpu"
7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
8 8
9#include <linux/kernel.h> 9#include <linux/workqueue.h>
10#include <linux/mm.h>
11#include <linux/init.h>
12#include <linux/device.h>
13#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/cpuset.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/workqueue.h> 15#include <linux/init.h>
16#include <linux/delay.h>
16#include <linux/cpu.h> 17#include <linux/cpu.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <linux/cpuset.h> 19#include <linux/mm.h>
19#include <asm/delay.h>
20 20
21#define PTF_HORIZONTAL (0UL) 21#define PTF_HORIZONTAL (0UL)
22#define PTF_VERTICAL (1UL) 22#define PTF_VERTICAL (1UL)
@@ -31,7 +31,6 @@ struct mask_info {
31static int topology_enabled = 1; 31static int topology_enabled = 1;
32static void topology_work_fn(struct work_struct *work); 32static void topology_work_fn(struct work_struct *work);
33static struct sysinfo_15_1_x *tl_info; 33static struct sysinfo_15_1_x *tl_info;
34static struct timer_list topology_timer;
35static void set_topology_timer(void); 34static void set_topology_timer(void);
36static DECLARE_WORK(topology_work, topology_work_fn); 35static DECLARE_WORK(topology_work, topology_work_fn);
37/* topology_lock protects the core linked list */ 36/* topology_lock protects the core linked list */
@@ -41,11 +40,12 @@ static struct mask_info core_info;
41cpumask_t cpu_core_map[NR_CPUS]; 40cpumask_t cpu_core_map[NR_CPUS];
42unsigned char cpu_core_id[NR_CPUS]; 41unsigned char cpu_core_id[NR_CPUS];
43 42
44#ifdef CONFIG_SCHED_BOOK
45static struct mask_info book_info; 43static struct mask_info book_info;
46cpumask_t cpu_book_map[NR_CPUS]; 44cpumask_t cpu_book_map[NR_CPUS];
47unsigned char cpu_book_id[NR_CPUS]; 45unsigned char cpu_book_id[NR_CPUS];
48#endif 46
47/* smp_cpu_state_mutex must be held when accessing this array */
48int cpu_polarization[NR_CPUS];
49 49
50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
51{ 51{
@@ -71,7 +71,7 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
72 struct mask_info *book, 72 struct mask_info *book,
73 struct mask_info *core, 73 struct mask_info *core,
74 int z10) 74 int one_core_per_cpu)
75{ 75{
76 unsigned int cpu; 76 unsigned int cpu;
77 77
@@ -85,18 +85,16 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
85 for_each_present_cpu(lcpu) { 85 for_each_present_cpu(lcpu) {
86 if (cpu_logical_map(lcpu) != rcpu) 86 if (cpu_logical_map(lcpu) != rcpu)
87 continue; 87 continue;
88#ifdef CONFIG_SCHED_BOOK
89 cpumask_set_cpu(lcpu, &book->mask); 88 cpumask_set_cpu(lcpu, &book->mask);
90 cpu_book_id[lcpu] = book->id; 89 cpu_book_id[lcpu] = book->id;
91#endif
92 cpumask_set_cpu(lcpu, &core->mask); 90 cpumask_set_cpu(lcpu, &core->mask);
93 if (z10) { 91 if (one_core_per_cpu) {
94 cpu_core_id[lcpu] = rcpu; 92 cpu_core_id[lcpu] = rcpu;
95 core = core->next; 93 core = core->next;
96 } else { 94 } else {
97 cpu_core_id[lcpu] = core->id; 95 cpu_core_id[lcpu] = core->id;
98 } 96 }
99 smp_cpu_polarization[lcpu] = tl_cpu->pp; 97 cpu_set_polarization(lcpu, tl_cpu->pp);
100 } 98 }
101 } 99 }
102 return core; 100 return core;
@@ -111,13 +109,11 @@ static void clear_masks(void)
111 cpumask_clear(&info->mask); 109 cpumask_clear(&info->mask);
112 info = info->next; 110 info = info->next;
113 } 111 }
114#ifdef CONFIG_SCHED_BOOK
115 info = &book_info; 112 info = &book_info;
116 while (info) { 113 while (info) {
117 cpumask_clear(&info->mask); 114 cpumask_clear(&info->mask);
118 info = info->next; 115 info = info->next;
119 } 116 }
120#endif
121} 117}
122 118
123static union topology_entry *next_tle(union topology_entry *tle) 119static union topology_entry *next_tle(union topology_entry *tle)
@@ -127,66 +123,75 @@ static union topology_entry *next_tle(union topology_entry *tle)
127 return (union topology_entry *)((struct topology_container *)tle + 1); 123 return (union topology_entry *)((struct topology_container *)tle + 1);
128} 124}
129 125
130static void tl_to_cores(struct sysinfo_15_1_x *info) 126static void __tl_to_cores_generic(struct sysinfo_15_1_x *info)
131{ 127{
132#ifdef CONFIG_SCHED_BOOK
133 struct mask_info *book = &book_info;
134 struct cpuid cpu_id;
135#else
136 struct mask_info *book = NULL;
137#endif
138 struct mask_info *core = &core_info; 128 struct mask_info *core = &core_info;
129 struct mask_info *book = &book_info;
139 union topology_entry *tle, *end; 130 union topology_entry *tle, *end;
140 int z10 = 0;
141 131
142#ifdef CONFIG_SCHED_BOOK
143 get_cpu_id(&cpu_id);
144 z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
145#endif
146 spin_lock_irq(&topology_lock);
147 clear_masks();
148 tle = info->tle; 132 tle = info->tle;
149 end = (union topology_entry *)((unsigned long)info + info->length); 133 end = (union topology_entry *)((unsigned long)info + info->length);
150 while (tle < end) { 134 while (tle < end) {
151#ifdef CONFIG_SCHED_BOOK
152 if (z10) {
153 switch (tle->nl) {
154 case 1:
155 book = book->next;
156 book->id = tle->container.id;
157 break;
158 case 0:
159 core = add_cpus_to_mask(&tle->cpu, book, core, z10);
160 break;
161 default:
162 clear_masks();
163 goto out;
164 }
165 tle = next_tle(tle);
166 continue;
167 }
168#endif
169 switch (tle->nl) { 135 switch (tle->nl) {
170#ifdef CONFIG_SCHED_BOOK
171 case 2: 136 case 2:
172 book = book->next; 137 book = book->next;
173 book->id = tle->container.id; 138 book->id = tle->container.id;
174 break; 139 break;
175#endif
176 case 1: 140 case 1:
177 core = core->next; 141 core = core->next;
178 core->id = tle->container.id; 142 core->id = tle->container.id;
179 break; 143 break;
180 case 0: 144 case 0:
181 add_cpus_to_mask(&tle->cpu, book, core, z10); 145 add_cpus_to_mask(&tle->cpu, book, core, 0);
182 break; 146 break;
183 default: 147 default:
184 clear_masks(); 148 clear_masks();
185 goto out; 149 return;
186 } 150 }
187 tle = next_tle(tle); 151 tle = next_tle(tle);
188 } 152 }
189out: 153}
154
155static void __tl_to_cores_z10(struct sysinfo_15_1_x *info)
156{
157 struct mask_info *core = &core_info;
158 struct mask_info *book = &book_info;
159 union topology_entry *tle, *end;
160
161 tle = info->tle;
162 end = (union topology_entry *)((unsigned long)info + info->length);
163 while (tle < end) {
164 switch (tle->nl) {
165 case 1:
166 book = book->next;
167 book->id = tle->container.id;
168 break;
169 case 0:
170 core = add_cpus_to_mask(&tle->cpu, book, core, 1);
171 break;
172 default:
173 clear_masks();
174 return;
175 }
176 tle = next_tle(tle);
177 }
178}
179
180static void tl_to_cores(struct sysinfo_15_1_x *info)
181{
182 struct cpuid cpu_id;
183
184 get_cpu_id(&cpu_id);
185 spin_lock_irq(&topology_lock);
186 clear_masks();
187 switch (cpu_id.machine) {
188 case 0x2097:
189 case 0x2098:
190 __tl_to_cores_z10(info);
191 break;
192 default:
193 __tl_to_cores_generic(info);
194 }
190 spin_unlock_irq(&topology_lock); 195 spin_unlock_irq(&topology_lock);
191} 196}
192 197
@@ -196,7 +201,7 @@ static void topology_update_polarization_simple(void)
196 201
197 mutex_lock(&smp_cpu_state_mutex); 202 mutex_lock(&smp_cpu_state_mutex);
198 for_each_possible_cpu(cpu) 203 for_each_possible_cpu(cpu)
199 smp_cpu_polarization[cpu] = POLARIZATION_HRZ; 204 cpu_set_polarization(cpu, POLARIZATION_HRZ);
200 mutex_unlock(&smp_cpu_state_mutex); 205 mutex_unlock(&smp_cpu_state_mutex);
201} 206}
202 207
@@ -215,8 +220,7 @@ static int ptf(unsigned long fc)
215 220
216int topology_set_cpu_management(int fc) 221int topology_set_cpu_management(int fc)
217{ 222{
218 int cpu; 223 int cpu, rc;
219 int rc;
220 224
221 if (!MACHINE_HAS_TOPOLOGY) 225 if (!MACHINE_HAS_TOPOLOGY)
222 return -EOPNOTSUPP; 226 return -EOPNOTSUPP;
@@ -227,7 +231,7 @@ int topology_set_cpu_management(int fc)
227 if (rc) 231 if (rc)
228 return -EBUSY; 232 return -EBUSY;
229 for_each_possible_cpu(cpu) 233 for_each_possible_cpu(cpu)
230 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 234 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
231 return rc; 235 return rc;
232} 236}
233 237
@@ -239,22 +243,18 @@ static void update_cpu_core_map(void)
239 spin_lock_irqsave(&topology_lock, flags); 243 spin_lock_irqsave(&topology_lock, flags);
240 for_each_possible_cpu(cpu) { 244 for_each_possible_cpu(cpu) {
241 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu); 245 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
242#ifdef CONFIG_SCHED_BOOK
243 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu); 246 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
244#endif
245 } 247 }
246 spin_unlock_irqrestore(&topology_lock, flags); 248 spin_unlock_irqrestore(&topology_lock, flags);
247} 249}
248 250
249void store_topology(struct sysinfo_15_1_x *info) 251void store_topology(struct sysinfo_15_1_x *info)
250{ 252{
251#ifdef CONFIG_SCHED_BOOK
252 int rc; 253 int rc;
253 254
254 rc = stsi(info, 15, 1, 3); 255 rc = stsi(info, 15, 1, 3);
255 if (rc != -ENOSYS) 256 if (rc != -ENOSYS)
256 return; 257 return;
257#endif
258 stsi(info, 15, 1, 2); 258 stsi(info, 15, 1, 2);
259} 259}
260 260
@@ -296,12 +296,30 @@ static void topology_timer_fn(unsigned long ignored)
296 set_topology_timer(); 296 set_topology_timer();
297} 297}
298 298
299static struct timer_list topology_timer =
300 TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0);
301
302static atomic_t topology_poll = ATOMIC_INIT(0);
303
299static void set_topology_timer(void) 304static void set_topology_timer(void)
300{ 305{
301 topology_timer.function = topology_timer_fn; 306 if (atomic_add_unless(&topology_poll, -1, 0))
302 topology_timer.data = 0; 307 mod_timer(&topology_timer, jiffies + HZ / 10);
303 topology_timer.expires = jiffies + 60 * HZ; 308 else
304 add_timer(&topology_timer); 309 mod_timer(&topology_timer, jiffies + HZ * 60);
310}
311
312void topology_expect_change(void)
313{
314 if (!MACHINE_HAS_TOPOLOGY)
315 return;
316 /* This is racy, but it doesn't matter since it is just a heuristic.
317 * Worst case is that we poll in a higher frequency for a bit longer.
318 */
319 if (atomic_read(&topology_poll) > 60)
320 return;
321 atomic_add(60, &topology_poll);
322 set_topology_timer();
305} 323}
306 324
307static int __init early_parse_topology(char *p) 325static int __init early_parse_topology(char *p)
@@ -313,23 +331,6 @@ static int __init early_parse_topology(char *p)
313} 331}
314early_param("topology", early_parse_topology); 332early_param("topology", early_parse_topology);
315 333
316static int __init init_topology_update(void)
317{
318 int rc;
319
320 rc = 0;
321 if (!MACHINE_HAS_TOPOLOGY) {
322 topology_update_polarization_simple();
323 goto out;
324 }
325 init_timer_deferrable(&topology_timer);
326 set_topology_timer();
327out:
328 update_cpu_core_map();
329 return rc;
330}
331__initcall(init_topology_update);
332
333static void __init alloc_masks(struct sysinfo_15_1_x *info, 334static void __init alloc_masks(struct sysinfo_15_1_x *info,
334 struct mask_info *mask, int offset) 335 struct mask_info *mask, int offset)
335{ 336{
@@ -357,10 +358,108 @@ void __init s390_init_cpu_topology(void)
357 store_topology(info); 358 store_topology(info);
358 pr_info("The CPU configuration topology of the machine is:"); 359 pr_info("The CPU configuration topology of the machine is:");
359 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 360 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
360 printk(" %d", info->mag[i]); 361 printk(KERN_CONT " %d", info->mag[i]);
361 printk(" / %d\n", info->mnest); 362 printk(KERN_CONT " / %d\n", info->mnest);
362 alloc_masks(info, &core_info, 1); 363 alloc_masks(info, &core_info, 1);
363#ifdef CONFIG_SCHED_BOOK
364 alloc_masks(info, &book_info, 2); 364 alloc_masks(info, &book_info, 2);
365#endif
366} 365}
366
367static int cpu_management;
368
369static ssize_t dispatching_show(struct device *dev,
370 struct device_attribute *attr,
371 char *buf)
372{
373 ssize_t count;
374
375 mutex_lock(&smp_cpu_state_mutex);
376 count = sprintf(buf, "%d\n", cpu_management);
377 mutex_unlock(&smp_cpu_state_mutex);
378 return count;
379}
380
381static ssize_t dispatching_store(struct device *dev,
382 struct device_attribute *attr,
383 const char *buf,
384 size_t count)
385{
386 int val, rc;
387 char delim;
388
389 if (sscanf(buf, "%d %c", &val, &delim) != 1)
390 return -EINVAL;
391 if (val != 0 && val != 1)
392 return -EINVAL;
393 rc = 0;
394 get_online_cpus();
395 mutex_lock(&smp_cpu_state_mutex);
396 if (cpu_management == val)
397 goto out;
398 rc = topology_set_cpu_management(val);
399 if (rc)
400 goto out;
401 cpu_management = val;
402 topology_expect_change();
403out:
404 mutex_unlock(&smp_cpu_state_mutex);
405 put_online_cpus();
406 return rc ? rc : count;
407}
408static DEVICE_ATTR(dispatching, 0644, dispatching_show,
409 dispatching_store);
410
411static ssize_t cpu_polarization_show(struct device *dev,
412 struct device_attribute *attr, char *buf)
413{
414 int cpu = dev->id;
415 ssize_t count;
416
417 mutex_lock(&smp_cpu_state_mutex);
418 switch (cpu_read_polarization(cpu)) {
419 case POLARIZATION_HRZ:
420 count = sprintf(buf, "horizontal\n");
421 break;
422 case POLARIZATION_VL:
423 count = sprintf(buf, "vertical:low\n");
424 break;
425 case POLARIZATION_VM:
426 count = sprintf(buf, "vertical:medium\n");
427 break;
428 case POLARIZATION_VH:
429 count = sprintf(buf, "vertical:high\n");
430 break;
431 default:
432 count = sprintf(buf, "unknown\n");
433 break;
434 }
435 mutex_unlock(&smp_cpu_state_mutex);
436 return count;
437}
438static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
439
440static struct attribute *topology_cpu_attrs[] = {
441 &dev_attr_polarization.attr,
442 NULL,
443};
444
445static struct attribute_group topology_cpu_attr_group = {
446 .attrs = topology_cpu_attrs,
447};
448
449int topology_cpu_init(struct cpu *cpu)
450{
451 return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group);
452}
453
454static int __init topology_init(void)
455{
456 if (!MACHINE_HAS_TOPOLOGY) {
457 topology_update_polarization_simple();
458 goto out;
459 }
460 set_topology_timer();
461out:
462 update_cpu_core_map();
463 return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
464}
465device_initcall(topology_init);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a9807dd8627..5ce3750b181 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -43,9 +43,9 @@
43#include <asm/debug.h> 43#include <asm/debug.h>
44#include "entry.h" 44#include "entry.h"
45 45
46void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 46void (*pgm_check_table[128])(struct pt_regs *regs);
47 47
48int show_unhandled_signals; 48int show_unhandled_signals = 1;
49 49
50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
51 51
@@ -234,7 +234,7 @@ void show_regs(struct pt_regs *regs)
234 234
235static DEFINE_SPINLOCK(die_lock); 235static DEFINE_SPINLOCK(die_lock);
236 236
237void die(const char * str, struct pt_regs * regs, long err) 237void die(struct pt_regs *regs, const char *str)
238{ 238{
239 static int die_counter; 239 static int die_counter;
240 240
@@ -243,7 +243,7 @@ void die(const char * str, struct pt_regs * regs, long err)
243 console_verbose(); 243 console_verbose();
244 spin_lock_irq(&die_lock); 244 spin_lock_irq(&die_lock);
245 bust_spinlocks(1); 245 bust_spinlocks(1);
246 printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); 246 printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter);
247#ifdef CONFIG_PREEMPT 247#ifdef CONFIG_PREEMPT
248 printk("PREEMPT "); 248 printk("PREEMPT ");
249#endif 249#endif
@@ -254,7 +254,7 @@ void die(const char * str, struct pt_regs * regs, long err)
254 printk("DEBUG_PAGEALLOC"); 254 printk("DEBUG_PAGEALLOC");
255#endif 255#endif
256 printk("\n"); 256 printk("\n");
257 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 257 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
258 show_regs(regs); 258 show_regs(regs);
259 bust_spinlocks(0); 259 bust_spinlocks(0);
260 add_taint(TAINT_DIE); 260 add_taint(TAINT_DIE);
@@ -267,8 +267,7 @@ void die(const char * str, struct pt_regs * regs, long err)
267 do_exit(SIGSEGV); 267 do_exit(SIGSEGV);
268} 268}
269 269
270static void inline report_user_fault(struct pt_regs *regs, long int_code, 270static inline void report_user_fault(struct pt_regs *regs, int signr)
271 int signr)
272{ 271{
273 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 272 if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
274 return; 273 return;
@@ -276,7 +275,7 @@ static void inline report_user_fault(struct pt_regs *regs, long int_code,
276 return; 275 return;
277 if (!printk_ratelimit()) 276 if (!printk_ratelimit())
278 return; 277 return;
279 printk("User process fault: interruption code 0x%lX ", int_code); 278 printk("User process fault: interruption code 0x%X ", regs->int_code);
280 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); 279 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
281 printk("\n"); 280 printk("\n");
282 show_regs(regs); 281 show_regs(regs);
@@ -287,19 +286,28 @@ int is_valid_bugaddr(unsigned long addr)
287 return 1; 286 return 1;
288} 287}
289 288
290static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str, 289static inline void __user *get_psw_address(struct pt_regs *regs)
291 struct pt_regs *regs, siginfo_t *info)
292{ 290{
293 if (notify_die(DIE_TRAP, str, regs, pgm_int_code, 291 return (void __user *)
294 pgm_int_code, signr) == NOTIFY_STOP) 292 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
293}
294
295static void __kprobes do_trap(struct pt_regs *regs,
296 int si_signo, int si_code, char *str)
297{
298 siginfo_t info;
299
300 if (notify_die(DIE_TRAP, str, regs, 0,
301 regs->int_code, si_signo) == NOTIFY_STOP)
295 return; 302 return;
296 303
297 if (regs->psw.mask & PSW_MASK_PSTATE) { 304 if (regs->psw.mask & PSW_MASK_PSTATE) {
298 struct task_struct *tsk = current; 305 info.si_signo = si_signo;
299 306 info.si_errno = 0;
300 tsk->thread.trap_no = pgm_int_code & 0xffff; 307 info.si_code = si_code;
301 force_sig_info(signr, info, tsk); 308 info.si_addr = get_psw_address(regs);
302 report_user_fault(regs, pgm_int_code, signr); 309 force_sig_info(si_signo, &info, current);
310 report_user_fault(regs, si_signo);
303 } else { 311 } else {
304 const struct exception_table_entry *fixup; 312 const struct exception_table_entry *fixup;
305 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 313 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -311,18 +319,11 @@ static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
311 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); 319 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
312 if (btt == BUG_TRAP_TYPE_WARN) 320 if (btt == BUG_TRAP_TYPE_WARN)
313 return; 321 return;
314 die(str, regs, pgm_int_code); 322 die(regs, str);
315 } 323 }
316 } 324 }
317} 325}
318 326
319static inline void __user *get_psw_address(struct pt_regs *regs,
320 long pgm_int_code)
321{
322 return (void __user *)
323 ((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
324}
325
326void __kprobes do_per_trap(struct pt_regs *regs) 327void __kprobes do_per_trap(struct pt_regs *regs)
327{ 328{
328 siginfo_t info; 329 siginfo_t info;
@@ -339,26 +340,19 @@ void __kprobes do_per_trap(struct pt_regs *regs)
339 force_sig_info(SIGTRAP, &info, current); 340 force_sig_info(SIGTRAP, &info, current);
340} 341}
341 342
342static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, 343static void default_trap_handler(struct pt_regs *regs)
343 unsigned long trans_exc_code)
344{ 344{
345 if (regs->psw.mask & PSW_MASK_PSTATE) { 345 if (regs->psw.mask & PSW_MASK_PSTATE) {
346 report_user_fault(regs, pgm_int_code, SIGSEGV); 346 report_user_fault(regs, SIGSEGV);
347 do_exit(SIGSEGV); 347 do_exit(SIGSEGV);
348 } else 348 } else
349 die("Unknown program exception", regs, pgm_int_code); 349 die(regs, "Unknown program exception");
350} 350}
351 351
352#define DO_ERROR_INFO(name, signr, sicode, str) \ 352#define DO_ERROR_INFO(name, signr, sicode, str) \
353static void name(struct pt_regs *regs, long pgm_int_code, \ 353static void name(struct pt_regs *regs) \
354 unsigned long trans_exc_code) \
355{ \ 354{ \
356 siginfo_t info; \ 355 do_trap(regs, signr, sicode, str); \
357 info.si_signo = signr; \
358 info.si_errno = 0; \
359 info.si_code = sicode; \
360 info.si_addr = get_psw_address(regs, pgm_int_code); \
361 do_trap(pgm_int_code, signr, str, regs, &info); \
362} 356}
363 357
364DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, 358DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR,
@@ -388,42 +382,34 @@ DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
388DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, 382DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
389 "translation exception") 383 "translation exception")
390 384
391static inline void do_fp_trap(struct pt_regs *regs, void __user *location, 385static inline void do_fp_trap(struct pt_regs *regs, int fpc)
392 int fpc, long pgm_int_code)
393{ 386{
394 siginfo_t si; 387 int si_code = 0;
395
396 si.si_signo = SIGFPE;
397 si.si_errno = 0;
398 si.si_addr = location;
399 si.si_code = 0;
400 /* FPC[2] is Data Exception Code */ 388 /* FPC[2] is Data Exception Code */
401 if ((fpc & 0x00000300) == 0) { 389 if ((fpc & 0x00000300) == 0) {
402 /* bits 6 and 7 of DXC are 0 iff IEEE exception */ 390 /* bits 6 and 7 of DXC are 0 iff IEEE exception */
403 if (fpc & 0x8000) /* invalid fp operation */ 391 if (fpc & 0x8000) /* invalid fp operation */
404 si.si_code = FPE_FLTINV; 392 si_code = FPE_FLTINV;
405 else if (fpc & 0x4000) /* div by 0 */ 393 else if (fpc & 0x4000) /* div by 0 */
406 si.si_code = FPE_FLTDIV; 394 si_code = FPE_FLTDIV;
407 else if (fpc & 0x2000) /* overflow */ 395 else if (fpc & 0x2000) /* overflow */
408 si.si_code = FPE_FLTOVF; 396 si_code = FPE_FLTOVF;
409 else if (fpc & 0x1000) /* underflow */ 397 else if (fpc & 0x1000) /* underflow */
410 si.si_code = FPE_FLTUND; 398 si_code = FPE_FLTUND;
411 else if (fpc & 0x0800) /* inexact */ 399 else if (fpc & 0x0800) /* inexact */
412 si.si_code = FPE_FLTRES; 400 si_code = FPE_FLTRES;
413 } 401 }
414 do_trap(pgm_int_code, SIGFPE, 402 do_trap(regs, SIGFPE, si_code, "floating point exception");
415 "floating point exception", regs, &si);
416} 403}
417 404
418static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, 405static void __kprobes illegal_op(struct pt_regs *regs)
419 unsigned long trans_exc_code)
420{ 406{
421 siginfo_t info; 407 siginfo_t info;
422 __u8 opcode[6]; 408 __u8 opcode[6];
423 __u16 __user *location; 409 __u16 __user *location;
424 int signal = 0; 410 int signal = 0;
425 411
426 location = get_psw_address(regs, pgm_int_code); 412 location = get_psw_address(regs);
427 413
428 if (regs->psw.mask & PSW_MASK_PSTATE) { 414 if (regs->psw.mask & PSW_MASK_PSTATE) {
429 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 415 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -467,44 +453,31 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
467 * If we get an illegal op in kernel mode, send it through the 453 * If we get an illegal op in kernel mode, send it through the
468 * kprobes notifier. If kprobes doesn't pick it up, SIGILL 454 * kprobes notifier. If kprobes doesn't pick it up, SIGILL
469 */ 455 */
470 if (notify_die(DIE_BPT, "bpt", regs, pgm_int_code, 456 if (notify_die(DIE_BPT, "bpt", regs, 0,
471 3, SIGTRAP) != NOTIFY_STOP) 457 3, SIGTRAP) != NOTIFY_STOP)
472 signal = SIGILL; 458 signal = SIGILL;
473 } 459 }
474 460
475#ifdef CONFIG_MATHEMU 461#ifdef CONFIG_MATHEMU
476 if (signal == SIGFPE) 462 if (signal == SIGFPE)
477 do_fp_trap(regs, location, 463 do_fp_trap(regs, current->thread.fp_regs.fpc);
478 current->thread.fp_regs.fpc, pgm_int_code); 464 else if (signal == SIGSEGV)
479 else if (signal == SIGSEGV) { 465 do_trap(regs, signal, SEGV_MAPERR, "user address fault");
480 info.si_signo = signal; 466 else
481 info.si_errno = 0;
482 info.si_code = SEGV_MAPERR;
483 info.si_addr = (void __user *) location;
484 do_trap(pgm_int_code, signal,
485 "user address fault", regs, &info);
486 } else
487#endif 467#endif
488 if (signal) { 468 if (signal)
489 info.si_signo = signal; 469 do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
490 info.si_errno = 0;
491 info.si_code = ILL_ILLOPC;
492 info.si_addr = (void __user *) location;
493 do_trap(pgm_int_code, signal,
494 "illegal operation", regs, &info);
495 }
496} 470}
497 471
498 472
499#ifdef CONFIG_MATHEMU 473#ifdef CONFIG_MATHEMU
500void specification_exception(struct pt_regs *regs, long pgm_int_code, 474void specification_exception(struct pt_regs *regs)
501 unsigned long trans_exc_code)
502{ 475{
503 __u8 opcode[6]; 476 __u8 opcode[6];
504 __u16 __user *location = NULL; 477 __u16 __user *location = NULL;
505 int signal = 0; 478 int signal = 0;
506 479
507 location = (__u16 __user *) get_psw_address(regs, pgm_int_code); 480 location = (__u16 __user *) get_psw_address(regs);
508 481
509 if (regs->psw.mask & PSW_MASK_PSTATE) { 482 if (regs->psw.mask & PSW_MASK_PSTATE) {
510 get_user(*((__u16 *) opcode), location); 483 get_user(*((__u16 *) opcode), location);
@@ -539,30 +512,21 @@ void specification_exception(struct pt_regs *regs, long pgm_int_code,
539 signal = SIGILL; 512 signal = SIGILL;
540 513
541 if (signal == SIGFPE) 514 if (signal == SIGFPE)
542 do_fp_trap(regs, location, 515 do_fp_trap(regs, current->thread.fp_regs.fpc);
543 current->thread.fp_regs.fpc, pgm_int_code); 516 else if (signal)
544 else if (signal) { 517 do_trap(regs, signal, ILL_ILLOPN, "specification exception");
545 siginfo_t info;
546 info.si_signo = signal;
547 info.si_errno = 0;
548 info.si_code = ILL_ILLOPN;
549 info.si_addr = location;
550 do_trap(pgm_int_code, signal,
551 "specification exception", regs, &info);
552 }
553} 518}
554#else 519#else
555DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, 520DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
556 "specification exception"); 521 "specification exception");
557#endif 522#endif
558 523
559static void data_exception(struct pt_regs *regs, long pgm_int_code, 524static void data_exception(struct pt_regs *regs)
560 unsigned long trans_exc_code)
561{ 525{
562 __u16 __user *location; 526 __u16 __user *location;
563 int signal = 0; 527 int signal = 0;
564 528
565 location = get_psw_address(regs, pgm_int_code); 529 location = get_psw_address(regs);
566 530
567 if (MACHINE_HAS_IEEE) 531 if (MACHINE_HAS_IEEE)
568 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 532 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -627,32 +591,18 @@ static void data_exception(struct pt_regs *regs, long pgm_int_code,
627 else 591 else
628 signal = SIGILL; 592 signal = SIGILL;
629 if (signal == SIGFPE) 593 if (signal == SIGFPE)
630 do_fp_trap(regs, location, 594 do_fp_trap(regs, current->thread.fp_regs.fpc);
631 current->thread.fp_regs.fpc, pgm_int_code); 595 else if (signal)
632 else if (signal) { 596 do_trap(regs, signal, ILL_ILLOPN, "data exception");
633 siginfo_t info;
634 info.si_signo = signal;
635 info.si_errno = 0;
636 info.si_code = ILL_ILLOPN;
637 info.si_addr = location;
638 do_trap(pgm_int_code, signal, "data exception", regs, &info);
639 }
640} 597}
641 598
642static void space_switch_exception(struct pt_regs *regs, long pgm_int_code, 599static void space_switch_exception(struct pt_regs *regs)
643 unsigned long trans_exc_code)
644{ 600{
645 siginfo_t info;
646
647 /* Set user psw back to home space mode. */ 601 /* Set user psw back to home space mode. */
648 if (regs->psw.mask & PSW_MASK_PSTATE) 602 if (regs->psw.mask & PSW_MASK_PSTATE)
649 regs->psw.mask |= PSW_ASC_HOME; 603 regs->psw.mask |= PSW_ASC_HOME;
650 /* Send SIGILL. */ 604 /* Send SIGILL. */
651 info.si_signo = SIGILL; 605 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
652 info.si_errno = 0;
653 info.si_code = ILL_PRVOPC;
654 info.si_addr = get_psw_address(regs, pgm_int_code);
655 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
656} 606}
657 607
658void __kprobes kernel_stack_overflow(struct pt_regs * regs) 608void __kprobes kernel_stack_overflow(struct pt_regs * regs)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index a9a301866b3..354dd39073e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -125,8 +125,7 @@ static inline int user_space_fault(unsigned long trans_exc_code)
125 return trans_exc_code != 3; 125 return trans_exc_code != 3;
126} 126}
127 127
128static inline void report_user_fault(struct pt_regs *regs, long int_code, 128static inline void report_user_fault(struct pt_regs *regs, long signr)
129 int signr, unsigned long address)
130{ 129{
131 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 130 if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
132 return; 131 return;
@@ -134,10 +133,12 @@ static inline void report_user_fault(struct pt_regs *regs, long int_code,
134 return; 133 return;
135 if (!printk_ratelimit()) 134 if (!printk_ratelimit())
136 return; 135 return;
137 printk("User process fault: interruption code 0x%lX ", int_code); 136 printk(KERN_ALERT "User process fault: interruption code 0x%X ",
137 regs->int_code);
138 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); 138 print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
139 printk("\n"); 139 printk(KERN_CONT "\n");
140 printk("failing address: %lX\n", address); 140 printk(KERN_ALERT "failing address: %lX\n",
141 regs->int_parm_long & __FAIL_ADDR_MASK);
141 show_regs(regs); 142 show_regs(regs);
142} 143}
143 144
@@ -145,24 +146,18 @@ static inline void report_user_fault(struct pt_regs *regs, long int_code,
145 * Send SIGSEGV to task. This is an external routine 146 * Send SIGSEGV to task. This is an external routine
146 * to keep the stack usage of do_page_fault small. 147 * to keep the stack usage of do_page_fault small.
147 */ 148 */
148static noinline void do_sigsegv(struct pt_regs *regs, long int_code, 149static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
149 int si_code, unsigned long trans_exc_code)
150{ 150{
151 struct siginfo si; 151 struct siginfo si;
152 unsigned long address;
153 152
154 address = trans_exc_code & __FAIL_ADDR_MASK; 153 report_user_fault(regs, SIGSEGV);
155 current->thread.prot_addr = address;
156 current->thread.trap_no = int_code;
157 report_user_fault(regs, int_code, SIGSEGV, address);
158 si.si_signo = SIGSEGV; 154 si.si_signo = SIGSEGV;
159 si.si_code = si_code; 155 si.si_code = si_code;
160 si.si_addr = (void __user *) address; 156 si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
161 force_sig_info(SIGSEGV, &si, current); 157 force_sig_info(SIGSEGV, &si, current);
162} 158}
163 159
164static noinline void do_no_context(struct pt_regs *regs, long int_code, 160static noinline void do_no_context(struct pt_regs *regs)
165 unsigned long trans_exc_code)
166{ 161{
167 const struct exception_table_entry *fixup; 162 const struct exception_table_entry *fixup;
168 unsigned long address; 163 unsigned long address;
@@ -178,55 +173,48 @@ static noinline void do_no_context(struct pt_regs *regs, long int_code,
178 * Oops. The kernel tried to access some bad page. We'll have to 173 * Oops. The kernel tried to access some bad page. We'll have to
179 * terminate things with extreme prejudice. 174 * terminate things with extreme prejudice.
180 */ 175 */
181 address = trans_exc_code & __FAIL_ADDR_MASK; 176 address = regs->int_parm_long & __FAIL_ADDR_MASK;
182 if (!user_space_fault(trans_exc_code)) 177 if (!user_space_fault(regs->int_parm_long))
183 printk(KERN_ALERT "Unable to handle kernel pointer dereference" 178 printk(KERN_ALERT "Unable to handle kernel pointer dereference"
184 " at virtual kernel address %p\n", (void *)address); 179 " at virtual kernel address %p\n", (void *)address);
185 else 180 else
186 printk(KERN_ALERT "Unable to handle kernel paging request" 181 printk(KERN_ALERT "Unable to handle kernel paging request"
187 " at virtual user address %p\n", (void *)address); 182 " at virtual user address %p\n", (void *)address);
188 183
189 die("Oops", regs, int_code); 184 die(regs, "Oops");
190 do_exit(SIGKILL); 185 do_exit(SIGKILL);
191} 186}
192 187
193static noinline void do_low_address(struct pt_regs *regs, long int_code, 188static noinline void do_low_address(struct pt_regs *regs)
194 unsigned long trans_exc_code)
195{ 189{
196 /* Low-address protection hit in kernel mode means 190 /* Low-address protection hit in kernel mode means
197 NULL pointer write access in kernel mode. */ 191 NULL pointer write access in kernel mode. */
198 if (regs->psw.mask & PSW_MASK_PSTATE) { 192 if (regs->psw.mask & PSW_MASK_PSTATE) {
199 /* Low-address protection hit in user mode 'cannot happen'. */ 193 /* Low-address protection hit in user mode 'cannot happen'. */
200 die ("Low-address protection", regs, int_code); 194 die (regs, "Low-address protection");
201 do_exit(SIGKILL); 195 do_exit(SIGKILL);
202 } 196 }
203 197
204 do_no_context(regs, int_code, trans_exc_code); 198 do_no_context(regs);
205} 199}
206 200
207static noinline void do_sigbus(struct pt_regs *regs, long int_code, 201static noinline void do_sigbus(struct pt_regs *regs)
208 unsigned long trans_exc_code)
209{ 202{
210 struct task_struct *tsk = current; 203 struct task_struct *tsk = current;
211 unsigned long address;
212 struct siginfo si; 204 struct siginfo si;
213 205
214 /* 206 /*
215 * Send a sigbus, regardless of whether we were in kernel 207 * Send a sigbus, regardless of whether we were in kernel
216 * or user mode. 208 * or user mode.
217 */ 209 */
218 address = trans_exc_code & __FAIL_ADDR_MASK;
219 tsk->thread.prot_addr = address;
220 tsk->thread.trap_no = int_code;
221 si.si_signo = SIGBUS; 210 si.si_signo = SIGBUS;
222 si.si_errno = 0; 211 si.si_errno = 0;
223 si.si_code = BUS_ADRERR; 212 si.si_code = BUS_ADRERR;
224 si.si_addr = (void __user *) address; 213 si.si_addr = (void __user *)(regs->int_parm_long & __FAIL_ADDR_MASK);
225 force_sig_info(SIGBUS, &si, tsk); 214 force_sig_info(SIGBUS, &si, tsk);
226} 215}
227 216
228static noinline void do_fault_error(struct pt_regs *regs, long int_code, 217static noinline void do_fault_error(struct pt_regs *regs, int fault)
229 unsigned long trans_exc_code, int fault)
230{ 218{
231 int si_code; 219 int si_code;
232 220
@@ -238,24 +226,24 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
238 /* User mode accesses just cause a SIGSEGV */ 226 /* User mode accesses just cause a SIGSEGV */
239 si_code = (fault == VM_FAULT_BADMAP) ? 227 si_code = (fault == VM_FAULT_BADMAP) ?
240 SEGV_MAPERR : SEGV_ACCERR; 228 SEGV_MAPERR : SEGV_ACCERR;
241 do_sigsegv(regs, int_code, si_code, trans_exc_code); 229 do_sigsegv(regs, si_code);
242 return; 230 return;
243 } 231 }
244 case VM_FAULT_BADCONTEXT: 232 case VM_FAULT_BADCONTEXT:
245 do_no_context(regs, int_code, trans_exc_code); 233 do_no_context(regs);
246 break; 234 break;
247 default: /* fault & VM_FAULT_ERROR */ 235 default: /* fault & VM_FAULT_ERROR */
248 if (fault & VM_FAULT_OOM) { 236 if (fault & VM_FAULT_OOM) {
249 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 237 if (!(regs->psw.mask & PSW_MASK_PSTATE))
250 do_no_context(regs, int_code, trans_exc_code); 238 do_no_context(regs);
251 else 239 else
252 pagefault_out_of_memory(); 240 pagefault_out_of_memory();
253 } else if (fault & VM_FAULT_SIGBUS) { 241 } else if (fault & VM_FAULT_SIGBUS) {
254 /* Kernel mode? Handle exceptions or die */ 242 /* Kernel mode? Handle exceptions or die */
255 if (!(regs->psw.mask & PSW_MASK_PSTATE)) 243 if (!(regs->psw.mask & PSW_MASK_PSTATE))
256 do_no_context(regs, int_code, trans_exc_code); 244 do_no_context(regs);
257 else 245 else
258 do_sigbus(regs, int_code, trans_exc_code); 246 do_sigbus(regs);
259 } else 247 } else
260 BUG(); 248 BUG();
261 break; 249 break;
@@ -273,12 +261,12 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code,
273 * 11 Page translation -> Not present (nullification) 261 * 11 Page translation -> Not present (nullification)
274 * 3b Region third trans. -> Not present (nullification) 262 * 3b Region third trans. -> Not present (nullification)
275 */ 263 */
276static inline int do_exception(struct pt_regs *regs, int access, 264static inline int do_exception(struct pt_regs *regs, int access)
277 unsigned long trans_exc_code)
278{ 265{
279 struct task_struct *tsk; 266 struct task_struct *tsk;
280 struct mm_struct *mm; 267 struct mm_struct *mm;
281 struct vm_area_struct *vma; 268 struct vm_area_struct *vma;
269 unsigned long trans_exc_code;
282 unsigned long address; 270 unsigned long address;
283 unsigned int flags; 271 unsigned int flags;
284 int fault; 272 int fault;
@@ -288,6 +276,7 @@ static inline int do_exception(struct pt_regs *regs, int access,
288 276
289 tsk = current; 277 tsk = current;
290 mm = tsk->mm; 278 mm = tsk->mm;
279 trans_exc_code = regs->int_parm_long;
291 280
292 /* 281 /*
293 * Verify that the fault happened in user space, that 282 * Verify that the fault happened in user space, that
@@ -387,45 +376,46 @@ out:
387 return fault; 376 return fault;
388} 377}
389 378
390void __kprobes do_protection_exception(struct pt_regs *regs, long pgm_int_code, 379void __kprobes do_protection_exception(struct pt_regs *regs)
391 unsigned long trans_exc_code)
392{ 380{
381 unsigned long trans_exc_code;
393 int fault; 382 int fault;
394 383
384 trans_exc_code = regs->int_parm_long;
395 /* Protection exception is suppressing, decrement psw address. */ 385 /* Protection exception is suppressing, decrement psw address. */
396 regs->psw.addr = __rewind_psw(regs->psw, pgm_int_code >> 16); 386 regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16);
397 /* 387 /*
398 * Check for low-address protection. This needs to be treated 388 * Check for low-address protection. This needs to be treated
399 * as a special case because the translation exception code 389 * as a special case because the translation exception code
400 * field is not guaranteed to contain valid data in this case. 390 * field is not guaranteed to contain valid data in this case.
401 */ 391 */
402 if (unlikely(!(trans_exc_code & 4))) { 392 if (unlikely(!(trans_exc_code & 4))) {
403 do_low_address(regs, pgm_int_code, trans_exc_code); 393 do_low_address(regs);
404 return; 394 return;
405 } 395 }
406 fault = do_exception(regs, VM_WRITE, trans_exc_code); 396 fault = do_exception(regs, VM_WRITE);
407 if (unlikely(fault)) 397 if (unlikely(fault))
408 do_fault_error(regs, 4, trans_exc_code, fault); 398 do_fault_error(regs, fault);
409} 399}
410 400
411void __kprobes do_dat_exception(struct pt_regs *regs, long pgm_int_code, 401void __kprobes do_dat_exception(struct pt_regs *regs)
412 unsigned long trans_exc_code)
413{ 402{
414 int access, fault; 403 int access, fault;
415 404
416 access = VM_READ | VM_EXEC | VM_WRITE; 405 access = VM_READ | VM_EXEC | VM_WRITE;
417 fault = do_exception(regs, access, trans_exc_code); 406 fault = do_exception(regs, access);
418 if (unlikely(fault)) 407 if (unlikely(fault))
419 do_fault_error(regs, pgm_int_code & 255, trans_exc_code, fault); 408 do_fault_error(regs, fault);
420} 409}
421 410
422#ifdef CONFIG_64BIT 411#ifdef CONFIG_64BIT
423void __kprobes do_asce_exception(struct pt_regs *regs, long pgm_int_code, 412void __kprobes do_asce_exception(struct pt_regs *regs)
424 unsigned long trans_exc_code)
425{ 413{
426 struct mm_struct *mm = current->mm; 414 struct mm_struct *mm = current->mm;
427 struct vm_area_struct *vma; 415 struct vm_area_struct *vma;
416 unsigned long trans_exc_code;
428 417
418 trans_exc_code = regs->int_parm_long;
429 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) 419 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
430 goto no_context; 420 goto no_context;
431 421
@@ -440,12 +430,12 @@ void __kprobes do_asce_exception(struct pt_regs *regs, long pgm_int_code,
440 430
441 /* User mode accesses just cause a SIGSEGV */ 431 /* User mode accesses just cause a SIGSEGV */
442 if (regs->psw.mask & PSW_MASK_PSTATE) { 432 if (regs->psw.mask & PSW_MASK_PSTATE) {
443 do_sigsegv(regs, pgm_int_code, SEGV_MAPERR, trans_exc_code); 433 do_sigsegv(regs, SEGV_MAPERR);
444 return; 434 return;
445 } 435 }
446 436
447no_context: 437no_context:
448 do_no_context(regs, pgm_int_code, trans_exc_code); 438 do_no_context(regs);
449} 439}
450#endif 440#endif
451 441
@@ -459,14 +449,15 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
459 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; 449 regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
460 regs.psw.addr = (unsigned long) __builtin_return_address(0); 450 regs.psw.addr = (unsigned long) __builtin_return_address(0);
461 regs.psw.addr |= PSW_ADDR_AMODE; 451 regs.psw.addr |= PSW_ADDR_AMODE;
462 uaddr &= PAGE_MASK; 452 regs.int_code = pgm_int_code;
453 regs.int_parm_long = (uaddr & PAGE_MASK) | 2;
463 access = write ? VM_WRITE : VM_READ; 454 access = write ? VM_WRITE : VM_READ;
464 fault = do_exception(&regs, access, uaddr | 2); 455 fault = do_exception(&regs, access);
465 if (unlikely(fault)) { 456 if (unlikely(fault)) {
466 if (fault & VM_FAULT_OOM) 457 if (fault & VM_FAULT_OOM)
467 return -EFAULT; 458 return -EFAULT;
468 else if (fault & VM_FAULT_SIGBUS) 459 else if (fault & VM_FAULT_SIGBUS)
469 do_sigbus(&regs, pgm_int_code, uaddr); 460 do_sigbus(&regs);
470 } 461 }
471 return fault ? -EFAULT : 0; 462 return fault ? -EFAULT : 0;
472} 463}
@@ -509,7 +500,7 @@ int pfault_init(void)
509 .reserved = __PF_RES_FIELD }; 500 .reserved = __PF_RES_FIELD };
510 int rc; 501 int rc;
511 502
512 if (!MACHINE_IS_VM || pfault_disable) 503 if (pfault_disable)
513 return -1; 504 return -1;
514 asm volatile( 505 asm volatile(
515 " diag %1,%0,0x258\n" 506 " diag %1,%0,0x258\n"
@@ -530,7 +521,7 @@ void pfault_fini(void)
530 .refversn = 2, 521 .refversn = 2,
531 }; 522 };
532 523
533 if (!MACHINE_IS_VM || pfault_disable) 524 if (pfault_disable)
534 return; 525 return;
535 asm volatile( 526 asm volatile(
536 " diag %0,0,0x258\n" 527 " diag %0,0,0x258\n"
@@ -643,8 +634,6 @@ static int __init pfault_irq_init(void)
643{ 634{
644 int rc; 635 int rc;
645 636
646 if (!MACHINE_IS_VM)
647 return 0;
648 rc = register_external_interrupt(0x2603, pfault_interrupt); 637 rc = register_external_interrupt(0x2603, pfault_interrupt);
649 if (rc) 638 if (rc)
650 goto out_extint; 639 goto out_extint;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index d4b9fb4d004..5d633019d8f 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -93,18 +93,22 @@ static unsigned long setup_zero_pages(void)
93void __init paging_init(void) 93void __init paging_init(void)
94{ 94{
95 unsigned long max_zone_pfns[MAX_NR_ZONES]; 95 unsigned long max_zone_pfns[MAX_NR_ZONES];
96 unsigned long pgd_type; 96 unsigned long pgd_type, asce_bits;
97 97
98 init_mm.pgd = swapper_pg_dir; 98 init_mm.pgd = swapper_pg_dir;
99 S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
100#ifdef CONFIG_64BIT 99#ifdef CONFIG_64BIT
101 /* A three level page table (4TB) is enough for the kernel space. */ 100 if (VMALLOC_END > (1UL << 42)) {
102 S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH; 101 asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH;
103 pgd_type = _REGION3_ENTRY_EMPTY; 102 pgd_type = _REGION2_ENTRY_EMPTY;
103 } else {
104 asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
105 pgd_type = _REGION3_ENTRY_EMPTY;
106 }
104#else 107#else
105 S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH; 108 asce_bits = _ASCE_TABLE_LENGTH;
106 pgd_type = _SEGMENT_ENTRY_EMPTY; 109 pgd_type = _SEGMENT_ENTRY_EMPTY;
107#endif 110#endif
111 S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
108 clear_table((unsigned long *) init_mm.pgd, pgd_type, 112 clear_table((unsigned long *) init_mm.pgd, pgd_type,
109 sizeof(unsigned long)*2048); 113 sizeof(unsigned long)*2048);
110 vmem_map_init(); 114 vmem_map_init();
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 301c84d3b54..9a4d02f64f1 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -33,17 +33,6 @@
33#define FRAG_MASK 0x03 33#define FRAG_MASK 0x03
34#endif 34#endif
35 35
36unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE;
37EXPORT_SYMBOL(VMALLOC_START);
38
39static int __init parse_vmalloc(char *arg)
40{
41 if (!arg)
42 return -EINVAL;
43 VMALLOC_START = (VMALLOC_END - memparse(arg, &arg)) & PAGE_MASK;
44 return 0;
45}
46early_param("vmalloc", parse_vmalloc);
47 36
48unsigned long *crst_table_alloc(struct mm_struct *mm) 37unsigned long *crst_table_alloc(struct mm_struct *mm)
49{ 38{
@@ -267,7 +256,10 @@ static int gmap_alloc_table(struct gmap *gmap,
267 struct page *page; 256 struct page *page;
268 unsigned long *new; 257 unsigned long *new;
269 258
259 /* since we dont free the gmap table until gmap_free we can unlock */
260 spin_unlock(&gmap->mm->page_table_lock);
270 page = alloc_pages(GFP_KERNEL, ALLOC_ORDER); 261 page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
262 spin_lock(&gmap->mm->page_table_lock);
271 if (!page) 263 if (!page)
272 return -ENOMEM; 264 return -ENOMEM;
273 new = (unsigned long *) page_to_phys(page); 265 new = (unsigned long *) page_to_phys(page);
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index 8b0c9464aa9..3df65d39abc 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -4,6 +4,7 @@ config SCORE
4 def_bool y 4 def_bool y
5 select HAVE_GENERIC_HARDIRQS 5 select HAVE_GENERIC_HARDIRQS
6 select GENERIC_IRQ_SHOW 6 select GENERIC_IRQ_SHOW
7 select GENERIC_IOMAP
7 select HAVE_MEMBLOCK 8 select HAVE_MEMBLOCK
8 select HAVE_MEMBLOCK_NODE_MAP 9 select HAVE_MEMBLOCK_NODE_MAP
9 select ARCH_DISCARD_MEMBLOCK 10 select ARCH_DISCARD_MEMBLOCK
@@ -36,9 +37,6 @@ endmenu
36config CPU_SCORE7 37config CPU_SCORE7
37 bool 38 bool
38 39
39config GENERIC_IOMAP
40 def_bool y
41
42config NO_DMA 40config NO_DMA
43 bool 41 bool
44 default y 42 default y
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 47a2f1c2cb0..3c8db65c89e 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -85,9 +85,6 @@ config GENERIC_GPIO
85config GENERIC_CALIBRATE_DELAY 85config GENERIC_CALIBRATE_DELAY
86 bool 86 bool
87 87
88config GENERIC_IOMAP
89 bool
90
91config GENERIC_CLOCKEVENTS 88config GENERIC_CLOCKEVENTS
92 def_bool y 89 def_bool y
93 90
@@ -861,6 +858,7 @@ config PCI
861 bool "PCI support" 858 bool "PCI support"
862 depends on SYS_SUPPORTS_PCI 859 depends on SYS_SUPPORTS_PCI
863 select PCI_DOMAINS 860 select PCI_DOMAINS
861 select GENERIC_PCI_IOMAP
864 help 862 help
865 Find out whether you have a PCI motherboard. PCI is the name of a 863 Find out whether you have a PCI motherboard. PCI is the name of a
866 bus system, i.e. the way the CPU talks to the other stuff inside 864 bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index c2691afe8f7..11aaf2fdec8 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -393,29 +393,6 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
393 return (void __iomem *)(chan->io_map_base + port); 393 return (void __iomem *)(chan->io_map_base + port);
394} 394}
395 395
396void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
397{
398 resource_size_t start = pci_resource_start(dev, bar);
399 resource_size_t len = pci_resource_len(dev, bar);
400 unsigned long flags = pci_resource_flags(dev, bar);
401
402 if (unlikely(!len || !start))
403 return NULL;
404 if (maxlen && len > maxlen)
405 len = maxlen;
406
407 if (flags & IORESOURCE_IO)
408 return ioport_map_pci(dev, start, len);
409 if (flags & IORESOURCE_MEM) {
410 if (flags & IORESOURCE_CACHEABLE)
411 return ioremap(start, len);
412 return ioremap_nocache(start, len);
413 }
414
415 return NULL;
416}
417EXPORT_SYMBOL(pci_iomap);
418
419void pci_iounmap(struct pci_dev *dev, void __iomem *addr) 396void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
420{ 397{
421 iounmap(addr); 398 iounmap(addr);
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 1f51225426a..ae08cbbfa56 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,35 +15,78 @@
15#include <asm/cacheflush.h> 15#include <asm/cacheflush.h>
16#include <asm/io.h> 16#include <asm/io.h>
17 17
18/*
19 * The maximum number of pages we support up to when doing ranged dcache
20 * flushing. Anything exceeding this will simply flush the dcache in its
21 * entirety.
22 */
23#define MAX_OCACHE_PAGES 32
24#define MAX_ICACHE_PAGES 32
25
26static void sh2a_flush_oc_line(unsigned long v, int way)
27{
28 unsigned long addr = (v & 0x000007f0) | (way << 11);
29 unsigned long data;
30
31 data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr);
32 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) {
33 data &= ~SH_CACHE_UPDATED;
34 __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
35 }
36}
37
38static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
39{
40 /* Set associative bit to hit all ways */
41 unsigned long addr = (v & 0x000007f0) | SH_CACHE_ASSOC;
42 __raw_writel((addr & CACHE_PHYSADDR_MASK), cache_addr | addr);
43}
44
45/*
46 * Write back the dirty D-caches, but not invalidate them.
47 */
18static void sh2a__flush_wback_region(void *start, int size) 48static void sh2a__flush_wback_region(void *start, int size)
19{ 49{
50#ifdef CONFIG_CACHE_WRITEBACK
20 unsigned long v; 51 unsigned long v;
21 unsigned long begin, end; 52 unsigned long begin, end;
22 unsigned long flags; 53 unsigned long flags;
54 int nr_ways;
23 55
24 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 56 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
25 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 57 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
26 & ~(L1_CACHE_BYTES-1); 58 & ~(L1_CACHE_BYTES-1);
59 nr_ways = current_cpu_data.dcache.ways;
27 60
28 local_irq_save(flags); 61 local_irq_save(flags);
29 jump_to_uncached(); 62 jump_to_uncached();
30 63
31 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 64 /* If there are too many pages then flush the entire cache */
32 unsigned long addr = CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0); 65 if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
66 begin = CACHE_OC_ADDRESS_ARRAY;
67 end = begin + (nr_ways * current_cpu_data.dcache.way_size);
68
69 for (v = begin; v < end; v += L1_CACHE_BYTES) {
70 unsigned long data = __raw_readl(v);
71 if (data & SH_CACHE_UPDATED)
72 __raw_writel(data & ~SH_CACHE_UPDATED, v);
73 }
74 } else {
33 int way; 75 int way;
34 for (way = 0; way < 4; way++) { 76 for (way = 0; way < nr_ways; way++) {
35 unsigned long data = __raw_readl(addr | (way << 11)); 77 for (v = begin; v < end; v += L1_CACHE_BYTES)
36 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { 78 sh2a_flush_oc_line(v, way);
37 data &= ~SH_CACHE_UPDATED;
38 __raw_writel(data, addr | (way << 11));
39 }
40 } 79 }
41 } 80 }
42 81
43 back_to_cached(); 82 back_to_cached();
44 local_irq_restore(flags); 83 local_irq_restore(flags);
84#endif
45} 85}
46 86
87/*
88 * Write back the dirty D-caches and invalidate them.
89 */
47static void sh2a__flush_purge_region(void *start, int size) 90static void sh2a__flush_purge_region(void *start, int size)
48{ 91{
49 unsigned long v; 92 unsigned long v;
@@ -58,13 +101,22 @@ static void sh2a__flush_purge_region(void *start, int size)
58 jump_to_uncached(); 101 jump_to_uncached();
59 102
60 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 103 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
61 __raw_writel((v & CACHE_PHYSADDR_MASK), 104#ifdef CONFIG_CACHE_WRITEBACK
62 CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); 105 int way;
106 int nr_ways = current_cpu_data.dcache.ways;
107 for (way = 0; way < nr_ways; way++)
108 sh2a_flush_oc_line(v, way);
109#endif
110 sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
63 } 111 }
112
64 back_to_cached(); 113 back_to_cached();
65 local_irq_restore(flags); 114 local_irq_restore(flags);
66} 115}
67 116
117/*
118 * Invalidate the D-caches, but no write back please
119 */
68static void sh2a__flush_invalidate_region(void *start, int size) 120static void sh2a__flush_invalidate_region(void *start, int size)
69{ 121{
70 unsigned long v; 122 unsigned long v;
@@ -74,29 +126,25 @@ static void sh2a__flush_invalidate_region(void *start, int size)
74 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); 126 begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
75 end = ((unsigned long)start + size + L1_CACHE_BYTES-1) 127 end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
76 & ~(L1_CACHE_BYTES-1); 128 & ~(L1_CACHE_BYTES-1);
129
77 local_irq_save(flags); 130 local_irq_save(flags);
78 jump_to_uncached(); 131 jump_to_uncached();
79 132
80#ifdef CONFIG_CACHE_WRITEBACK 133 /* If there are too many pages then just blow the cache */
81 __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR); 134 if (((end - begin) >> PAGE_SHIFT) >= MAX_OCACHE_PAGES) {
82 /* I-cache invalidate */ 135 __raw_writel(__raw_readl(CCR) | CCR_OCACHE_INVALIDATE, CCR);
83 for (v = begin; v < end; v+=L1_CACHE_BYTES) { 136 } else {
84 __raw_writel((v & CACHE_PHYSADDR_MASK), 137 for (v = begin; v < end; v += L1_CACHE_BYTES)
85 CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008); 138 sh2a_invalidate_line(CACHE_OC_ADDRESS_ARRAY, v);
86 }
87#else
88 for (v = begin; v < end; v+=L1_CACHE_BYTES) {
89 __raw_writel((v & CACHE_PHYSADDR_MASK),
90 CACHE_IC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
91 __raw_writel((v & CACHE_PHYSADDR_MASK),
92 CACHE_OC_ADDRESS_ARRAY | (v & 0x000007f0) | 0x00000008);
93 } 139 }
94#endif 140
95 back_to_cached(); 141 back_to_cached();
96 local_irq_restore(flags); 142 local_irq_restore(flags);
97} 143}
98 144
99/* WBack O-Cache and flush I-Cache */ 145/*
146 * Write back the range of D-cache, and purge the I-cache.
147 */
100static void sh2a_flush_icache_range(void *args) 148static void sh2a_flush_icache_range(void *args)
101{ 149{
102 struct flusher_data *data = args; 150 struct flusher_data *data = args;
@@ -107,23 +155,20 @@ static void sh2a_flush_icache_range(void *args)
107 start = data->addr1 & ~(L1_CACHE_BYTES-1); 155 start = data->addr1 & ~(L1_CACHE_BYTES-1);
108 end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1); 156 end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
109 157
158#ifdef CONFIG_CACHE_WRITEBACK
159 sh2a__flush_wback_region((void *)start, end-start);
160#endif
161
110 local_irq_save(flags); 162 local_irq_save(flags);
111 jump_to_uncached(); 163 jump_to_uncached();
112 164
113 for (v = start; v < end; v+=L1_CACHE_BYTES) { 165 /* I-Cache invalidate */
114 unsigned long addr = (v & 0x000007f0); 166 /* If there are too many pages then just blow the cache */
115 int way; 167 if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
116 /* O-Cache writeback */ 168 __raw_writel(__raw_readl(CCR) | CCR_ICACHE_INVALIDATE, CCR);
117 for (way = 0; way < 4; way++) { 169 } else {
118 unsigned long data = __raw_readl(CACHE_OC_ADDRESS_ARRAY | addr | (way << 11)); 170 for (v = start; v < end; v += L1_CACHE_BYTES)
119 if ((data & CACHE_PHYSADDR_MASK) == (v & CACHE_PHYSADDR_MASK)) { 171 sh2a_invalidate_line(CACHE_IC_ADDRESS_ARRAY, v);
120 data &= ~SH_CACHE_UPDATED;
121 __raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr | (way << 11));
122 }
123 }
124 /* I-Cache invalidate */
125 __raw_writel(addr,
126 CACHE_IC_ADDRESS_ARRAY | addr | 0x00000008);
127 } 172 }
128 173
129 back_to_cached(); 174 back_to_cached();
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 70ae9d81870..96657992a72 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -28,9 +28,11 @@ config SPARC
28 select HAVE_GENERIC_HARDIRQS 28 select HAVE_GENERIC_HARDIRQS
29 select GENERIC_IRQ_SHOW 29 select GENERIC_IRQ_SHOW
30 select USE_GENERIC_SMP_HELPERS if SMP 30 select USE_GENERIC_SMP_HELPERS if SMP
31 select GENERIC_PCI_IOMAP
31 32
32config SPARC32 33config SPARC32
33 def_bool !64BIT 34 def_bool !64BIT
35 select GENERIC_ATOMIC64
34 36
35config SPARC64 37config SPARC64
36 def_bool 64BIT 38 def_bool 64BIT
@@ -383,9 +385,7 @@ config SCHED_MC
383 making when dealing with multi-core CPU chips at a cost of slightly 385 making when dealing with multi-core CPU chips at a cost of slightly
384 increased overhead in some places. If unsure say N here. 386 increased overhead in some places. If unsure say N here.
385 387
386if SPARC64
387source "kernel/Kconfig.preempt" 388source "kernel/Kconfig.preempt"
388endif
389 389
390config CMDLINE_BOOL 390config CMDLINE_BOOL
391 bool "Default bootloader kernel arguments" 391 bool "Default bootloader kernel arguments"
diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h
index 5c3c8b69884..9dd0a769fa1 100644
--- a/arch/sparc/include/asm/atomic_32.h
+++ b/arch/sparc/include/asm/atomic_32.h
@@ -13,7 +13,7 @@
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15 15
16#ifdef __KERNEL__ 16#include <asm-generic/atomic64.h>
17 17
18#include <asm/system.h> 18#include <asm/system.h>
19 19
@@ -52,112 +52,10 @@ extern void atomic_set(atomic_t *, int);
52#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) 52#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
53#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) 53#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
54 54
55
56/* This is the old 24-bit implementation. It's still used internally
57 * by some sparc-specific code, notably the semaphore implementation.
58 */
59typedef struct { volatile int counter; } atomic24_t;
60
61#ifndef CONFIG_SMP
62
63#define ATOMIC24_INIT(i) { (i) }
64#define atomic24_read(v) ((v)->counter)
65#define atomic24_set(v, i) (((v)->counter) = i)
66
67#else
68/* We do the bulk of the actual work out of line in two common
69 * routines in assembler, see arch/sparc/lib/atomic.S for the
70 * "fun" details.
71 *
72 * For SMP the trick is you embed the spin lock byte within
73 * the word, use the low byte so signedness is easily retained
74 * via a quick arithmetic shift. It looks like this:
75 *
76 * ----------------------------------------
77 * | signed 24-bit counter value | lock | atomic_t
78 * ----------------------------------------
79 * 31 8 7 0
80 */
81
82#define ATOMIC24_INIT(i) { ((i) << 8) }
83
84static inline int atomic24_read(const atomic24_t *v)
85{
86 int ret = v->counter;
87
88 while(ret & 0xff)
89 ret = v->counter;
90
91 return ret >> 8;
92}
93
94#define atomic24_set(v, i) (((v)->counter) = ((i) << 8))
95#endif
96
97static inline int __atomic24_add(int i, atomic24_t *v)
98{
99 register volatile int *ptr asm("g1");
100 register int increment asm("g2");
101 register int tmp1 asm("g3");
102 register int tmp2 asm("g4");
103 register int tmp3 asm("g7");
104
105 ptr = &v->counter;
106 increment = i;
107
108 __asm__ __volatile__(
109 "mov %%o7, %%g4\n\t"
110 "call ___atomic24_add\n\t"
111 " add %%o7, 8, %%o7\n"
112 : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
113 : "0" (increment), "r" (ptr)
114 : "memory", "cc");
115
116 return increment;
117}
118
119static inline int __atomic24_sub(int i, atomic24_t *v)
120{
121 register volatile int *ptr asm("g1");
122 register int increment asm("g2");
123 register int tmp1 asm("g3");
124 register int tmp2 asm("g4");
125 register int tmp3 asm("g7");
126
127 ptr = &v->counter;
128 increment = i;
129
130 __asm__ __volatile__(
131 "mov %%o7, %%g4\n\t"
132 "call ___atomic24_sub\n\t"
133 " add %%o7, 8, %%o7\n"
134 : "=&r" (increment), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
135 : "0" (increment), "r" (ptr)
136 : "memory", "cc");
137
138 return increment;
139}
140
141#define atomic24_add(i, v) ((void)__atomic24_add((i), (v)))
142#define atomic24_sub(i, v) ((void)__atomic24_sub((i), (v)))
143
144#define atomic24_dec_return(v) __atomic24_sub(1, (v))
145#define atomic24_inc_return(v) __atomic24_add(1, (v))
146
147#define atomic24_sub_and_test(i, v) (__atomic24_sub((i), (v)) == 0)
148#define atomic24_dec_and_test(v) (__atomic24_sub(1, (v)) == 0)
149
150#define atomic24_inc(v) ((void)__atomic24_add(1, (v)))
151#define atomic24_dec(v) ((void)__atomic24_sub(1, (v)))
152
153#define atomic24_add_negative(i, v) (__atomic24_add((i), (v)) < 0)
154
155/* Atomic operations are already serializing */ 55/* Atomic operations are already serializing */
156#define smp_mb__before_atomic_dec() barrier() 56#define smp_mb__before_atomic_dec() barrier()
157#define smp_mb__after_atomic_dec() barrier() 57#define smp_mb__after_atomic_dec() barrier()
158#define smp_mb__before_atomic_inc() barrier() 58#define smp_mb__before_atomic_inc() barrier()
159#define smp_mb__after_atomic_inc() barrier() 59#define smp_mb__after_atomic_inc() barrier()
160 60
161#endif /* !(__KERNEL__) */
162
163#endif /* !(__ARCH_SPARC_ATOMIC__) */ 61#endif /* !(__ARCH_SPARC_ATOMIC__) */
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index c2ced21c9dc..2006e5d359d 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -7,6 +7,7 @@
7 7
8#include <asm/page.h> /* IO address mapping routines need this */ 8#include <asm/page.h> /* IO address mapping routines need this */
9#include <asm/system.h> 9#include <asm/system.h>
10#include <asm-generic/pci_iomap.h>
10 11
11#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 12#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
12 13
@@ -324,7 +325,6 @@ extern void ioport_unmap(void __iomem *);
324 325
325/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 326/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
326struct pci_dev; 327struct pci_dev;
327extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
328extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 328extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
329 329
330/* 330/*
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 9c8965415f0..9481e5a6fa9 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -8,6 +8,7 @@
8#include <asm/page.h> /* IO address mapping routines need this */ 8#include <asm/page.h> /* IO address mapping routines need this */
9#include <asm/system.h> 9#include <asm/system.h>
10#include <asm/asi.h> 10#include <asm/asi.h>
11#include <asm-generic/pci_iomap.h>
11 12
12/* PC crapola... */ 13/* PC crapola... */
13#define __SLOW_DOWN_IO do { } while (0) 14#define __SLOW_DOWN_IO do { } while (0)
@@ -514,7 +515,6 @@ extern void ioport_unmap(void __iomem *);
514 515
515/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ 516/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
516struct pci_dev; 517struct pci_dev;
517extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
518extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 518extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
519 519
520static inline int sbus_can_dma_64bit(void) 520static inline int sbus_can_dma_64bit(void)
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index 156707b0f18..bb5c2ac4055 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -8,14 +8,10 @@
8#ifndef _SPARC_PAGE_H 8#ifndef _SPARC_PAGE_H
9#define _SPARC_PAGE_H 9#define _SPARC_PAGE_H
10 10
11#define PAGE_SHIFT 12 11#include <linux/const.h>
12 12
13#ifndef __ASSEMBLY__ 13#define PAGE_SHIFT 12
14/* I have my suspicions... -DaveM */ 14#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
15#define PAGE_SIZE (1UL << PAGE_SHIFT)
16#else
17#define PAGE_SIZE (1 << PAGE_SHIFT)
18#endif
19#define PAGE_MASK (~(PAGE_SIZE-1)) 15#define PAGE_MASK (~(PAGE_SIZE-1))
20 16
21#include <asm/btfixup.h> 17#include <asm/btfixup.h>
diff --git a/arch/sparc/include/asm/pgtsun4.h b/arch/sparc/include/asm/pgtsun4.h
deleted file mode 100644
index 5a0d661fb82..00000000000
--- a/arch/sparc/include/asm/pgtsun4.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * pgtsun4.h: Sun4 specific pgtable.h defines and code.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 */
7#ifndef _SPARC_PGTSUN4C_H
8#define _SPARC_PGTSUN4C_H
9
10#include <asm/contregs.h>
11
12/* PMD_SHIFT determines the size of the area a second-level page table can map */
13#define SUN4C_PMD_SHIFT 23
14
15/* PGDIR_SHIFT determines what a third-level page table entry can map */
16#define SUN4C_PGDIR_SHIFT 23
17#define SUN4C_PGDIR_SIZE (1UL << SUN4C_PGDIR_SHIFT)
18#define SUN4C_PGDIR_MASK (~(SUN4C_PGDIR_SIZE-1))
19#define SUN4C_PGDIR_ALIGN(addr) (((addr)+SUN4C_PGDIR_SIZE-1)&SUN4C_PGDIR_MASK)
20
21/* To represent how the sun4c mmu really lays things out. */
22#define SUN4C_REAL_PGDIR_SHIFT 18
23#define SUN4C_REAL_PGDIR_SIZE (1UL << SUN4C_REAL_PGDIR_SHIFT)
24#define SUN4C_REAL_PGDIR_MASK (~(SUN4C_REAL_PGDIR_SIZE-1))
25#define SUN4C_REAL_PGDIR_ALIGN(addr) (((addr)+SUN4C_REAL_PGDIR_SIZE-1)&SUN4C_REAL_PGDIR_MASK)
26
27/* 19 bit PFN on sun4 */
28#define SUN4C_PFN_MASK 0x7ffff
29
30/* Don't increase these unless the structures in sun4c.c are fixed */
31#define SUN4C_MAX_SEGMAPS 256
32#define SUN4C_MAX_CONTEXTS 16
33
34/*
35 * To be efficient, and not have to worry about allocating such
36 * a huge pgd, we make the kernel sun4c tables each hold 1024
37 * entries and the pgd similarly just like the i386 tables.
38 */
39#define SUN4C_PTRS_PER_PTE 1024
40#define SUN4C_PTRS_PER_PMD 1
41#define SUN4C_PTRS_PER_PGD 1024
42
43/*
44 * Sparc SUN4C pte fields.
45 */
46#define _SUN4C_PAGE_VALID 0x80000000
47#define _SUN4C_PAGE_SILENT_READ 0x80000000 /* synonym */
48#define _SUN4C_PAGE_DIRTY 0x40000000
49#define _SUN4C_PAGE_SILENT_WRITE 0x40000000 /* synonym */
50#define _SUN4C_PAGE_PRIV 0x20000000 /* privileged page */
51#define _SUN4C_PAGE_NOCACHE 0x10000000 /* non-cacheable page */
52#define _SUN4C_PAGE_PRESENT 0x08000000 /* implemented in software */
53#define _SUN4C_PAGE_IO 0x04000000 /* I/O page */
54#define _SUN4C_PAGE_FILE 0x02000000 /* implemented in software */
55#define _SUN4C_PAGE_READ 0x00800000 /* implemented in software */
56#define _SUN4C_PAGE_WRITE 0x00400000 /* implemented in software */
57#define _SUN4C_PAGE_ACCESSED 0x00200000 /* implemented in software */
58#define _SUN4C_PAGE_MODIFIED 0x00100000 /* implemented in software */
59
60#define _SUN4C_READABLE (_SUN4C_PAGE_READ|_SUN4C_PAGE_SILENT_READ|\
61 _SUN4C_PAGE_ACCESSED)
62#define _SUN4C_WRITEABLE (_SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE|\
63 _SUN4C_PAGE_MODIFIED)
64
65#define _SUN4C_PAGE_CHG_MASK (0xffff|_SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_MODIFIED)
66
67#define SUN4C_PAGE_NONE __pgprot(_SUN4C_PAGE_PRESENT)
68#define SUN4C_PAGE_SHARED __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE|\
69 _SUN4C_PAGE_WRITE)
70#define SUN4C_PAGE_COPY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE)
71#define SUN4C_PAGE_READONLY __pgprot(_SUN4C_PAGE_PRESENT|_SUN4C_READABLE)
72#define SUN4C_PAGE_KERNEL __pgprot(_SUN4C_READABLE|_SUN4C_WRITEABLE|\
73 _SUN4C_PAGE_DIRTY|_SUN4C_PAGE_PRIV)
74
75/* SUN4C swap entry encoding
76 *
77 * We use 5 bits for the type and 19 for the offset. This gives us
78 * 32 swapfiles of 4GB each. Encoding looks like:
79 *
80 * RRRRRRRRooooooooooooooooooottttt
81 * fedcba9876543210fedcba9876543210
82 *
83 * The top 8 bits are reserved for protection and status bits, especially
84 * FILE and PRESENT.
85 */
86#define SUN4C_SWP_TYPE_MASK 0x1f
87#define SUN4C_SWP_OFF_MASK 0x7ffff
88#define SUN4C_SWP_OFF_SHIFT 5
89
90#ifndef __ASSEMBLY__
91
92static inline unsigned long sun4c_get_synchronous_error(void)
93{
94 unsigned long sync_err;
95
96 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
97 "=r" (sync_err) :
98 "r" (AC_SYNC_ERR), "i" (ASI_CONTROL));
99 return sync_err;
100}
101
102static inline unsigned long sun4c_get_synchronous_address(void)
103{
104 unsigned long sync_addr;
105
106 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
107 "=r" (sync_addr) :
108 "r" (AC_SYNC_VA), "i" (ASI_CONTROL));
109 return sync_addr;
110}
111
112/* SUN4 pte, segmap, and context manipulation */
113static inline unsigned long sun4c_get_segmap(unsigned long addr)
114{
115 register unsigned long entry;
116
117 __asm__ __volatile__("\n\tlduha [%1] %2, %0\n\t" :
118 "=r" (entry) :
119 "r" (addr), "i" (ASI_SEGMAP));
120 return entry;
121}
122
123static inline void sun4c_put_segmap(unsigned long addr, unsigned long entry)
124{
125 __asm__ __volatile__("\n\tstha %1, [%0] %2; nop; nop; nop;\n\t" : :
126 "r" (addr), "r" (entry),
127 "i" (ASI_SEGMAP)
128 : "memory");
129}
130
131static inline unsigned long sun4c_get_pte(unsigned long addr)
132{
133 register unsigned long entry;
134
135 __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" :
136 "=r" (entry) :
137 "r" (addr), "i" (ASI_PTE));
138 return entry;
139}
140
141static inline void sun4c_put_pte(unsigned long addr, unsigned long entry)
142{
143 __asm__ __volatile__("\n\tsta %1, [%0] %2; nop; nop; nop;\n\t" : :
144 "r" (addr),
145 "r" ((entry & ~(_SUN4C_PAGE_PRESENT))), "i" (ASI_PTE)
146 : "memory");
147}
148
149static inline int sun4c_get_context(void)
150{
151 register int ctx;
152
153 __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
154 "=r" (ctx) :
155 "r" (AC_CONTEXT), "i" (ASI_CONTROL));
156
157 return ctx;
158}
159
160static inline int sun4c_set_context(int ctx)
161{
162 __asm__ __volatile__("\n\tstba %0, [%1] %2; nop; nop; nop;\n\t" : :
163 "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL)
164 : "memory");
165
166 return ctx;
167}
168
169#endif /* !(__ASSEMBLY__) */
170
171#endif /* !(_SPARC_PGTSUN4_H) */
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h
index e49b828a247..aa42fe30d5b 100644
--- a/arch/sparc/include/asm/signal.h
+++ b/arch/sparc/include/asm/signal.h
@@ -143,10 +143,11 @@ struct sigstack {
143#define SA_ONSTACK _SV_SSTACK 143#define SA_ONSTACK _SV_SSTACK
144#define SA_RESTART _SV_INTR 144#define SA_RESTART _SV_INTR
145#define SA_ONESHOT _SV_RESET 145#define SA_ONESHOT _SV_RESET
146#define SA_NOMASK 0x20u 146#define SA_NODEFER 0x20u
147#define SA_NOCLDWAIT 0x100u 147#define SA_NOCLDWAIT 0x100u
148#define SA_SIGINFO 0x200u 148#define SA_SIGINFO 0x200u
149 149
150#define SA_NOMASK SA_NODEFER
150 151
151#define SIG_BLOCK 0x01 /* for blocking signals */ 152#define SIG_BLOCK 0x01 /* for blocking signals */
152#define SIG_UNBLOCK 0x02 /* for unblocking signals */ 153#define SIG_UNBLOCK 0x02 /* for unblocking signals */
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 5cc5888ad5a..c2a1080cdd3 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -95,7 +95,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
95 * Observe the order of get_free_pages() in alloc_thread_info_node(). 95 * Observe the order of get_free_pages() in alloc_thread_info_node().
96 * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste. 96 * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
97 */ 97 */
98#define THREAD_SIZE 8192 98#define THREAD_SIZE (2 * PAGE_SIZE)
99 99
100/* 100/*
101 * Offsets in thread_info structure, used in assembly code 101 * Offsets in thread_info structure, used in assembly code
diff --git a/arch/sparc/lib/atomic_32.S b/arch/sparc/lib/atomic_32.S
index 178cbb8ae1b..eb6c7359cbd 100644
--- a/arch/sparc/lib/atomic_32.S
+++ b/arch/sparc/lib/atomic_32.S
@@ -40,60 +40,5 @@ ___xchg32_sun4md:
40 mov %g4, %o7 40 mov %g4, %o7
41#endif 41#endif
42 42
43 /* Read asm-sparc/atomic.h carefully to understand how this works for SMP.
44 * Really, some things here for SMP are overly clever, go read the header.
45 */
46 .globl ___atomic24_add
47___atomic24_add:
48 rd %psr, %g3 ! Keep the code small, old way was stupid
49 nop; nop; nop; ! Let the bits set
50 or %g3, PSR_PIL, %g7 ! Disable interrupts
51 wr %g7, 0x0, %psr ! Set %psr
52 nop; nop; nop; ! Let the bits set
53#ifdef CONFIG_SMP
541: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
55 orcc %g7, 0x0, %g0 ! Did we get it?
56 bne 1b ! Nope...
57 ld [%g1], %g7 ! Load locked atomic24_t
58 sra %g7, 8, %g7 ! Get signed 24-bit integer
59 add %g7, %g2, %g2 ! Add in argument
60 sll %g2, 8, %g7 ! Transpose back to atomic24_t
61 st %g7, [%g1] ! Clever: This releases the lock as well.
62#else
63 ld [%g1], %g7 ! Load locked atomic24_t
64 add %g7, %g2, %g2 ! Add in argument
65 st %g2, [%g1] ! Store it back
66#endif
67 wr %g3, 0x0, %psr ! Restore original PSR_PIL
68 nop; nop; nop; ! Let the bits set
69 jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
70 mov %g4, %o7 ! Restore %o7
71
72 .globl ___atomic24_sub
73___atomic24_sub:
74 rd %psr, %g3 ! Keep the code small, old way was stupid
75 nop; nop; nop; ! Let the bits set
76 or %g3, PSR_PIL, %g7 ! Disable interrupts
77 wr %g7, 0x0, %psr ! Set %psr
78 nop; nop; nop; ! Let the bits set
79#ifdef CONFIG_SMP
801: ldstub [%g1 + 3], %g7 ! Spin on the byte lock for SMP.
81 orcc %g7, 0x0, %g0 ! Did we get it?
82 bne 1b ! Nope...
83 ld [%g1], %g7 ! Load locked atomic24_t
84 sra %g7, 8, %g7 ! Get signed 24-bit integer
85 sub %g7, %g2, %g2 ! Subtract argument
86 sll %g2, 8, %g7 ! Transpose back to atomic24_t
87 st %g7, [%g1] ! Clever: This releases the lock as well
88#else
89 ld [%g1], %g7 ! Load locked atomic24_t
90 sub %g7, %g2, %g2 ! Subtract argument
91 st %g2, [%g1] ! Store it back
92#endif
93 wr %g3, 0x0, %psr ! Restore original PSR_PIL
94 nop; nop; nop; ! Let the bits set
95 jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h
96 mov %g4, %o7 ! Restore %o7
97
98 .globl __atomic_end 43 .globl __atomic_end
99__atomic_end: 44__atomic_end:
diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c
index 9ef37e13a92..c4d42a50ebc 100644
--- a/arch/sparc/lib/iomap.c
+++ b/arch/sparc/lib/iomap.c
@@ -18,31 +18,8 @@ void ioport_unmap(void __iomem *addr)
18EXPORT_SYMBOL(ioport_map); 18EXPORT_SYMBOL(ioport_map);
19EXPORT_SYMBOL(ioport_unmap); 19EXPORT_SYMBOL(ioport_unmap);
20 20
21/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
22void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
23{
24 resource_size_t start = pci_resource_start(dev, bar);
25 resource_size_t len = pci_resource_len(dev, bar);
26 unsigned long flags = pci_resource_flags(dev, bar);
27
28 if (!len || !start)
29 return NULL;
30 if (maxlen && len > maxlen)
31 len = maxlen;
32 if (flags & IORESOURCE_IO)
33 return ioport_map(start, len);
34 if (flags & IORESOURCE_MEM) {
35 if (flags & IORESOURCE_CACHEABLE)
36 return ioremap(start, len);
37 return ioremap_nocache(start, len);
38 }
39 /* What? */
40 return NULL;
41}
42
43void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 21void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
44{ 22{
45 /* nothing to do */ 23 /* nothing to do */
46} 24}
47EXPORT_SYMBOL(pci_iomap);
48EXPORT_SYMBOL(pci_iounmap); 25EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
index 1b30bb3bfdb..f73c2240fe6 100644
--- a/arch/sparc/lib/ksyms.c
+++ b/arch/sparc/lib/ksyms.c
@@ -62,8 +62,6 @@ extern void ___rw_read_enter(void);
62extern void ___rw_read_try(void); 62extern void ___rw_read_try(void);
63extern void ___rw_read_exit(void); 63extern void ___rw_read_exit(void);
64extern void ___rw_write_enter(void); 64extern void ___rw_write_enter(void);
65extern void ___atomic24_add(void);
66extern void ___atomic24_sub(void);
67 65
68/* Alias functions whose names begin with "." and export the aliases. 66/* Alias functions whose names begin with "." and export the aliases.
69 * The module references will be fixed up by module_frob_arch_sections. 67 * The module references will be fixed up by module_frob_arch_sections.
@@ -97,10 +95,6 @@ EXPORT_SYMBOL(___rw_read_exit);
97EXPORT_SYMBOL(___rw_write_enter); 95EXPORT_SYMBOL(___rw_write_enter);
98#endif 96#endif
99 97
100/* Atomic operations. */
101EXPORT_SYMBOL(___atomic24_add);
102EXPORT_SYMBOL(___atomic24_sub);
103
104EXPORT_SYMBOL(__ashrdi3); 98EXPORT_SYMBOL(__ashrdi3);
105EXPORT_SYMBOL(__ashldi3); 99EXPORT_SYMBOL(__ashldi3);
106EXPORT_SYMBOL(__lshrdi3); 100EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 70a0de46cd1..11270ca22c0 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -321,6 +321,7 @@ config PCI
321 bool "PCI support" 321 bool "PCI support"
322 default y 322 default y
323 select PCI_DOMAINS 323 select PCI_DOMAINS
324 select GENERIC_PCI_IOMAP
324 ---help--- 325 ---help---
325 Enable PCI root complex support, so PCIe endpoint devices can 326 Enable PCI root complex support, so PCIe endpoint devices can
326 be attached to the Tile chip. Many, but not all, PCI devices 327 be attached to the Tile chip. Many, but not all, PCI devices
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index c9ea1652af0..d2152deb1f3 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -204,7 +204,8 @@ static inline long ioport_panic(void)
204 204
205static inline void __iomem *ioport_map(unsigned long port, unsigned int len) 205static inline void __iomem *ioport_map(unsigned long port, unsigned int len)
206{ 206{
207 return (void __iomem *) ioport_panic(); 207 pr_info("ioport_map: mapping IO resources is unsupported on tile.\n");
208 return NULL;
208} 209}
209 210
210static inline void ioport_unmap(void __iomem *addr) 211static inline void ioport_unmap(void __iomem *addr)
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index 7f03cefed1b..1d25fea42e5 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -16,6 +16,7 @@
16#define _ASM_TILE_PCI_H 16#define _ASM_TILE_PCI_H
17 17
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <asm-generic/pci_iomap.h>
19 20
20/* 21/*
21 * Structure of a PCI controller (host bridge) 22 * Structure of a PCI controller (host bridge)
@@ -49,7 +50,6 @@ struct pci_controller {
49int __devinit tile_pci_init(void); 50int __devinit tile_pci_init(void);
50int __devinit pcibios_init(void); 51int __devinit pcibios_init(void);
51 52
52void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
53static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} 53static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
54 54
55void __devinit pcibios_fixup_bus(struct pci_bus *bus); 55void __devinit pcibios_fixup_bus(struct pci_bus *bus);
diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c
index 9d610d3fb11..25567934a21 100644
--- a/arch/tile/kernel/pci.c
+++ b/arch/tile/kernel/pci.c
@@ -466,27 +466,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
466 return 0; 466 return 0;
467} 467}
468 468
469void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
470{
471 unsigned long start = pci_resource_start(dev, bar);
472 unsigned long len = pci_resource_len(dev, bar);
473 unsigned long flags = pci_resource_flags(dev, bar);
474
475 if (!len)
476 return NULL;
477 if (max && len > max)
478 len = max;
479
480 if (!(flags & IORESOURCE_MEM)) {
481 pr_info("PCI: Trying to map invalid resource %#lx\n", flags);
482 start = 0;
483 }
484
485 return (void __iomem *)start;
486}
487EXPORT_SYMBOL(pci_iomap);
488
489
490/**************************************************************** 469/****************************************************************
491 * 470 *
492 * Tile PCI config space read/write routines 471 * Tile PCI config space read/write routines
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 942ed6174f1..eeb8054c7cd 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -12,6 +12,7 @@ config UNICORE32
12 select GENERIC_IRQ_PROBE 12 select GENERIC_IRQ_PROBE
13 select GENERIC_IRQ_SHOW 13 select GENERIC_IRQ_SHOW
14 select ARCH_WANT_FRAME_POINTERS 14 select ARCH_WANT_FRAME_POINTERS
15 select GENERIC_IOMAP
15 help 16 help
16 UniCore-32 is 32-bit Instruction Set Architecture, 17 UniCore-32 is 32-bit Instruction Set Architecture,
17 including a series of low-power-consumption RISC chip 18 including a series of low-power-consumption RISC chip
@@ -30,9 +31,6 @@ config GENERIC_CLOCKEVENTS
30config GENERIC_CSUM 31config GENERIC_CSUM
31 def_bool y 32 def_bool y
32 33
33config GENERIC_IOMAP
34 def_bool y
35
36config NO_IOPORT 34config NO_IOPORT
37 bool 35 bool
38 36
diff --git a/arch/unicore32/include/asm/io.h b/arch/unicore32/include/asm/io.h
index 1a5c5a5eb39..adddf6d6407 100644
--- a/arch/unicore32/include/asm/io.h
+++ b/arch/unicore32/include/asm/io.h
@@ -37,15 +37,9 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
37 */ 37 */
38#define ioremap(cookie, size) __uc32_ioremap(cookie, size) 38#define ioremap(cookie, size) __uc32_ioremap(cookie, size)
39#define ioremap_cached(cookie, size) __uc32_ioremap_cached(cookie, size) 39#define ioremap_cached(cookie, size) __uc32_ioremap_cached(cookie, size)
40#define ioremap_nocache(cookie, size) __uc32_ioremap(cookie, size)
40#define iounmap(cookie) __uc32_iounmap(cookie) 41#define iounmap(cookie) __uc32_iounmap(cookie)
41 42
42/*
43 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
44 * access
45 */
46#undef xlate_dev_mem_ptr
47#define xlate_dev_mem_ptr(p) __va(p)
48
49#define HAVE_ARCH_PIO_SIZE 43#define HAVE_ARCH_PIO_SIZE
50#define PIO_OFFSET (unsigned int)(PCI_IOBASE) 44#define PIO_OFFSET (unsigned int)(PCI_IOBASE)
51#define PIO_MASK (unsigned int)(IO_SPACE_LIMIT) 45#define PIO_MASK (unsigned int)(IO_SPACE_LIMIT)
diff --git a/arch/unicore32/kernel/puv3-nb0916.c b/arch/unicore32/kernel/puv3-nb0916.c
index 37b12a06b49..181108b8ecc 100644
--- a/arch/unicore32/kernel/puv3-nb0916.c
+++ b/arch/unicore32/kernel/puv3-nb0916.c
@@ -123,7 +123,7 @@ int __init mach_nb0916_init(void)
123 123
124 if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF), 124 if (request_irq(gpio_to_irq(GPI_LCD_CASE_OFF),
125 &nb0916_lcdcaseoff_handler, 125 &nb0916_lcdcaseoff_handler,
126 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 126 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
127 "NB0916 lcd case off", NULL) < 0) { 127 "NB0916 lcd case off", NULL) < 0) {
128 128
129 printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n", 129 printk(KERN_DEBUG "LCD-Case-OFF IRQ %d not available\n",
@@ -131,7 +131,7 @@ int __init mach_nb0916_init(void)
131 } 131 }
132 132
133 if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler, 133 if (request_irq(gpio_to_irq(GPI_OTP_INT), &nb0916_overheat_handler,
134 IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 134 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
135 "NB0916 overheating protection", NULL) < 0) { 135 "NB0916 overheating protection", NULL) < 0) {
136 136
137 printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n", 137 printk(KERN_DEBUG "Overheating Protection IRQ %d not available\n",
diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c
index 673d7a89d8f..87adbf5ebfe 100644
--- a/arch/unicore32/kernel/setup.c
+++ b/arch/unicore32/kernel/setup.c
@@ -65,7 +65,7 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
65 */ 65 */
66static struct resource mem_res[] = { 66static struct resource mem_res[] = {
67 { 67 {
68 .name = "Kernel text", 68 .name = "Kernel code",
69 .start = 0, 69 .start = 0,
70 .end = 0, 70 .end = 0,
71 .flags = IORESOURCE_MEM 71 .flags = IORESOURCE_MEM
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index b163fca5678..911b549a6df 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -63,10 +63,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
63 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); 63 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
64 if (err == 0) { 64 if (err == 0) {
65 sigdelsetmask(&set, ~_BLOCKABLE); 65 sigdelsetmask(&set, ~_BLOCKABLE);
66 spin_lock_irq(&current->sighand->siglock); 66 set_current_blocked(&set);
67 current->blocked = set;
68 recalc_sigpending();
69 spin_unlock_irq(&current->sighand->siglock);
70 } 67 }
71 68
72 err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00); 69 err |= __get_user(regs->UCreg_00, &sf->uc.uc_mcontext.regs.UCreg_00);
@@ -321,6 +318,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
321{ 318{
322 struct thread_info *thread = current_thread_info(); 319 struct thread_info *thread = current_thread_info();
323 struct task_struct *tsk = current; 320 struct task_struct *tsk = current;
321 sigset_t blocked;
324 int usig = sig; 322 int usig = sig;
325 int ret; 323 int ret;
326 324
@@ -372,13 +370,10 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
372 /* 370 /*
373 * Block the signal if we were successful. 371 * Block the signal if we were successful.
374 */ 372 */
375 spin_lock_irq(&tsk->sighand->siglock); 373 sigorsets(&blocked, &tsk->blocked, &ka->sa.sa_mask);
376 sigorsets(&tsk->blocked, &tsk->blocked,
377 &ka->sa.sa_mask);
378 if (!(ka->sa.sa_flags & SA_NODEFER)) 374 if (!(ka->sa.sa_flags & SA_NODEFER))
379 sigaddset(&tsk->blocked, sig); 375 sigaddset(&blocked, sig);
380 recalc_sigpending(); 376 set_current_blocked(&blocked);
381 spin_unlock_irq(&tsk->sighand->siglock);
382 377
383 return 0; 378 return 0;
384} 379}
diff --git a/arch/unicore32/kernel/time.c b/arch/unicore32/kernel/time.c
index 080710c0924..d3824b2ff64 100644
--- a/arch/unicore32/kernel/time.c
+++ b/arch/unicore32/kernel/time.c
@@ -86,7 +86,7 @@ static struct clocksource cksrc_puv3_oscr = {
86 86
87static struct irqaction puv3_timer_irq = { 87static struct irqaction puv3_timer_irq = {
88 .name = "ost0", 88 .name = "ost0",
89 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 89 .flags = IRQF_TIMER | IRQF_IRQPOLL,
90 .handler = puv3_ost0_interrupt, 90 .handler = puv3_ost0_interrupt,
91 .dev_id = &ckevt_puv3_osmr0, 91 .dev_id = &ckevt_puv3_osmr0,
92}; 92};
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1d2a69dd36d..1a31254ceb8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -62,6 +62,7 @@ config X86
62 select ANON_INODES 62 select ANON_INODES
63 select HAVE_ARCH_KMEMCHECK 63 select HAVE_ARCH_KMEMCHECK
64 select HAVE_USER_RETURN_NOTIFIER 64 select HAVE_USER_RETURN_NOTIFIER
65 select ARCH_BINFMT_ELF_RANDOMIZE_PIE
65 select HAVE_ARCH_JUMP_LABEL 66 select HAVE_ARCH_JUMP_LABEL
66 select HAVE_TEXT_POKE_SMP 67 select HAVE_TEXT_POKE_SMP
67 select HAVE_GENERIC_HARDIRQS 68 select HAVE_GENERIC_HARDIRQS
@@ -77,6 +78,7 @@ config X86
77 select HAVE_BPF_JIT if (X86_64 && NET) 78 select HAVE_BPF_JIT if (X86_64 && NET)
78 select CLKEVT_I8253 79 select CLKEVT_I8253
79 select ARCH_HAVE_NMI_SAFE_CMPXCHG 80 select ARCH_HAVE_NMI_SAFE_CMPXCHG
81 select GENERIC_IOMAP
80 82
81config INSTRUCTION_DECODER 83config INSTRUCTION_DECODER
82 def_bool (KPROBES || PERF_EVENTS) 84 def_bool (KPROBES || PERF_EVENTS)
@@ -142,9 +144,6 @@ config NEED_SG_DMA_LENGTH
142config GENERIC_ISA_DMA 144config GENERIC_ISA_DMA
143 def_bool ISA_DMA_API 145 def_bool ISA_DMA_API
144 146
145config GENERIC_IOMAP
146 def_bool y
147
148config GENERIC_BUG 147config GENERIC_BUG
149 def_bool y 148 def_bool y
150 depends on BUG 149 depends on BUG
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index f3444f700f3..17c5d4bdee5 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -197,7 +197,10 @@
197 197
198/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ 198/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
199#define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ 199#define X86_FEATURE_FSGSBASE (9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
200#define X86_FEATURE_BMI1 (9*32+ 3) /* 1st group bit manipulation extensions */
201#define X86_FEATURE_AVX2 (9*32+ 5) /* AVX2 instructions */
200#define X86_FEATURE_SMEP (9*32+ 7) /* Supervisor Mode Execution Protection */ 202#define X86_FEATURE_SMEP (9*32+ 7) /* Supervisor Mode Execution Protection */
203#define X86_FEATURE_BMI2 (9*32+ 8) /* 2nd group bit manipulation extensions */
201#define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */ 204#define X86_FEATURE_ERMS (9*32+ 9) /* Enhanced REP MOVSB/STOSB */
202 205
203#if defined(__KERNEL__) && !defined(__ASSEMBLY__) 206#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index 345c99cef15..dffc38ee625 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -5,6 +5,7 @@ extern struct dma_map_ops nommu_dma_ops;
5extern int force_iommu, no_iommu; 5extern int force_iommu, no_iommu;
6extern int iommu_detected; 6extern int iommu_detected;
7extern int iommu_pass_through; 7extern int iommu_pass_through;
8extern int iommu_group_mf;
8 9
9/* 10 seconds */ 10/* 10 seconds */
10#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) 11#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index a026507893e..ab4092e3214 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -181,6 +181,7 @@ struct x86_emulate_ops {
181 int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value); 181 int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
182 int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data); 182 int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
183 int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata); 183 int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
184 int (*read_pmc)(struct x86_emulate_ctxt *ctxt, u32 pmc, u64 *pdata);
184 void (*halt)(struct x86_emulate_ctxt *ctxt); 185 void (*halt)(struct x86_emulate_ctxt *ctxt);
185 void (*wbinvd)(struct x86_emulate_ctxt *ctxt); 186 void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
186 int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt); 187 int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt);
@@ -364,6 +365,7 @@ enum x86_intercept {
364#endif 365#endif
365 366
366int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len); 367int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len);
368bool x86_page_table_writing_insn(struct x86_emulate_ctxt *ctxt);
367#define EMULATION_FAILED -1 369#define EMULATION_FAILED -1
368#define EMULATION_OK 0 370#define EMULATION_OK 0
369#define EMULATION_RESTART 1 371#define EMULATION_RESTART 1
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index b4973f4dab9..52d6640a5ca 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -16,10 +16,12 @@
16#include <linux/mmu_notifier.h> 16#include <linux/mmu_notifier.h>
17#include <linux/tracepoint.h> 17#include <linux/tracepoint.h>
18#include <linux/cpumask.h> 18#include <linux/cpumask.h>
19#include <linux/irq_work.h>
19 20
20#include <linux/kvm.h> 21#include <linux/kvm.h>
21#include <linux/kvm_para.h> 22#include <linux/kvm_para.h>
22#include <linux/kvm_types.h> 23#include <linux/kvm_types.h>
24#include <linux/perf_event.h>
23 25
24#include <asm/pvclock-abi.h> 26#include <asm/pvclock-abi.h>
25#include <asm/desc.h> 27#include <asm/desc.h>
@@ -31,6 +33,8 @@
31#define KVM_MEMORY_SLOTS 32 33#define KVM_MEMORY_SLOTS 32
32/* memory slots that does not exposed to userspace */ 34/* memory slots that does not exposed to userspace */
33#define KVM_PRIVATE_MEM_SLOTS 4 35#define KVM_PRIVATE_MEM_SLOTS 4
36#define KVM_MEM_SLOTS_NUM (KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS)
37
34#define KVM_MMIO_SIZE 16 38#define KVM_MMIO_SIZE 16
35 39
36#define KVM_PIO_PAGE_OFFSET 1 40#define KVM_PIO_PAGE_OFFSET 1
@@ -228,7 +232,7 @@ struct kvm_mmu_page {
228 * One bit set per slot which has memory 232 * One bit set per slot which has memory
229 * in this shadow page. 233 * in this shadow page.
230 */ 234 */
231 DECLARE_BITMAP(slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); 235 DECLARE_BITMAP(slot_bitmap, KVM_MEM_SLOTS_NUM);
232 bool unsync; 236 bool unsync;
233 int root_count; /* Currently serving as active root */ 237 int root_count; /* Currently serving as active root */
234 unsigned int unsync_children; 238 unsigned int unsync_children;
@@ -239,14 +243,9 @@ struct kvm_mmu_page {
239 int clear_spte_count; 243 int clear_spte_count;
240#endif 244#endif
241 245
242 struct rcu_head rcu; 246 int write_flooding_count;
243};
244 247
245struct kvm_pv_mmu_op_buffer { 248 struct rcu_head rcu;
246 void *ptr;
247 unsigned len;
248 unsigned processed;
249 char buf[512] __aligned(sizeof(long));
250}; 249};
251 250
252struct kvm_pio_request { 251struct kvm_pio_request {
@@ -294,6 +293,37 @@ struct kvm_mmu {
294 u64 pdptrs[4]; /* pae */ 293 u64 pdptrs[4]; /* pae */
295}; 294};
296 295
296enum pmc_type {
297 KVM_PMC_GP = 0,
298 KVM_PMC_FIXED,
299};
300
301struct kvm_pmc {
302 enum pmc_type type;
303 u8 idx;
304 u64 counter;
305 u64 eventsel;
306 struct perf_event *perf_event;
307 struct kvm_vcpu *vcpu;
308};
309
310struct kvm_pmu {
311 unsigned nr_arch_gp_counters;
312 unsigned nr_arch_fixed_counters;
313 unsigned available_event_types;
314 u64 fixed_ctr_ctrl;
315 u64 global_ctrl;
316 u64 global_status;
317 u64 global_ovf_ctrl;
318 u64 counter_bitmask[2];
319 u64 global_ctrl_mask;
320 u8 version;
321 struct kvm_pmc gp_counters[X86_PMC_MAX_GENERIC];
322 struct kvm_pmc fixed_counters[X86_PMC_MAX_FIXED];
323 struct irq_work irq_work;
324 u64 reprogram_pmi;
325};
326
297struct kvm_vcpu_arch { 327struct kvm_vcpu_arch {
298 /* 328 /*
299 * rip and regs accesses must go through 329 * rip and regs accesses must go through
@@ -345,19 +375,10 @@ struct kvm_vcpu_arch {
345 */ 375 */
346 struct kvm_mmu *walk_mmu; 376 struct kvm_mmu *walk_mmu;
347 377
348 /* only needed in kvm_pv_mmu_op() path, but it's hot so
349 * put it here to avoid allocation */
350 struct kvm_pv_mmu_op_buffer mmu_op_buffer;
351
352 struct kvm_mmu_memory_cache mmu_pte_list_desc_cache; 378 struct kvm_mmu_memory_cache mmu_pte_list_desc_cache;
353 struct kvm_mmu_memory_cache mmu_page_cache; 379 struct kvm_mmu_memory_cache mmu_page_cache;
354 struct kvm_mmu_memory_cache mmu_page_header_cache; 380 struct kvm_mmu_memory_cache mmu_page_header_cache;
355 381
356 gfn_t last_pt_write_gfn;
357 int last_pt_write_count;
358 u64 *last_pte_updated;
359 gfn_t last_pte_gfn;
360
361 struct fpu guest_fpu; 382 struct fpu guest_fpu;
362 u64 xcr0; 383 u64 xcr0;
363 384
@@ -436,6 +457,8 @@ struct kvm_vcpu_arch {
436 unsigned access; 457 unsigned access;
437 gfn_t mmio_gfn; 458 gfn_t mmio_gfn;
438 459
460 struct kvm_pmu pmu;
461
439 /* used for guest single stepping over the given code position */ 462 /* used for guest single stepping over the given code position */
440 unsigned long singlestep_rip; 463 unsigned long singlestep_rip;
441 464
@@ -444,6 +467,9 @@ struct kvm_vcpu_arch {
444 467
445 cpumask_var_t wbinvd_dirty_mask; 468 cpumask_var_t wbinvd_dirty_mask;
446 469
470 unsigned long last_retry_eip;
471 unsigned long last_retry_addr;
472
447 struct { 473 struct {
448 bool halted; 474 bool halted;
449 gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)]; 475 gfn_t gfns[roundup_pow_of_two(ASYNC_PF_PER_VCPU)];
@@ -459,7 +485,6 @@ struct kvm_arch {
459 unsigned int n_requested_mmu_pages; 485 unsigned int n_requested_mmu_pages;
460 unsigned int n_max_mmu_pages; 486 unsigned int n_max_mmu_pages;
461 unsigned int indirect_shadow_pages; 487 unsigned int indirect_shadow_pages;
462 atomic_t invlpg_counter;
463 struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; 488 struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
464 /* 489 /*
465 * Hash table of struct kvm_mmu_page. 490 * Hash table of struct kvm_mmu_page.
@@ -660,6 +685,8 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
660 685
661int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); 686int kvm_mmu_reset_context(struct kvm_vcpu *vcpu);
662void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); 687void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot);
688int kvm_mmu_rmap_write_protect(struct kvm *kvm, u64 gfn,
689 struct kvm_memory_slot *slot);
663void kvm_mmu_zap_all(struct kvm *kvm); 690void kvm_mmu_zap_all(struct kvm *kvm);
664unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); 691unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm);
665void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); 692void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages);
@@ -668,8 +695,6 @@ int load_pdptrs(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long cr3);
668 695
669int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, 696int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
670 const void *val, int bytes); 697 const void *val, int bytes);
671int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
672 gpa_t addr, unsigned long *ret);
673u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn); 698u8 kvm_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn);
674 699
675extern bool tdp_enabled; 700extern bool tdp_enabled;
@@ -692,6 +717,7 @@ enum emulation_result {
692#define EMULTYPE_NO_DECODE (1 << 0) 717#define EMULTYPE_NO_DECODE (1 << 0)
693#define EMULTYPE_TRAP_UD (1 << 1) 718#define EMULTYPE_TRAP_UD (1 << 1)
694#define EMULTYPE_SKIP (1 << 2) 719#define EMULTYPE_SKIP (1 << 2)
720#define EMULTYPE_RETRY (1 << 3)
695int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2, 721int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2,
696 int emulation_type, void *insn, int insn_len); 722 int emulation_type, void *insn, int insn_len);
697 723
@@ -734,6 +760,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
734 760
735unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu); 761unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu);
736void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags); 762void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
763bool kvm_rdpmc(struct kvm_vcpu *vcpu);
737 764
738void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr); 765void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
739void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code); 766void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
@@ -754,13 +781,14 @@ int fx_init(struct kvm_vcpu *vcpu);
754 781
755void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu); 782void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu);
756void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, 783void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
757 const u8 *new, int bytes, 784 const u8 *new, int bytes);
758 bool guest_initiated); 785int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn);
759int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva); 786int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
760void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); 787void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
761int kvm_mmu_load(struct kvm_vcpu *vcpu); 788int kvm_mmu_load(struct kvm_vcpu *vcpu);
762void kvm_mmu_unload(struct kvm_vcpu *vcpu); 789void kvm_mmu_unload(struct kvm_vcpu *vcpu);
763void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu); 790void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
791gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access);
764gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva, 792gpa_t kvm_mmu_gva_to_gpa_read(struct kvm_vcpu *vcpu, gva_t gva,
765 struct x86_exception *exception); 793 struct x86_exception *exception);
766gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva, 794gpa_t kvm_mmu_gva_to_gpa_fetch(struct kvm_vcpu *vcpu, gva_t gva,
@@ -782,6 +810,11 @@ void kvm_disable_tdp(void);
782int complete_pio(struct kvm_vcpu *vcpu); 810int complete_pio(struct kvm_vcpu *vcpu);
783bool kvm_check_iopl(struct kvm_vcpu *vcpu); 811bool kvm_check_iopl(struct kvm_vcpu *vcpu);
784 812
813static inline gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
814{
815 return gpa;
816}
817
785static inline struct kvm_mmu_page *page_header(hpa_t shadow_page) 818static inline struct kvm_mmu_page *page_header(hpa_t shadow_page)
786{ 819{
787 struct page *page = pfn_to_page(shadow_page >> PAGE_SHIFT); 820 struct page *page = pfn_to_page(shadow_page >> PAGE_SHIFT);
@@ -894,4 +927,17 @@ extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn);
894 927
895void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err); 928void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err);
896 929
930int kvm_is_in_guest(void);
931
932void kvm_pmu_init(struct kvm_vcpu *vcpu);
933void kvm_pmu_destroy(struct kvm_vcpu *vcpu);
934void kvm_pmu_reset(struct kvm_vcpu *vcpu);
935void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu);
936bool kvm_pmu_msr(struct kvm_vcpu *vcpu, u32 msr);
937int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
938int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
939int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data);
940void kvm_handle_pmu_event(struct kvm_vcpu *vcpu);
941void kvm_deliver_pmi(struct kvm_vcpu *vcpu);
942
897#endif /* _ASM_X86_KVM_HOST_H */ 943#endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index 93f79094c22..0a0a9546043 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -67,7 +67,7 @@ extern struct console early_mrst_console;
67extern void mrst_early_console_init(void); 67extern void mrst_early_console_init(void);
68 68
69extern struct console early_hsu_console; 69extern struct console early_hsu_console;
70extern void hsu_early_console_init(void); 70extern void hsu_early_console_init(const char *);
71 71
72extern void intel_scu_devices_create(void); 72extern void intel_scu_devices_create(void);
73extern void intel_scu_devices_destroy(void); 73extern void intel_scu_devices_destroy(void);
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 529bf07e806..7a11910a63c 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -414,22 +414,6 @@ do { \
414#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval) 414#define this_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
415#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval) 415#define this_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
416 416
417#define irqsafe_cpu_add_1(pcp, val) percpu_add_op((pcp), val)
418#define irqsafe_cpu_add_2(pcp, val) percpu_add_op((pcp), val)
419#define irqsafe_cpu_add_4(pcp, val) percpu_add_op((pcp), val)
420#define irqsafe_cpu_and_1(pcp, val) percpu_to_op("and", (pcp), val)
421#define irqsafe_cpu_and_2(pcp, val) percpu_to_op("and", (pcp), val)
422#define irqsafe_cpu_and_4(pcp, val) percpu_to_op("and", (pcp), val)
423#define irqsafe_cpu_or_1(pcp, val) percpu_to_op("or", (pcp), val)
424#define irqsafe_cpu_or_2(pcp, val) percpu_to_op("or", (pcp), val)
425#define irqsafe_cpu_or_4(pcp, val) percpu_to_op("or", (pcp), val)
426#define irqsafe_cpu_xor_1(pcp, val) percpu_to_op("xor", (pcp), val)
427#define irqsafe_cpu_xor_2(pcp, val) percpu_to_op("xor", (pcp), val)
428#define irqsafe_cpu_xor_4(pcp, val) percpu_to_op("xor", (pcp), val)
429#define irqsafe_cpu_xchg_1(pcp, nval) percpu_xchg_op(pcp, nval)
430#define irqsafe_cpu_xchg_2(pcp, nval) percpu_xchg_op(pcp, nval)
431#define irqsafe_cpu_xchg_4(pcp, nval) percpu_xchg_op(pcp, nval)
432
433#ifndef CONFIG_M386 417#ifndef CONFIG_M386
434#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val) 418#define __this_cpu_add_return_1(pcp, val) percpu_add_return_op(pcp, val)
435#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val) 419#define __this_cpu_add_return_2(pcp, val) percpu_add_return_op(pcp, val)
@@ -445,9 +429,6 @@ do { \
445#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval) 429#define this_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
446#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval) 430#define this_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
447 431
448#define irqsafe_cpu_cmpxchg_1(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
449#define irqsafe_cpu_cmpxchg_2(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
450#define irqsafe_cpu_cmpxchg_4(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
451#endif /* !CONFIG_M386 */ 432#endif /* !CONFIG_M386 */
452 433
453#ifdef CONFIG_X86_CMPXCHG64 434#ifdef CONFIG_X86_CMPXCHG64
@@ -464,7 +445,6 @@ do { \
464 445
465#define __this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double 446#define __this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double
466#define this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double 447#define this_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double
467#define irqsafe_cpu_cmpxchg_double_4 percpu_cmpxchg8b_double
468#endif /* CONFIG_X86_CMPXCHG64 */ 448#endif /* CONFIG_X86_CMPXCHG64 */
469 449
470/* 450/*
@@ -492,13 +472,6 @@ do { \
492#define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval) 472#define this_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
493#define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval) 473#define this_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
494 474
495#define irqsafe_cpu_add_8(pcp, val) percpu_add_op((pcp), val)
496#define irqsafe_cpu_and_8(pcp, val) percpu_to_op("and", (pcp), val)
497#define irqsafe_cpu_or_8(pcp, val) percpu_to_op("or", (pcp), val)
498#define irqsafe_cpu_xor_8(pcp, val) percpu_to_op("xor", (pcp), val)
499#define irqsafe_cpu_xchg_8(pcp, nval) percpu_xchg_op(pcp, nval)
500#define irqsafe_cpu_cmpxchg_8(pcp, oval, nval) percpu_cmpxchg_op(pcp, oval, nval)
501
502/* 475/*
503 * Pretty complex macro to generate cmpxchg16 instruction. The instruction 476 * Pretty complex macro to generate cmpxchg16 instruction. The instruction
504 * is not supported on early AMD64 processors so we must be able to emulate 477 * is not supported on early AMD64 processors so we must be able to emulate
@@ -521,7 +494,6 @@ do { \
521 494
522#define __this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double 495#define __this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double
523#define this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double 496#define this_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double
524#define irqsafe_cpu_cmpxchg_double_8 percpu_cmpxchg16b_double
525 497
526#endif 498#endif
527 499
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index cd28a350f7f..9d42a52d233 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -247,7 +247,7 @@ static int __init setup_early_printk(char *buf)
247 } 247 }
248 248
249 if (!strncmp(buf, "hsu", 3)) { 249 if (!strncmp(buf, "hsu", 3)) {
250 hsu_early_console_init(); 250 hsu_early_console_init(buf + 3);
251 early_console_register(&early_hsu_console, keep); 251 early_console_register(&early_hsu_console, keep);
252 } 252 }
253#endif 253#endif
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a9c2116001d..f0c6fd6f176 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -39,8 +39,6 @@
39#include <asm/desc.h> 39#include <asm/desc.h>
40#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
41 41
42#define MMU_QUEUE_SIZE 1024
43
44static int kvmapf = 1; 42static int kvmapf = 1;
45 43
46static int parse_no_kvmapf(char *arg) 44static int parse_no_kvmapf(char *arg)
@@ -60,21 +58,10 @@ static int parse_no_stealacc(char *arg)
60 58
61early_param("no-steal-acc", parse_no_stealacc); 59early_param("no-steal-acc", parse_no_stealacc);
62 60
63struct kvm_para_state {
64 u8 mmu_queue[MMU_QUEUE_SIZE];
65 int mmu_queue_len;
66};
67
68static DEFINE_PER_CPU(struct kvm_para_state, para_state);
69static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64); 61static DEFINE_PER_CPU(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
70static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64); 62static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
71static int has_steal_clock = 0; 63static int has_steal_clock = 0;
72 64
73static struct kvm_para_state *kvm_para_state(void)
74{
75 return &per_cpu(para_state, raw_smp_processor_id());
76}
77
78/* 65/*
79 * No need for any "IO delay" on KVM 66 * No need for any "IO delay" on KVM
80 */ 67 */
@@ -271,151 +258,6 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
271 } 258 }
272} 259}
273 260
274static void kvm_mmu_op(void *buffer, unsigned len)
275{
276 int r;
277 unsigned long a1, a2;
278
279 do {
280 a1 = __pa(buffer);
281 a2 = 0; /* on i386 __pa() always returns <4G */
282 r = kvm_hypercall3(KVM_HC_MMU_OP, len, a1, a2);
283 buffer += r;
284 len -= r;
285 } while (len);
286}
287
288static void mmu_queue_flush(struct kvm_para_state *state)
289{
290 if (state->mmu_queue_len) {
291 kvm_mmu_op(state->mmu_queue, state->mmu_queue_len);
292 state->mmu_queue_len = 0;
293 }
294}
295
296static void kvm_deferred_mmu_op(void *buffer, int len)
297{
298 struct kvm_para_state *state = kvm_para_state();
299
300 if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) {
301 kvm_mmu_op(buffer, len);
302 return;
303 }
304 if (state->mmu_queue_len + len > sizeof state->mmu_queue)
305 mmu_queue_flush(state);
306 memcpy(state->mmu_queue + state->mmu_queue_len, buffer, len);
307 state->mmu_queue_len += len;
308}
309
310static void kvm_mmu_write(void *dest, u64 val)
311{
312 __u64 pte_phys;
313 struct kvm_mmu_op_write_pte wpte;
314
315#ifdef CONFIG_HIGHPTE
316 struct page *page;
317 unsigned long dst = (unsigned long) dest;
318
319 page = kmap_atomic_to_page(dest);
320 pte_phys = page_to_pfn(page);
321 pte_phys <<= PAGE_SHIFT;
322 pte_phys += (dst & ~(PAGE_MASK));
323#else
324 pte_phys = (unsigned long)__pa(dest);
325#endif
326 wpte.header.op = KVM_MMU_OP_WRITE_PTE;
327 wpte.pte_val = val;
328 wpte.pte_phys = pte_phys;
329
330 kvm_deferred_mmu_op(&wpte, sizeof wpte);
331}
332
333/*
334 * We only need to hook operations that are MMU writes. We hook these so that
335 * we can use lazy MMU mode to batch these operations. We could probably
336 * improve the performance of the host code if we used some of the information
337 * here to simplify processing of batched writes.
338 */
339static void kvm_set_pte(pte_t *ptep, pte_t pte)
340{
341 kvm_mmu_write(ptep, pte_val(pte));
342}
343
344static void kvm_set_pte_at(struct mm_struct *mm, unsigned long addr,
345 pte_t *ptep, pte_t pte)
346{
347 kvm_mmu_write(ptep, pte_val(pte));
348}
349
350static void kvm_set_pmd(pmd_t *pmdp, pmd_t pmd)
351{
352 kvm_mmu_write(pmdp, pmd_val(pmd));
353}
354
355#if PAGETABLE_LEVELS >= 3
356#ifdef CONFIG_X86_PAE
357static void kvm_set_pte_atomic(pte_t *ptep, pte_t pte)
358{
359 kvm_mmu_write(ptep, pte_val(pte));
360}
361
362static void kvm_pte_clear(struct mm_struct *mm,
363 unsigned long addr, pte_t *ptep)
364{
365 kvm_mmu_write(ptep, 0);
366}
367
368static void kvm_pmd_clear(pmd_t *pmdp)
369{
370 kvm_mmu_write(pmdp, 0);
371}
372#endif
373
374static void kvm_set_pud(pud_t *pudp, pud_t pud)
375{
376 kvm_mmu_write(pudp, pud_val(pud));
377}
378
379#if PAGETABLE_LEVELS == 4
380static void kvm_set_pgd(pgd_t *pgdp, pgd_t pgd)
381{
382 kvm_mmu_write(pgdp, pgd_val(pgd));
383}
384#endif
385#endif /* PAGETABLE_LEVELS >= 3 */
386
387static void kvm_flush_tlb(void)
388{
389 struct kvm_mmu_op_flush_tlb ftlb = {
390 .header.op = KVM_MMU_OP_FLUSH_TLB,
391 };
392
393 kvm_deferred_mmu_op(&ftlb, sizeof ftlb);
394}
395
396static void kvm_release_pt(unsigned long pfn)
397{
398 struct kvm_mmu_op_release_pt rpt = {
399 .header.op = KVM_MMU_OP_RELEASE_PT,
400 .pt_phys = (u64)pfn << PAGE_SHIFT,
401 };
402
403 kvm_mmu_op(&rpt, sizeof rpt);
404}
405
406static void kvm_enter_lazy_mmu(void)
407{
408 paravirt_enter_lazy_mmu();
409}
410
411static void kvm_leave_lazy_mmu(void)
412{
413 struct kvm_para_state *state = kvm_para_state();
414
415 mmu_queue_flush(state);
416 paravirt_leave_lazy_mmu();
417}
418
419static void __init paravirt_ops_setup(void) 261static void __init paravirt_ops_setup(void)
420{ 262{
421 pv_info.name = "KVM"; 263 pv_info.name = "KVM";
@@ -424,29 +266,6 @@ static void __init paravirt_ops_setup(void)
424 if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) 266 if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
425 pv_cpu_ops.io_delay = kvm_io_delay; 267 pv_cpu_ops.io_delay = kvm_io_delay;
426 268
427 if (kvm_para_has_feature(KVM_FEATURE_MMU_OP)) {
428 pv_mmu_ops.set_pte = kvm_set_pte;
429 pv_mmu_ops.set_pte_at = kvm_set_pte_at;
430 pv_mmu_ops.set_pmd = kvm_set_pmd;
431#if PAGETABLE_LEVELS >= 3
432#ifdef CONFIG_X86_PAE
433 pv_mmu_ops.set_pte_atomic = kvm_set_pte_atomic;
434 pv_mmu_ops.pte_clear = kvm_pte_clear;
435 pv_mmu_ops.pmd_clear = kvm_pmd_clear;
436#endif
437 pv_mmu_ops.set_pud = kvm_set_pud;
438#if PAGETABLE_LEVELS == 4
439 pv_mmu_ops.set_pgd = kvm_set_pgd;
440#endif
441#endif
442 pv_mmu_ops.flush_tlb_user = kvm_flush_tlb;
443 pv_mmu_ops.release_pte = kvm_release_pt;
444 pv_mmu_ops.release_pmd = kvm_release_pt;
445 pv_mmu_ops.release_pud = kvm_release_pt;
446
447 pv_mmu_ops.lazy_mode.enter = kvm_enter_lazy_mmu;
448 pv_mmu_ops.lazy_mode.leave = kvm_leave_lazy_mmu;
449 }
450#ifdef CONFIG_X86_IO_APIC 269#ifdef CONFIG_X86_IO_APIC
451 no_timer_check = 1; 270 no_timer_check = 1;
452#endif 271#endif
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 80dc793b3f6..1c4d769e21e 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -45,6 +45,15 @@ int iommu_detected __read_mostly = 0;
45 */ 45 */
46int iommu_pass_through __read_mostly; 46int iommu_pass_through __read_mostly;
47 47
48/*
49 * Group multi-function PCI devices into a single device-group for the
50 * iommu_device_group interface. This tells the iommu driver to pretend
51 * it cannot distinguish between functions of a device, exposing only one
52 * group for the device. Useful for disallowing use of individual PCI
53 * functions from userspace drivers.
54 */
55int iommu_group_mf __read_mostly;
56
48extern struct iommu_table_entry __iommu_table[], __iommu_table_end[]; 57extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
49 58
50/* Dummy device used for NULL arguments (normally ISA). */ 59/* Dummy device used for NULL arguments (normally ISA). */
@@ -169,6 +178,8 @@ static __init int iommu_setup(char *p)
169#endif 178#endif
170 if (!strncmp(p, "pt", 2)) 179 if (!strncmp(p, "pt", 2))
171 iommu_pass_through = 1; 180 iommu_pass_through = 1;
181 if (!strncmp(p, "group_mf", 8))
182 iommu_group_mf = 1;
172 183
173 gart_parse_options(p); 184 gart_parse_options(p);
174 185
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 54ddaeb221c..46a01bdc27e 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -682,7 +682,6 @@ static int
682handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, 682handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
683 struct pt_regs *regs) 683 struct pt_regs *regs)
684{ 684{
685 sigset_t blocked;
686 int ret; 685 int ret;
687 686
688 /* Are we from a system call? */ 687 /* Are we from a system call? */
@@ -733,10 +732,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
733 */ 732 */
734 regs->flags &= ~X86_EFLAGS_TF; 733 regs->flags &= ~X86_EFLAGS_TF;
735 734
736 sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask); 735 block_sigmask(ka, sig);
737 if (!(ka->sa.sa_flags & SA_NODEFER))
738 sigaddset(&blocked, sig);
739 set_current_blocked(&blocked);
740 736
741 tracehook_signal_handler(sig, info, ka, regs, 737 tracehook_signal_handler(sig, info, ka, regs,
742 test_thread_flag(TIF_SINGLESTEP)); 738 test_thread_flag(TIF_SINGLESTEP));
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ff5790d8e99..1a7fe868f37 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -35,6 +35,7 @@ config KVM
35 select KVM_MMIO 35 select KVM_MMIO
36 select TASKSTATS 36 select TASKSTATS
37 select TASK_DELAY_ACCT 37 select TASK_DELAY_ACCT
38 select PERF_EVENTS
38 ---help--- 39 ---help---
39 Support hosting fully virtualized guest machines using hardware 40 Support hosting fully virtualized guest machines using hardware
40 virtualization extensions. You will need a fairly recent 41 virtualization extensions. You will need a fairly recent
@@ -52,6 +53,8 @@ config KVM
52config KVM_INTEL 53config KVM_INTEL
53 tristate "KVM for Intel processors support" 54 tristate "KVM for Intel processors support"
54 depends on KVM 55 depends on KVM
56 # for perf_guest_get_msrs():
57 depends on CPU_SUP_INTEL
55 ---help--- 58 ---help---
56 Provides support for KVM on Intel processors equipped with the VT 59 Provides support for KVM on Intel processors equipped with the VT
57 extensions. 60 extensions.
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index f15501f431c..4f579e8dcac 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -12,7 +12,7 @@ kvm-$(CONFIG_IOMMU_API) += $(addprefix ../../../virt/kvm/, iommu.o)
12kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o) 12kvm-$(CONFIG_KVM_ASYNC_PF) += $(addprefix ../../../virt/kvm/, async_pf.o)
13 13
14kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \ 14kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
15 i8254.o timer.o 15 i8254.o timer.o cpuid.o pmu.o
16kvm-intel-y += vmx.o 16kvm-intel-y += vmx.o
17kvm-amd-y += svm.o 17kvm-amd-y += svm.o
18 18
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
new file mode 100644
index 00000000000..89b02bfaaca
--- /dev/null
+++ b/arch/x86/kvm/cpuid.c
@@ -0,0 +1,670 @@
1/*
2 * Kernel-based Virtual Machine driver for Linux
3 * cpuid support routines
4 *
5 * derived from arch/x86/kvm/x86.c
6 *
7 * Copyright 2011 Red Hat, Inc. and/or its affiliates.
8 * Copyright IBM Corporation, 2008
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
12 *
13 */
14
15#include <linux/kvm_host.h>
16#include <linux/module.h>
17#include <linux/vmalloc.h>
18#include <linux/uaccess.h>
19#include <asm/user.h>
20#include <asm/xsave.h>
21#include "cpuid.h"
22#include "lapic.h"
23#include "mmu.h"
24#include "trace.h"
25
26void kvm_update_cpuid(struct kvm_vcpu *vcpu)
27{
28 struct kvm_cpuid_entry2 *best;
29 struct kvm_lapic *apic = vcpu->arch.apic;
30
31 best = kvm_find_cpuid_entry(vcpu, 1, 0);
32 if (!best)
33 return;
34
35 /* Update OSXSAVE bit */
36 if (cpu_has_xsave && best->function == 0x1) {
37 best->ecx &= ~(bit(X86_FEATURE_OSXSAVE));
38 if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE))
39 best->ecx |= bit(X86_FEATURE_OSXSAVE);
40 }
41
42 if (apic) {
43 if (best->ecx & bit(X86_FEATURE_TSC_DEADLINE_TIMER))
44 apic->lapic_timer.timer_mode_mask = 3 << 17;
45 else
46 apic->lapic_timer.timer_mode_mask = 1 << 17;
47 }
48
49 kvm_pmu_cpuid_update(vcpu);
50}
51
52static int is_efer_nx(void)
53{
54 unsigned long long efer = 0;
55
56 rdmsrl_safe(MSR_EFER, &efer);
57 return efer & EFER_NX;
58}
59
60static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
61{
62 int i;
63 struct kvm_cpuid_entry2 *e, *entry;
64
65 entry = NULL;
66 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
67 e = &vcpu->arch.cpuid_entries[i];
68 if (e->function == 0x80000001) {
69 entry = e;
70 break;
71 }
72 }
73 if (entry && (entry->edx & (1 << 20)) && !is_efer_nx()) {
74 entry->edx &= ~(1 << 20);
75 printk(KERN_INFO "kvm: guest NX capability removed\n");
76 }
77}
78
79/* when an old userspace process fills a new kernel module */
80int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
81 struct kvm_cpuid *cpuid,
82 struct kvm_cpuid_entry __user *entries)
83{
84 int r, i;
85 struct kvm_cpuid_entry *cpuid_entries;
86
87 r = -E2BIG;
88 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
89 goto out;
90 r = -ENOMEM;
91 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
92 if (!cpuid_entries)
93 goto out;
94 r = -EFAULT;
95 if (copy_from_user(cpuid_entries, entries,
96 cpuid->nent * sizeof(struct kvm_cpuid_entry)))
97 goto out_free;
98 for (i = 0; i < cpuid->nent; i++) {
99 vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
100 vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
101 vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
102 vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
103 vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
104 vcpu->arch.cpuid_entries[i].index = 0;
105 vcpu->arch.cpuid_entries[i].flags = 0;
106 vcpu->arch.cpuid_entries[i].padding[0] = 0;
107 vcpu->arch.cpuid_entries[i].padding[1] = 0;
108 vcpu->arch.cpuid_entries[i].padding[2] = 0;
109 }
110 vcpu->arch.cpuid_nent = cpuid->nent;
111 cpuid_fix_nx_cap(vcpu);
112 r = 0;
113 kvm_apic_set_version(vcpu);
114 kvm_x86_ops->cpuid_update(vcpu);
115 kvm_update_cpuid(vcpu);
116
117out_free:
118 vfree(cpuid_entries);
119out:
120 return r;
121}
122
123int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
124 struct kvm_cpuid2 *cpuid,
125 struct kvm_cpuid_entry2 __user *entries)
126{
127 int r;
128
129 r = -E2BIG;
130 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
131 goto out;
132 r = -EFAULT;
133 if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
134 cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
135 goto out;
136 vcpu->arch.cpuid_nent = cpuid->nent;
137 kvm_apic_set_version(vcpu);
138 kvm_x86_ops->cpuid_update(vcpu);
139 kvm_update_cpuid(vcpu);
140 return 0;
141
142out:
143 return r;
144}
145
146int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
147 struct kvm_cpuid2 *cpuid,
148 struct kvm_cpuid_entry2 __user *entries)
149{
150 int r;
151
152 r = -E2BIG;
153 if (cpuid->nent < vcpu->arch.cpuid_nent)
154 goto out;
155 r = -EFAULT;
156 if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
157 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
158 goto out;
159 return 0;
160
161out:
162 cpuid->nent = vcpu->arch.cpuid_nent;
163 return r;
164}
165
166static void cpuid_mask(u32 *word, int wordnum)
167{
168 *word &= boot_cpu_data.x86_capability[wordnum];
169}
170
171static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
172 u32 index)
173{
174 entry->function = function;
175 entry->index = index;
176 cpuid_count(entry->function, entry->index,
177 &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
178 entry->flags = 0;
179}
180
181static bool supported_xcr0_bit(unsigned bit)
182{
183 u64 mask = ((u64)1 << bit);
184
185 return mask & (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) & host_xcr0;
186}
187
188#define F(x) bit(X86_FEATURE_##x)
189
190static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
191 u32 index, int *nent, int maxnent)
192{
193 int r;
194 unsigned f_nx = is_efer_nx() ? F(NX) : 0;
195#ifdef CONFIG_X86_64
196 unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
197 ? F(GBPAGES) : 0;
198 unsigned f_lm = F(LM);
199#else
200 unsigned f_gbpages = 0;
201 unsigned f_lm = 0;
202#endif
203 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
204
205 /* cpuid 1.edx */
206 const u32 kvm_supported_word0_x86_features =
207 F(FPU) | F(VME) | F(DE) | F(PSE) |
208 F(TSC) | F(MSR) | F(PAE) | F(MCE) |
209 F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) |
210 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
211 F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLSH) |
212 0 /* Reserved, DS, ACPI */ | F(MMX) |
213 F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) |
214 0 /* HTT, TM, Reserved, PBE */;
215 /* cpuid 0x80000001.edx */
216 const u32 kvm_supported_word1_x86_features =
217 F(FPU) | F(VME) | F(DE) | F(PSE) |
218 F(TSC) | F(MSR) | F(PAE) | F(MCE) |
219 F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) |
220 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
221 F(PAT) | F(PSE36) | 0 /* Reserved */ |
222 f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
223 F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
224 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
225 /* cpuid 1.ecx */
226 const u32 kvm_supported_word4_x86_features =
227 F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ |
228 0 /* DS-CPL, VMX, SMX, EST */ |
229 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
230 F(FMA) | F(CX16) | 0 /* xTPR Update, PDCM */ |
231 0 /* Reserved, DCA */ | F(XMM4_1) |
232 F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
233 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
234 F(F16C) | F(RDRAND);
235 /* cpuid 0x80000001.ecx */
236 const u32 kvm_supported_word6_x86_features =
237 F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
238 F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
239 F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) |
240 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
241
242 /* cpuid 0xC0000001.edx */
243 const u32 kvm_supported_word5_x86_features =
244 F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
245 F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
246 F(PMM) | F(PMM_EN);
247
248 /* cpuid 7.0.ebx */
249 const u32 kvm_supported_word9_x86_features =
250 F(FSGSBASE) | F(BMI1) | F(AVX2) | F(SMEP) | F(BMI2) | F(ERMS);
251
252 /* all calls to cpuid_count() should be made on the same cpu */
253 get_cpu();
254
255 r = -E2BIG;
256
257 if (*nent >= maxnent)
258 goto out;
259
260 do_cpuid_1_ent(entry, function, index);
261 ++*nent;
262
263 switch (function) {
264 case 0:
265 entry->eax = min(entry->eax, (u32)0xd);
266 break;
267 case 1:
268 entry->edx &= kvm_supported_word0_x86_features;
269 cpuid_mask(&entry->edx, 0);
270 entry->ecx &= kvm_supported_word4_x86_features;
271 cpuid_mask(&entry->ecx, 4);
272 /* we support x2apic emulation even if host does not support
273 * it since we emulate x2apic in software */
274 entry->ecx |= F(X2APIC);
275 break;
276 /* function 2 entries are STATEFUL. That is, repeated cpuid commands
277 * may return different values. This forces us to get_cpu() before
278 * issuing the first command, and also to emulate this annoying behavior
279 * in kvm_emulate_cpuid() using KVM_CPUID_FLAG_STATE_READ_NEXT */
280 case 2: {
281 int t, times = entry->eax & 0xff;
282
283 entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
284 entry->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
285 for (t = 1; t < times; ++t) {
286 if (*nent >= maxnent)
287 goto out;
288
289 do_cpuid_1_ent(&entry[t], function, 0);
290 entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
291 ++*nent;
292 }
293 break;
294 }
295 /* function 4 has additional index. */
296 case 4: {
297 int i, cache_type;
298
299 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
300 /* read more entries until cache_type is zero */
301 for (i = 1; ; ++i) {
302 if (*nent >= maxnent)
303 goto out;
304
305 cache_type = entry[i - 1].eax & 0x1f;
306 if (!cache_type)
307 break;
308 do_cpuid_1_ent(&entry[i], function, i);
309 entry[i].flags |=
310 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
311 ++*nent;
312 }
313 break;
314 }
315 case 7: {
316 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
317 /* Mask ebx against host capbability word 9 */
318 if (index == 0) {
319 entry->ebx &= kvm_supported_word9_x86_features;
320 cpuid_mask(&entry->ebx, 9);
321 } else
322 entry->ebx = 0;
323 entry->eax = 0;
324 entry->ecx = 0;
325 entry->edx = 0;
326 break;
327 }
328 case 9:
329 break;
330 case 0xa: { /* Architectural Performance Monitoring */
331 struct x86_pmu_capability cap;
332 union cpuid10_eax eax;
333 union cpuid10_edx edx;
334
335 perf_get_x86_pmu_capability(&cap);
336
337 /*
338 * Only support guest architectural pmu on a host
339 * with architectural pmu.
340 */
341 if (!cap.version)
342 memset(&cap, 0, sizeof(cap));
343
344 eax.split.version_id = min(cap.version, 2);
345 eax.split.num_counters = cap.num_counters_gp;
346 eax.split.bit_width = cap.bit_width_gp;
347 eax.split.mask_length = cap.events_mask_len;
348
349 edx.split.num_counters_fixed = cap.num_counters_fixed;
350 edx.split.bit_width_fixed = cap.bit_width_fixed;
351 edx.split.reserved = 0;
352
353 entry->eax = eax.full;
354 entry->ebx = cap.events_mask;
355 entry->ecx = 0;
356 entry->edx = edx.full;
357 break;
358 }
359 /* function 0xb has additional index. */
360 case 0xb: {
361 int i, level_type;
362
363 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
364 /* read more entries until level_type is zero */
365 for (i = 1; ; ++i) {
366 if (*nent >= maxnent)
367 goto out;
368
369 level_type = entry[i - 1].ecx & 0xff00;
370 if (!level_type)
371 break;
372 do_cpuid_1_ent(&entry[i], function, i);
373 entry[i].flags |=
374 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
375 ++*nent;
376 }
377 break;
378 }
379 case 0xd: {
380 int idx, i;
381
382 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
383 for (idx = 1, i = 1; idx < 64; ++idx) {
384 if (*nent >= maxnent)
385 goto out;
386
387 do_cpuid_1_ent(&entry[i], function, idx);
388 if (entry[i].eax == 0 || !supported_xcr0_bit(idx))
389 continue;
390 entry[i].flags |=
391 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
392 ++*nent;
393 ++i;
394 }
395 break;
396 }
397 case KVM_CPUID_SIGNATURE: {
398 char signature[12] = "KVMKVMKVM\0\0";
399 u32 *sigptr = (u32 *)signature;
400 entry->eax = 0;
401 entry->ebx = sigptr[0];
402 entry->ecx = sigptr[1];
403 entry->edx = sigptr[2];
404 break;
405 }
406 case KVM_CPUID_FEATURES:
407 entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
408 (1 << KVM_FEATURE_NOP_IO_DELAY) |
409 (1 << KVM_FEATURE_CLOCKSOURCE2) |
410 (1 << KVM_FEATURE_ASYNC_PF) |
411 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
412
413 if (sched_info_on())
414 entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
415
416 entry->ebx = 0;
417 entry->ecx = 0;
418 entry->edx = 0;
419 break;
420 case 0x80000000:
421 entry->eax = min(entry->eax, 0x8000001a);
422 break;
423 case 0x80000001:
424 entry->edx &= kvm_supported_word1_x86_features;
425 cpuid_mask(&entry->edx, 1);
426 entry->ecx &= kvm_supported_word6_x86_features;
427 cpuid_mask(&entry->ecx, 6);
428 break;
429 case 0x80000008: {
430 unsigned g_phys_as = (entry->eax >> 16) & 0xff;
431 unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
432 unsigned phys_as = entry->eax & 0xff;
433
434 if (!g_phys_as)
435 g_phys_as = phys_as;
436 entry->eax = g_phys_as | (virt_as << 8);
437 entry->ebx = entry->edx = 0;
438 break;
439 }
440 case 0x80000019:
441 entry->ecx = entry->edx = 0;
442 break;
443 case 0x8000001a:
444 break;
445 case 0x8000001d:
446 break;
447 /*Add support for Centaur's CPUID instruction*/
448 case 0xC0000000:
449 /*Just support up to 0xC0000004 now*/
450 entry->eax = min(entry->eax, 0xC0000004);
451 break;
452 case 0xC0000001:
453 entry->edx &= kvm_supported_word5_x86_features;
454 cpuid_mask(&entry->edx, 5);
455 break;
456 case 3: /* Processor serial number */
457 case 5: /* MONITOR/MWAIT */
458 case 6: /* Thermal management */
459 case 0x80000007: /* Advanced power management */
460 case 0xC0000002:
461 case 0xC0000003:
462 case 0xC0000004:
463 default:
464 entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
465 break;
466 }
467
468 kvm_x86_ops->set_supported_cpuid(function, entry);
469
470 r = 0;
471
472out:
473 put_cpu();
474
475 return r;
476}
477
478#undef F
479
480struct kvm_cpuid_param {
481 u32 func;
482 u32 idx;
483 bool has_leaf_count;
484 bool (*qualifier)(struct kvm_cpuid_param *param);
485};
486
487static bool is_centaur_cpu(struct kvm_cpuid_param *param)
488{
489 return boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR;
490}
491
492int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
493 struct kvm_cpuid_entry2 __user *entries)
494{
495 struct kvm_cpuid_entry2 *cpuid_entries;
496 int limit, nent = 0, r = -E2BIG, i;
497 u32 func;
498 static struct kvm_cpuid_param param[] = {
499 { .func = 0, .has_leaf_count = true },
500 { .func = 0x80000000, .has_leaf_count = true },
501 { .func = 0xC0000000, .qualifier = is_centaur_cpu, .has_leaf_count = true },
502 { .func = KVM_CPUID_SIGNATURE },
503 { .func = KVM_CPUID_FEATURES },
504 };
505
506 if (cpuid->nent < 1)
507 goto out;
508 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
509 cpuid->nent = KVM_MAX_CPUID_ENTRIES;
510 r = -ENOMEM;
511 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
512 if (!cpuid_entries)
513 goto out;
514
515 r = 0;
516 for (i = 0; i < ARRAY_SIZE(param); i++) {
517 struct kvm_cpuid_param *ent = &param[i];
518
519 if (ent->qualifier && !ent->qualifier(ent))
520 continue;
521
522 r = do_cpuid_ent(&cpuid_entries[nent], ent->func, ent->idx,
523 &nent, cpuid->nent);
524
525 if (r)
526 goto out_free;
527
528 if (!ent->has_leaf_count)
529 continue;
530
531 limit = cpuid_entries[nent - 1].eax;
532 for (func = ent->func + 1; func <= limit && nent < cpuid->nent && r == 0; ++func)
533 r = do_cpuid_ent(&cpuid_entries[nent], func, ent->idx,
534 &nent, cpuid->nent);
535
536 if (r)
537 goto out_free;
538 }
539
540 r = -EFAULT;
541 if (copy_to_user(entries, cpuid_entries,
542 nent * sizeof(struct kvm_cpuid_entry2)))
543 goto out_free;
544 cpuid->nent = nent;
545 r = 0;
546
547out_free:
548 vfree(cpuid_entries);
549out:
550 return r;
551}
552
553static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
554{
555 struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
556 int j, nent = vcpu->arch.cpuid_nent;
557
558 e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
559 /* when no next entry is found, the current entry[i] is reselected */
560 for (j = i + 1; ; j = (j + 1) % nent) {
561 struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
562 if (ej->function == e->function) {
563 ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
564 return j;
565 }
566 }
567 return 0; /* silence gcc, even though control never reaches here */
568}
569
570/* find an entry with matching function, matching index (if needed), and that
571 * should be read next (if it's stateful) */
572static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
573 u32 function, u32 index)
574{
575 if (e->function != function)
576 return 0;
577 if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index)
578 return 0;
579 if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
580 !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
581 return 0;
582 return 1;
583}
584
585struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
586 u32 function, u32 index)
587{
588 int i;
589 struct kvm_cpuid_entry2 *best = NULL;
590
591 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
592 struct kvm_cpuid_entry2 *e;
593
594 e = &vcpu->arch.cpuid_entries[i];
595 if (is_matching_cpuid_entry(e, function, index)) {
596 if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
597 move_to_next_stateful_cpuid_entry(vcpu, i);
598 best = e;
599 break;
600 }
601 }
602 return best;
603}
604EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
605
606int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
607{
608 struct kvm_cpuid_entry2 *best;
609
610 best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0);
611 if (!best || best->eax < 0x80000008)
612 goto not_found;
613 best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
614 if (best)
615 return best->eax & 0xff;
616not_found:
617 return 36;
618}
619
620/*
621 * If no match is found, check whether we exceed the vCPU's limit
622 * and return the content of the highest valid _standard_ leaf instead.
623 * This is to satisfy the CPUID specification.
624 */
625static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
626 u32 function, u32 index)
627{
628 struct kvm_cpuid_entry2 *maxlevel;
629
630 maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
631 if (!maxlevel || maxlevel->eax >= function)
632 return NULL;
633 if (function & 0x80000000) {
634 maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
635 if (!maxlevel)
636 return NULL;
637 }
638 return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
639}
640
641void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
642{
643 u32 function, index;
644 struct kvm_cpuid_entry2 *best;
645
646 function = kvm_register_read(vcpu, VCPU_REGS_RAX);
647 index = kvm_register_read(vcpu, VCPU_REGS_RCX);
648 kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
649 kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
650 kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
651 kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
652 best = kvm_find_cpuid_entry(vcpu, function, index);
653
654 if (!best)
655 best = check_cpuid_limit(vcpu, function, index);
656
657 if (best) {
658 kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
659 kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);
660 kvm_register_write(vcpu, VCPU_REGS_RCX, best->ecx);
661 kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx);
662 }
663 kvm_x86_ops->skip_emulated_instruction(vcpu);
664 trace_kvm_cpuid(function,
665 kvm_register_read(vcpu, VCPU_REGS_RAX),
666 kvm_register_read(vcpu, VCPU_REGS_RBX),
667 kvm_register_read(vcpu, VCPU_REGS_RCX),
668 kvm_register_read(vcpu, VCPU_REGS_RDX));
669}
670EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
new file mode 100644
index 00000000000..5b97e1797a6
--- /dev/null
+++ b/arch/x86/kvm/cpuid.h
@@ -0,0 +1,46 @@
1#ifndef ARCH_X86_KVM_CPUID_H
2#define ARCH_X86_KVM_CPUID_H
3
4#include "x86.h"
5
6void kvm_update_cpuid(struct kvm_vcpu *vcpu);
7struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
8 u32 function, u32 index);
9int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
10 struct kvm_cpuid_entry2 __user *entries);
11int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
12 struct kvm_cpuid *cpuid,
13 struct kvm_cpuid_entry __user *entries);
14int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
15 struct kvm_cpuid2 *cpuid,
16 struct kvm_cpuid_entry2 __user *entries);
17int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
18 struct kvm_cpuid2 *cpuid,
19 struct kvm_cpuid_entry2 __user *entries);
20
21
22static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
23{
24 struct kvm_cpuid_entry2 *best;
25
26 best = kvm_find_cpuid_entry(vcpu, 1, 0);
27 return best && (best->ecx & bit(X86_FEATURE_XSAVE));
28}
29
30static inline bool guest_cpuid_has_smep(struct kvm_vcpu *vcpu)
31{
32 struct kvm_cpuid_entry2 *best;
33
34 best = kvm_find_cpuid_entry(vcpu, 7, 0);
35 return best && (best->ebx & bit(X86_FEATURE_SMEP));
36}
37
38static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
39{
40 struct kvm_cpuid_entry2 *best;
41
42 best = kvm_find_cpuid_entry(vcpu, 7, 0);
43 return best && (best->ebx & bit(X86_FEATURE_FSGSBASE));
44}
45
46#endif
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index f1e3be18a08..05a562b8502 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -125,8 +125,9 @@
125#define Lock (1<<26) /* lock prefix is allowed for the instruction */ 125#define Lock (1<<26) /* lock prefix is allowed for the instruction */
126#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */ 126#define Priv (1<<27) /* instruction generates #GP if current CPL != 0 */
127#define No64 (1<<28) 127#define No64 (1<<28)
128#define PageTable (1 << 29) /* instruction used to write page table */
128/* Source 2 operand type */ 129/* Source 2 operand type */
129#define Src2Shift (29) 130#define Src2Shift (30)
130#define Src2None (OpNone << Src2Shift) 131#define Src2None (OpNone << Src2Shift)
131#define Src2CL (OpCL << Src2Shift) 132#define Src2CL (OpCL << Src2Shift)
132#define Src2ImmByte (OpImmByte << Src2Shift) 133#define Src2ImmByte (OpImmByte << Src2Shift)
@@ -1674,11 +1675,6 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
1674 return X86EMUL_CONTINUE; 1675 return X86EMUL_CONTINUE;
1675} 1676}
1676 1677
1677static int em_grp1a(struct x86_emulate_ctxt *ctxt)
1678{
1679 return emulate_pop(ctxt, &ctxt->dst.val, ctxt->dst.bytes);
1680}
1681
1682static int em_grp2(struct x86_emulate_ctxt *ctxt) 1678static int em_grp2(struct x86_emulate_ctxt *ctxt)
1683{ 1679{
1684 switch (ctxt->modrm_reg) { 1680 switch (ctxt->modrm_reg) {
@@ -1788,7 +1784,7 @@ static int em_grp45(struct x86_emulate_ctxt *ctxt)
1788 return rc; 1784 return rc;
1789} 1785}
1790 1786
1791static int em_grp9(struct x86_emulate_ctxt *ctxt) 1787static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
1792{ 1788{
1793 u64 old = ctxt->dst.orig_val64; 1789 u64 old = ctxt->dst.orig_val64;
1794 1790
@@ -1831,6 +1827,24 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
1831 return rc; 1827 return rc;
1832} 1828}
1833 1829
1830static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
1831{
1832 /* Save real source value, then compare EAX against destination. */
1833 ctxt->src.orig_val = ctxt->src.val;
1834 ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
1835 emulate_2op_SrcV(ctxt, "cmp");
1836
1837 if (ctxt->eflags & EFLG_ZF) {
1838 /* Success: write back to memory. */
1839 ctxt->dst.val = ctxt->src.orig_val;
1840 } else {
1841 /* Failure: write the value we saw to EAX. */
1842 ctxt->dst.type = OP_REG;
1843 ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
1844 }
1845 return X86EMUL_CONTINUE;
1846}
1847
1834static int em_lseg(struct x86_emulate_ctxt *ctxt) 1848static int em_lseg(struct x86_emulate_ctxt *ctxt)
1835{ 1849{
1836 int seg = ctxt->src2.val; 1850 int seg = ctxt->src2.val;
@@ -2481,6 +2495,15 @@ static int em_das(struct x86_emulate_ctxt *ctxt)
2481 return X86EMUL_CONTINUE; 2495 return X86EMUL_CONTINUE;
2482} 2496}
2483 2497
2498static int em_call(struct x86_emulate_ctxt *ctxt)
2499{
2500 long rel = ctxt->src.val;
2501
2502 ctxt->src.val = (unsigned long)ctxt->_eip;
2503 jmp_rel(ctxt, rel);
2504 return em_push(ctxt);
2505}
2506
2484static int em_call_far(struct x86_emulate_ctxt *ctxt) 2507static int em_call_far(struct x86_emulate_ctxt *ctxt)
2485{ 2508{
2486 u16 sel, old_cs; 2509 u16 sel, old_cs;
@@ -2622,12 +2645,75 @@ static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
2622 return X86EMUL_CONTINUE; 2645 return X86EMUL_CONTINUE;
2623} 2646}
2624 2647
2648static int em_rdpmc(struct x86_emulate_ctxt *ctxt)
2649{
2650 u64 pmc;
2651
2652 if (ctxt->ops->read_pmc(ctxt, ctxt->regs[VCPU_REGS_RCX], &pmc))
2653 return emulate_gp(ctxt, 0);
2654 ctxt->regs[VCPU_REGS_RAX] = (u32)pmc;
2655 ctxt->regs[VCPU_REGS_RDX] = pmc >> 32;
2656 return X86EMUL_CONTINUE;
2657}
2658
2625static int em_mov(struct x86_emulate_ctxt *ctxt) 2659static int em_mov(struct x86_emulate_ctxt *ctxt)
2626{ 2660{
2627 ctxt->dst.val = ctxt->src.val; 2661 ctxt->dst.val = ctxt->src.val;
2628 return X86EMUL_CONTINUE; 2662 return X86EMUL_CONTINUE;
2629} 2663}
2630 2664
2665static int em_cr_write(struct x86_emulate_ctxt *ctxt)
2666{
2667 if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
2668 return emulate_gp(ctxt, 0);
2669
2670 /* Disable writeback. */
2671 ctxt->dst.type = OP_NONE;
2672 return X86EMUL_CONTINUE;
2673}
2674
2675static int em_dr_write(struct x86_emulate_ctxt *ctxt)
2676{
2677 unsigned long val;
2678
2679 if (ctxt->mode == X86EMUL_MODE_PROT64)
2680 val = ctxt->src.val & ~0ULL;
2681 else
2682 val = ctxt->src.val & ~0U;
2683
2684 /* #UD condition is already handled. */
2685 if (ctxt->ops->set_dr(ctxt, ctxt->modrm_reg, val) < 0)
2686 return emulate_gp(ctxt, 0);
2687
2688 /* Disable writeback. */
2689 ctxt->dst.type = OP_NONE;
2690 return X86EMUL_CONTINUE;
2691}
2692
2693static int em_wrmsr(struct x86_emulate_ctxt *ctxt)
2694{
2695 u64 msr_data;
2696
2697 msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
2698 | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32);
2699 if (ctxt->ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data))
2700 return emulate_gp(ctxt, 0);
2701
2702 return X86EMUL_CONTINUE;
2703}
2704
2705static int em_rdmsr(struct x86_emulate_ctxt *ctxt)
2706{
2707 u64 msr_data;
2708
2709 if (ctxt->ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data))
2710 return emulate_gp(ctxt, 0);
2711
2712 ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data;
2713 ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32;
2714 return X86EMUL_CONTINUE;
2715}
2716
2631static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt) 2717static int em_mov_rm_sreg(struct x86_emulate_ctxt *ctxt)
2632{ 2718{
2633 if (ctxt->modrm_reg > VCPU_SREG_GS) 2719 if (ctxt->modrm_reg > VCPU_SREG_GS)
@@ -2775,6 +2861,24 @@ static int em_jcxz(struct x86_emulate_ctxt *ctxt)
2775 return X86EMUL_CONTINUE; 2861 return X86EMUL_CONTINUE;
2776} 2862}
2777 2863
2864static int em_in(struct x86_emulate_ctxt *ctxt)
2865{
2866 if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val,
2867 &ctxt->dst.val))
2868 return X86EMUL_IO_NEEDED;
2869
2870 return X86EMUL_CONTINUE;
2871}
2872
2873static int em_out(struct x86_emulate_ctxt *ctxt)
2874{
2875 ctxt->ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val,
2876 &ctxt->src.val, 1);
2877 /* Disable writeback. */
2878 ctxt->dst.type = OP_NONE;
2879 return X86EMUL_CONTINUE;
2880}
2881
2778static int em_cli(struct x86_emulate_ctxt *ctxt) 2882static int em_cli(struct x86_emulate_ctxt *ctxt)
2779{ 2883{
2780 if (emulator_bad_iopl(ctxt)) 2884 if (emulator_bad_iopl(ctxt))
@@ -2794,6 +2898,69 @@ static int em_sti(struct x86_emulate_ctxt *ctxt)
2794 return X86EMUL_CONTINUE; 2898 return X86EMUL_CONTINUE;
2795} 2899}
2796 2900
2901static int em_bt(struct x86_emulate_ctxt *ctxt)
2902{
2903 /* Disable writeback. */
2904 ctxt->dst.type = OP_NONE;
2905 /* only subword offset */
2906 ctxt->src.val &= (ctxt->dst.bytes << 3) - 1;
2907
2908 emulate_2op_SrcV_nobyte(ctxt, "bt");
2909 return X86EMUL_CONTINUE;
2910}
2911
2912static int em_bts(struct x86_emulate_ctxt *ctxt)
2913{
2914 emulate_2op_SrcV_nobyte(ctxt, "bts");
2915 return X86EMUL_CONTINUE;
2916}
2917
2918static int em_btr(struct x86_emulate_ctxt *ctxt)
2919{
2920 emulate_2op_SrcV_nobyte(ctxt, "btr");
2921 return X86EMUL_CONTINUE;
2922}
2923
2924static int em_btc(struct x86_emulate_ctxt *ctxt)
2925{
2926 emulate_2op_SrcV_nobyte(ctxt, "btc");
2927 return X86EMUL_CONTINUE;
2928}
2929
2930static int em_bsf(struct x86_emulate_ctxt *ctxt)
2931{
2932 u8 zf;
2933
2934 __asm__ ("bsf %2, %0; setz %1"
2935 : "=r"(ctxt->dst.val), "=q"(zf)
2936 : "r"(ctxt->src.val));
2937
2938 ctxt->eflags &= ~X86_EFLAGS_ZF;
2939 if (zf) {
2940 ctxt->eflags |= X86_EFLAGS_ZF;
2941 /* Disable writeback. */
2942 ctxt->dst.type = OP_NONE;
2943 }
2944 return X86EMUL_CONTINUE;
2945}
2946
2947static int em_bsr(struct x86_emulate_ctxt *ctxt)
2948{
2949 u8 zf;
2950
2951 __asm__ ("bsr %2, %0; setz %1"
2952 : "=r"(ctxt->dst.val), "=q"(zf)
2953 : "r"(ctxt->src.val));
2954
2955 ctxt->eflags &= ~X86_EFLAGS_ZF;
2956 if (zf) {
2957 ctxt->eflags |= X86_EFLAGS_ZF;
2958 /* Disable writeback. */
2959 ctxt->dst.type = OP_NONE;
2960 }
2961 return X86EMUL_CONTINUE;
2962}
2963
2797static bool valid_cr(int nr) 2964static bool valid_cr(int nr)
2798{ 2965{
2799 switch (nr) { 2966 switch (nr) {
@@ -2867,9 +3034,6 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt)
2867 break; 3034 break;
2868 } 3035 }
2869 case 4: { 3036 case 4: {
2870 u64 cr4;
2871
2872 cr4 = ctxt->ops->get_cr(ctxt, 4);
2873 ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); 3037 ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
2874 3038
2875 if ((efer & EFER_LMA) && !(new_val & X86_CR4_PAE)) 3039 if ((efer & EFER_LMA) && !(new_val & X86_CR4_PAE))
@@ -3003,6 +3167,8 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
3003#define D2bv(_f) D((_f) | ByteOp), D(_f) 3167#define D2bv(_f) D((_f) | ByteOp), D(_f)
3004#define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p) 3168#define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p)
3005#define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e) 3169#define I2bv(_f, _e) I((_f) | ByteOp, _e), I(_f, _e)
3170#define I2bvIP(_f, _e, _i, _p) \
3171 IIP((_f) | ByteOp, _e, _i, _p), IIP(_f, _e, _i, _p)
3006 3172
3007#define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \ 3173#define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e), \
3008 I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \ 3174 I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e), \
@@ -3033,17 +3199,17 @@ static struct opcode group7_rm7[] = {
3033 3199
3034static struct opcode group1[] = { 3200static struct opcode group1[] = {
3035 I(Lock, em_add), 3201 I(Lock, em_add),
3036 I(Lock, em_or), 3202 I(Lock | PageTable, em_or),
3037 I(Lock, em_adc), 3203 I(Lock, em_adc),
3038 I(Lock, em_sbb), 3204 I(Lock, em_sbb),
3039 I(Lock, em_and), 3205 I(Lock | PageTable, em_and),
3040 I(Lock, em_sub), 3206 I(Lock, em_sub),
3041 I(Lock, em_xor), 3207 I(Lock, em_xor),
3042 I(0, em_cmp), 3208 I(0, em_cmp),
3043}; 3209};
3044 3210
3045static struct opcode group1A[] = { 3211static struct opcode group1A[] = {
3046 D(DstMem | SrcNone | ModRM | Mov | Stack), N, N, N, N, N, N, N, 3212 I(DstMem | SrcNone | ModRM | Mov | Stack, em_pop), N, N, N, N, N, N, N,
3047}; 3213};
3048 3214
3049static struct opcode group3[] = { 3215static struct opcode group3[] = {
@@ -3058,16 +3224,19 @@ static struct opcode group3[] = {
3058}; 3224};
3059 3225
3060static struct opcode group4[] = { 3226static struct opcode group4[] = {
3061 D(ByteOp | DstMem | SrcNone | ModRM | Lock), D(ByteOp | DstMem | SrcNone | ModRM | Lock), 3227 I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45),
3228 I(ByteOp | DstMem | SrcNone | ModRM | Lock, em_grp45),
3062 N, N, N, N, N, N, 3229 N, N, N, N, N, N,
3063}; 3230};
3064 3231
3065static struct opcode group5[] = { 3232static struct opcode group5[] = {
3066 D(DstMem | SrcNone | ModRM | Lock), D(DstMem | SrcNone | ModRM | Lock), 3233 I(DstMem | SrcNone | ModRM | Lock, em_grp45),
3067 D(SrcMem | ModRM | Stack), 3234 I(DstMem | SrcNone | ModRM | Lock, em_grp45),
3235 I(SrcMem | ModRM | Stack, em_grp45),
3068 I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far), 3236 I(SrcMemFAddr | ModRM | ImplicitOps | Stack, em_call_far),
3069 D(SrcMem | ModRM | Stack), D(SrcMemFAddr | ModRM | ImplicitOps), 3237 I(SrcMem | ModRM | Stack, em_grp45),
3070 D(SrcMem | ModRM | Stack), N, 3238 I(SrcMemFAddr | ModRM | ImplicitOps, em_grp45),
3239 I(SrcMem | ModRM | Stack, em_grp45), N,
3071}; 3240};
3072 3241
3073static struct opcode group6[] = { 3242static struct opcode group6[] = {
@@ -3096,18 +3265,21 @@ static struct group_dual group7 = { {
3096 3265
3097static struct opcode group8[] = { 3266static struct opcode group8[] = {
3098 N, N, N, N, 3267 N, N, N, N,
3099 D(DstMem | SrcImmByte | ModRM), D(DstMem | SrcImmByte | ModRM | Lock), 3268 I(DstMem | SrcImmByte | ModRM, em_bt),
3100 D(DstMem | SrcImmByte | ModRM | Lock), D(DstMem | SrcImmByte | ModRM | Lock), 3269 I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_bts),
3270 I(DstMem | SrcImmByte | ModRM | Lock, em_btr),
3271 I(DstMem | SrcImmByte | ModRM | Lock | PageTable, em_btc),
3101}; 3272};
3102 3273
3103static struct group_dual group9 = { { 3274static struct group_dual group9 = { {
3104 N, D(DstMem64 | ModRM | Lock), N, N, N, N, N, N, 3275 N, I(DstMem64 | ModRM | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N,
3105}, { 3276}, {
3106 N, N, N, N, N, N, N, N, 3277 N, N, N, N, N, N, N, N,
3107} }; 3278} };
3108 3279
3109static struct opcode group11[] = { 3280static struct opcode group11[] = {
3110 I(DstMem | SrcImm | ModRM | Mov, em_mov), X7(D(Undefined)), 3281 I(DstMem | SrcImm | ModRM | Mov | PageTable, em_mov),
3282 X7(D(Undefined)),
3111}; 3283};
3112 3284
3113static struct gprefix pfx_0f_6f_0f_7f = { 3285static struct gprefix pfx_0f_6f_0f_7f = {
@@ -3120,7 +3292,7 @@ static struct opcode opcode_table[256] = {
3120 I(ImplicitOps | Stack | No64 | Src2ES, em_push_sreg), 3292 I(ImplicitOps | Stack | No64 | Src2ES, em_push_sreg),
3121 I(ImplicitOps | Stack | No64 | Src2ES, em_pop_sreg), 3293 I(ImplicitOps | Stack | No64 | Src2ES, em_pop_sreg),
3122 /* 0x08 - 0x0F */ 3294 /* 0x08 - 0x0F */
3123 I6ALU(Lock, em_or), 3295 I6ALU(Lock | PageTable, em_or),
3124 I(ImplicitOps | Stack | No64 | Src2CS, em_push_sreg), 3296 I(ImplicitOps | Stack | No64 | Src2CS, em_push_sreg),
3125 N, 3297 N,
3126 /* 0x10 - 0x17 */ 3298 /* 0x10 - 0x17 */
@@ -3132,7 +3304,7 @@ static struct opcode opcode_table[256] = {
3132 I(ImplicitOps | Stack | No64 | Src2DS, em_push_sreg), 3304 I(ImplicitOps | Stack | No64 | Src2DS, em_push_sreg),
3133 I(ImplicitOps | Stack | No64 | Src2DS, em_pop_sreg), 3305 I(ImplicitOps | Stack | No64 | Src2DS, em_pop_sreg),
3134 /* 0x20 - 0x27 */ 3306 /* 0x20 - 0x27 */
3135 I6ALU(Lock, em_and), N, N, 3307 I6ALU(Lock | PageTable, em_and), N, N,
3136 /* 0x28 - 0x2F */ 3308 /* 0x28 - 0x2F */
3137 I6ALU(Lock, em_sub), N, I(ByteOp | DstAcc | No64, em_das), 3309 I6ALU(Lock, em_sub), N, I(ByteOp | DstAcc | No64, em_das),
3138 /* 0x30 - 0x37 */ 3310 /* 0x30 - 0x37 */
@@ -3155,8 +3327,8 @@ static struct opcode opcode_table[256] = {
3155 I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op), 3327 I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
3156 I(SrcImmByte | Mov | Stack, em_push), 3328 I(SrcImmByte | Mov | Stack, em_push),
3157 I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op), 3329 I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
3158 D2bvIP(DstDI | SrcDX | Mov | String, ins, check_perm_in), /* insb, insw/insd */ 3330 I2bvIP(DstDI | SrcDX | Mov | String, em_in, ins, check_perm_in), /* insb, insw/insd */
3159 D2bvIP(SrcSI | DstDX | String, outs, check_perm_out), /* outsb, outsw/outsd */ 3331 I2bvIP(SrcSI | DstDX | String, em_out, outs, check_perm_out), /* outsb, outsw/outsd */
3160 /* 0x70 - 0x7F */ 3332 /* 0x70 - 0x7F */
3161 X16(D(SrcImmByte)), 3333 X16(D(SrcImmByte)),
3162 /* 0x80 - 0x87 */ 3334 /* 0x80 - 0x87 */
@@ -3165,11 +3337,11 @@ static struct opcode opcode_table[256] = {
3165 G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1), 3337 G(ByteOp | DstMem | SrcImm | ModRM | No64 | Group, group1),
3166 G(DstMem | SrcImmByte | ModRM | Group, group1), 3338 G(DstMem | SrcImmByte | ModRM | Group, group1),
3167 I2bv(DstMem | SrcReg | ModRM, em_test), 3339 I2bv(DstMem | SrcReg | ModRM, em_test),
3168 I2bv(DstMem | SrcReg | ModRM | Lock, em_xchg), 3340 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_xchg),
3169 /* 0x88 - 0x8F */ 3341 /* 0x88 - 0x8F */
3170 I2bv(DstMem | SrcReg | ModRM | Mov, em_mov), 3342 I2bv(DstMem | SrcReg | ModRM | Mov | PageTable, em_mov),
3171 I2bv(DstReg | SrcMem | ModRM | Mov, em_mov), 3343 I2bv(DstReg | SrcMem | ModRM | Mov, em_mov),
3172 I(DstMem | SrcNone | ModRM | Mov, em_mov_rm_sreg), 3344 I(DstMem | SrcNone | ModRM | Mov | PageTable, em_mov_rm_sreg),
3173 D(ModRM | SrcMem | NoAccess | DstReg), 3345 D(ModRM | SrcMem | NoAccess | DstReg),
3174 I(ImplicitOps | SrcMem16 | ModRM, em_mov_sreg_rm), 3346 I(ImplicitOps | SrcMem16 | ModRM, em_mov_sreg_rm),
3175 G(0, group1A), 3347 G(0, group1A),
@@ -3182,7 +3354,7 @@ static struct opcode opcode_table[256] = {
3182 II(ImplicitOps | Stack, em_popf, popf), N, N, 3354 II(ImplicitOps | Stack, em_popf, popf), N, N,
3183 /* 0xA0 - 0xA7 */ 3355 /* 0xA0 - 0xA7 */
3184 I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov), 3356 I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
3185 I2bv(DstMem | SrcAcc | Mov | MemAbs, em_mov), 3357 I2bv(DstMem | SrcAcc | Mov | MemAbs | PageTable, em_mov),
3186 I2bv(SrcSI | DstDI | Mov | String, em_mov), 3358 I2bv(SrcSI | DstDI | Mov | String, em_mov),
3187 I2bv(SrcSI | DstDI | String, em_cmp), 3359 I2bv(SrcSI | DstDI | String, em_cmp),
3188 /* 0xA8 - 0xAF */ 3360 /* 0xA8 - 0xAF */
@@ -3213,13 +3385,13 @@ static struct opcode opcode_table[256] = {
3213 /* 0xE0 - 0xE7 */ 3385 /* 0xE0 - 0xE7 */
3214 X3(I(SrcImmByte, em_loop)), 3386 X3(I(SrcImmByte, em_loop)),
3215 I(SrcImmByte, em_jcxz), 3387 I(SrcImmByte, em_jcxz),
3216 D2bvIP(SrcImmUByte | DstAcc, in, check_perm_in), 3388 I2bvIP(SrcImmUByte | DstAcc, em_in, in, check_perm_in),
3217 D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out), 3389 I2bvIP(SrcAcc | DstImmUByte, em_out, out, check_perm_out),
3218 /* 0xE8 - 0xEF */ 3390 /* 0xE8 - 0xEF */
3219 D(SrcImm | Stack), D(SrcImm | ImplicitOps), 3391 I(SrcImm | Stack, em_call), D(SrcImm | ImplicitOps),
3220 I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps), 3392 I(SrcImmFAddr | No64, em_jmp_far), D(SrcImmByte | ImplicitOps),
3221 D2bvIP(SrcDX | DstAcc, in, check_perm_in), 3393 I2bvIP(SrcDX | DstAcc, em_in, in, check_perm_in),
3222 D2bvIP(SrcAcc | DstDX, out, check_perm_out), 3394 I2bvIP(SrcAcc | DstDX, em_out, out, check_perm_out),
3223 /* 0xF0 - 0xF7 */ 3395 /* 0xF0 - 0xF7 */
3224 N, DI(ImplicitOps, icebp), N, N, 3396 N, DI(ImplicitOps, icebp), N, N,
3225 DI(ImplicitOps | Priv, hlt), D(ImplicitOps), 3397 DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
@@ -3242,15 +3414,15 @@ static struct opcode twobyte_table[256] = {
3242 /* 0x20 - 0x2F */ 3414 /* 0x20 - 0x2F */
3243 DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read), 3415 DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
3244 DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read), 3416 DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
3245 DIP(ModRM | SrcMem | Priv | Op3264, cr_write, check_cr_write), 3417 IIP(ModRM | SrcMem | Priv | Op3264, em_cr_write, cr_write, check_cr_write),
3246 DIP(ModRM | SrcMem | Priv | Op3264, dr_write, check_dr_write), 3418 IIP(ModRM | SrcMem | Priv | Op3264, em_dr_write, dr_write, check_dr_write),
3247 N, N, N, N, 3419 N, N, N, N,
3248 N, N, N, N, N, N, N, N, 3420 N, N, N, N, N, N, N, N,
3249 /* 0x30 - 0x3F */ 3421 /* 0x30 - 0x3F */
3250 DI(ImplicitOps | Priv, wrmsr), 3422 II(ImplicitOps | Priv, em_wrmsr, wrmsr),
3251 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc), 3423 IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
3252 DI(ImplicitOps | Priv, rdmsr), 3424 II(ImplicitOps | Priv, em_rdmsr, rdmsr),
3253 DIP(ImplicitOps | Priv, rdpmc, check_rdpmc), 3425 IIP(ImplicitOps, em_rdpmc, rdpmc, check_rdpmc),
3254 I(ImplicitOps | VendorSpecific, em_sysenter), 3426 I(ImplicitOps | VendorSpecific, em_sysenter),
3255 I(ImplicitOps | Priv | VendorSpecific, em_sysexit), 3427 I(ImplicitOps | Priv | VendorSpecific, em_sysexit),
3256 N, N, 3428 N, N,
@@ -3275,26 +3447,28 @@ static struct opcode twobyte_table[256] = {
3275 X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), 3447 X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
3276 /* 0xA0 - 0xA7 */ 3448 /* 0xA0 - 0xA7 */
3277 I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg), 3449 I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg),
3278 DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp), 3450 DI(ImplicitOps, cpuid), I(DstMem | SrcReg | ModRM | BitOp, em_bt),
3279 D(DstMem | SrcReg | Src2ImmByte | ModRM), 3451 D(DstMem | SrcReg | Src2ImmByte | ModRM),
3280 D(DstMem | SrcReg | Src2CL | ModRM), N, N, 3452 D(DstMem | SrcReg | Src2CL | ModRM), N, N,
3281 /* 0xA8 - 0xAF */ 3453 /* 0xA8 - 0xAF */
3282 I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg), 3454 I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
3283 DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock), 3455 DI(ImplicitOps, rsm),
3456 I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
3284 D(DstMem | SrcReg | Src2ImmByte | ModRM), 3457 D(DstMem | SrcReg | Src2ImmByte | ModRM),
3285 D(DstMem | SrcReg | Src2CL | ModRM), 3458 D(DstMem | SrcReg | Src2CL | ModRM),
3286 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul), 3459 D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
3287 /* 0xB0 - 0xB7 */ 3460 /* 0xB0 - 0xB7 */
3288 D2bv(DstMem | SrcReg | ModRM | Lock), 3461 I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
3289 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), 3462 I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
3290 D(DstMem | SrcReg | ModRM | BitOp | Lock), 3463 I(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
3291 I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg), 3464 I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
3292 I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg), 3465 I(DstReg | SrcMemFAddr | ModRM | Src2GS, em_lseg),
3293 D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), 3466 D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
3294 /* 0xB8 - 0xBF */ 3467 /* 0xB8 - 0xBF */
3295 N, N, 3468 N, N,
3296 G(BitOp, group8), D(DstMem | SrcReg | ModRM | BitOp | Lock), 3469 G(BitOp, group8),
3297 D(DstReg | SrcMem | ModRM), D(DstReg | SrcMem | ModRM), 3470 I(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_btc),
3471 I(DstReg | SrcMem | ModRM, em_bsf), I(DstReg | SrcMem | ModRM, em_bsr),
3298 D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov), 3472 D(ByteOp | DstReg | SrcMem | ModRM | Mov), D(DstReg | SrcMem16 | ModRM | Mov),
3299 /* 0xC0 - 0xCF */ 3473 /* 0xC0 - 0xCF */
3300 D2bv(DstMem | SrcReg | ModRM | Lock), 3474 D2bv(DstMem | SrcReg | ModRM | Lock),
@@ -3320,6 +3494,7 @@ static struct opcode twobyte_table[256] = {
3320#undef D2bv 3494#undef D2bv
3321#undef D2bvIP 3495#undef D2bvIP
3322#undef I2bv 3496#undef I2bv
3497#undef I2bvIP
3323#undef I6ALU 3498#undef I6ALU
3324 3499
3325static unsigned imm_size(struct x86_emulate_ctxt *ctxt) 3500static unsigned imm_size(struct x86_emulate_ctxt *ctxt)
@@ -3697,6 +3872,11 @@ done:
3697 return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; 3872 return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
3698} 3873}
3699 3874
3875bool x86_page_table_writing_insn(struct x86_emulate_ctxt *ctxt)
3876{
3877 return ctxt->d & PageTable;
3878}
3879
3700static bool string_insn_completed(struct x86_emulate_ctxt *ctxt) 3880static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
3701{ 3881{
3702 /* The second termination condition only applies for REPE 3882 /* The second termination condition only applies for REPE
@@ -3720,7 +3900,6 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
3720int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) 3900int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
3721{ 3901{
3722 struct x86_emulate_ops *ops = ctxt->ops; 3902 struct x86_emulate_ops *ops = ctxt->ops;
3723 u64 msr_data;
3724 int rc = X86EMUL_CONTINUE; 3903 int rc = X86EMUL_CONTINUE;
3725 int saved_dst_type = ctxt->dst.type; 3904 int saved_dst_type = ctxt->dst.type;
3726 3905
@@ -3854,15 +4033,6 @@ special_insn:
3854 goto cannot_emulate; 4033 goto cannot_emulate;
3855 ctxt->dst.val = (s32) ctxt->src.val; 4034 ctxt->dst.val = (s32) ctxt->src.val;
3856 break; 4035 break;
3857 case 0x6c: /* insb */
3858 case 0x6d: /* insw/insd */
3859 ctxt->src.val = ctxt->regs[VCPU_REGS_RDX];
3860 goto do_io_in;
3861 case 0x6e: /* outsb */
3862 case 0x6f: /* outsw/outsd */
3863 ctxt->dst.val = ctxt->regs[VCPU_REGS_RDX];
3864 goto do_io_out;
3865 break;
3866 case 0x70 ... 0x7f: /* jcc (short) */ 4036 case 0x70 ... 0x7f: /* jcc (short) */
3867 if (test_cc(ctxt->b, ctxt->eflags)) 4037 if (test_cc(ctxt->b, ctxt->eflags))
3868 jmp_rel(ctxt, ctxt->src.val); 4038 jmp_rel(ctxt, ctxt->src.val);
@@ -3870,9 +4040,6 @@ special_insn:
3870 case 0x8d: /* lea r16/r32, m */ 4040 case 0x8d: /* lea r16/r32, m */
3871 ctxt->dst.val = ctxt->src.addr.mem.ea; 4041 ctxt->dst.val = ctxt->src.addr.mem.ea;
3872 break; 4042 break;
3873 case 0x8f: /* pop (sole member of Grp1a) */
3874 rc = em_grp1a(ctxt);
3875 break;
3876 case 0x90 ... 0x97: /* nop / xchg reg, rax */ 4043 case 0x90 ... 0x97: /* nop / xchg reg, rax */
3877 if (ctxt->dst.addr.reg == &ctxt->regs[VCPU_REGS_RAX]) 4044 if (ctxt->dst.addr.reg == &ctxt->regs[VCPU_REGS_RAX])
3878 break; 4045 break;
@@ -3905,38 +4072,11 @@ special_insn:
3905 ctxt->src.val = ctxt->regs[VCPU_REGS_RCX]; 4072 ctxt->src.val = ctxt->regs[VCPU_REGS_RCX];
3906 rc = em_grp2(ctxt); 4073 rc = em_grp2(ctxt);
3907 break; 4074 break;
3908 case 0xe4: /* inb */
3909 case 0xe5: /* in */
3910 goto do_io_in;
3911 case 0xe6: /* outb */
3912 case 0xe7: /* out */
3913 goto do_io_out;
3914 case 0xe8: /* call (near) */ {
3915 long int rel = ctxt->src.val;
3916 ctxt->src.val = (unsigned long) ctxt->_eip;
3917 jmp_rel(ctxt, rel);
3918 rc = em_push(ctxt);
3919 break;
3920 }
3921 case 0xe9: /* jmp rel */ 4075 case 0xe9: /* jmp rel */
3922 case 0xeb: /* jmp rel short */ 4076 case 0xeb: /* jmp rel short */
3923 jmp_rel(ctxt, ctxt->src.val); 4077 jmp_rel(ctxt, ctxt->src.val);
3924 ctxt->dst.type = OP_NONE; /* Disable writeback. */ 4078 ctxt->dst.type = OP_NONE; /* Disable writeback. */
3925 break; 4079 break;
3926 case 0xec: /* in al,dx */
3927 case 0xed: /* in (e/r)ax,dx */
3928 do_io_in:
3929 if (!pio_in_emulated(ctxt, ctxt->dst.bytes, ctxt->src.val,
3930 &ctxt->dst.val))
3931 goto done; /* IO is needed */
3932 break;
3933 case 0xee: /* out dx,al */
3934 case 0xef: /* out dx,(e/r)ax */
3935 do_io_out:
3936 ops->pio_out_emulated(ctxt, ctxt->src.bytes, ctxt->dst.val,
3937 &ctxt->src.val, 1);
3938 ctxt->dst.type = OP_NONE; /* Disable writeback. */
3939 break;
3940 case 0xf4: /* hlt */ 4080 case 0xf4: /* hlt */
3941 ctxt->ops->halt(ctxt); 4081 ctxt->ops->halt(ctxt);
3942 break; 4082 break;
@@ -3956,12 +4096,6 @@ special_insn:
3956 case 0xfd: /* std */ 4096 case 0xfd: /* std */
3957 ctxt->eflags |= EFLG_DF; 4097 ctxt->eflags |= EFLG_DF;
3958 break; 4098 break;
3959 case 0xfe: /* Grp4 */
3960 rc = em_grp45(ctxt);
3961 break;
3962 case 0xff: /* Grp5 */
3963 rc = em_grp45(ctxt);
3964 break;
3965 default: 4099 default:
3966 goto cannot_emulate; 4100 goto cannot_emulate;
3967 } 4101 }
@@ -4036,49 +4170,6 @@ twobyte_insn:
4036 case 0x21: /* mov from dr to reg */ 4170 case 0x21: /* mov from dr to reg */
4037 ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val); 4171 ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
4038 break; 4172 break;
4039 case 0x22: /* mov reg, cr */
4040 if (ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) {
4041 emulate_gp(ctxt, 0);
4042 rc = X86EMUL_PROPAGATE_FAULT;
4043 goto done;
4044 }
4045 ctxt->dst.type = OP_NONE;
4046 break;
4047 case 0x23: /* mov from reg to dr */
4048 if (ops->set_dr(ctxt, ctxt->modrm_reg, ctxt->src.val &
4049 ((ctxt->mode == X86EMUL_MODE_PROT64) ?
4050 ~0ULL : ~0U)) < 0) {
4051 /* #UD condition is already handled by the code above */
4052 emulate_gp(ctxt, 0);
4053 rc = X86EMUL_PROPAGATE_FAULT;
4054 goto done;
4055 }
4056
4057 ctxt->dst.type = OP_NONE; /* no writeback */
4058 break;
4059 case 0x30:
4060 /* wrmsr */
4061 msr_data = (u32)ctxt->regs[VCPU_REGS_RAX]
4062 | ((u64)ctxt->regs[VCPU_REGS_RDX] << 32);
4063 if (ops->set_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], msr_data)) {
4064 emulate_gp(ctxt, 0);
4065 rc = X86EMUL_PROPAGATE_FAULT;
4066 goto done;
4067 }
4068 rc = X86EMUL_CONTINUE;
4069 break;
4070 case 0x32:
4071 /* rdmsr */
4072 if (ops->get_msr(ctxt, ctxt->regs[VCPU_REGS_RCX], &msr_data)) {
4073 emulate_gp(ctxt, 0);
4074 rc = X86EMUL_PROPAGATE_FAULT;
4075 goto done;
4076 } else {
4077 ctxt->regs[VCPU_REGS_RAX] = (u32)msr_data;
4078 ctxt->regs[VCPU_REGS_RDX] = msr_data >> 32;
4079 }
4080 rc = X86EMUL_CONTINUE;
4081 break;
4082 case 0x40 ... 0x4f: /* cmov */ 4173 case 0x40 ... 0x4f: /* cmov */
4083 ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val; 4174 ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val;
4084 if (!test_cc(ctxt->b, ctxt->eflags)) 4175 if (!test_cc(ctxt->b, ctxt->eflags))
@@ -4091,93 +4182,21 @@ twobyte_insn:
4091 case 0x90 ... 0x9f: /* setcc r/m8 */ 4182 case 0x90 ... 0x9f: /* setcc r/m8 */
4092 ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); 4183 ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags);
4093 break; 4184 break;
4094 case 0xa3:
4095 bt: /* bt */
4096 ctxt->dst.type = OP_NONE;
4097 /* only subword offset */
4098 ctxt->src.val &= (ctxt->dst.bytes << 3) - 1;
4099 emulate_2op_SrcV_nobyte(ctxt, "bt");
4100 break;
4101 case 0xa4: /* shld imm8, r, r/m */ 4185 case 0xa4: /* shld imm8, r, r/m */
4102 case 0xa5: /* shld cl, r, r/m */ 4186 case 0xa5: /* shld cl, r, r/m */
4103 emulate_2op_cl(ctxt, "shld"); 4187 emulate_2op_cl(ctxt, "shld");
4104 break; 4188 break;
4105 case 0xab:
4106 bts: /* bts */
4107 emulate_2op_SrcV_nobyte(ctxt, "bts");
4108 break;
4109 case 0xac: /* shrd imm8, r, r/m */ 4189 case 0xac: /* shrd imm8, r, r/m */
4110 case 0xad: /* shrd cl, r, r/m */ 4190 case 0xad: /* shrd cl, r, r/m */
4111 emulate_2op_cl(ctxt, "shrd"); 4191 emulate_2op_cl(ctxt, "shrd");
4112 break; 4192 break;
4113 case 0xae: /* clflush */ 4193 case 0xae: /* clflush */
4114 break; 4194 break;
4115 case 0xb0 ... 0xb1: /* cmpxchg */
4116 /*
4117 * Save real source value, then compare EAX against
4118 * destination.
4119 */
4120 ctxt->src.orig_val = ctxt->src.val;
4121 ctxt->src.val = ctxt->regs[VCPU_REGS_RAX];
4122 emulate_2op_SrcV(ctxt, "cmp");
4123 if (ctxt->eflags & EFLG_ZF) {
4124 /* Success: write back to memory. */
4125 ctxt->dst.val = ctxt->src.orig_val;
4126 } else {
4127 /* Failure: write the value we saw to EAX. */
4128 ctxt->dst.type = OP_REG;
4129 ctxt->dst.addr.reg = (unsigned long *)&ctxt->regs[VCPU_REGS_RAX];
4130 }
4131 break;
4132 case 0xb3:
4133 btr: /* btr */
4134 emulate_2op_SrcV_nobyte(ctxt, "btr");
4135 break;
4136 case 0xb6 ... 0xb7: /* movzx */ 4195 case 0xb6 ... 0xb7: /* movzx */
4137 ctxt->dst.bytes = ctxt->op_bytes; 4196 ctxt->dst.bytes = ctxt->op_bytes;
4138 ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val 4197 ctxt->dst.val = (ctxt->d & ByteOp) ? (u8) ctxt->src.val
4139 : (u16) ctxt->src.val; 4198 : (u16) ctxt->src.val;
4140 break; 4199 break;
4141 case 0xba: /* Grp8 */
4142 switch (ctxt->modrm_reg & 3) {
4143 case 0:
4144 goto bt;
4145 case 1:
4146 goto bts;
4147 case 2:
4148 goto btr;
4149 case 3:
4150 goto btc;
4151 }
4152 break;
4153 case 0xbb:
4154 btc: /* btc */
4155 emulate_2op_SrcV_nobyte(ctxt, "btc");
4156 break;
4157 case 0xbc: { /* bsf */
4158 u8 zf;
4159 __asm__ ("bsf %2, %0; setz %1"
4160 : "=r"(ctxt->dst.val), "=q"(zf)
4161 : "r"(ctxt->src.val));
4162 ctxt->eflags &= ~X86_EFLAGS_ZF;
4163 if (zf) {
4164 ctxt->eflags |= X86_EFLAGS_ZF;
4165 ctxt->dst.type = OP_NONE; /* Disable writeback. */
4166 }
4167 break;
4168 }
4169 case 0xbd: { /* bsr */
4170 u8 zf;
4171 __asm__ ("bsr %2, %0; setz %1"
4172 : "=r"(ctxt->dst.val), "=q"(zf)
4173 : "r"(ctxt->src.val));
4174 ctxt->eflags &= ~X86_EFLAGS_ZF;
4175 if (zf) {
4176 ctxt->eflags |= X86_EFLAGS_ZF;
4177 ctxt->dst.type = OP_NONE; /* Disable writeback. */
4178 }
4179 break;
4180 }
4181 case 0xbe ... 0xbf: /* movsx */ 4200 case 0xbe ... 0xbf: /* movsx */
4182 ctxt->dst.bytes = ctxt->op_bytes; 4201 ctxt->dst.bytes = ctxt->op_bytes;
4183 ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val : 4202 ctxt->dst.val = (ctxt->d & ByteOp) ? (s8) ctxt->src.val :
@@ -4194,9 +4213,6 @@ twobyte_insn:
4194 ctxt->dst.val = (ctxt->op_bytes == 4) ? (u32) ctxt->src.val : 4213 ctxt->dst.val = (ctxt->op_bytes == 4) ? (u32) ctxt->src.val :
4195 (u64) ctxt->src.val; 4214 (u64) ctxt->src.val;
4196 break; 4215 break;
4197 case 0xc7: /* Grp9 (cmpxchg8b) */
4198 rc = em_grp9(ctxt);
4199 break;
4200 default: 4216 default:
4201 goto cannot_emulate; 4217 goto cannot_emulate;
4202 } 4218 }
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 405f2620392..d68f99df690 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -344,7 +344,7 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
344 struct kvm_timer *pt = &ps->pit_timer; 344 struct kvm_timer *pt = &ps->pit_timer;
345 s64 interval; 345 s64 interval;
346 346
347 if (!irqchip_in_kernel(kvm)) 347 if (!irqchip_in_kernel(kvm) || ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)
348 return; 348 return;
349 349
350 interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); 350 interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
@@ -397,15 +397,11 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
397 case 1: 397 case 1:
398 /* FIXME: enhance mode 4 precision */ 398 /* FIXME: enhance mode 4 precision */
399 case 4: 399 case 4:
400 if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) { 400 create_pit_timer(kvm, val, 0);
401 create_pit_timer(kvm, val, 0);
402 }
403 break; 401 break;
404 case 2: 402 case 2:
405 case 3: 403 case 3:
406 if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){ 404 create_pit_timer(kvm, val, 1);
407 create_pit_timer(kvm, val, 1);
408 }
409 break; 405 break;
410 default: 406 default:
411 destroy_pit_timer(kvm->arch.vpit); 407 destroy_pit_timer(kvm->arch.vpit);
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index cac4746d7ff..b6a73537e1e 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -262,9 +262,10 @@ int kvm_pic_read_irq(struct kvm *kvm)
262 262
263void kvm_pic_reset(struct kvm_kpic_state *s) 263void kvm_pic_reset(struct kvm_kpic_state *s)
264{ 264{
265 int irq; 265 int irq, i;
266 struct kvm_vcpu *vcpu0 = s->pics_state->kvm->bsp_vcpu; 266 struct kvm_vcpu *vcpu;
267 u8 irr = s->irr, isr = s->imr; 267 u8 irr = s->irr, isr = s->imr;
268 bool found = false;
268 269
269 s->last_irr = 0; 270 s->last_irr = 0;
270 s->irr = 0; 271 s->irr = 0;
@@ -281,12 +282,19 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
281 s->special_fully_nested_mode = 0; 282 s->special_fully_nested_mode = 0;
282 s->init4 = 0; 283 s->init4 = 0;
283 284
284 for (irq = 0; irq < PIC_NUM_PINS/2; irq++) { 285 kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm)
285 if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0)) 286 if (kvm_apic_accept_pic_intr(vcpu)) {
286 if (irr & (1 << irq) || isr & (1 << irq)) { 287 found = true;
287 pic_clear_isr(s, irq); 288 break;
288 } 289 }
289 } 290
291
292 if (!found)
293 return;
294
295 for (irq = 0; irq < PIC_NUM_PINS/2; irq++)
296 if (irr & (1 << irq) || isr & (1 << irq))
297 pic_clear_isr(s, irq);
290} 298}
291 299
292static void pic_ioport_write(void *opaque, u32 addr, u32 val) 300static void pic_ioport_write(void *opaque, u32 addr, u32 val)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 54abb40199d..cfdc6e0ef00 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -38,6 +38,7 @@
38#include "irq.h" 38#include "irq.h"
39#include "trace.h" 39#include "trace.h"
40#include "x86.h" 40#include "x86.h"
41#include "cpuid.h"
41 42
42#ifndef CONFIG_X86_64 43#ifndef CONFIG_X86_64
43#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) 44#define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@@ -1120,7 +1121,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu)
1120 return 0; 1121 return 0;
1121} 1122}
1122 1123
1123static int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) 1124int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type)
1124{ 1125{
1125 u32 reg = apic_get_reg(apic, lvt_type); 1126 u32 reg = apic_get_reg(apic, lvt_type);
1126 int vector, mode, trig_mode; 1127 int vector, mode, trig_mode;
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index 138e8cc6fea..6f4ce2575d0 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -34,6 +34,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu);
34int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest); 34int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
35int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda); 35int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
36int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq); 36int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq);
37int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
37 38
38u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); 39u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
39void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); 40void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index f1b36cf3e3d..2a2a9b40db1 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -59,15 +59,6 @@ enum {
59 AUDIT_POST_SYNC 59 AUDIT_POST_SYNC
60}; 60};
61 61
62char *audit_point_name[] = {
63 "pre page fault",
64 "post page fault",
65 "pre pte write",
66 "post pte write",
67 "pre sync",
68 "post sync"
69};
70
71#undef MMU_DEBUG 62#undef MMU_DEBUG
72 63
73#ifdef MMU_DEBUG 64#ifdef MMU_DEBUG
@@ -87,9 +78,6 @@ static int dbg = 0;
87module_param(dbg, bool, 0644); 78module_param(dbg, bool, 0644);
88#endif 79#endif
89 80
90static int oos_shadow = 1;
91module_param(oos_shadow, bool, 0644);
92
93#ifndef MMU_DEBUG 81#ifndef MMU_DEBUG
94#define ASSERT(x) do { } while (0) 82#define ASSERT(x) do { } while (0)
95#else 83#else
@@ -593,6 +581,11 @@ static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
593 return 0; 581 return 0;
594} 582}
595 583
584static int mmu_memory_cache_free_objects(struct kvm_mmu_memory_cache *cache)
585{
586 return cache->nobjs;
587}
588
596static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc, 589static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc,
597 struct kmem_cache *cache) 590 struct kmem_cache *cache)
598{ 591{
@@ -953,21 +946,35 @@ static void pte_list_walk(unsigned long *pte_list, pte_list_walk_fn fn)
953 } 946 }
954} 947}
955 948
949static unsigned long *__gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level,
950 struct kvm_memory_slot *slot)
951{
952 struct kvm_lpage_info *linfo;
953
954 if (likely(level == PT_PAGE_TABLE_LEVEL))
955 return &slot->rmap[gfn - slot->base_gfn];
956
957 linfo = lpage_info_slot(gfn, slot, level);
958 return &linfo->rmap_pde;
959}
960
956/* 961/*
957 * Take gfn and return the reverse mapping to it. 962 * Take gfn and return the reverse mapping to it.
958 */ 963 */
959static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level) 964static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level)
960{ 965{
961 struct kvm_memory_slot *slot; 966 struct kvm_memory_slot *slot;
962 struct kvm_lpage_info *linfo;
963 967
964 slot = gfn_to_memslot(kvm, gfn); 968 slot = gfn_to_memslot(kvm, gfn);
965 if (likely(level == PT_PAGE_TABLE_LEVEL)) 969 return __gfn_to_rmap(kvm, gfn, level, slot);
966 return &slot->rmap[gfn - slot->base_gfn]; 970}
967 971
968 linfo = lpage_info_slot(gfn, slot, level); 972static bool rmap_can_add(struct kvm_vcpu *vcpu)
973{
974 struct kvm_mmu_memory_cache *cache;
969 975
970 return &linfo->rmap_pde; 976 cache = &vcpu->arch.mmu_pte_list_desc_cache;
977 return mmu_memory_cache_free_objects(cache);
971} 978}
972 979
973static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) 980static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
@@ -1004,17 +1011,16 @@ static void drop_spte(struct kvm *kvm, u64 *sptep)
1004 rmap_remove(kvm, sptep); 1011 rmap_remove(kvm, sptep);
1005} 1012}
1006 1013
1007static int rmap_write_protect(struct kvm *kvm, u64 gfn) 1014int kvm_mmu_rmap_write_protect(struct kvm *kvm, u64 gfn,
1015 struct kvm_memory_slot *slot)
1008{ 1016{
1009 unsigned long *rmapp; 1017 unsigned long *rmapp;
1010 u64 *spte; 1018 u64 *spte;
1011 int i, write_protected = 0; 1019 int i, write_protected = 0;
1012 1020
1013 rmapp = gfn_to_rmap(kvm, gfn, PT_PAGE_TABLE_LEVEL); 1021 rmapp = __gfn_to_rmap(kvm, gfn, PT_PAGE_TABLE_LEVEL, slot);
1014
1015 spte = rmap_next(kvm, rmapp, NULL); 1022 spte = rmap_next(kvm, rmapp, NULL);
1016 while (spte) { 1023 while (spte) {
1017 BUG_ON(!spte);
1018 BUG_ON(!(*spte & PT_PRESENT_MASK)); 1024 BUG_ON(!(*spte & PT_PRESENT_MASK));
1019 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); 1025 rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
1020 if (is_writable_pte(*spte)) { 1026 if (is_writable_pte(*spte)) {
@@ -1027,12 +1033,11 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
1027 /* check for huge page mappings */ 1033 /* check for huge page mappings */
1028 for (i = PT_DIRECTORY_LEVEL; 1034 for (i = PT_DIRECTORY_LEVEL;
1029 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) { 1035 i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
1030 rmapp = gfn_to_rmap(kvm, gfn, i); 1036 rmapp = __gfn_to_rmap(kvm, gfn, i, slot);
1031 spte = rmap_next(kvm, rmapp, NULL); 1037 spte = rmap_next(kvm, rmapp, NULL);
1032 while (spte) { 1038 while (spte) {
1033 BUG_ON(!spte);
1034 BUG_ON(!(*spte & PT_PRESENT_MASK)); 1039 BUG_ON(!(*spte & PT_PRESENT_MASK));
1035 BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)); 1040 BUG_ON(!is_large_pte(*spte));
1036 pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn); 1041 pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
1037 if (is_writable_pte(*spte)) { 1042 if (is_writable_pte(*spte)) {
1038 drop_spte(kvm, spte); 1043 drop_spte(kvm, spte);
@@ -1047,6 +1052,14 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
1047 return write_protected; 1052 return write_protected;
1048} 1053}
1049 1054
1055static int rmap_write_protect(struct kvm *kvm, u64 gfn)
1056{
1057 struct kvm_memory_slot *slot;
1058
1059 slot = gfn_to_memslot(kvm, gfn);
1060 return kvm_mmu_rmap_write_protect(kvm, gfn, slot);
1061}
1062
1050static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, 1063static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp,
1051 unsigned long data) 1064 unsigned long data)
1052{ 1065{
@@ -1103,15 +1116,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
1103 int (*handler)(struct kvm *kvm, unsigned long *rmapp, 1116 int (*handler)(struct kvm *kvm, unsigned long *rmapp,
1104 unsigned long data)) 1117 unsigned long data))
1105{ 1118{
1106 int i, j; 1119 int j;
1107 int ret; 1120 int ret;
1108 int retval = 0; 1121 int retval = 0;
1109 struct kvm_memslots *slots; 1122 struct kvm_memslots *slots;
1123 struct kvm_memory_slot *memslot;
1110 1124
1111 slots = kvm_memslots(kvm); 1125 slots = kvm_memslots(kvm);
1112 1126
1113 for (i = 0; i < slots->nmemslots; i++) { 1127 kvm_for_each_memslot(memslot, slots) {
1114 struct kvm_memory_slot *memslot = &slots->memslots[i];
1115 unsigned long start = memslot->userspace_addr; 1128 unsigned long start = memslot->userspace_addr;
1116 unsigned long end; 1129 unsigned long end;
1117 1130
@@ -1324,7 +1337,7 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
1324 PAGE_SIZE); 1337 PAGE_SIZE);
1325 set_page_private(virt_to_page(sp->spt), (unsigned long)sp); 1338 set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
1326 list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages); 1339 list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
1327 bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS); 1340 bitmap_zero(sp->slot_bitmap, KVM_MEM_SLOTS_NUM);
1328 sp->parent_ptes = 0; 1341 sp->parent_ptes = 0;
1329 mmu_page_add_parent_pte(vcpu, sp, parent_pte); 1342 mmu_page_add_parent_pte(vcpu, sp, parent_pte);
1330 kvm_mod_used_mmu_pages(vcpu->kvm, +1); 1343 kvm_mod_used_mmu_pages(vcpu->kvm, +1);
@@ -1511,6 +1524,13 @@ static int kvm_sync_page_transient(struct kvm_vcpu *vcpu,
1511 return ret; 1524 return ret;
1512} 1525}
1513 1526
1527#ifdef CONFIG_KVM_MMU_AUDIT
1528#include "mmu_audit.c"
1529#else
1530static void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point) { }
1531static void mmu_audit_disable(void) { }
1532#endif
1533
1514static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, 1534static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
1515 struct list_head *invalid_list) 1535 struct list_head *invalid_list)
1516{ 1536{
@@ -1640,6 +1660,18 @@ static void init_shadow_page_table(struct kvm_mmu_page *sp)
1640 sp->spt[i] = 0ull; 1660 sp->spt[i] = 0ull;
1641} 1661}
1642 1662
1663static void __clear_sp_write_flooding_count(struct kvm_mmu_page *sp)
1664{
1665 sp->write_flooding_count = 0;
1666}
1667
1668static void clear_sp_write_flooding_count(u64 *spte)
1669{
1670 struct kvm_mmu_page *sp = page_header(__pa(spte));
1671
1672 __clear_sp_write_flooding_count(sp);
1673}
1674
1643static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, 1675static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1644 gfn_t gfn, 1676 gfn_t gfn,
1645 gva_t gaddr, 1677 gva_t gaddr,
@@ -1683,6 +1715,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
1683 } else if (sp->unsync) 1715 } else if (sp->unsync)
1684 kvm_mmu_mark_parents_unsync(sp); 1716 kvm_mmu_mark_parents_unsync(sp);
1685 1717
1718 __clear_sp_write_flooding_count(sp);
1686 trace_kvm_mmu_get_page(sp, false); 1719 trace_kvm_mmu_get_page(sp, false);
1687 return sp; 1720 return sp;
1688 } 1721 }
@@ -1796,7 +1829,7 @@ static void validate_direct_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1796 } 1829 }
1797} 1830}
1798 1831
1799static void mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp, 1832static bool mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
1800 u64 *spte) 1833 u64 *spte)
1801{ 1834{
1802 u64 pte; 1835 u64 pte;
@@ -1804,17 +1837,21 @@ static void mmu_page_zap_pte(struct kvm *kvm, struct kvm_mmu_page *sp,
1804 1837
1805 pte = *spte; 1838 pte = *spte;
1806 if (is_shadow_present_pte(pte)) { 1839 if (is_shadow_present_pte(pte)) {
1807 if (is_last_spte(pte, sp->role.level)) 1840 if (is_last_spte(pte, sp->role.level)) {
1808 drop_spte(kvm, spte); 1841 drop_spte(kvm, spte);
1809 else { 1842 if (is_large_pte(pte))
1843 --kvm->stat.lpages;
1844 } else {
1810 child = page_header(pte & PT64_BASE_ADDR_MASK); 1845 child = page_header(pte & PT64_BASE_ADDR_MASK);
1811 drop_parent_pte(child, spte); 1846 drop_parent_pte(child, spte);
1812 } 1847 }
1813 } else if (is_mmio_spte(pte)) 1848 return true;
1849 }
1850
1851 if (is_mmio_spte(pte))
1814 mmu_spte_clear_no_track(spte); 1852 mmu_spte_clear_no_track(spte);
1815 1853
1816 if (is_large_pte(pte)) 1854 return false;
1817 --kvm->stat.lpages;
1818} 1855}
1819 1856
1820static void kvm_mmu_page_unlink_children(struct kvm *kvm, 1857static void kvm_mmu_page_unlink_children(struct kvm *kvm,
@@ -1831,15 +1868,6 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
1831 mmu_page_remove_parent_pte(sp, parent_pte); 1868 mmu_page_remove_parent_pte(sp, parent_pte);
1832} 1869}
1833 1870
1834static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
1835{
1836 int i;
1837 struct kvm_vcpu *vcpu;
1838
1839 kvm_for_each_vcpu(i, vcpu, kvm)
1840 vcpu->arch.last_pte_updated = NULL;
1841}
1842
1843static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp) 1871static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
1844{ 1872{
1845 u64 *parent_pte; 1873 u64 *parent_pte;
@@ -1899,7 +1927,6 @@ static int kvm_mmu_prepare_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp,
1899 } 1927 }
1900 1928
1901 sp->role.invalid = 1; 1929 sp->role.invalid = 1;
1902 kvm_mmu_reset_last_pte_updated(kvm);
1903 return ret; 1930 return ret;
1904} 1931}
1905 1932
@@ -1985,7 +2012,7 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int goal_nr_mmu_pages)
1985 kvm->arch.n_max_mmu_pages = goal_nr_mmu_pages; 2012 kvm->arch.n_max_mmu_pages = goal_nr_mmu_pages;
1986} 2013}
1987 2014
1988static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) 2015int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
1989{ 2016{
1990 struct kvm_mmu_page *sp; 2017 struct kvm_mmu_page *sp;
1991 struct hlist_node *node; 2018 struct hlist_node *node;
@@ -1994,7 +2021,7 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
1994 2021
1995 pgprintk("%s: looking for gfn %llx\n", __func__, gfn); 2022 pgprintk("%s: looking for gfn %llx\n", __func__, gfn);
1996 r = 0; 2023 r = 0;
1997 2024 spin_lock(&kvm->mmu_lock);
1998 for_each_gfn_indirect_valid_sp(kvm, sp, gfn, node) { 2025 for_each_gfn_indirect_valid_sp(kvm, sp, gfn, node) {
1999 pgprintk("%s: gfn %llx role %x\n", __func__, gfn, 2026 pgprintk("%s: gfn %llx role %x\n", __func__, gfn,
2000 sp->role.word); 2027 sp->role.word);
@@ -2002,22 +2029,11 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
2002 kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); 2029 kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
2003 } 2030 }
2004 kvm_mmu_commit_zap_page(kvm, &invalid_list); 2031 kvm_mmu_commit_zap_page(kvm, &invalid_list);
2005 return r; 2032 spin_unlock(&kvm->mmu_lock);
2006}
2007
2008static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
2009{
2010 struct kvm_mmu_page *sp;
2011 struct hlist_node *node;
2012 LIST_HEAD(invalid_list);
2013 2033
2014 for_each_gfn_indirect_valid_sp(kvm, sp, gfn, node) { 2034 return r;
2015 pgprintk("%s: zap %llx %x\n",
2016 __func__, gfn, sp->role.word);
2017 kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
2018 }
2019 kvm_mmu_commit_zap_page(kvm, &invalid_list);
2020} 2035}
2036EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page);
2021 2037
2022static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn) 2038static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
2023{ 2039{
@@ -2169,8 +2185,6 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
2169 return 1; 2185 return 1;
2170 2186
2171 if (!need_unsync && !s->unsync) { 2187 if (!need_unsync && !s->unsync) {
2172 if (!oos_shadow)
2173 return 1;
2174 need_unsync = true; 2188 need_unsync = true;
2175 } 2189 }
2176 } 2190 }
@@ -2191,11 +2205,6 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
2191 if (set_mmio_spte(sptep, gfn, pfn, pte_access)) 2205 if (set_mmio_spte(sptep, gfn, pfn, pte_access))
2192 return 0; 2206 return 0;
2193 2207
2194 /*
2195 * We don't set the accessed bit, since we sometimes want to see
2196 * whether the guest actually used the pte (in order to detect
2197 * demand paging).
2198 */
2199 spte = PT_PRESENT_MASK; 2208 spte = PT_PRESENT_MASK;
2200 if (!speculative) 2209 if (!speculative)
2201 spte |= shadow_accessed_mask; 2210 spte |= shadow_accessed_mask;
@@ -2346,10 +2355,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
2346 } 2355 }
2347 } 2356 }
2348 kvm_release_pfn_clean(pfn); 2357 kvm_release_pfn_clean(pfn);
2349 if (speculative) {
2350 vcpu->arch.last_pte_updated = sptep;
2351 vcpu->arch.last_pte_gfn = gfn;
2352 }
2353} 2358}
2354 2359
2355static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) 2360static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
@@ -2840,12 +2845,12 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
2840 return; 2845 return;
2841 2846
2842 vcpu_clear_mmio_info(vcpu, ~0ul); 2847 vcpu_clear_mmio_info(vcpu, ~0ul);
2843 trace_kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC); 2848 kvm_mmu_audit(vcpu, AUDIT_PRE_SYNC);
2844 if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) { 2849 if (vcpu->arch.mmu.root_level == PT64_ROOT_LEVEL) {
2845 hpa_t root = vcpu->arch.mmu.root_hpa; 2850 hpa_t root = vcpu->arch.mmu.root_hpa;
2846 sp = page_header(root); 2851 sp = page_header(root);
2847 mmu_sync_children(vcpu, sp); 2852 mmu_sync_children(vcpu, sp);
2848 trace_kvm_mmu_audit(vcpu, AUDIT_POST_SYNC); 2853 kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
2849 return; 2854 return;
2850 } 2855 }
2851 for (i = 0; i < 4; ++i) { 2856 for (i = 0; i < 4; ++i) {
@@ -2857,7 +2862,7 @@ static void mmu_sync_roots(struct kvm_vcpu *vcpu)
2857 mmu_sync_children(vcpu, sp); 2862 mmu_sync_children(vcpu, sp);
2858 } 2863 }
2859 } 2864 }
2860 trace_kvm_mmu_audit(vcpu, AUDIT_POST_SYNC); 2865 kvm_mmu_audit(vcpu, AUDIT_POST_SYNC);
2861} 2866}
2862 2867
2863void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu) 2868void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
@@ -3510,28 +3515,119 @@ static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, bool zap_page,
3510 kvm_mmu_flush_tlb(vcpu); 3515 kvm_mmu_flush_tlb(vcpu);
3511} 3516}
3512 3517
3513static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu) 3518static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
3519 const u8 *new, int *bytes)
3514{ 3520{
3515 u64 *spte = vcpu->arch.last_pte_updated; 3521 u64 gentry;
3522 int r;
3523
3524 /*
3525 * Assume that the pte write on a page table of the same type
3526 * as the current vcpu paging mode since we update the sptes only
3527 * when they have the same mode.
3528 */
3529 if (is_pae(vcpu) && *bytes == 4) {
3530 /* Handle a 32-bit guest writing two halves of a 64-bit gpte */
3531 *gpa &= ~(gpa_t)7;
3532 *bytes = 8;
3533 r = kvm_read_guest(vcpu->kvm, *gpa, &gentry, min(*bytes, 8));
3534 if (r)
3535 gentry = 0;
3536 new = (const u8 *)&gentry;
3537 }
3516 3538
3517 return !!(spte && (*spte & shadow_accessed_mask)); 3539 switch (*bytes) {
3540 case 4:
3541 gentry = *(const u32 *)new;
3542 break;
3543 case 8:
3544 gentry = *(const u64 *)new;
3545 break;
3546 default:
3547 gentry = 0;
3548 break;
3549 }
3550
3551 return gentry;
3518} 3552}
3519 3553
3520static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn) 3554/*
3555 * If we're seeing too many writes to a page, it may no longer be a page table,
3556 * or we may be forking, in which case it is better to unmap the page.
3557 */
3558static bool detect_write_flooding(struct kvm_mmu_page *sp, u64 *spte)
3521{ 3559{
3522 u64 *spte = vcpu->arch.last_pte_updated; 3560 /*
3561 * Skip write-flooding detected for the sp whose level is 1, because
3562 * it can become unsync, then the guest page is not write-protected.
3563 */
3564 if (sp->role.level == 1)
3565 return false;
3523 3566
3524 if (spte 3567 return ++sp->write_flooding_count >= 3;
3525 && vcpu->arch.last_pte_gfn == gfn 3568}
3526 && shadow_accessed_mask 3569
3527 && !(*spte & shadow_accessed_mask) 3570/*
3528 && is_shadow_present_pte(*spte)) 3571 * Misaligned accesses are too much trouble to fix up; also, they usually
3529 set_bit(PT_ACCESSED_SHIFT, (unsigned long *)spte); 3572 * indicate a page is not used as a page table.
3573 */
3574static bool detect_write_misaligned(struct kvm_mmu_page *sp, gpa_t gpa,
3575 int bytes)
3576{
3577 unsigned offset, pte_size, misaligned;
3578
3579 pgprintk("misaligned: gpa %llx bytes %d role %x\n",
3580 gpa, bytes, sp->role.word);
3581
3582 offset = offset_in_page(gpa);
3583 pte_size = sp->role.cr4_pae ? 8 : 4;
3584
3585 /*
3586 * Sometimes, the OS only writes the last one bytes to update status
3587 * bits, for example, in linux, andb instruction is used in clear_bit().
3588 */
3589 if (!(offset & (pte_size - 1)) && bytes == 1)
3590 return false;
3591
3592 misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
3593 misaligned |= bytes < 4;
3594
3595 return misaligned;
3596}
3597
3598static u64 *get_written_sptes(struct kvm_mmu_page *sp, gpa_t gpa, int *nspte)
3599{
3600 unsigned page_offset, quadrant;
3601 u64 *spte;
3602 int level;
3603
3604 page_offset = offset_in_page(gpa);
3605 level = sp->role.level;
3606 *nspte = 1;
3607 if (!sp->role.cr4_pae) {
3608 page_offset <<= 1; /* 32->64 */
3609 /*
3610 * A 32-bit pde maps 4MB while the shadow pdes map
3611 * only 2MB. So we need to double the offset again
3612 * and zap two pdes instead of one.
3613 */
3614 if (level == PT32_ROOT_LEVEL) {
3615 page_offset &= ~7; /* kill rounding error */
3616 page_offset <<= 1;
3617 *nspte = 2;
3618 }
3619 quadrant = page_offset >> PAGE_SHIFT;
3620 page_offset &= ~PAGE_MASK;
3621 if (quadrant != sp->role.quadrant)
3622 return NULL;
3623 }
3624
3625 spte = &sp->spt[page_offset / sizeof(*spte)];
3626 return spte;
3530} 3627}
3531 3628
3532void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, 3629void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
3533 const u8 *new, int bytes, 3630 const u8 *new, int bytes)
3534 bool guest_initiated)
3535{ 3631{
3536 gfn_t gfn = gpa >> PAGE_SHIFT; 3632 gfn_t gfn = gpa >> PAGE_SHIFT;
3537 union kvm_mmu_page_role mask = { .word = 0 }; 3633 union kvm_mmu_page_role mask = { .word = 0 };
@@ -3539,8 +3635,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
3539 struct hlist_node *node; 3635 struct hlist_node *node;
3540 LIST_HEAD(invalid_list); 3636 LIST_HEAD(invalid_list);
3541 u64 entry, gentry, *spte; 3637 u64 entry, gentry, *spte;
3542 unsigned pte_size, page_offset, misaligned, quadrant, offset; 3638 int npte;
3543 int level, npte, invlpg_counter, r, flooded = 0;
3544 bool remote_flush, local_flush, zap_page; 3639 bool remote_flush, local_flush, zap_page;
3545 3640
3546 /* 3641 /*
@@ -3551,112 +3646,45 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
3551 return; 3646 return;
3552 3647
3553 zap_page = remote_flush = local_flush = false; 3648 zap_page = remote_flush = local_flush = false;
3554 offset = offset_in_page(gpa);
3555 3649
3556 pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); 3650 pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
3557 3651
3558 invlpg_counter = atomic_read(&vcpu->kvm->arch.invlpg_counter); 3652 gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes);
3559 3653
3560 /* 3654 /*
3561 * Assume that the pte write on a page table of the same type 3655 * No need to care whether allocation memory is successful
3562 * as the current vcpu paging mode since we update the sptes only 3656 * or not since pte prefetch is skiped if it does not have
3563 * when they have the same mode. 3657 * enough objects in the cache.
3564 */ 3658 */
3565 if ((is_pae(vcpu) && bytes == 4) || !new) { 3659 mmu_topup_memory_caches(vcpu);
3566 /* Handle a 32-bit guest writing two halves of a 64-bit gpte */
3567 if (is_pae(vcpu)) {
3568 gpa &= ~(gpa_t)7;
3569 bytes = 8;
3570 }
3571 r = kvm_read_guest(vcpu->kvm, gpa, &gentry, min(bytes, 8));
3572 if (r)
3573 gentry = 0;
3574 new = (const u8 *)&gentry;
3575 }
3576
3577 switch (bytes) {
3578 case 4:
3579 gentry = *(const u32 *)new;
3580 break;
3581 case 8:
3582 gentry = *(const u64 *)new;
3583 break;
3584 default:
3585 gentry = 0;
3586 break;
3587 }
3588 3660
3589 spin_lock(&vcpu->kvm->mmu_lock); 3661 spin_lock(&vcpu->kvm->mmu_lock);
3590 if (atomic_read(&vcpu->kvm->arch.invlpg_counter) != invlpg_counter)
3591 gentry = 0;
3592 kvm_mmu_free_some_pages(vcpu);
3593 ++vcpu->kvm->stat.mmu_pte_write; 3662 ++vcpu->kvm->stat.mmu_pte_write;
3594 trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE); 3663 kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
3595 if (guest_initiated) {
3596 kvm_mmu_access_page(vcpu, gfn);
3597 if (gfn == vcpu->arch.last_pt_write_gfn
3598 && !last_updated_pte_accessed(vcpu)) {
3599 ++vcpu->arch.last_pt_write_count;
3600 if (vcpu->arch.last_pt_write_count >= 3)
3601 flooded = 1;
3602 } else {
3603 vcpu->arch.last_pt_write_gfn = gfn;
3604 vcpu->arch.last_pt_write_count = 1;
3605 vcpu->arch.last_pte_updated = NULL;
3606 }
3607 }
3608 3664
3609 mask.cr0_wp = mask.cr4_pae = mask.nxe = 1; 3665 mask.cr0_wp = mask.cr4_pae = mask.nxe = 1;
3610 for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn, node) { 3666 for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn, node) {
3611 pte_size = sp->role.cr4_pae ? 8 : 4; 3667 spte = get_written_sptes(sp, gpa, &npte);
3612 misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1); 3668
3613 misaligned |= bytes < 4; 3669 if (detect_write_misaligned(sp, gpa, bytes) ||
3614 if (misaligned || flooded) { 3670 detect_write_flooding(sp, spte)) {
3615 /*
3616 * Misaligned accesses are too much trouble to fix
3617 * up; also, they usually indicate a page is not used
3618 * as a page table.
3619 *
3620 * If we're seeing too many writes to a page,
3621 * it may no longer be a page table, or we may be
3622 * forking, in which case it is better to unmap the
3623 * page.
3624 */
3625 pgprintk("misaligned: gpa %llx bytes %d role %x\n",
3626 gpa, bytes, sp->role.word);
3627 zap_page |= !!kvm_mmu_prepare_zap_page(vcpu->kvm, sp, 3671 zap_page |= !!kvm_mmu_prepare_zap_page(vcpu->kvm, sp,
3628 &invalid_list); 3672 &invalid_list);
3629 ++vcpu->kvm->stat.mmu_flooded; 3673 ++vcpu->kvm->stat.mmu_flooded;
3630 continue; 3674 continue;
3631 } 3675 }
3632 page_offset = offset; 3676
3633 level = sp->role.level; 3677 spte = get_written_sptes(sp, gpa, &npte);
3634 npte = 1; 3678 if (!spte)
3635 if (!sp->role.cr4_pae) { 3679 continue;
3636 page_offset <<= 1; /* 32->64 */ 3680
3637 /*
3638 * A 32-bit pde maps 4MB while the shadow pdes map
3639 * only 2MB. So we need to double the offset again
3640 * and zap two pdes instead of one.
3641 */
3642 if (level == PT32_ROOT_LEVEL) {
3643 page_offset &= ~7; /* kill rounding error */
3644 page_offset <<= 1;
3645 npte = 2;
3646 }
3647 quadrant = page_offset >> PAGE_SHIFT;
3648 page_offset &= ~PAGE_MASK;
3649 if (quadrant != sp->role.quadrant)
3650 continue;
3651 }
3652 local_flush = true; 3681 local_flush = true;
3653 spte = &sp->spt[page_offset / sizeof(*spte)];
3654 while (npte--) { 3682 while (npte--) {
3655 entry = *spte; 3683 entry = *spte;
3656 mmu_page_zap_pte(vcpu->kvm, sp, spte); 3684 mmu_page_zap_pte(vcpu->kvm, sp, spte);
3657 if (gentry && 3685 if (gentry &&
3658 !((sp->role.word ^ vcpu->arch.mmu.base_role.word) 3686 !((sp->role.word ^ vcpu->arch.mmu.base_role.word)
3659 & mask.word)) 3687 & mask.word) && rmap_can_add(vcpu))
3660 mmu_pte_write_new_pte(vcpu, sp, spte, &gentry); 3688 mmu_pte_write_new_pte(vcpu, sp, spte, &gentry);
3661 if (!remote_flush && need_remote_flush(entry, *spte)) 3689 if (!remote_flush && need_remote_flush(entry, *spte))
3662 remote_flush = true; 3690 remote_flush = true;
@@ -3665,7 +3693,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
3665 } 3693 }
3666 mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush); 3694 mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush);
3667 kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list); 3695 kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
3668 trace_kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE); 3696 kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
3669 spin_unlock(&vcpu->kvm->mmu_lock); 3697 spin_unlock(&vcpu->kvm->mmu_lock);
3670} 3698}
3671 3699
@@ -3679,9 +3707,8 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
3679 3707
3680 gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL); 3708 gpa = kvm_mmu_gva_to_gpa_read(vcpu, gva, NULL);
3681 3709
3682 spin_lock(&vcpu->kvm->mmu_lock);
3683 r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT); 3710 r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
3684 spin_unlock(&vcpu->kvm->mmu_lock); 3711
3685 return r; 3712 return r;
3686} 3713}
3687EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt); 3714EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
@@ -3702,10 +3729,18 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
3702 kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list); 3729 kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
3703} 3730}
3704 3731
3732static bool is_mmio_page_fault(struct kvm_vcpu *vcpu, gva_t addr)
3733{
3734 if (vcpu->arch.mmu.direct_map || mmu_is_nested(vcpu))
3735 return vcpu_match_mmio_gpa(vcpu, addr);
3736
3737 return vcpu_match_mmio_gva(vcpu, addr);
3738}
3739
3705int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code, 3740int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code,
3706 void *insn, int insn_len) 3741 void *insn, int insn_len)
3707{ 3742{
3708 int r; 3743 int r, emulation_type = EMULTYPE_RETRY;
3709 enum emulation_result er; 3744 enum emulation_result er;
3710 3745
3711 r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code, false); 3746 r = vcpu->arch.mmu.page_fault(vcpu, cr2, error_code, false);
@@ -3717,11 +3752,10 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code,
3717 goto out; 3752 goto out;
3718 } 3753 }
3719 3754
3720 r = mmu_topup_memory_caches(vcpu); 3755 if (is_mmio_page_fault(vcpu, cr2))
3721 if (r) 3756 emulation_type = 0;
3722 goto out;
3723 3757
3724 er = x86_emulate_instruction(vcpu, cr2, 0, insn, insn_len); 3758 er = x86_emulate_instruction(vcpu, cr2, emulation_type, insn, insn_len);
3725 3759
3726 switch (er) { 3760 switch (er) {
3727 case EMULATE_DONE: 3761 case EMULATE_DONE:
@@ -3792,7 +3826,11 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
3792int kvm_mmu_create(struct kvm_vcpu *vcpu) 3826int kvm_mmu_create(struct kvm_vcpu *vcpu)
3793{ 3827{
3794 ASSERT(vcpu); 3828 ASSERT(vcpu);
3795 ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa)); 3829
3830 vcpu->arch.walk_mmu = &vcpu->arch.mmu;
3831 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
3832 vcpu->arch.mmu.translate_gpa = translate_gpa;
3833 vcpu->arch.nested_mmu.translate_gpa = translate_nested_gpa;
3796 3834
3797 return alloc_mmu_pages(vcpu); 3835 return alloc_mmu_pages(vcpu);
3798} 3836}
@@ -3852,14 +3890,14 @@ restart:
3852 spin_unlock(&kvm->mmu_lock); 3890 spin_unlock(&kvm->mmu_lock);
3853} 3891}
3854 3892
3855static int kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm, 3893static void kvm_mmu_remove_some_alloc_mmu_pages(struct kvm *kvm,
3856 struct list_head *invalid_list) 3894 struct list_head *invalid_list)
3857{ 3895{
3858 struct kvm_mmu_page *page; 3896 struct kvm_mmu_page *page;
3859 3897
3860 page = container_of(kvm->arch.active_mmu_pages.prev, 3898 page = container_of(kvm->arch.active_mmu_pages.prev,
3861 struct kvm_mmu_page, link); 3899 struct kvm_mmu_page, link);
3862 return kvm_mmu_prepare_zap_page(kvm, page, invalid_list); 3900 kvm_mmu_prepare_zap_page(kvm, page, invalid_list);
3863} 3901}
3864 3902
3865static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc) 3903static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)
@@ -3874,15 +3912,15 @@ static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)
3874 raw_spin_lock(&kvm_lock); 3912 raw_spin_lock(&kvm_lock);
3875 3913
3876 list_for_each_entry(kvm, &vm_list, vm_list) { 3914 list_for_each_entry(kvm, &vm_list, vm_list) {
3877 int idx, freed_pages; 3915 int idx;
3878 LIST_HEAD(invalid_list); 3916 LIST_HEAD(invalid_list);
3879 3917
3880 idx = srcu_read_lock(&kvm->srcu); 3918 idx = srcu_read_lock(&kvm->srcu);
3881 spin_lock(&kvm->mmu_lock); 3919 spin_lock(&kvm->mmu_lock);
3882 if (!kvm_freed && nr_to_scan > 0 && 3920 if (!kvm_freed && nr_to_scan > 0 &&
3883 kvm->arch.n_used_mmu_pages > 0) { 3921 kvm->arch.n_used_mmu_pages > 0) {
3884 freed_pages = kvm_mmu_remove_some_alloc_mmu_pages(kvm, 3922 kvm_mmu_remove_some_alloc_mmu_pages(kvm,
3885 &invalid_list); 3923 &invalid_list);
3886 kvm_freed = kvm; 3924 kvm_freed = kvm;
3887 } 3925 }
3888 nr_to_scan--; 3926 nr_to_scan--;
@@ -3944,15 +3982,15 @@ nomem:
3944 */ 3982 */
3945unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm) 3983unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
3946{ 3984{
3947 int i;
3948 unsigned int nr_mmu_pages; 3985 unsigned int nr_mmu_pages;
3949 unsigned int nr_pages = 0; 3986 unsigned int nr_pages = 0;
3950 struct kvm_memslots *slots; 3987 struct kvm_memslots *slots;
3988 struct kvm_memory_slot *memslot;
3951 3989
3952 slots = kvm_memslots(kvm); 3990 slots = kvm_memslots(kvm);
3953 3991
3954 for (i = 0; i < slots->nmemslots; i++) 3992 kvm_for_each_memslot(memslot, slots)
3955 nr_pages += slots->memslots[i].npages; 3993 nr_pages += memslot->npages;
3956 3994
3957 nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000; 3995 nr_mmu_pages = nr_pages * KVM_PERMILLE_MMU_PAGES / 1000;
3958 nr_mmu_pages = max(nr_mmu_pages, 3996 nr_mmu_pages = max(nr_mmu_pages,
@@ -3961,127 +3999,6 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm)
3961 return nr_mmu_pages; 3999 return nr_mmu_pages;
3962} 4000}
3963 4001
3964static void *pv_mmu_peek_buffer(struct kvm_pv_mmu_op_buffer *buffer,
3965 unsigned len)
3966{
3967 if (len > buffer->len)
3968 return NULL;
3969 return buffer->ptr;
3970}
3971
3972static void *pv_mmu_read_buffer(struct kvm_pv_mmu_op_buffer *buffer,
3973 unsigned len)
3974{
3975 void *ret;
3976
3977 ret = pv_mmu_peek_buffer(buffer, len);
3978 if (!ret)
3979 return ret;
3980 buffer->ptr += len;
3981 buffer->len -= len;
3982 buffer->processed += len;
3983 return ret;
3984}
3985
3986static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu,
3987 gpa_t addr, gpa_t value)
3988{
3989 int bytes = 8;
3990 int r;
3991
3992 if (!is_long_mode(vcpu) && !is_pae(vcpu))
3993 bytes = 4;
3994
3995 r = mmu_topup_memory_caches(vcpu);
3996 if (r)
3997 return r;
3998
3999 if (!emulator_write_phys(vcpu, addr, &value, bytes))
4000 return -EFAULT;
4001
4002 return 1;
4003}
4004
4005static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu)
4006{
4007 (void)kvm_set_cr3(vcpu, kvm_read_cr3(vcpu));
4008 return 1;
4009}
4010
4011static int kvm_pv_mmu_release_pt(struct kvm_vcpu *vcpu, gpa_t addr)
4012{
4013 spin_lock(&vcpu->kvm->mmu_lock);
4014 mmu_unshadow(vcpu->kvm, addr >> PAGE_SHIFT);
4015 spin_unlock(&vcpu->kvm->mmu_lock);
4016 return 1;
4017}
4018
4019static int kvm_pv_mmu_op_one(struct kvm_vcpu *vcpu,
4020 struct kvm_pv_mmu_op_buffer *buffer)
4021{
4022 struct kvm_mmu_op_header *header;
4023
4024 header = pv_mmu_peek_buffer(buffer, sizeof *header);
4025 if (!header)
4026 return 0;
4027 switch (header->op) {
4028 case KVM_MMU_OP_WRITE_PTE: {
4029 struct kvm_mmu_op_write_pte *wpte;
4030
4031 wpte = pv_mmu_read_buffer(buffer, sizeof *wpte);
4032 if (!wpte)
4033 return 0;
4034 return kvm_pv_mmu_write(vcpu, wpte->pte_phys,
4035 wpte->pte_val);
4036 }
4037 case KVM_MMU_OP_FLUSH_TLB: {
4038 struct kvm_mmu_op_flush_tlb *ftlb;
4039
4040 ftlb = pv_mmu_read_buffer(buffer, sizeof *ftlb);
4041 if (!ftlb)
4042 return 0;
4043 return kvm_pv_mmu_flush_tlb(vcpu);
4044 }
4045 case KVM_MMU_OP_RELEASE_PT: {
4046 struct kvm_mmu_op_release_pt *rpt;
4047
4048 rpt = pv_mmu_read_buffer(buffer, sizeof *rpt);
4049 if (!rpt)
4050 return 0;
4051 return kvm_pv_mmu_release_pt(vcpu, rpt->pt_phys);
4052 }
4053 default: return 0;
4054 }
4055}
4056
4057int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
4058 gpa_t addr, unsigned long *ret)
4059{
4060 int r;
4061 struct kvm_pv_mmu_op_buffer *buffer = &vcpu->arch.mmu_op_buffer;
4062
4063 buffer->ptr = buffer->buf;
4064 buffer->len = min_t(unsigned long, bytes, sizeof buffer->buf);
4065 buffer->processed = 0;
4066
4067 r = kvm_read_guest(vcpu->kvm, addr, buffer->buf, buffer->len);
4068 if (r)
4069 goto out;
4070
4071 while (buffer->len) {
4072 r = kvm_pv_mmu_op_one(vcpu, buffer);
4073 if (r < 0)
4074 goto out;
4075 if (r == 0)
4076 break;
4077 }
4078
4079 r = 1;
4080out:
4081 *ret = buffer->processed;
4082 return r;
4083}
4084
4085int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]) 4002int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
4086{ 4003{
4087 struct kvm_shadow_walk_iterator iterator; 4004 struct kvm_shadow_walk_iterator iterator;
@@ -4110,12 +4027,6 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu)
4110 mmu_free_memory_caches(vcpu); 4027 mmu_free_memory_caches(vcpu);
4111} 4028}
4112 4029
4113#ifdef CONFIG_KVM_MMU_AUDIT
4114#include "mmu_audit.c"
4115#else
4116static void mmu_audit_disable(void) { }
4117#endif
4118
4119void kvm_mmu_module_exit(void) 4030void kvm_mmu_module_exit(void)
4120{ 4031{
4121 mmu_destroy_caches(); 4032 mmu_destroy_caches();
diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c
index 746ec259d02..fe15dcc07a6 100644
--- a/arch/x86/kvm/mmu_audit.c
+++ b/arch/x86/kvm/mmu_audit.c
@@ -19,6 +19,15 @@
19 19
20#include <linux/ratelimit.h> 20#include <linux/ratelimit.h>
21 21
22char const *audit_point_name[] = {
23 "pre page fault",
24 "post page fault",
25 "pre pte write",
26 "post pte write",
27 "pre sync",
28 "post sync"
29};
30
22#define audit_printk(kvm, fmt, args...) \ 31#define audit_printk(kvm, fmt, args...) \
23 printk(KERN_ERR "audit: (%s) error: " \ 32 printk(KERN_ERR "audit: (%s) error: " \
24 fmt, audit_point_name[kvm->arch.audit_point], ##args) 33 fmt, audit_point_name[kvm->arch.audit_point], ##args)
@@ -224,7 +233,10 @@ static void audit_vcpu_spte(struct kvm_vcpu *vcpu)
224 mmu_spte_walk(vcpu, audit_spte); 233 mmu_spte_walk(vcpu, audit_spte);
225} 234}
226 235
227static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int point) 236static bool mmu_audit;
237static struct jump_label_key mmu_audit_key;
238
239static void __kvm_mmu_audit(struct kvm_vcpu *vcpu, int point)
228{ 240{
229 static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10); 241 static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
230 242
@@ -236,18 +248,18 @@ static void kvm_mmu_audit(void *ignore, struct kvm_vcpu *vcpu, int point)
236 audit_vcpu_spte(vcpu); 248 audit_vcpu_spte(vcpu);
237} 249}
238 250
239static bool mmu_audit; 251static inline void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point)
252{
253 if (static_branch((&mmu_audit_key)))
254 __kvm_mmu_audit(vcpu, point);
255}
240 256
241static void mmu_audit_enable(void) 257static void mmu_audit_enable(void)
242{ 258{
243 int ret;
244
245 if (mmu_audit) 259 if (mmu_audit)
246 return; 260 return;
247 261
248 ret = register_trace_kvm_mmu_audit(kvm_mmu_audit, NULL); 262 jump_label_inc(&mmu_audit_key);
249 WARN_ON(ret);
250
251 mmu_audit = true; 263 mmu_audit = true;
252} 264}
253 265
@@ -256,8 +268,7 @@ static void mmu_audit_disable(void)
256 if (!mmu_audit) 268 if (!mmu_audit)
257 return; 269 return;
258 270
259 unregister_trace_kvm_mmu_audit(kvm_mmu_audit, NULL); 271 jump_label_dec(&mmu_audit_key);
260 tracepoint_synchronize_unregister();
261 mmu_audit = false; 272 mmu_audit = false;
262} 273}
263 274
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h
index eed67f34146..89fb0e81322 100644
--- a/arch/x86/kvm/mmutrace.h
+++ b/arch/x86/kvm/mmutrace.h
@@ -243,25 +243,6 @@ TRACE_EVENT(
243 TP_printk("addr:%llx gfn %llx access %x", __entry->addr, __entry->gfn, 243 TP_printk("addr:%llx gfn %llx access %x", __entry->addr, __entry->gfn,
244 __entry->access) 244 __entry->access)
245); 245);
246
247TRACE_EVENT(
248 kvm_mmu_audit,
249 TP_PROTO(struct kvm_vcpu *vcpu, int audit_point),
250 TP_ARGS(vcpu, audit_point),
251
252 TP_STRUCT__entry(
253 __field(struct kvm_vcpu *, vcpu)
254 __field(int, audit_point)
255 ),
256
257 TP_fast_assign(
258 __entry->vcpu = vcpu;
259 __entry->audit_point = audit_point;
260 ),
261
262 TP_printk("vcpu:%d %s", __entry->vcpu->cpu,
263 audit_point_name[__entry->audit_point])
264);
265#endif /* _TRACE_KVMMMU_H */ 246#endif /* _TRACE_KVMMMU_H */
266 247
267#undef TRACE_INCLUDE_PATH 248#undef TRACE_INCLUDE_PATH
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 92994100638..15610285ebb 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -497,6 +497,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
497 shadow_walk_next(&it)) { 497 shadow_walk_next(&it)) {
498 gfn_t table_gfn; 498 gfn_t table_gfn;
499 499
500 clear_sp_write_flooding_count(it.sptep);
500 drop_large_spte(vcpu, it.sptep); 501 drop_large_spte(vcpu, it.sptep);
501 502
502 sp = NULL; 503 sp = NULL;
@@ -522,6 +523,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
522 shadow_walk_next(&it)) { 523 shadow_walk_next(&it)) {
523 gfn_t direct_gfn; 524 gfn_t direct_gfn;
524 525
526 clear_sp_write_flooding_count(it.sptep);
525 validate_direct_spte(vcpu, it.sptep, direct_access); 527 validate_direct_spte(vcpu, it.sptep, direct_access);
526 528
527 drop_large_spte(vcpu, it.sptep); 529 drop_large_spte(vcpu, it.sptep);
@@ -536,6 +538,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
536 link_shadow_page(it.sptep, sp); 538 link_shadow_page(it.sptep, sp);
537 } 539 }
538 540
541 clear_sp_write_flooding_count(it.sptep);
539 mmu_set_spte(vcpu, it.sptep, access, gw->pte_access, 542 mmu_set_spte(vcpu, it.sptep, access, gw->pte_access,
540 user_fault, write_fault, emulate, it.level, 543 user_fault, write_fault, emulate, it.level,
541 gw->gfn, pfn, prefault, map_writable); 544 gw->gfn, pfn, prefault, map_writable);
@@ -599,11 +602,9 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
599 */ 602 */
600 if (!r) { 603 if (!r) {
601 pgprintk("%s: guest page fault\n", __func__); 604 pgprintk("%s: guest page fault\n", __func__);
602 if (!prefault) { 605 if (!prefault)
603 inject_page_fault(vcpu, &walker.fault); 606 inject_page_fault(vcpu, &walker.fault);
604 /* reset fork detector */ 607
605 vcpu->arch.last_pt_write_count = 0;
606 }
607 return 0; 608 return 0;
608 } 609 }
609 610
@@ -631,7 +632,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
631 if (mmu_notifier_retry(vcpu, mmu_seq)) 632 if (mmu_notifier_retry(vcpu, mmu_seq))
632 goto out_unlock; 633 goto out_unlock;
633 634
634 trace_kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT); 635 kvm_mmu_audit(vcpu, AUDIT_PRE_PAGE_FAULT);
635 kvm_mmu_free_some_pages(vcpu); 636 kvm_mmu_free_some_pages(vcpu);
636 if (!force_pt_level) 637 if (!force_pt_level)
637 transparent_hugepage_adjust(vcpu, &walker.gfn, &pfn, &level); 638 transparent_hugepage_adjust(vcpu, &walker.gfn, &pfn, &level);
@@ -641,11 +642,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,
641 pgprintk("%s: shadow pte %p %llx emulate %d\n", __func__, 642 pgprintk("%s: shadow pte %p %llx emulate %d\n", __func__,
642 sptep, *sptep, emulate); 643 sptep, *sptep, emulate);
643 644
644 if (!emulate)
645 vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
646
647 ++vcpu->stat.pf_fixed; 645 ++vcpu->stat.pf_fixed;
648 trace_kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT); 646 kvm_mmu_audit(vcpu, AUDIT_POST_PAGE_FAULT);
649 spin_unlock(&vcpu->kvm->mmu_lock); 647 spin_unlock(&vcpu->kvm->mmu_lock);
650 648
651 return emulate; 649 return emulate;
@@ -656,65 +654,66 @@ out_unlock:
656 return 0; 654 return 0;
657} 655}
658 656
657static gpa_t FNAME(get_level1_sp_gpa)(struct kvm_mmu_page *sp)
658{
659 int offset = 0;
660
661 WARN_ON(sp->role.level != 1);
662
663 if (PTTYPE == 32)
664 offset = sp->role.quadrant << PT64_LEVEL_BITS;
665
666 return gfn_to_gpa(sp->gfn) + offset * sizeof(pt_element_t);
667}
668
659static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva) 669static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
660{ 670{
661 struct kvm_shadow_walk_iterator iterator; 671 struct kvm_shadow_walk_iterator iterator;
662 struct kvm_mmu_page *sp; 672 struct kvm_mmu_page *sp;
663 gpa_t pte_gpa = -1;
664 int level; 673 int level;
665 u64 *sptep; 674 u64 *sptep;
666 int need_flush = 0;
667 675
668 vcpu_clear_mmio_info(vcpu, gva); 676 vcpu_clear_mmio_info(vcpu, gva);
669 677
670 spin_lock(&vcpu->kvm->mmu_lock); 678 /*
679 * No need to check return value here, rmap_can_add() can
680 * help us to skip pte prefetch later.
681 */
682 mmu_topup_memory_caches(vcpu);
671 683
684 spin_lock(&vcpu->kvm->mmu_lock);
672 for_each_shadow_entry(vcpu, gva, iterator) { 685 for_each_shadow_entry(vcpu, gva, iterator) {
673 level = iterator.level; 686 level = iterator.level;
674 sptep = iterator.sptep; 687 sptep = iterator.sptep;
675 688
676 sp = page_header(__pa(sptep)); 689 sp = page_header(__pa(sptep));
677 if (is_last_spte(*sptep, level)) { 690 if (is_last_spte(*sptep, level)) {
678 int offset, shift; 691 pt_element_t gpte;
692 gpa_t pte_gpa;
679 693
680 if (!sp->unsync) 694 if (!sp->unsync)
681 break; 695 break;
682 696
683 shift = PAGE_SHIFT - 697 pte_gpa = FNAME(get_level1_sp_gpa)(sp);
684 (PT_LEVEL_BITS - PT64_LEVEL_BITS) * level;
685 offset = sp->role.quadrant << shift;
686
687 pte_gpa = (sp->gfn << PAGE_SHIFT) + offset;
688 pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t); 698 pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
689 699
690 if (is_shadow_present_pte(*sptep)) { 700 if (mmu_page_zap_pte(vcpu->kvm, sp, sptep))
691 if (is_large_pte(*sptep)) 701 kvm_flush_remote_tlbs(vcpu->kvm);
692 --vcpu->kvm->stat.lpages;
693 drop_spte(vcpu->kvm, sptep);
694 need_flush = 1;
695 } else if (is_mmio_spte(*sptep))
696 mmu_spte_clear_no_track(sptep);
697 702
698 break; 703 if (!rmap_can_add(vcpu))
704 break;
705
706 if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
707 sizeof(pt_element_t)))
708 break;
709
710 FNAME(update_pte)(vcpu, sp, sptep, &gpte);
699 } 711 }
700 712
701 if (!is_shadow_present_pte(*sptep) || !sp->unsync_children) 713 if (!is_shadow_present_pte(*sptep) || !sp->unsync_children)
702 break; 714 break;
703 } 715 }
704
705 if (need_flush)
706 kvm_flush_remote_tlbs(vcpu->kvm);
707
708 atomic_inc(&vcpu->kvm->arch.invlpg_counter);
709
710 spin_unlock(&vcpu->kvm->mmu_lock); 716 spin_unlock(&vcpu->kvm->mmu_lock);
711
712 if (pte_gpa == -1)
713 return;
714
715 if (mmu_topup_memory_caches(vcpu))
716 return;
717 kvm_mmu_pte_write(vcpu, pte_gpa, NULL, sizeof(pt_element_t), 0);
718} 717}
719 718
720static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access, 719static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,
@@ -769,19 +768,14 @@ static gpa_t FNAME(gva_to_gpa_nested)(struct kvm_vcpu *vcpu, gva_t vaddr,
769 */ 768 */
770static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) 769static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
771{ 770{
772 int i, offset, nr_present; 771 int i, nr_present = 0;
773 bool host_writable; 772 bool host_writable;
774 gpa_t first_pte_gpa; 773 gpa_t first_pte_gpa;
775 774
776 offset = nr_present = 0;
777
778 /* direct kvm_mmu_page can not be unsync. */ 775 /* direct kvm_mmu_page can not be unsync. */
779 BUG_ON(sp->role.direct); 776 BUG_ON(sp->role.direct);
780 777
781 if (PTTYPE == 32) 778 first_pte_gpa = FNAME(get_level1_sp_gpa)(sp);
782 offset = sp->role.quadrant << PT64_LEVEL_BITS;
783
784 first_pte_gpa = gfn_to_gpa(sp->gfn) + offset * sizeof(pt_element_t);
785 779
786 for (i = 0; i < PT64_ENT_PER_PAGE; i++) { 780 for (i = 0; i < PT64_ENT_PER_PAGE; i++) {
787 unsigned pte_access; 781 unsigned pte_access;
diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
new file mode 100644
index 00000000000..7aad5446f39
--- /dev/null
+++ b/arch/x86/kvm/pmu.c
@@ -0,0 +1,533 @@
1/*
2 * Kernel-based Virtual Machine -- Performane Monitoring Unit support
3 *
4 * Copyright 2011 Red Hat, Inc. and/or its affiliates.
5 *
6 * Authors:
7 * Avi Kivity <avi@redhat.com>
8 * Gleb Natapov <gleb@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU GPL, version 2. See
11 * the COPYING file in the top-level directory.
12 *
13 */
14
15#include <linux/types.h>
16#include <linux/kvm_host.h>
17#include <linux/perf_event.h>
18#include "x86.h"
19#include "cpuid.h"
20#include "lapic.h"
21
22static struct kvm_arch_event_perf_mapping {
23 u8 eventsel;
24 u8 unit_mask;
25 unsigned event_type;
26 bool inexact;
27} arch_events[] = {
28 /* Index must match CPUID 0x0A.EBX bit vector */
29 [0] = { 0x3c, 0x00, PERF_COUNT_HW_CPU_CYCLES },
30 [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS },
31 [2] = { 0x3c, 0x01, PERF_COUNT_HW_BUS_CYCLES },
32 [3] = { 0x2e, 0x4f, PERF_COUNT_HW_CACHE_REFERENCES },
33 [4] = { 0x2e, 0x41, PERF_COUNT_HW_CACHE_MISSES },
34 [5] = { 0xc4, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
35 [6] = { 0xc5, 0x00, PERF_COUNT_HW_BRANCH_MISSES },
36};
37
38/* mapping between fixed pmc index and arch_events array */
39int fixed_pmc_events[] = {1, 0, 2};
40
41static bool pmc_is_gp(struct kvm_pmc *pmc)
42{
43 return pmc->type == KVM_PMC_GP;
44}
45
46static inline u64 pmc_bitmask(struct kvm_pmc *pmc)
47{
48 struct kvm_pmu *pmu = &pmc->vcpu->arch.pmu;
49
50 return pmu->counter_bitmask[pmc->type];
51}
52
53static inline bool pmc_enabled(struct kvm_pmc *pmc)
54{
55 struct kvm_pmu *pmu = &pmc->vcpu->arch.pmu;
56 return test_bit(pmc->idx, (unsigned long *)&pmu->global_ctrl);
57}
58
59static inline struct kvm_pmc *get_gp_pmc(struct kvm_pmu *pmu, u32 msr,
60 u32 base)
61{
62 if (msr >= base && msr < base + pmu->nr_arch_gp_counters)
63 return &pmu->gp_counters[msr - base];
64 return NULL;
65}
66
67static inline struct kvm_pmc *get_fixed_pmc(struct kvm_pmu *pmu, u32 msr)
68{
69 int base = MSR_CORE_PERF_FIXED_CTR0;
70 if (msr >= base && msr < base + pmu->nr_arch_fixed_counters)
71 return &pmu->fixed_counters[msr - base];
72 return NULL;
73}
74
75static inline struct kvm_pmc *get_fixed_pmc_idx(struct kvm_pmu *pmu, int idx)
76{
77 return get_fixed_pmc(pmu, MSR_CORE_PERF_FIXED_CTR0 + idx);
78}
79
80static struct kvm_pmc *global_idx_to_pmc(struct kvm_pmu *pmu, int idx)
81{
82 if (idx < X86_PMC_IDX_FIXED)
83 return get_gp_pmc(pmu, MSR_P6_EVNTSEL0 + idx, MSR_P6_EVNTSEL0);
84 else
85 return get_fixed_pmc_idx(pmu, idx - X86_PMC_IDX_FIXED);
86}
87
88void kvm_deliver_pmi(struct kvm_vcpu *vcpu)
89{
90 if (vcpu->arch.apic)
91 kvm_apic_local_deliver(vcpu->arch.apic, APIC_LVTPC);
92}
93
94static void trigger_pmi(struct irq_work *irq_work)
95{
96 struct kvm_pmu *pmu = container_of(irq_work, struct kvm_pmu,
97 irq_work);
98 struct kvm_vcpu *vcpu = container_of(pmu, struct kvm_vcpu,
99 arch.pmu);
100
101 kvm_deliver_pmi(vcpu);
102}
103
104static void kvm_perf_overflow(struct perf_event *perf_event,
105 struct perf_sample_data *data,
106 struct pt_regs *regs)
107{
108 struct kvm_pmc *pmc = perf_event->overflow_handler_context;
109 struct kvm_pmu *pmu = &pmc->vcpu->arch.pmu;
110 __set_bit(pmc->idx, (unsigned long *)&pmu->global_status);
111}
112
113static void kvm_perf_overflow_intr(struct perf_event *perf_event,
114 struct perf_sample_data *data, struct pt_regs *regs)
115{
116 struct kvm_pmc *pmc = perf_event->overflow_handler_context;
117 struct kvm_pmu *pmu = &pmc->vcpu->arch.pmu;
118 if (!test_and_set_bit(pmc->idx, (unsigned long *)&pmu->reprogram_pmi)) {
119 kvm_perf_overflow(perf_event, data, regs);
120 kvm_make_request(KVM_REQ_PMU, pmc->vcpu);
121 /*
122 * Inject PMI. If vcpu was in a guest mode during NMI PMI
123 * can be ejected on a guest mode re-entry. Otherwise we can't
124 * be sure that vcpu wasn't executing hlt instruction at the
125 * time of vmexit and is not going to re-enter guest mode until,
126 * woken up. So we should wake it, but this is impossible from
127 * NMI context. Do it from irq work instead.
128 */
129 if (!kvm_is_in_guest())
130 irq_work_queue(&pmc->vcpu->arch.pmu.irq_work);
131 else
132 kvm_make_request(KVM_REQ_PMI, pmc->vcpu);
133 }
134}
135
136static u64 read_pmc(struct kvm_pmc *pmc)
137{
138 u64 counter, enabled, running;
139
140 counter = pmc->counter;
141
142 if (pmc->perf_event)
143 counter += perf_event_read_value(pmc->perf_event,
144 &enabled, &running);
145
146 /* FIXME: Scaling needed? */
147
148 return counter & pmc_bitmask(pmc);
149}
150
151static void stop_counter(struct kvm_pmc *pmc)
152{
153 if (pmc->perf_event) {
154 pmc->counter = read_pmc(pmc);
155 perf_event_release_kernel(pmc->perf_event);
156 pmc->perf_event = NULL;
157 }
158}
159
160static void reprogram_counter(struct kvm_pmc *pmc, u32 type,
161 unsigned config, bool exclude_user, bool exclude_kernel,
162 bool intr)
163{
164 struct perf_event *event;
165 struct perf_event_attr attr = {
166 .type = type,
167 .size = sizeof(attr),
168 .pinned = true,
169 .exclude_idle = true,
170 .exclude_host = 1,
171 .exclude_user = exclude_user,
172 .exclude_kernel = exclude_kernel,
173 .config = config,
174 };
175
176 attr.sample_period = (-pmc->counter) & pmc_bitmask(pmc);
177
178 event = perf_event_create_kernel_counter(&attr, -1, current,
179 intr ? kvm_perf_overflow_intr :
180 kvm_perf_overflow, pmc);
181 if (IS_ERR(event)) {
182 printk_once("kvm: pmu event creation failed %ld\n",
183 PTR_ERR(event));
184 return;
185 }
186
187 pmc->perf_event = event;
188 clear_bit(pmc->idx, (unsigned long*)&pmc->vcpu->arch.pmu.reprogram_pmi);
189}
190
191static unsigned find_arch_event(struct kvm_pmu *pmu, u8 event_select,
192 u8 unit_mask)
193{
194 int i;
195
196 for (i = 0; i < ARRAY_SIZE(arch_events); i++)
197 if (arch_events[i].eventsel == event_select
198 && arch_events[i].unit_mask == unit_mask
199 && (pmu->available_event_types & (1 << i)))
200 break;
201
202 if (i == ARRAY_SIZE(arch_events))
203 return PERF_COUNT_HW_MAX;
204
205 return arch_events[i].event_type;
206}
207
208static void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
209{
210 unsigned config, type = PERF_TYPE_RAW;
211 u8 event_select, unit_mask;
212
213 pmc->eventsel = eventsel;
214
215 stop_counter(pmc);
216
217 if (!(eventsel & ARCH_PERFMON_EVENTSEL_ENABLE) || !pmc_enabled(pmc))
218 return;
219
220 event_select = eventsel & ARCH_PERFMON_EVENTSEL_EVENT;
221 unit_mask = (eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8;
222
223 if (!(event_select & (ARCH_PERFMON_EVENTSEL_EDGE |
224 ARCH_PERFMON_EVENTSEL_INV |
225 ARCH_PERFMON_EVENTSEL_CMASK))) {
226 config = find_arch_event(&pmc->vcpu->arch.pmu, event_select,
227 unit_mask);
228 if (config != PERF_COUNT_HW_MAX)
229 type = PERF_TYPE_HARDWARE;
230 }
231
232 if (type == PERF_TYPE_RAW)
233 config = eventsel & X86_RAW_EVENT_MASK;
234
235 reprogram_counter(pmc, type, config,
236 !(eventsel & ARCH_PERFMON_EVENTSEL_USR),
237 !(eventsel & ARCH_PERFMON_EVENTSEL_OS),
238 eventsel & ARCH_PERFMON_EVENTSEL_INT);
239}
240
241static void reprogram_fixed_counter(struct kvm_pmc *pmc, u8 en_pmi, int idx)
242{
243 unsigned en = en_pmi & 0x3;
244 bool pmi = en_pmi & 0x8;
245
246 stop_counter(pmc);
247
248 if (!en || !pmc_enabled(pmc))
249 return;
250
251 reprogram_counter(pmc, PERF_TYPE_HARDWARE,
252 arch_events[fixed_pmc_events[idx]].event_type,
253 !(en & 0x2), /* exclude user */
254 !(en & 0x1), /* exclude kernel */
255 pmi);
256}
257
258static inline u8 fixed_en_pmi(u64 ctrl, int idx)
259{
260 return (ctrl >> (idx * 4)) & 0xf;
261}
262
263static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
264{
265 int i;
266
267 for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
268 u8 en_pmi = fixed_en_pmi(data, i);
269 struct kvm_pmc *pmc = get_fixed_pmc_idx(pmu, i);
270
271 if (fixed_en_pmi(pmu->fixed_ctr_ctrl, i) == en_pmi)
272 continue;
273
274 reprogram_fixed_counter(pmc, en_pmi, i);
275 }
276
277 pmu->fixed_ctr_ctrl = data;
278}
279
280static void reprogram_idx(struct kvm_pmu *pmu, int idx)
281{
282 struct kvm_pmc *pmc = global_idx_to_pmc(pmu, idx);
283
284 if (!pmc)
285 return;
286
287 if (pmc_is_gp(pmc))
288 reprogram_gp_counter(pmc, pmc->eventsel);
289 else {
290 int fidx = idx - X86_PMC_IDX_FIXED;
291 reprogram_fixed_counter(pmc,
292 fixed_en_pmi(pmu->fixed_ctr_ctrl, fidx), fidx);
293 }
294}
295
296static void global_ctrl_changed(struct kvm_pmu *pmu, u64 data)
297{
298 int bit;
299 u64 diff = pmu->global_ctrl ^ data;
300
301 pmu->global_ctrl = data;
302
303 for_each_set_bit(bit, (unsigned long *)&diff, X86_PMC_IDX_MAX)
304 reprogram_idx(pmu, bit);
305}
306
307bool kvm_pmu_msr(struct kvm_vcpu *vcpu, u32 msr)
308{
309 struct kvm_pmu *pmu = &vcpu->arch.pmu;
310 int ret;
311
312 switch (msr) {
313 case MSR_CORE_PERF_FIXED_CTR_CTRL:
314 case MSR_CORE_PERF_GLOBAL_STATUS:
315 case MSR_CORE_PERF_GLOBAL_CTRL:
316 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
317 ret = pmu->version > 1;
318 break;
319 default:
320 ret = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0)
321 || get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0)
322 || get_fixed_pmc(pmu, msr);
323 break;
324 }
325 return ret;
326}
327
328int kvm_pmu_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
329{
330 struct kvm_pmu *pmu = &vcpu->arch.pmu;
331 struct kvm_pmc *pmc;
332
333 switch (index) {
334 case MSR_CORE_PERF_FIXED_CTR_CTRL:
335 *data = pmu->fixed_ctr_ctrl;
336 return 0;
337 case MSR_CORE_PERF_GLOBAL_STATUS:
338 *data = pmu->global_status;
339 return 0;
340 case MSR_CORE_PERF_GLOBAL_CTRL:
341 *data = pmu->global_ctrl;
342 return 0;
343 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
344 *data = pmu->global_ovf_ctrl;
345 return 0;
346 default:
347 if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
348 (pmc = get_fixed_pmc(pmu, index))) {
349 *data = read_pmc(pmc);
350 return 0;
351 } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) {
352 *data = pmc->eventsel;
353 return 0;
354 }
355 }
356 return 1;
357}
358
359int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data)
360{
361 struct kvm_pmu *pmu = &vcpu->arch.pmu;
362 struct kvm_pmc *pmc;
363
364 switch (index) {
365 case MSR_CORE_PERF_FIXED_CTR_CTRL:
366 if (pmu->fixed_ctr_ctrl == data)
367 return 0;
368 if (!(data & 0xfffffffffffff444)) {
369 reprogram_fixed_counters(pmu, data);
370 return 0;
371 }
372 break;
373 case MSR_CORE_PERF_GLOBAL_STATUS:
374 break; /* RO MSR */
375 case MSR_CORE_PERF_GLOBAL_CTRL:
376 if (pmu->global_ctrl == data)
377 return 0;
378 if (!(data & pmu->global_ctrl_mask)) {
379 global_ctrl_changed(pmu, data);
380 return 0;
381 }
382 break;
383 case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
384 if (!(data & (pmu->global_ctrl_mask & ~(3ull<<62)))) {
385 pmu->global_status &= ~data;
386 pmu->global_ovf_ctrl = data;
387 return 0;
388 }
389 break;
390 default:
391 if ((pmc = get_gp_pmc(pmu, index, MSR_IA32_PERFCTR0)) ||
392 (pmc = get_fixed_pmc(pmu, index))) {
393 data = (s64)(s32)data;
394 pmc->counter += data - read_pmc(pmc);
395 return 0;
396 } else if ((pmc = get_gp_pmc(pmu, index, MSR_P6_EVNTSEL0))) {
397 if (data == pmc->eventsel)
398 return 0;
399 if (!(data & 0xffffffff00200000ull)) {
400 reprogram_gp_counter(pmc, data);
401 return 0;
402 }
403 }
404 }
405 return 1;
406}
407
408int kvm_pmu_read_pmc(struct kvm_vcpu *vcpu, unsigned pmc, u64 *data)
409{
410 struct kvm_pmu *pmu = &vcpu->arch.pmu;
411 bool fast_mode = pmc & (1u << 31);
412 bool fixed = pmc & (1u << 30);
413 struct kvm_pmc *counters;
414 u64 ctr;
415
416 pmc &= (3u << 30) - 1;
417 if (!fixed && pmc >= pmu->nr_arch_gp_counters)
418 return 1;
419 if (fixed && pmc >= pmu->nr_arch_fixed_counters)
420 return 1;
421 counters = fixed ? pmu->fixed_counters : pmu->gp_counters;
422 ctr = read_pmc(&counters[pmc]);
423 if (fast_mode)
424 ctr = (u32)ctr;
425 *data = ctr;
426
427 return 0;
428}
429
430void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
431{
432 struct kvm_pmu *pmu = &vcpu->arch.pmu;
433 struct kvm_cpuid_entry2 *entry;
434 unsigned bitmap_len;
435
436 pmu->nr_arch_gp_counters = 0;
437 pmu->nr_arch_fixed_counters = 0;
438 pmu->counter_bitmask[KVM_PMC_GP] = 0;
439 pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
440 pmu->version = 0;
441
442 entry = kvm_find_cpuid_entry(vcpu, 0xa, 0);
443 if (!entry)
444 return;
445
446 pmu->version = entry->eax & 0xff;
447 if (!pmu->version)
448 return;
449
450 pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff,
451 X86_PMC_MAX_GENERIC);
452 pmu->counter_bitmask[KVM_PMC_GP] =
453 ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1;
454 bitmap_len = (entry->eax >> 24) & 0xff;
455 pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
456
457 if (pmu->version == 1) {
458 pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
459 return;
460 }
461
462 pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
463 X86_PMC_MAX_FIXED);
464 pmu->counter_bitmask[KVM_PMC_FIXED] =
465 ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
466 pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1)
467 | (((1ull << pmu->nr_arch_fixed_counters) - 1)
468 << X86_PMC_IDX_FIXED));
469}
470
471void kvm_pmu_init(struct kvm_vcpu *vcpu)
472{
473 int i;
474 struct kvm_pmu *pmu = &vcpu->arch.pmu;
475
476 memset(pmu, 0, sizeof(*pmu));
477 for (i = 0; i < X86_PMC_MAX_GENERIC; i++) {
478 pmu->gp_counters[i].type = KVM_PMC_GP;
479 pmu->gp_counters[i].vcpu = vcpu;
480 pmu->gp_counters[i].idx = i;
481 }
482 for (i = 0; i < X86_PMC_MAX_FIXED; i++) {
483 pmu->fixed_counters[i].type = KVM_PMC_FIXED;
484 pmu->fixed_counters[i].vcpu = vcpu;
485 pmu->fixed_counters[i].idx = i + X86_PMC_IDX_FIXED;
486 }
487 init_irq_work(&pmu->irq_work, trigger_pmi);
488 kvm_pmu_cpuid_update(vcpu);
489}
490
491void kvm_pmu_reset(struct kvm_vcpu *vcpu)
492{
493 struct kvm_pmu *pmu = &vcpu->arch.pmu;
494 int i;
495
496 irq_work_sync(&pmu->irq_work);
497 for (i = 0; i < X86_PMC_MAX_GENERIC; i++) {
498 struct kvm_pmc *pmc = &pmu->gp_counters[i];
499 stop_counter(pmc);
500 pmc->counter = pmc->eventsel = 0;
501 }
502
503 for (i = 0; i < X86_PMC_MAX_FIXED; i++)
504 stop_counter(&pmu->fixed_counters[i]);
505
506 pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status =
507 pmu->global_ovf_ctrl = 0;
508}
509
510void kvm_pmu_destroy(struct kvm_vcpu *vcpu)
511{
512 kvm_pmu_reset(vcpu);
513}
514
515void kvm_handle_pmu_event(struct kvm_vcpu *vcpu)
516{
517 struct kvm_pmu *pmu = &vcpu->arch.pmu;
518 u64 bitmask;
519 int bit;
520
521 bitmask = pmu->reprogram_pmi;
522
523 for_each_set_bit(bit, (unsigned long *)&bitmask, X86_PMC_IDX_MAX) {
524 struct kvm_pmc *pmc = global_idx_to_pmc(pmu, bit);
525
526 if (unlikely(!pmc || !pmc->perf_event)) {
527 clear_bit(bit, (unsigned long *)&pmu->reprogram_pmi);
528 continue;
529 }
530
531 reprogram_idx(pmu, bit);
532 }
533}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index e32243eac2f..5fa553babe5 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1014,6 +1014,7 @@ static void init_vmcb(struct vcpu_svm *svm)
1014 set_intercept(svm, INTERCEPT_NMI); 1014 set_intercept(svm, INTERCEPT_NMI);
1015 set_intercept(svm, INTERCEPT_SMI); 1015 set_intercept(svm, INTERCEPT_SMI);
1016 set_intercept(svm, INTERCEPT_SELECTIVE_CR0); 1016 set_intercept(svm, INTERCEPT_SELECTIVE_CR0);
1017 set_intercept(svm, INTERCEPT_RDPMC);
1017 set_intercept(svm, INTERCEPT_CPUID); 1018 set_intercept(svm, INTERCEPT_CPUID);
1018 set_intercept(svm, INTERCEPT_INVD); 1019 set_intercept(svm, INTERCEPT_INVD);
1019 set_intercept(svm, INTERCEPT_HLT); 1020 set_intercept(svm, INTERCEPT_HLT);
@@ -2770,6 +2771,19 @@ static int emulate_on_interception(struct vcpu_svm *svm)
2770 return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE; 2771 return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
2771} 2772}
2772 2773
2774static int rdpmc_interception(struct vcpu_svm *svm)
2775{
2776 int err;
2777
2778 if (!static_cpu_has(X86_FEATURE_NRIPS))
2779 return emulate_on_interception(svm);
2780
2781 err = kvm_rdpmc(&svm->vcpu);
2782 kvm_complete_insn_gp(&svm->vcpu, err);
2783
2784 return 1;
2785}
2786
2773bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val) 2787bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val)
2774{ 2788{
2775 unsigned long cr0 = svm->vcpu.arch.cr0; 2789 unsigned long cr0 = svm->vcpu.arch.cr0;
@@ -3190,6 +3204,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = {
3190 [SVM_EXIT_SMI] = nop_on_interception, 3204 [SVM_EXIT_SMI] = nop_on_interception,
3191 [SVM_EXIT_INIT] = nop_on_interception, 3205 [SVM_EXIT_INIT] = nop_on_interception,
3192 [SVM_EXIT_VINTR] = interrupt_window_interception, 3206 [SVM_EXIT_VINTR] = interrupt_window_interception,
3207 [SVM_EXIT_RDPMC] = rdpmc_interception,
3193 [SVM_EXIT_CPUID] = cpuid_interception, 3208 [SVM_EXIT_CPUID] = cpuid_interception,
3194 [SVM_EXIT_IRET] = iret_interception, 3209 [SVM_EXIT_IRET] = iret_interception,
3195 [SVM_EXIT_INVD] = emulate_on_interception, 3210 [SVM_EXIT_INVD] = emulate_on_interception,
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
index ae432ea1cd8..6b85cc647f3 100644
--- a/arch/x86/kvm/timer.c
+++ b/arch/x86/kvm/timer.c
@@ -18,9 +18,10 @@
18#include <linux/atomic.h> 18#include <linux/atomic.h>
19#include "kvm_timer.h" 19#include "kvm_timer.h"
20 20
21static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer) 21enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
22{ 22{
23 int restart_timer = 0; 23 struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
24 struct kvm_vcpu *vcpu = ktimer->vcpu;
24 wait_queue_head_t *q = &vcpu->wq; 25 wait_queue_head_t *q = &vcpu->wq;
25 26
26 /* 27 /*
@@ -40,26 +41,7 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
40 41
41 if (ktimer->t_ops->is_periodic(ktimer)) { 42 if (ktimer->t_ops->is_periodic(ktimer)) {
42 hrtimer_add_expires_ns(&ktimer->timer, ktimer->period); 43 hrtimer_add_expires_ns(&ktimer->timer, ktimer->period);
43 restart_timer = 1;
44 }
45
46 return restart_timer;
47}
48
49enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
50{
51 int restart_timer;
52 struct kvm_vcpu *vcpu;
53 struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
54
55 vcpu = ktimer->vcpu;
56 if (!vcpu)
57 return HRTIMER_NORESTART;
58
59 restart_timer = __kvm_timer_fn(vcpu, ktimer);
60 if (restart_timer)
61 return HRTIMER_RESTART; 44 return HRTIMER_RESTART;
62 else 45 } else
63 return HRTIMER_NORESTART; 46 return HRTIMER_NORESTART;
64} 47}
65
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 579a0b51696..906a7e84200 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -18,6 +18,7 @@
18 18
19#include "irq.h" 19#include "irq.h"
20#include "mmu.h" 20#include "mmu.h"
21#include "cpuid.h"
21 22
22#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
23#include <linux/module.h> 24#include <linux/module.h>
@@ -1747,7 +1748,6 @@ static void setup_msrs(struct vcpu_vmx *vmx)
1747 int save_nmsrs, index; 1748 int save_nmsrs, index;
1748 unsigned long *msr_bitmap; 1749 unsigned long *msr_bitmap;
1749 1750
1750 vmx_load_host_state(vmx);
1751 save_nmsrs = 0; 1751 save_nmsrs = 0;
1752#ifdef CONFIG_X86_64 1752#ifdef CONFIG_X86_64
1753 if (is_long_mode(&vmx->vcpu)) { 1753 if (is_long_mode(&vmx->vcpu)) {
@@ -1956,6 +1956,7 @@ static __init void nested_vmx_setup_ctls_msrs(void)
1956#endif 1956#endif
1957 CPU_BASED_MOV_DR_EXITING | CPU_BASED_UNCOND_IO_EXITING | 1957 CPU_BASED_MOV_DR_EXITING | CPU_BASED_UNCOND_IO_EXITING |
1958 CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MONITOR_EXITING | 1958 CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MONITOR_EXITING |
1959 CPU_BASED_RDPMC_EXITING |
1959 CPU_BASED_ACTIVATE_SECONDARY_CONTROLS; 1960 CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
1960 /* 1961 /*
1961 * We can allow some features even when not supported by the 1962 * We can allow some features even when not supported by the
@@ -2142,12 +2143,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
2142 return 1; 2143 return 1;
2143 /* Otherwise falls through */ 2144 /* Otherwise falls through */
2144 default: 2145 default:
2145 vmx_load_host_state(to_vmx(vcpu));
2146 if (vmx_get_vmx_msr(vcpu, msr_index, pdata)) 2146 if (vmx_get_vmx_msr(vcpu, msr_index, pdata))
2147 return 0; 2147 return 0;
2148 msr = find_msr_entry(to_vmx(vcpu), msr_index); 2148 msr = find_msr_entry(to_vmx(vcpu), msr_index);
2149 if (msr) { 2149 if (msr) {
2150 vmx_load_host_state(to_vmx(vcpu));
2151 data = msr->data; 2150 data = msr->data;
2152 break; 2151 break;
2153 } 2152 }
@@ -2171,7 +2170,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
2171 2170
2172 switch (msr_index) { 2171 switch (msr_index) {
2173 case MSR_EFER: 2172 case MSR_EFER:
2174 vmx_load_host_state(vmx);
2175 ret = kvm_set_msr_common(vcpu, msr_index, data); 2173 ret = kvm_set_msr_common(vcpu, msr_index, data);
2176 break; 2174 break;
2177#ifdef CONFIG_X86_64 2175#ifdef CONFIG_X86_64
@@ -2220,7 +2218,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
2220 break; 2218 break;
2221 msr = find_msr_entry(vmx, msr_index); 2219 msr = find_msr_entry(vmx, msr_index);
2222 if (msr) { 2220 if (msr) {
2223 vmx_load_host_state(vmx);
2224 msr->data = data; 2221 msr->data = data;
2225 break; 2222 break;
2226 } 2223 }
@@ -2414,7 +2411,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
2414 CPU_BASED_USE_TSC_OFFSETING | 2411 CPU_BASED_USE_TSC_OFFSETING |
2415 CPU_BASED_MWAIT_EXITING | 2412 CPU_BASED_MWAIT_EXITING |
2416 CPU_BASED_MONITOR_EXITING | 2413 CPU_BASED_MONITOR_EXITING |
2417 CPU_BASED_INVLPG_EXITING; 2414 CPU_BASED_INVLPG_EXITING |
2415 CPU_BASED_RDPMC_EXITING;
2418 2416
2419 if (yield_on_hlt) 2417 if (yield_on_hlt)
2420 min |= CPU_BASED_HLT_EXITING; 2418 min |= CPU_BASED_HLT_EXITING;
@@ -2716,11 +2714,13 @@ static gva_t rmode_tss_base(struct kvm *kvm)
2716{ 2714{
2717 if (!kvm->arch.tss_addr) { 2715 if (!kvm->arch.tss_addr) {
2718 struct kvm_memslots *slots; 2716 struct kvm_memslots *slots;
2717 struct kvm_memory_slot *slot;
2719 gfn_t base_gfn; 2718 gfn_t base_gfn;
2720 2719
2721 slots = kvm_memslots(kvm); 2720 slots = kvm_memslots(kvm);
2722 base_gfn = slots->memslots[0].base_gfn + 2721 slot = id_to_memslot(slots, 0);
2723 kvm->memslots->memslots[0].npages - 3; 2722 base_gfn = slot->base_gfn + slot->npages - 3;
2723
2724 return base_gfn << PAGE_SHIFT; 2724 return base_gfn << PAGE_SHIFT;
2725 } 2725 }
2726 return kvm->arch.tss_addr; 2726 return kvm->arch.tss_addr;
@@ -3945,12 +3945,15 @@ static bool nested_exit_on_intr(struct kvm_vcpu *vcpu)
3945static void enable_irq_window(struct kvm_vcpu *vcpu) 3945static void enable_irq_window(struct kvm_vcpu *vcpu)
3946{ 3946{
3947 u32 cpu_based_vm_exec_control; 3947 u32 cpu_based_vm_exec_control;
3948 if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) 3948 if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) {
3949 /* We can get here when nested_run_pending caused 3949 /*
3950 * vmx_interrupt_allowed() to return false. In this case, do 3950 * We get here if vmx_interrupt_allowed() said we can't
3951 * nothing - the interrupt will be injected later. 3951 * inject to L1 now because L2 must run. Ask L2 to exit
3952 * right after entry, so we can inject to L1 more promptly.
3952 */ 3953 */
3954 kvm_make_request(KVM_REQ_IMMEDIATE_EXIT, vcpu);
3953 return; 3955 return;
3956 }
3954 3957
3955 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); 3958 cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
3956 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; 3959 cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
@@ -4077,11 +4080,12 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
4077static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu) 4080static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu)
4078{ 4081{
4079 if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) { 4082 if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu)) {
4080 struct vmcs12 *vmcs12; 4083 struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
4081 if (to_vmx(vcpu)->nested.nested_run_pending) 4084 if (to_vmx(vcpu)->nested.nested_run_pending ||
4085 (vmcs12->idt_vectoring_info_field &
4086 VECTORING_INFO_VALID_MASK))
4082 return 0; 4087 return 0;
4083 nested_vmx_vmexit(vcpu); 4088 nested_vmx_vmexit(vcpu);
4084 vmcs12 = get_vmcs12(vcpu);
4085 vmcs12->vm_exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT; 4089 vmcs12->vm_exit_reason = EXIT_REASON_EXTERNAL_INTERRUPT;
4086 vmcs12->vm_exit_intr_info = 0; 4090 vmcs12->vm_exit_intr_info = 0;
4087 /* fall through to normal code, but now in L1, not L2 */ 4091 /* fall through to normal code, but now in L1, not L2 */
@@ -4611,6 +4615,16 @@ static int handle_invlpg(struct kvm_vcpu *vcpu)
4611 return 1; 4615 return 1;
4612} 4616}
4613 4617
4618static int handle_rdpmc(struct kvm_vcpu *vcpu)
4619{
4620 int err;
4621
4622 err = kvm_rdpmc(vcpu);
4623 kvm_complete_insn_gp(vcpu, err);
4624
4625 return 1;
4626}
4627
4614static int handle_wbinvd(struct kvm_vcpu *vcpu) 4628static int handle_wbinvd(struct kvm_vcpu *vcpu)
4615{ 4629{
4616 skip_emulated_instruction(vcpu); 4630 skip_emulated_instruction(vcpu);
@@ -5561,6 +5575,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
5561 [EXIT_REASON_HLT] = handle_halt, 5575 [EXIT_REASON_HLT] = handle_halt,
5562 [EXIT_REASON_INVD] = handle_invd, 5576 [EXIT_REASON_INVD] = handle_invd,
5563 [EXIT_REASON_INVLPG] = handle_invlpg, 5577 [EXIT_REASON_INVLPG] = handle_invlpg,
5578 [EXIT_REASON_RDPMC] = handle_rdpmc,
5564 [EXIT_REASON_VMCALL] = handle_vmcall, 5579 [EXIT_REASON_VMCALL] = handle_vmcall,
5565 [EXIT_REASON_VMCLEAR] = handle_vmclear, 5580 [EXIT_REASON_VMCLEAR] = handle_vmclear,
5566 [EXIT_REASON_VMLAUNCH] = handle_vmlaunch, 5581 [EXIT_REASON_VMLAUNCH] = handle_vmlaunch,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 4c938da2ba0..1171def5f96 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -26,6 +26,7 @@
26#include "tss.h" 26#include "tss.h"
27#include "kvm_cache_regs.h" 27#include "kvm_cache_regs.h"
28#include "x86.h" 28#include "x86.h"
29#include "cpuid.h"
29 30
30#include <linux/clocksource.h> 31#include <linux/clocksource.h>
31#include <linux/interrupt.h> 32#include <linux/interrupt.h>
@@ -82,8 +83,6 @@ static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
82#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU 83#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
83 84
84static void update_cr8_intercept(struct kvm_vcpu *vcpu); 85static void update_cr8_intercept(struct kvm_vcpu *vcpu);
85static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
86 struct kvm_cpuid_entry2 __user *entries);
87static void process_nmi(struct kvm_vcpu *vcpu); 86static void process_nmi(struct kvm_vcpu *vcpu);
88 87
89struct kvm_x86_ops *kvm_x86_ops; 88struct kvm_x86_ops *kvm_x86_ops;
@@ -574,54 +573,6 @@ int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
574} 573}
575EXPORT_SYMBOL_GPL(kvm_set_xcr); 574EXPORT_SYMBOL_GPL(kvm_set_xcr);
576 575
577static bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
578{
579 struct kvm_cpuid_entry2 *best;
580
581 best = kvm_find_cpuid_entry(vcpu, 1, 0);
582 return best && (best->ecx & bit(X86_FEATURE_XSAVE));
583}
584
585static bool guest_cpuid_has_smep(struct kvm_vcpu *vcpu)
586{
587 struct kvm_cpuid_entry2 *best;
588
589 best = kvm_find_cpuid_entry(vcpu, 7, 0);
590 return best && (best->ebx & bit(X86_FEATURE_SMEP));
591}
592
593static bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu)
594{
595 struct kvm_cpuid_entry2 *best;
596
597 best = kvm_find_cpuid_entry(vcpu, 7, 0);
598 return best && (best->ebx & bit(X86_FEATURE_FSGSBASE));
599}
600
601static void update_cpuid(struct kvm_vcpu *vcpu)
602{
603 struct kvm_cpuid_entry2 *best;
604 struct kvm_lapic *apic = vcpu->arch.apic;
605
606 best = kvm_find_cpuid_entry(vcpu, 1, 0);
607 if (!best)
608 return;
609
610 /* Update OSXSAVE bit */
611 if (cpu_has_xsave && best->function == 0x1) {
612 best->ecx &= ~(bit(X86_FEATURE_OSXSAVE));
613 if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE))
614 best->ecx |= bit(X86_FEATURE_OSXSAVE);
615 }
616
617 if (apic) {
618 if (best->ecx & bit(X86_FEATURE_TSC_DEADLINE_TIMER))
619 apic->lapic_timer.timer_mode_mask = 3 << 17;
620 else
621 apic->lapic_timer.timer_mode_mask = 1 << 17;
622 }
623}
624
625int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) 576int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
626{ 577{
627 unsigned long old_cr4 = kvm_read_cr4(vcpu); 578 unsigned long old_cr4 = kvm_read_cr4(vcpu);
@@ -655,7 +606,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
655 kvm_mmu_reset_context(vcpu); 606 kvm_mmu_reset_context(vcpu);
656 607
657 if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) 608 if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE)
658 update_cpuid(vcpu); 609 kvm_update_cpuid(vcpu);
659 610
660 return 0; 611 return 0;
661} 612}
@@ -809,6 +760,21 @@ int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
809} 760}
810EXPORT_SYMBOL_GPL(kvm_get_dr); 761EXPORT_SYMBOL_GPL(kvm_get_dr);
811 762
763bool kvm_rdpmc(struct kvm_vcpu *vcpu)
764{
765 u32 ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
766 u64 data;
767 int err;
768
769 err = kvm_pmu_read_pmc(vcpu, ecx, &data);
770 if (err)
771 return err;
772 kvm_register_write(vcpu, VCPU_REGS_RAX, (u32)data);
773 kvm_register_write(vcpu, VCPU_REGS_RDX, data >> 32);
774 return err;
775}
776EXPORT_SYMBOL_GPL(kvm_rdpmc);
777
812/* 778/*
813 * List of msr numbers which we expose to userspace through KVM_GET_MSRS 779 * List of msr numbers which we expose to userspace through KVM_GET_MSRS
814 * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. 780 * and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
@@ -1358,12 +1324,11 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
1358 if (page_num >= blob_size) 1324 if (page_num >= blob_size)
1359 goto out; 1325 goto out;
1360 r = -ENOMEM; 1326 r = -ENOMEM;
1361 page = kzalloc(PAGE_SIZE, GFP_KERNEL); 1327 page = memdup_user(blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE);
1362 if (!page) 1328 if (IS_ERR(page)) {
1329 r = PTR_ERR(page);
1363 goto out; 1330 goto out;
1364 r = -EFAULT; 1331 }
1365 if (copy_from_user(page, blob_addr + (page_num * PAGE_SIZE), PAGE_SIZE))
1366 goto out_free;
1367 if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE)) 1332 if (kvm_write_guest(kvm, page_addr, page, PAGE_SIZE))
1368 goto out_free; 1333 goto out_free;
1369 r = 0; 1334 r = 0;
@@ -1652,8 +1617,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1652 * which we perfectly emulate ;-). Any other value should be at least 1617 * which we perfectly emulate ;-). Any other value should be at least
1653 * reported, some guests depend on them. 1618 * reported, some guests depend on them.
1654 */ 1619 */
1655 case MSR_P6_EVNTSEL0:
1656 case MSR_P6_EVNTSEL1:
1657 case MSR_K7_EVNTSEL0: 1620 case MSR_K7_EVNTSEL0:
1658 case MSR_K7_EVNTSEL1: 1621 case MSR_K7_EVNTSEL1:
1659 case MSR_K7_EVNTSEL2: 1622 case MSR_K7_EVNTSEL2:
@@ -1665,8 +1628,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1665 /* at least RHEL 4 unconditionally writes to the perfctr registers, 1628 /* at least RHEL 4 unconditionally writes to the perfctr registers,
1666 * so we ignore writes to make it happy. 1629 * so we ignore writes to make it happy.
1667 */ 1630 */
1668 case MSR_P6_PERFCTR0:
1669 case MSR_P6_PERFCTR1:
1670 case MSR_K7_PERFCTR0: 1631 case MSR_K7_PERFCTR0:
1671 case MSR_K7_PERFCTR1: 1632 case MSR_K7_PERFCTR1:
1672 case MSR_K7_PERFCTR2: 1633 case MSR_K7_PERFCTR2:
@@ -1703,6 +1664,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1703 default: 1664 default:
1704 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr)) 1665 if (msr && (msr == vcpu->kvm->arch.xen_hvm_config.msr))
1705 return xen_hvm_config(vcpu, data); 1666 return xen_hvm_config(vcpu, data);
1667 if (kvm_pmu_msr(vcpu, msr))
1668 return kvm_pmu_set_msr(vcpu, msr, data);
1706 if (!ignore_msrs) { 1669 if (!ignore_msrs) {
1707 pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", 1670 pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n",
1708 msr, data); 1671 msr, data);
@@ -1865,10 +1828,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
1865 case MSR_K8_SYSCFG: 1828 case MSR_K8_SYSCFG:
1866 case MSR_K7_HWCR: 1829 case MSR_K7_HWCR:
1867 case MSR_VM_HSAVE_PA: 1830 case MSR_VM_HSAVE_PA:
1868 case MSR_P6_PERFCTR0:
1869 case MSR_P6_PERFCTR1:
1870 case MSR_P6_EVNTSEL0:
1871 case MSR_P6_EVNTSEL1:
1872 case MSR_K7_EVNTSEL0: 1831 case MSR_K7_EVNTSEL0:
1873 case MSR_K7_PERFCTR0: 1832 case MSR_K7_PERFCTR0:
1874 case MSR_K8_INT_PENDING_MSG: 1833 case MSR_K8_INT_PENDING_MSG:
@@ -1979,6 +1938,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
1979 data = 0xbe702111; 1938 data = 0xbe702111;
1980 break; 1939 break;
1981 default: 1940 default:
1941 if (kvm_pmu_msr(vcpu, msr))
1942 return kvm_pmu_get_msr(vcpu, msr, pdata);
1982 if (!ignore_msrs) { 1943 if (!ignore_msrs) {
1983 pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr); 1944 pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
1984 return 1; 1945 return 1;
@@ -2037,15 +1998,12 @@ static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs,
2037 if (msrs.nmsrs >= MAX_IO_MSRS) 1998 if (msrs.nmsrs >= MAX_IO_MSRS)
2038 goto out; 1999 goto out;
2039 2000
2040 r = -ENOMEM;
2041 size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; 2001 size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
2042 entries = kmalloc(size, GFP_KERNEL); 2002 entries = memdup_user(user_msrs->entries, size);
2043 if (!entries) 2003 if (IS_ERR(entries)) {
2004 r = PTR_ERR(entries);
2044 goto out; 2005 goto out;
2045 2006 }
2046 r = -EFAULT;
2047 if (copy_from_user(entries, user_msrs->entries, size))
2048 goto out_free;
2049 2007
2050 r = n = __msr_io(vcpu, &msrs, entries, do_msr); 2008 r = n = __msr_io(vcpu, &msrs, entries, do_msr);
2051 if (r < 0) 2009 if (r < 0)
@@ -2265,466 +2223,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
2265 vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu); 2223 vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu);
2266} 2224}
2267 2225
2268static int is_efer_nx(void)
2269{
2270 unsigned long long efer = 0;
2271
2272 rdmsrl_safe(MSR_EFER, &efer);
2273 return efer & EFER_NX;
2274}
2275
2276static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
2277{
2278 int i;
2279 struct kvm_cpuid_entry2 *e, *entry;
2280
2281 entry = NULL;
2282 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
2283 e = &vcpu->arch.cpuid_entries[i];
2284 if (e->function == 0x80000001) {
2285 entry = e;
2286 break;
2287 }
2288 }
2289 if (entry && (entry->edx & (1 << 20)) && !is_efer_nx()) {
2290 entry->edx &= ~(1 << 20);
2291 printk(KERN_INFO "kvm: guest NX capability removed\n");
2292 }
2293}
2294
2295/* when an old userspace process fills a new kernel module */
2296static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
2297 struct kvm_cpuid *cpuid,
2298 struct kvm_cpuid_entry __user *entries)
2299{
2300 int r, i;
2301 struct kvm_cpuid_entry *cpuid_entries;
2302
2303 r = -E2BIG;
2304 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
2305 goto out;
2306 r = -ENOMEM;
2307 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) * cpuid->nent);
2308 if (!cpuid_entries)
2309 goto out;
2310 r = -EFAULT;
2311 if (copy_from_user(cpuid_entries, entries,
2312 cpuid->nent * sizeof(struct kvm_cpuid_entry)))
2313 goto out_free;
2314 for (i = 0; i < cpuid->nent; i++) {
2315 vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
2316 vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
2317 vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
2318 vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
2319 vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
2320 vcpu->arch.cpuid_entries[i].index = 0;
2321 vcpu->arch.cpuid_entries[i].flags = 0;
2322 vcpu->arch.cpuid_entries[i].padding[0] = 0;
2323 vcpu->arch.cpuid_entries[i].padding[1] = 0;
2324 vcpu->arch.cpuid_entries[i].padding[2] = 0;
2325 }
2326 vcpu->arch.cpuid_nent = cpuid->nent;
2327 cpuid_fix_nx_cap(vcpu);
2328 r = 0;
2329 kvm_apic_set_version(vcpu);
2330 kvm_x86_ops->cpuid_update(vcpu);
2331 update_cpuid(vcpu);
2332
2333out_free:
2334 vfree(cpuid_entries);
2335out:
2336 return r;
2337}
2338
2339static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
2340 struct kvm_cpuid2 *cpuid,
2341 struct kvm_cpuid_entry2 __user *entries)
2342{
2343 int r;
2344
2345 r = -E2BIG;
2346 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
2347 goto out;
2348 r = -EFAULT;
2349 if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
2350 cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
2351 goto out;
2352 vcpu->arch.cpuid_nent = cpuid->nent;
2353 kvm_apic_set_version(vcpu);
2354 kvm_x86_ops->cpuid_update(vcpu);
2355 update_cpuid(vcpu);
2356 return 0;
2357
2358out:
2359 return r;
2360}
2361
2362static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
2363 struct kvm_cpuid2 *cpuid,
2364 struct kvm_cpuid_entry2 __user *entries)
2365{
2366 int r;
2367
2368 r = -E2BIG;
2369 if (cpuid->nent < vcpu->arch.cpuid_nent)
2370 goto out;
2371 r = -EFAULT;
2372 if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
2373 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
2374 goto out;
2375 return 0;
2376
2377out:
2378 cpuid->nent = vcpu->arch.cpuid_nent;
2379 return r;
2380}
2381
2382static void cpuid_mask(u32 *word, int wordnum)
2383{
2384 *word &= boot_cpu_data.x86_capability[wordnum];
2385}
2386
2387static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
2388 u32 index)
2389{
2390 entry->function = function;
2391 entry->index = index;
2392 cpuid_count(entry->function, entry->index,
2393 &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
2394 entry->flags = 0;
2395}
2396
2397static bool supported_xcr0_bit(unsigned bit)
2398{
2399 u64 mask = ((u64)1 << bit);
2400
2401 return mask & (XSTATE_FP | XSTATE_SSE | XSTATE_YMM) & host_xcr0;
2402}
2403
2404#define F(x) bit(X86_FEATURE_##x)
2405
2406static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
2407 u32 index, int *nent, int maxnent)
2408{
2409 unsigned f_nx = is_efer_nx() ? F(NX) : 0;
2410#ifdef CONFIG_X86_64
2411 unsigned f_gbpages = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
2412 ? F(GBPAGES) : 0;
2413 unsigned f_lm = F(LM);
2414#else
2415 unsigned f_gbpages = 0;
2416 unsigned f_lm = 0;
2417#endif
2418 unsigned f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
2419
2420 /* cpuid 1.edx */
2421 const u32 kvm_supported_word0_x86_features =
2422 F(FPU) | F(VME) | F(DE) | F(PSE) |
2423 F(TSC) | F(MSR) | F(PAE) | F(MCE) |
2424 F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) |
2425 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
2426 F(PAT) | F(PSE36) | 0 /* PSN */ | F(CLFLSH) |
2427 0 /* Reserved, DS, ACPI */ | F(MMX) |
2428 F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) |
2429 0 /* HTT, TM, Reserved, PBE */;
2430 /* cpuid 0x80000001.edx */
2431 const u32 kvm_supported_word1_x86_features =
2432 F(FPU) | F(VME) | F(DE) | F(PSE) |
2433 F(TSC) | F(MSR) | F(PAE) | F(MCE) |
2434 F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) |
2435 F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
2436 F(PAT) | F(PSE36) | 0 /* Reserved */ |
2437 f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
2438 F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
2439 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
2440 /* cpuid 1.ecx */
2441 const u32 kvm_supported_word4_x86_features =
2442 F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ |
2443 0 /* DS-CPL, VMX, SMX, EST */ |
2444 0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
2445 0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ |
2446 0 /* Reserved, DCA */ | F(XMM4_1) |
2447 F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
2448 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
2449 F(F16C) | F(RDRAND);
2450 /* cpuid 0x80000001.ecx */
2451 const u32 kvm_supported_word6_x86_features =
2452 F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
2453 F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
2454 F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) |
2455 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
2456
2457 /* cpuid 0xC0000001.edx */
2458 const u32 kvm_supported_word5_x86_features =
2459 F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
2460 F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
2461 F(PMM) | F(PMM_EN);
2462
2463 /* cpuid 7.0.ebx */
2464 const u32 kvm_supported_word9_x86_features =
2465 F(SMEP) | F(FSGSBASE) | F(ERMS);
2466
2467 /* all calls to cpuid_count() should be made on the same cpu */
2468 get_cpu();
2469 do_cpuid_1_ent(entry, function, index);
2470 ++*nent;
2471
2472 switch (function) {
2473 case 0:
2474 entry->eax = min(entry->eax, (u32)0xd);
2475 break;
2476 case 1:
2477 entry->edx &= kvm_supported_word0_x86_features;
2478 cpuid_mask(&entry->edx, 0);
2479 entry->ecx &= kvm_supported_word4_x86_features;
2480 cpuid_mask(&entry->ecx, 4);
2481 /* we support x2apic emulation even if host does not support
2482 * it since we emulate x2apic in software */
2483 entry->ecx |= F(X2APIC);
2484 break;
2485 /* function 2 entries are STATEFUL. That is, repeated cpuid commands
2486 * may return different values. This forces us to get_cpu() before
2487 * issuing the first command, and also to emulate this annoying behavior
2488 * in kvm_emulate_cpuid() using KVM_CPUID_FLAG_STATE_READ_NEXT */
2489 case 2: {
2490 int t, times = entry->eax & 0xff;
2491
2492 entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
2493 entry->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
2494 for (t = 1; t < times && *nent < maxnent; ++t) {
2495 do_cpuid_1_ent(&entry[t], function, 0);
2496 entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
2497 ++*nent;
2498 }
2499 break;
2500 }
2501 /* function 4 has additional index. */
2502 case 4: {
2503 int i, cache_type;
2504
2505 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2506 /* read more entries until cache_type is zero */
2507 for (i = 1; *nent < maxnent; ++i) {
2508 cache_type = entry[i - 1].eax & 0x1f;
2509 if (!cache_type)
2510 break;
2511 do_cpuid_1_ent(&entry[i], function, i);
2512 entry[i].flags |=
2513 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2514 ++*nent;
2515 }
2516 break;
2517 }
2518 case 7: {
2519 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2520 /* Mask ebx against host capbability word 9 */
2521 if (index == 0) {
2522 entry->ebx &= kvm_supported_word9_x86_features;
2523 cpuid_mask(&entry->ebx, 9);
2524 } else
2525 entry->ebx = 0;
2526 entry->eax = 0;
2527 entry->ecx = 0;
2528 entry->edx = 0;
2529 break;
2530 }
2531 case 9:
2532 break;
2533 /* function 0xb has additional index. */
2534 case 0xb: {
2535 int i, level_type;
2536
2537 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2538 /* read more entries until level_type is zero */
2539 for (i = 1; *nent < maxnent; ++i) {
2540 level_type = entry[i - 1].ecx & 0xff00;
2541 if (!level_type)
2542 break;
2543 do_cpuid_1_ent(&entry[i], function, i);
2544 entry[i].flags |=
2545 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2546 ++*nent;
2547 }
2548 break;
2549 }
2550 case 0xd: {
2551 int idx, i;
2552
2553 entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2554 for (idx = 1, i = 1; *nent < maxnent && idx < 64; ++idx) {
2555 do_cpuid_1_ent(&entry[i], function, idx);
2556 if (entry[i].eax == 0 || !supported_xcr0_bit(idx))
2557 continue;
2558 entry[i].flags |=
2559 KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
2560 ++*nent;
2561 ++i;
2562 }
2563 break;
2564 }
2565 case KVM_CPUID_SIGNATURE: {
2566 char signature[12] = "KVMKVMKVM\0\0";
2567 u32 *sigptr = (u32 *)signature;
2568 entry->eax = 0;
2569 entry->ebx = sigptr[0];
2570 entry->ecx = sigptr[1];
2571 entry->edx = sigptr[2];
2572 break;
2573 }
2574 case KVM_CPUID_FEATURES:
2575 entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
2576 (1 << KVM_FEATURE_NOP_IO_DELAY) |
2577 (1 << KVM_FEATURE_CLOCKSOURCE2) |
2578 (1 << KVM_FEATURE_ASYNC_PF) |
2579 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
2580
2581 if (sched_info_on())
2582 entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
2583
2584 entry->ebx = 0;
2585 entry->ecx = 0;
2586 entry->edx = 0;
2587 break;
2588 case 0x80000000:
2589 entry->eax = min(entry->eax, 0x8000001a);
2590 break;
2591 case 0x80000001:
2592 entry->edx &= kvm_supported_word1_x86_features;
2593 cpuid_mask(&entry->edx, 1);
2594 entry->ecx &= kvm_supported_word6_x86_features;
2595 cpuid_mask(&entry->ecx, 6);
2596 break;
2597 case 0x80000008: {
2598 unsigned g_phys_as = (entry->eax >> 16) & 0xff;
2599 unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
2600 unsigned phys_as = entry->eax & 0xff;
2601
2602 if (!g_phys_as)
2603 g_phys_as = phys_as;
2604 entry->eax = g_phys_as | (virt_as << 8);
2605 entry->ebx = entry->edx = 0;
2606 break;
2607 }
2608 case 0x80000019:
2609 entry->ecx = entry->edx = 0;
2610 break;
2611 case 0x8000001a:
2612 break;
2613 case 0x8000001d:
2614 break;
2615 /*Add support for Centaur's CPUID instruction*/
2616 case 0xC0000000:
2617 /*Just support up to 0xC0000004 now*/
2618 entry->eax = min(entry->eax, 0xC0000004);
2619 break;
2620 case 0xC0000001:
2621 entry->edx &= kvm_supported_word5_x86_features;
2622 cpuid_mask(&entry->edx, 5);
2623 break;
2624 case 3: /* Processor serial number */
2625 case 5: /* MONITOR/MWAIT */
2626 case 6: /* Thermal management */
2627 case 0xA: /* Architectural Performance Monitoring */
2628 case 0x80000007: /* Advanced power management */
2629 case 0xC0000002:
2630 case 0xC0000003:
2631 case 0xC0000004:
2632 default:
2633 entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
2634 break;
2635 }
2636
2637 kvm_x86_ops->set_supported_cpuid(function, entry);
2638
2639 put_cpu();
2640}
2641
2642#undef F
2643
2644static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
2645 struct kvm_cpuid_entry2 __user *entries)
2646{
2647 struct kvm_cpuid_entry2 *cpuid_entries;
2648 int limit, nent = 0, r = -E2BIG;
2649 u32 func;
2650
2651 if (cpuid->nent < 1)
2652 goto out;
2653 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
2654 cpuid->nent = KVM_MAX_CPUID_ENTRIES;
2655 r = -ENOMEM;
2656 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
2657 if (!cpuid_entries)
2658 goto out;
2659
2660 do_cpuid_ent(&cpuid_entries[0], 0, 0, &nent, cpuid->nent);
2661 limit = cpuid_entries[0].eax;
2662 for (func = 1; func <= limit && nent < cpuid->nent; ++func)
2663 do_cpuid_ent(&cpuid_entries[nent], func, 0,
2664 &nent, cpuid->nent);
2665 r = -E2BIG;
2666 if (nent >= cpuid->nent)
2667 goto out_free;
2668
2669 do_cpuid_ent(&cpuid_entries[nent], 0x80000000, 0, &nent, cpuid->nent);
2670 limit = cpuid_entries[nent - 1].eax;
2671 for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
2672 do_cpuid_ent(&cpuid_entries[nent], func, 0,
2673 &nent, cpuid->nent);
2674
2675
2676
2677 r = -E2BIG;
2678 if (nent >= cpuid->nent)
2679 goto out_free;
2680
2681 /* Add support for Centaur's CPUID instruction. */
2682 if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) {
2683 do_cpuid_ent(&cpuid_entries[nent], 0xC0000000, 0,
2684 &nent, cpuid->nent);
2685
2686 r = -E2BIG;
2687 if (nent >= cpuid->nent)
2688 goto out_free;
2689
2690 limit = cpuid_entries[nent - 1].eax;
2691 for (func = 0xC0000001;
2692 func <= limit && nent < cpuid->nent; ++func)
2693 do_cpuid_ent(&cpuid_entries[nent], func, 0,
2694 &nent, cpuid->nent);
2695
2696 r = -E2BIG;
2697 if (nent >= cpuid->nent)
2698 goto out_free;
2699 }
2700
2701 do_cpuid_ent(&cpuid_entries[nent], KVM_CPUID_SIGNATURE, 0, &nent,
2702 cpuid->nent);
2703
2704 r = -E2BIG;
2705 if (nent >= cpuid->nent)
2706 goto out_free;
2707
2708 do_cpuid_ent(&cpuid_entries[nent], KVM_CPUID_FEATURES, 0, &nent,
2709 cpuid->nent);
2710
2711 r = -E2BIG;
2712 if (nent >= cpuid->nent)
2713 goto out_free;
2714
2715 r = -EFAULT;
2716 if (copy_to_user(entries, cpuid_entries,
2717 nent * sizeof(struct kvm_cpuid_entry2)))
2718 goto out_free;
2719 cpuid->nent = nent;
2720 r = 0;
2721
2722out_free:
2723 vfree(cpuid_entries);
2724out:
2725 return r;
2726}
2727
2728static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu, 2226static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
2729 struct kvm_lapic_state *s) 2227 struct kvm_lapic_state *s)
2730{ 2228{
@@ -3042,13 +2540,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
3042 r = -EINVAL; 2540 r = -EINVAL;
3043 if (!vcpu->arch.apic) 2541 if (!vcpu->arch.apic)
3044 goto out; 2542 goto out;
3045 u.lapic = kmalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL); 2543 u.lapic = memdup_user(argp, sizeof(*u.lapic));
3046 r = -ENOMEM; 2544 if (IS_ERR(u.lapic)) {
3047 if (!u.lapic) 2545 r = PTR_ERR(u.lapic);
3048 goto out;
3049 r = -EFAULT;
3050 if (copy_from_user(u.lapic, argp, sizeof(struct kvm_lapic_state)))
3051 goto out; 2546 goto out;
2547 }
2548
3052 r = kvm_vcpu_ioctl_set_lapic(vcpu, u.lapic); 2549 r = kvm_vcpu_ioctl_set_lapic(vcpu, u.lapic);
3053 if (r) 2550 if (r)
3054 goto out; 2551 goto out;
@@ -3227,14 +2724,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
3227 break; 2724 break;
3228 } 2725 }
3229 case KVM_SET_XSAVE: { 2726 case KVM_SET_XSAVE: {
3230 u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); 2727 u.xsave = memdup_user(argp, sizeof(*u.xsave));
3231 r = -ENOMEM; 2728 if (IS_ERR(u.xsave)) {
3232 if (!u.xsave) 2729 r = PTR_ERR(u.xsave);
3233 break; 2730 goto out;
3234 2731 }
3235 r = -EFAULT;
3236 if (copy_from_user(u.xsave, argp, sizeof(struct kvm_xsave)))
3237 break;
3238 2732
3239 r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, u.xsave); 2733 r = kvm_vcpu_ioctl_x86_set_xsave(vcpu, u.xsave);
3240 break; 2734 break;
@@ -3255,15 +2749,11 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
3255 break; 2749 break;
3256 } 2750 }
3257 case KVM_SET_XCRS: { 2751 case KVM_SET_XCRS: {
3258 u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); 2752 u.xcrs = memdup_user(argp, sizeof(*u.xcrs));
3259 r = -ENOMEM; 2753 if (IS_ERR(u.xcrs)) {
3260 if (!u.xcrs) 2754 r = PTR_ERR(u.xcrs);
3261 break; 2755 goto out;
3262 2756 }
3263 r = -EFAULT;
3264 if (copy_from_user(u.xcrs, argp,
3265 sizeof(struct kvm_xcrs)))
3266 break;
3267 2757
3268 r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs); 2758 r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs);
3269 break; 2759 break;
@@ -3460,16 +2950,59 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
3460 return 0; 2950 return 0;
3461} 2951}
3462 2952
2953/**
2954 * write_protect_slot - write protect a slot for dirty logging
2955 * @kvm: the kvm instance
2956 * @memslot: the slot we protect
2957 * @dirty_bitmap: the bitmap indicating which pages are dirty
2958 * @nr_dirty_pages: the number of dirty pages
2959 *
2960 * We have two ways to find all sptes to protect:
2961 * 1. Use kvm_mmu_slot_remove_write_access() which walks all shadow pages and
2962 * checks ones that have a spte mapping a page in the slot.
2963 * 2. Use kvm_mmu_rmap_write_protect() for each gfn found in the bitmap.
2964 *
2965 * Generally speaking, if there are not so many dirty pages compared to the
2966 * number of shadow pages, we should use the latter.
2967 *
2968 * Note that letting others write into a page marked dirty in the old bitmap
2969 * by using the remaining tlb entry is not a problem. That page will become
2970 * write protected again when we flush the tlb and then be reported dirty to
2971 * the user space by copying the old bitmap.
2972 */
2973static void write_protect_slot(struct kvm *kvm,
2974 struct kvm_memory_slot *memslot,
2975 unsigned long *dirty_bitmap,
2976 unsigned long nr_dirty_pages)
2977{
2978 /* Not many dirty pages compared to # of shadow pages. */
2979 if (nr_dirty_pages < kvm->arch.n_used_mmu_pages) {
2980 unsigned long gfn_offset;
2981
2982 for_each_set_bit(gfn_offset, dirty_bitmap, memslot->npages) {
2983 unsigned long gfn = memslot->base_gfn + gfn_offset;
2984
2985 spin_lock(&kvm->mmu_lock);
2986 kvm_mmu_rmap_write_protect(kvm, gfn, memslot);
2987 spin_unlock(&kvm->mmu_lock);
2988 }
2989 kvm_flush_remote_tlbs(kvm);
2990 } else {
2991 spin_lock(&kvm->mmu_lock);
2992 kvm_mmu_slot_remove_write_access(kvm, memslot->id);
2993 spin_unlock(&kvm->mmu_lock);
2994 }
2995}
2996
3463/* 2997/*
3464 * Get (and clear) the dirty memory log for a memory slot. 2998 * Get (and clear) the dirty memory log for a memory slot.
3465 */ 2999 */
3466int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, 3000int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
3467 struct kvm_dirty_log *log) 3001 struct kvm_dirty_log *log)
3468{ 3002{
3469 int r, i; 3003 int r;
3470 struct kvm_memory_slot *memslot; 3004 struct kvm_memory_slot *memslot;
3471 unsigned long n; 3005 unsigned long n, nr_dirty_pages;
3472 unsigned long is_dirty = 0;
3473 3006
3474 mutex_lock(&kvm->slots_lock); 3007 mutex_lock(&kvm->slots_lock);
3475 3008
@@ -3477,43 +3010,41 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
3477 if (log->slot >= KVM_MEMORY_SLOTS) 3010 if (log->slot >= KVM_MEMORY_SLOTS)
3478 goto out; 3011 goto out;
3479 3012
3480 memslot = &kvm->memslots->memslots[log->slot]; 3013 memslot = id_to_memslot(kvm->memslots, log->slot);
3481 r = -ENOENT; 3014 r = -ENOENT;
3482 if (!memslot->dirty_bitmap) 3015 if (!memslot->dirty_bitmap)
3483 goto out; 3016 goto out;
3484 3017
3485 n = kvm_dirty_bitmap_bytes(memslot); 3018 n = kvm_dirty_bitmap_bytes(memslot);
3486 3019 nr_dirty_pages = memslot->nr_dirty_pages;
3487 for (i = 0; !is_dirty && i < n/sizeof(long); i++)
3488 is_dirty = memslot->dirty_bitmap[i];
3489 3020
3490 /* If nothing is dirty, don't bother messing with page tables. */ 3021 /* If nothing is dirty, don't bother messing with page tables. */
3491 if (is_dirty) { 3022 if (nr_dirty_pages) {
3492 struct kvm_memslots *slots, *old_slots; 3023 struct kvm_memslots *slots, *old_slots;
3493 unsigned long *dirty_bitmap; 3024 unsigned long *dirty_bitmap, *dirty_bitmap_head;
3494 3025
3495 dirty_bitmap = memslot->dirty_bitmap_head; 3026 dirty_bitmap = memslot->dirty_bitmap;
3496 if (memslot->dirty_bitmap == dirty_bitmap) 3027 dirty_bitmap_head = memslot->dirty_bitmap_head;
3497 dirty_bitmap += n / sizeof(long); 3028 if (dirty_bitmap == dirty_bitmap_head)
3498 memset(dirty_bitmap, 0, n); 3029 dirty_bitmap_head += n / sizeof(long);
3030 memset(dirty_bitmap_head, 0, n);
3499 3031
3500 r = -ENOMEM; 3032 r = -ENOMEM;
3501 slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL); 3033 slots = kmemdup(kvm->memslots, sizeof(*kvm->memslots), GFP_KERNEL);
3502 if (!slots) 3034 if (!slots)
3503 goto out; 3035 goto out;
3504 memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots)); 3036
3505 slots->memslots[log->slot].dirty_bitmap = dirty_bitmap; 3037 memslot = id_to_memslot(slots, log->slot);
3506 slots->generation++; 3038 memslot->nr_dirty_pages = 0;
3039 memslot->dirty_bitmap = dirty_bitmap_head;
3040 update_memslots(slots, NULL);
3507 3041
3508 old_slots = kvm->memslots; 3042 old_slots = kvm->memslots;
3509 rcu_assign_pointer(kvm->memslots, slots); 3043 rcu_assign_pointer(kvm->memslots, slots);
3510 synchronize_srcu_expedited(&kvm->srcu); 3044 synchronize_srcu_expedited(&kvm->srcu);
3511 dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
3512 kfree(old_slots); 3045 kfree(old_slots);
3513 3046
3514 spin_lock(&kvm->mmu_lock); 3047 write_protect_slot(kvm, memslot, dirty_bitmap, nr_dirty_pages);
3515 kvm_mmu_slot_remove_write_access(kvm, log->slot);
3516 spin_unlock(&kvm->mmu_lock);
3517 3048
3518 r = -EFAULT; 3049 r = -EFAULT;
3519 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) 3050 if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
@@ -3658,14 +3189,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
3658 } 3189 }
3659 case KVM_GET_IRQCHIP: { 3190 case KVM_GET_IRQCHIP: {
3660 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ 3191 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
3661 struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); 3192 struct kvm_irqchip *chip;
3662 3193
3663 r = -ENOMEM; 3194 chip = memdup_user(argp, sizeof(*chip));
3664 if (!chip) 3195 if (IS_ERR(chip)) {
3196 r = PTR_ERR(chip);
3665 goto out; 3197 goto out;
3666 r = -EFAULT; 3198 }
3667 if (copy_from_user(chip, argp, sizeof *chip)) 3199
3668 goto get_irqchip_out;
3669 r = -ENXIO; 3200 r = -ENXIO;
3670 if (!irqchip_in_kernel(kvm)) 3201 if (!irqchip_in_kernel(kvm))
3671 goto get_irqchip_out; 3202 goto get_irqchip_out;
@@ -3684,14 +3215,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
3684 } 3215 }
3685 case KVM_SET_IRQCHIP: { 3216 case KVM_SET_IRQCHIP: {
3686 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */ 3217 /* 0: PIC master, 1: PIC slave, 2: IOAPIC */
3687 struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL); 3218 struct kvm_irqchip *chip;
3688 3219
3689 r = -ENOMEM; 3220 chip = memdup_user(argp, sizeof(*chip));
3690 if (!chip) 3221 if (IS_ERR(chip)) {
3222 r = PTR_ERR(chip);
3691 goto out; 3223 goto out;
3692 r = -EFAULT; 3224 }
3693 if (copy_from_user(chip, argp, sizeof *chip)) 3225
3694 goto set_irqchip_out;
3695 r = -ENXIO; 3226 r = -ENXIO;
3696 if (!irqchip_in_kernel(kvm)) 3227 if (!irqchip_in_kernel(kvm))
3697 goto set_irqchip_out; 3228 goto set_irqchip_out;
@@ -3898,12 +3429,7 @@ void kvm_get_segment(struct kvm_vcpu *vcpu,
3898 kvm_x86_ops->get_segment(vcpu, var, seg); 3429 kvm_x86_ops->get_segment(vcpu, var, seg);
3899} 3430}
3900 3431
3901static gpa_t translate_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access) 3432gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
3902{
3903 return gpa;
3904}
3905
3906static gpa_t translate_nested_gpa(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access)
3907{ 3433{
3908 gpa_t t_gpa; 3434 gpa_t t_gpa;
3909 struct x86_exception exception; 3435 struct x86_exception exception;
@@ -4087,7 +3613,7 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
4087 ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes); 3613 ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
4088 if (ret < 0) 3614 if (ret < 0)
4089 return 0; 3615 return 0;
4090 kvm_mmu_pte_write(vcpu, gpa, val, bytes, 1); 3616 kvm_mmu_pte_write(vcpu, gpa, val, bytes);
4091 return 1; 3617 return 1;
4092} 3618}
4093 3619
@@ -4324,7 +3850,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
4324 if (!exchanged) 3850 if (!exchanged)
4325 return X86EMUL_CMPXCHG_FAILED; 3851 return X86EMUL_CMPXCHG_FAILED;
4326 3852
4327 kvm_mmu_pte_write(vcpu, gpa, new, bytes, 1); 3853 kvm_mmu_pte_write(vcpu, gpa, new, bytes);
4328 3854
4329 return X86EMUL_CONTINUE; 3855 return X86EMUL_CONTINUE;
4330 3856
@@ -4349,32 +3875,24 @@ static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
4349 return r; 3875 return r;
4350} 3876}
4351 3877
4352 3878static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size,
4353static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt, 3879 unsigned short port, void *val,
4354 int size, unsigned short port, void *val, 3880 unsigned int count, bool in)
4355 unsigned int count)
4356{ 3881{
4357 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); 3882 trace_kvm_pio(!in, port, size, count);
4358
4359 if (vcpu->arch.pio.count)
4360 goto data_avail;
4361
4362 trace_kvm_pio(0, port, size, count);
4363 3883
4364 vcpu->arch.pio.port = port; 3884 vcpu->arch.pio.port = port;
4365 vcpu->arch.pio.in = 1; 3885 vcpu->arch.pio.in = in;
4366 vcpu->arch.pio.count = count; 3886 vcpu->arch.pio.count = count;
4367 vcpu->arch.pio.size = size; 3887 vcpu->arch.pio.size = size;
4368 3888
4369 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { 3889 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
4370 data_avail:
4371 memcpy(val, vcpu->arch.pio_data, size * count);
4372 vcpu->arch.pio.count = 0; 3890 vcpu->arch.pio.count = 0;
4373 return 1; 3891 return 1;
4374 } 3892 }
4375 3893
4376 vcpu->run->exit_reason = KVM_EXIT_IO; 3894 vcpu->run->exit_reason = KVM_EXIT_IO;
4377 vcpu->run->io.direction = KVM_EXIT_IO_IN; 3895 vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
4378 vcpu->run->io.size = size; 3896 vcpu->run->io.size = size;
4379 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; 3897 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
4380 vcpu->run->io.count = count; 3898 vcpu->run->io.count = count;
@@ -4383,36 +3901,37 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
4383 return 0; 3901 return 0;
4384} 3902}
4385 3903
4386static int emulator_pio_out_emulated(struct x86_emulate_ctxt *ctxt, 3904static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
4387 int size, unsigned short port, 3905 int size, unsigned short port, void *val,
4388 const void *val, unsigned int count) 3906 unsigned int count)
4389{ 3907{
4390 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); 3908 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
3909 int ret;
4391 3910
4392 trace_kvm_pio(1, port, size, count); 3911 if (vcpu->arch.pio.count)
4393 3912 goto data_avail;
4394 vcpu->arch.pio.port = port;
4395 vcpu->arch.pio.in = 0;
4396 vcpu->arch.pio.count = count;
4397 vcpu->arch.pio.size = size;
4398
4399 memcpy(vcpu->arch.pio_data, val, size * count);
4400 3913
4401 if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { 3914 ret = emulator_pio_in_out(vcpu, size, port, val, count, true);
3915 if (ret) {
3916data_avail:
3917 memcpy(val, vcpu->arch.pio_data, size * count);
4402 vcpu->arch.pio.count = 0; 3918 vcpu->arch.pio.count = 0;
4403 return 1; 3919 return 1;
4404 } 3920 }
4405 3921
4406 vcpu->run->exit_reason = KVM_EXIT_IO;
4407 vcpu->run->io.direction = KVM_EXIT_IO_OUT;
4408 vcpu->run->io.size = size;
4409 vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE;
4410 vcpu->run->io.count = count;
4411 vcpu->run->io.port = port;
4412
4413 return 0; 3922 return 0;
4414} 3923}
4415 3924
3925static int emulator_pio_out_emulated(struct x86_emulate_ctxt *ctxt,
3926 int size, unsigned short port,
3927 const void *val, unsigned int count)
3928{
3929 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
3930
3931 memcpy(vcpu->arch.pio_data, val, size * count);
3932 return emulator_pio_in_out(vcpu, size, port, (void *)val, count, false);
3933}
3934
4416static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) 3935static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
4417{ 3936{
4418 return kvm_x86_ops->get_segment_base(vcpu, seg); 3937 return kvm_x86_ops->get_segment_base(vcpu, seg);
@@ -4627,6 +4146,12 @@ static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
4627 return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data); 4146 return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data);
4628} 4147}
4629 4148
4149static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt,
4150 u32 pmc, u64 *pdata)
4151{
4152 return kvm_pmu_read_pmc(emul_to_vcpu(ctxt), pmc, pdata);
4153}
4154
4630static void emulator_halt(struct x86_emulate_ctxt *ctxt) 4155static void emulator_halt(struct x86_emulate_ctxt *ctxt)
4631{ 4156{
4632 emul_to_vcpu(ctxt)->arch.halt_request = 1; 4157 emul_to_vcpu(ctxt)->arch.halt_request = 1;
@@ -4679,6 +4204,7 @@ static struct x86_emulate_ops emulate_ops = {
4679 .set_dr = emulator_set_dr, 4204 .set_dr = emulator_set_dr,
4680 .set_msr = emulator_set_msr, 4205 .set_msr = emulator_set_msr,
4681 .get_msr = emulator_get_msr, 4206 .get_msr = emulator_get_msr,
4207 .read_pmc = emulator_read_pmc,
4682 .halt = emulator_halt, 4208 .halt = emulator_halt,
4683 .wbinvd = emulator_wbinvd, 4209 .wbinvd = emulator_wbinvd,
4684 .fix_hypercall = emulator_fix_hypercall, 4210 .fix_hypercall = emulator_fix_hypercall,
@@ -4836,6 +4362,50 @@ static bool reexecute_instruction(struct kvm_vcpu *vcpu, gva_t gva)
4836 return false; 4362 return false;
4837} 4363}
4838 4364
4365static bool retry_instruction(struct x86_emulate_ctxt *ctxt,
4366 unsigned long cr2, int emulation_type)
4367{
4368 struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
4369 unsigned long last_retry_eip, last_retry_addr, gpa = cr2;
4370
4371 last_retry_eip = vcpu->arch.last_retry_eip;
4372 last_retry_addr = vcpu->arch.last_retry_addr;
4373
4374 /*
4375 * If the emulation is caused by #PF and it is non-page_table
4376 * writing instruction, it means the VM-EXIT is caused by shadow
4377 * page protected, we can zap the shadow page and retry this
4378 * instruction directly.
4379 *
4380 * Note: if the guest uses a non-page-table modifying instruction
4381 * on the PDE that points to the instruction, then we will unmap
4382 * the instruction and go to an infinite loop. So, we cache the
4383 * last retried eip and the last fault address, if we meet the eip
4384 * and the address again, we can break out of the potential infinite
4385 * loop.
4386 */
4387 vcpu->arch.last_retry_eip = vcpu->arch.last_retry_addr = 0;
4388
4389 if (!(emulation_type & EMULTYPE_RETRY))
4390 return false;
4391
4392 if (x86_page_table_writing_insn(ctxt))
4393 return false;
4394
4395 if (ctxt->eip == last_retry_eip && last_retry_addr == cr2)
4396 return false;
4397
4398 vcpu->arch.last_retry_eip = ctxt->eip;
4399 vcpu->arch.last_retry_addr = cr2;
4400
4401 if (!vcpu->arch.mmu.direct_map)
4402 gpa = kvm_mmu_gva_to_gpa_write(vcpu, cr2, NULL);
4403
4404 kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT);
4405
4406 return true;
4407}
4408
4839int x86_emulate_instruction(struct kvm_vcpu *vcpu, 4409int x86_emulate_instruction(struct kvm_vcpu *vcpu,
4840 unsigned long cr2, 4410 unsigned long cr2,
4841 int emulation_type, 4411 int emulation_type,
@@ -4877,6 +4447,9 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
4877 return EMULATE_DONE; 4447 return EMULATE_DONE;
4878 } 4448 }
4879 4449
4450 if (retry_instruction(ctxt, cr2, emulation_type))
4451 return EMULATE_DONE;
4452
4880 /* this is needed for vmware backdoor interface to work since it 4453 /* this is needed for vmware backdoor interface to work since it
4881 changes registers values during IO operation */ 4454 changes registers values during IO operation */
4882 if (vcpu->arch.emulate_regs_need_sync_from_vcpu) { 4455 if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
@@ -5095,17 +4668,17 @@ static void kvm_timer_init(void)
5095 4668
5096static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu); 4669static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
5097 4670
5098static int kvm_is_in_guest(void) 4671int kvm_is_in_guest(void)
5099{ 4672{
5100 return percpu_read(current_vcpu) != NULL; 4673 return __this_cpu_read(current_vcpu) != NULL;
5101} 4674}
5102 4675
5103static int kvm_is_user_mode(void) 4676static int kvm_is_user_mode(void)
5104{ 4677{
5105 int user_mode = 3; 4678 int user_mode = 3;
5106 4679
5107 if (percpu_read(current_vcpu)) 4680 if (__this_cpu_read(current_vcpu))
5108 user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu)); 4681 user_mode = kvm_x86_ops->get_cpl(__this_cpu_read(current_vcpu));
5109 4682
5110 return user_mode != 0; 4683 return user_mode != 0;
5111} 4684}
@@ -5114,8 +4687,8 @@ static unsigned long kvm_get_guest_ip(void)
5114{ 4687{
5115 unsigned long ip = 0; 4688 unsigned long ip = 0;
5116 4689
5117 if (percpu_read(current_vcpu)) 4690 if (__this_cpu_read(current_vcpu))
5118 ip = kvm_rip_read(percpu_read(current_vcpu)); 4691 ip = kvm_rip_read(__this_cpu_read(current_vcpu));
5119 4692
5120 return ip; 4693 return ip;
5121} 4694}
@@ -5128,13 +4701,13 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
5128 4701
5129void kvm_before_handle_nmi(struct kvm_vcpu *vcpu) 4702void kvm_before_handle_nmi(struct kvm_vcpu *vcpu)
5130{ 4703{
5131 percpu_write(current_vcpu, vcpu); 4704 __this_cpu_write(current_vcpu, vcpu);
5132} 4705}
5133EXPORT_SYMBOL_GPL(kvm_before_handle_nmi); 4706EXPORT_SYMBOL_GPL(kvm_before_handle_nmi);
5134 4707
5135void kvm_after_handle_nmi(struct kvm_vcpu *vcpu) 4708void kvm_after_handle_nmi(struct kvm_vcpu *vcpu)
5136{ 4709{
5137 percpu_write(current_vcpu, NULL); 4710 __this_cpu_write(current_vcpu, NULL);
5138} 4711}
5139EXPORT_SYMBOL_GPL(kvm_after_handle_nmi); 4712EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
5140 4713
@@ -5233,15 +4806,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
5233} 4806}
5234EXPORT_SYMBOL_GPL(kvm_emulate_halt); 4807EXPORT_SYMBOL_GPL(kvm_emulate_halt);
5235 4808
5236static inline gpa_t hc_gpa(struct kvm_vcpu *vcpu, unsigned long a0,
5237 unsigned long a1)
5238{
5239 if (is_long_mode(vcpu))
5240 return a0;
5241 else
5242 return a0 | ((gpa_t)a1 << 32);
5243}
5244
5245int kvm_hv_hypercall(struct kvm_vcpu *vcpu) 4809int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
5246{ 4810{
5247 u64 param, ingpa, outgpa, ret; 4811 u64 param, ingpa, outgpa, ret;
@@ -5337,9 +4901,6 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
5337 case KVM_HC_VAPIC_POLL_IRQ: 4901 case KVM_HC_VAPIC_POLL_IRQ:
5338 ret = 0; 4902 ret = 0;
5339 break; 4903 break;
5340 case KVM_HC_MMU_OP:
5341 r = kvm_pv_mmu_op(vcpu, a0, hc_gpa(vcpu, a1, a2), &ret);
5342 break;
5343 default: 4904 default:
5344 ret = -KVM_ENOSYS; 4905 ret = -KVM_ENOSYS;
5345 break; 4906 break;
@@ -5369,125 +4930,6 @@ int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
5369 return emulator_write_emulated(ctxt, rip, instruction, 3, NULL); 4930 return emulator_write_emulated(ctxt, rip, instruction, 3, NULL);
5370} 4931}
5371 4932
5372static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
5373{
5374 struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
5375 int j, nent = vcpu->arch.cpuid_nent;
5376
5377 e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
5378 /* when no next entry is found, the current entry[i] is reselected */
5379 for (j = i + 1; ; j = (j + 1) % nent) {
5380 struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
5381 if (ej->function == e->function) {
5382 ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
5383 return j;
5384 }
5385 }
5386 return 0; /* silence gcc, even though control never reaches here */
5387}
5388
5389/* find an entry with matching function, matching index (if needed), and that
5390 * should be read next (if it's stateful) */
5391static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
5392 u32 function, u32 index)
5393{
5394 if (e->function != function)
5395 return 0;
5396 if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index)
5397 return 0;
5398 if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
5399 !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
5400 return 0;
5401 return 1;
5402}
5403
5404struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
5405 u32 function, u32 index)
5406{
5407 int i;
5408 struct kvm_cpuid_entry2 *best = NULL;
5409
5410 for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
5411 struct kvm_cpuid_entry2 *e;
5412
5413 e = &vcpu->arch.cpuid_entries[i];
5414 if (is_matching_cpuid_entry(e, function, index)) {
5415 if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
5416 move_to_next_stateful_cpuid_entry(vcpu, i);
5417 best = e;
5418 break;
5419 }
5420 }
5421 return best;
5422}
5423EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
5424
5425int cpuid_maxphyaddr(struct kvm_vcpu *vcpu)
5426{
5427 struct kvm_cpuid_entry2 *best;
5428
5429 best = kvm_find_cpuid_entry(vcpu, 0x80000000, 0);
5430 if (!best || best->eax < 0x80000008)
5431 goto not_found;
5432 best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
5433 if (best)
5434 return best->eax & 0xff;
5435not_found:
5436 return 36;
5437}
5438
5439/*
5440 * If no match is found, check whether we exceed the vCPU's limit
5441 * and return the content of the highest valid _standard_ leaf instead.
5442 * This is to satisfy the CPUID specification.
5443 */
5444static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
5445 u32 function, u32 index)
5446{
5447 struct kvm_cpuid_entry2 *maxlevel;
5448
5449 maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
5450 if (!maxlevel || maxlevel->eax >= function)
5451 return NULL;
5452 if (function & 0x80000000) {
5453 maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
5454 if (!maxlevel)
5455 return NULL;
5456 }
5457 return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
5458}
5459
5460void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
5461{
5462 u32 function, index;
5463 struct kvm_cpuid_entry2 *best;
5464
5465 function = kvm_register_read(vcpu, VCPU_REGS_RAX);
5466 index = kvm_register_read(vcpu, VCPU_REGS_RCX);
5467 kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
5468 kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
5469 kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
5470 kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
5471 best = kvm_find_cpuid_entry(vcpu, function, index);
5472
5473 if (!best)
5474 best = check_cpuid_limit(vcpu, function, index);
5475
5476 if (best) {
5477 kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
5478 kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);
5479 kvm_register_write(vcpu, VCPU_REGS_RCX, best->ecx);
5480 kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx);
5481 }
5482 kvm_x86_ops->skip_emulated_instruction(vcpu);
5483 trace_kvm_cpuid(function,
5484 kvm_register_read(vcpu, VCPU_REGS_RAX),
5485 kvm_register_read(vcpu, VCPU_REGS_RBX),
5486 kvm_register_read(vcpu, VCPU_REGS_RCX),
5487 kvm_register_read(vcpu, VCPU_REGS_RDX));
5488}
5489EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
5490
5491/* 4933/*
5492 * Check if userspace requested an interrupt window, and that the 4934 * Check if userspace requested an interrupt window, and that the
5493 * interrupt window is open. 4935 * interrupt window is open.
@@ -5648,6 +5090,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5648 int r; 5090 int r;
5649 bool req_int_win = !irqchip_in_kernel(vcpu->kvm) && 5091 bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
5650 vcpu->run->request_interrupt_window; 5092 vcpu->run->request_interrupt_window;
5093 bool req_immediate_exit = 0;
5651 5094
5652 if (vcpu->requests) { 5095 if (vcpu->requests) {
5653 if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu)) 5096 if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu))
@@ -5687,7 +5130,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5687 record_steal_time(vcpu); 5130 record_steal_time(vcpu);
5688 if (kvm_check_request(KVM_REQ_NMI, vcpu)) 5131 if (kvm_check_request(KVM_REQ_NMI, vcpu))
5689 process_nmi(vcpu); 5132 process_nmi(vcpu);
5690 5133 req_immediate_exit =
5134 kvm_check_request(KVM_REQ_IMMEDIATE_EXIT, vcpu);
5135 if (kvm_check_request(KVM_REQ_PMU, vcpu))
5136 kvm_handle_pmu_event(vcpu);
5137 if (kvm_check_request(KVM_REQ_PMI, vcpu))
5138 kvm_deliver_pmi(vcpu);
5691 } 5139 }
5692 5140
5693 r = kvm_mmu_reload(vcpu); 5141 r = kvm_mmu_reload(vcpu);
@@ -5738,6 +5186,9 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5738 5186
5739 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); 5187 srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
5740 5188
5189 if (req_immediate_exit)
5190 smp_send_reschedule(vcpu->cpu);
5191
5741 kvm_guest_enter(); 5192 kvm_guest_enter();
5742 5193
5743 if (unlikely(vcpu->arch.switch_db_regs)) { 5194 if (unlikely(vcpu->arch.switch_db_regs)) {
@@ -5943,10 +5394,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
5943 if (r <= 0) 5394 if (r <= 0)
5944 goto out; 5395 goto out;
5945 5396
5946 if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL)
5947 kvm_register_write(vcpu, VCPU_REGS_RAX,
5948 kvm_run->hypercall.ret);
5949
5950 r = __vcpu_run(vcpu); 5397 r = __vcpu_run(vcpu);
5951 5398
5952out: 5399out:
@@ -6148,7 +5595,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
6148 mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; 5595 mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
6149 kvm_x86_ops->set_cr4(vcpu, sregs->cr4); 5596 kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
6150 if (sregs->cr4 & X86_CR4_OSXSAVE) 5597 if (sregs->cr4 & X86_CR4_OSXSAVE)
6151 update_cpuid(vcpu); 5598 kvm_update_cpuid(vcpu);
6152 5599
6153 idx = srcu_read_lock(&vcpu->kvm->srcu); 5600 idx = srcu_read_lock(&vcpu->kvm->srcu);
6154 if (!is_long_mode(vcpu) && is_pae(vcpu)) { 5601 if (!is_long_mode(vcpu) && is_pae(vcpu)) {
@@ -6425,6 +5872,8 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
6425 kvm_async_pf_hash_reset(vcpu); 5872 kvm_async_pf_hash_reset(vcpu);
6426 vcpu->arch.apf.halted = false; 5873 vcpu->arch.apf.halted = false;
6427 5874
5875 kvm_pmu_reset(vcpu);
5876
6428 return kvm_x86_ops->vcpu_reset(vcpu); 5877 return kvm_x86_ops->vcpu_reset(vcpu);
6429} 5878}
6430 5879
@@ -6473,10 +5922,6 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
6473 kvm = vcpu->kvm; 5922 kvm = vcpu->kvm;
6474 5923
6475 vcpu->arch.emulate_ctxt.ops = &emulate_ops; 5924 vcpu->arch.emulate_ctxt.ops = &emulate_ops;
6476 vcpu->arch.walk_mmu = &vcpu->arch.mmu;
6477 vcpu->arch.mmu.root_hpa = INVALID_PAGE;
6478 vcpu->arch.mmu.translate_gpa = translate_gpa;
6479 vcpu->arch.nested_mmu.translate_gpa = translate_nested_gpa;
6480 if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu)) 5925 if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))
6481 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; 5926 vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
6482 else 5927 else
@@ -6513,6 +5958,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
6513 goto fail_free_mce_banks; 5958 goto fail_free_mce_banks;
6514 5959
6515 kvm_async_pf_hash_reset(vcpu); 5960 kvm_async_pf_hash_reset(vcpu);
5961 kvm_pmu_init(vcpu);
6516 5962
6517 return 0; 5963 return 0;
6518fail_free_mce_banks: 5964fail_free_mce_banks:
@@ -6531,6 +5977,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
6531{ 5977{
6532 int idx; 5978 int idx;
6533 5979
5980 kvm_pmu_destroy(vcpu);
6534 kfree(vcpu->arch.mce_banks); 5981 kfree(vcpu->arch.mce_banks);
6535 kvm_free_lapic(vcpu); 5982 kvm_free_lapic(vcpu);
6536 idx = srcu_read_lock(&vcpu->kvm->srcu); 5983 idx = srcu_read_lock(&vcpu->kvm->srcu);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index d36fe237c66..cb80c293cdd 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -33,9 +33,6 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
33 return (nr == BP_VECTOR) || (nr == OF_VECTOR); 33 return (nr == BP_VECTOR) || (nr == OF_VECTOR);
34} 34}
35 35
36struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
37 u32 function, u32 index);
38
39static inline bool is_protmode(struct kvm_vcpu *vcpu) 36static inline bool is_protmode(struct kvm_vcpu *vcpu)
40{ 37{
41 return kvm_read_cr0_bits(vcpu, X86_CR0_PE); 38 return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
@@ -125,4 +122,6 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
125 gva_t addr, void *val, unsigned int bytes, 122 gva_t addr, void *val, unsigned int bytes,
126 struct x86_exception *exception); 123 struct x86_exception *exception);
127 124
125extern u64 host_xcr0;
126
128#endif 127#endif
diff --git a/arch/x86/platform/mrst/early_printk_mrst.c b/arch/x86/platform/mrst/early_printk_mrst.c
index 25bfdbb5b13..3c6e328483c 100644
--- a/arch/x86/platform/mrst/early_printk_mrst.c
+++ b/arch/x86/platform/mrst/early_printk_mrst.c
@@ -245,16 +245,24 @@ struct console early_mrst_console = {
245 * Following is the early console based on Medfield HSU (High 245 * Following is the early console based on Medfield HSU (High
246 * Speed UART) device. 246 * Speed UART) device.
247 */ 247 */
248#define HSU_PORT2_PADDR 0xffa28180 248#define HSU_PORT_BASE 0xffa28080
249 249
250static void __iomem *phsu; 250static void __iomem *phsu;
251 251
252void hsu_early_console_init(void) 252void hsu_early_console_init(const char *s)
253{ 253{
254 unsigned long paddr, port = 0;
254 u8 lcr; 255 u8 lcr;
255 256
256 phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, 257 /*
257 HSU_PORT2_PADDR); 258 * Select the early HSU console port if specified by user in the
259 * kernel command line.
260 */
261 if (*s && !kstrtoul(s, 10, &port))
262 port = clamp_val(port, 0, 2);
263
264 paddr = HSU_PORT_BASE + port * 0x80;
265 phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr);
258 266
259 /* Disable FIFO */ 267 /* Disable FIFO */
260 writeb(0x0, phsu + UART_FCR); 268 writeb(0x0, phsu + UART_FCR);
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 26c731a106a..fdce49c7aff 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -29,7 +29,8 @@ config XEN_PVHVM
29 29
30config XEN_MAX_DOMAIN_MEMORY 30config XEN_MAX_DOMAIN_MEMORY
31 int 31 int
32 default 128 32 default 500 if X86_64
33 default 64 if X86_32
33 depends on XEN 34 depends on XEN
34 help 35 help
35 This only affects the sizing of some bss arrays, the unused 36 This only affects the sizing of some bss arrays, the unused
@@ -48,3 +49,4 @@ config XEN_DEBUG_FS
48 help 49 help
49 Enable statistics output and various tuning options in debugfs. 50 Enable statistics output and various tuning options in debugfs.
50 Enabling this option may incur a significant performance overhead. 51 Enabling this option may incur a significant performance overhead.
52
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 5a40d24ba33..3a5f55d5190 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -54,6 +54,20 @@ static int map_pte_fn(pte_t *pte, struct page *pmd_page,
54 return 0; 54 return 0;
55} 55}
56 56
57/*
58 * This function is used to map shared frames to store grant status. It is
59 * different from map_pte_fn above, the frames type here is uint64_t.
60 */
61static int map_pte_fn_status(pte_t *pte, struct page *pmd_page,
62 unsigned long addr, void *data)
63{
64 uint64_t **frames = (uint64_t **)data;
65
66 set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
67 (*frames)++;
68 return 0;
69}
70
57static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, 71static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
58 unsigned long addr, void *data) 72 unsigned long addr, void *data)
59{ 73{
@@ -64,10 +78,10 @@ static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
64 78
65int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, 79int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
66 unsigned long max_nr_gframes, 80 unsigned long max_nr_gframes,
67 struct grant_entry **__shared) 81 void **__shared)
68{ 82{
69 int rc; 83 int rc;
70 struct grant_entry *shared = *__shared; 84 void *shared = *__shared;
71 85
72 if (shared == NULL) { 86 if (shared == NULL) {
73 struct vm_struct *area = 87 struct vm_struct *area =
@@ -83,8 +97,30 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
83 return rc; 97 return rc;
84} 98}
85 99
86void arch_gnttab_unmap_shared(struct grant_entry *shared, 100int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
87 unsigned long nr_gframes) 101 unsigned long max_nr_gframes,
102 grant_status_t **__shared)
103{
104 int rc;
105 grant_status_t *shared = *__shared;
106
107 if (shared == NULL) {
108 /* No need to pass in PTE as we are going to do it
109 * in apply_to_page_range anyhow. */
110 struct vm_struct *area =
111 alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
112 BUG_ON(area == NULL);
113 shared = area->addr;
114 *__shared = shared;
115 }
116
117 rc = apply_to_page_range(&init_mm, (unsigned long)shared,
118 PAGE_SIZE * nr_gframes,
119 map_pte_fn_status, &frames);
120 return rc;
121}
122
123void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
88{ 124{
89 apply_to_page_range(&init_mm, (unsigned long)shared, 125 apply_to_page_range(&init_mm, (unsigned long)shared,
90 PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); 126 PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index f4bf8aa574f..58a0e46c404 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1852,7 +1852,7 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
1852 xen_write_cr3(__pa(initial_page_table)); 1852 xen_write_cr3(__pa(initial_page_table));
1853 1853
1854 memblock_reserve(__pa(xen_start_info->pt_base), 1854 memblock_reserve(__pa(xen_start_info->pt_base),
1855 xen_start_info->nr_pt_frames * PAGE_SIZE)); 1855 xen_start_info->nr_pt_frames * PAGE_SIZE);
1856 1856
1857 return initial_page_table; 1857 return initial_page_table;
1858} 1858}